TestParseEventsJSONLFile_TBT verifies that Time Between Turns is computed correctly from per-turn timestamps embedded in user.message events.
(t *testing.T)
| 289 | // TestParseEventsJSONLFile_TBT verifies that Time Between Turns is computed |
| 290 | // correctly from per-turn timestamps embedded in user.message events. |
| 291 | func 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") |
nothing calls this directly
no test coverage detected