MCPcopy Create free account
hub / github.com/github/gh-aw / TestParseEventsJSONLFile_TBT

Function TestParseEventsJSONLFile_TBT

pkg/cli/copilot_events_jsonl_test.go:291–350  ·  view source on GitHub ↗

TestParseEventsJSONLFile_TBT verifies that Time Between Turns is computed correctly from per-turn timestamps embedded in user.message events.

(t *testing.T)

Source from the content-addressed store, hash-verified

289// TestParseEventsJSONLFile_TBT verifies that Time Between Turns is computed
290// correctly from per-turn timestamps embedded in user.message events.
291func TestParseEventsJSONLFile_TBT(t *testing.T) {
292 // Helper that produces an events.jsonl line with a specific RFC3339 timestamp.
293 lineWithTimestamp := func(eventType, dataJSON, timestamp string) string {
294 return `{"type":"` + eventType + `","data":` + dataJSON + `,"id":"test-id","timestamp":"` + timestamp + `"}`
295 }
296
297 t.Run("computes avg and max TBT from multi-turn timestamps", func(t *testing.T) {
298 // Turn 1 at T+0s, Turn 2 at T+30s, Turn 3 at T+90s → intervals: 30s, 60s → avg 45s, max 60s
299 content := lineWithTimestamp("session.start", `{"sessionId":"s1","copilotVersion":"1.0.0"}`, "2026-01-01T10:00:00Z") + "\n" +
300 lineWithTimestamp("user.message", `{"content":"turn 1"}`, "2026-01-01T10:00:00Z") + "\n" +
301 lineWithTimestamp("user.message", `{"content":"turn 2"}`, "2026-01-01T10:00:30Z") + "\n" +
302 lineWithTimestamp("user.message", `{"content":"turn 3"}`, "2026-01-01T10:01:30Z") + "\n" +
303 lineWithTimestamp("session.shutdown", `{"shutdownType":"routine","modelMetrics":{"m":{"usage":{"inputTokens":100,"outputTokens":10}}}}`, "2026-01-01T10:02:00Z") + "\n"
304
305 dir := t.TempDir()
306 eventsPath := filepath.Join(dir, "events.jsonl")
307 require.NoError(t, os.WriteFile(eventsPath, []byte(content), 0644))
308
309 metrics, err := parseEventsJSONLMetrics(eventsPath, false)
310 require.NoError(t, err, "should parse without error")
311
312 assert.Equal(t, 3, metrics.Turns, "should detect 3 turns")
313 assert.Equal(t, 45*time.Second, metrics.AvgTimeBetweenTurns, "avg TBT should be 45s")
314 assert.Equal(t, 60*time.Second, metrics.MaxTimeBetweenTurns, "max TBT should be 60s")
315 })
316
317 t.Run("no TBT when only one turn", func(t *testing.T) {
318 content := lineWithTimestamp("user.message", `{"content":"single turn"}`, "2026-01-01T10:00:00Z") + "\n" +
319 lineWithTimestamp("session.shutdown", `{"shutdownType":"routine","modelMetrics":{"m":{"usage":{"inputTokens":50,"outputTokens":5}}}}`, "2026-01-01T10:01:00Z") + "\n"
320
321 dir := t.TempDir()
322 eventsPath := filepath.Join(dir, "events.jsonl")
323 require.NoError(t, os.WriteFile(eventsPath, []byte(content), 0644))
324
325 metrics, err := parseEventsJSONLMetrics(eventsPath, false)
326 require.NoError(t, err, "should parse without error")
327
328 assert.Equal(t, 1, metrics.Turns, "should detect 1 turn")
329 assert.Zero(t, metrics.AvgTimeBetweenTurns, "no TBT with a single turn")
330 assert.Zero(t, metrics.MaxTimeBetweenTurns, "no TBT with a single turn")
331 })
332
333 t.Run("no TBT when all timestamps are identical", func(t *testing.T) {
334 // Use realFormatEventsLine which always uses the same timestamp — no intervals.
335 content := realFormatEventsLine("user.message", `{"content":"turn 1"}`) + "\n" +
336 realFormatEventsLine("user.message", `{"content":"turn 2"}`) + "\n" +
337 realFormatEventsLine("session.shutdown", `{"shutdownType":"routine","modelMetrics":{"m":{"usage":{"inputTokens":50,"outputTokens":5}}}}`) + "\n"
338
339 dir := t.TempDir()
340 eventsPath := filepath.Join(dir, "events.jsonl")
341 require.NoError(t, os.WriteFile(eventsPath, []byte(content), 0644))
342
343 metrics, err := parseEventsJSONLMetrics(eventsPath, false)
344 require.NoError(t, err, "should parse without error")
345
346 assert.Equal(t, 2, metrics.Turns, "should detect 2 turns")
347 // All user.message events share the same timestamp → interval is 0 → TBT stays zero.
348 assert.Zero(t, metrics.AvgTimeBetweenTurns, "TBT should be zero when all timestamps are identical")

Callers

nothing calls this directly

Calls 3

parseEventsJSONLMetricsFunction · 0.85
realFormatEventsLineFunction · 0.85
RunMethod · 0.45

Tested by

no test coverage detected