(t *testing.T)
| 382 | } |
| 383 | |
| 384 | func TestAnalyzeTokenUsage(t *testing.T) { |
| 385 | t.Run("returns nil when no file found", func(t *testing.T) { |
| 386 | tmpDir := testutil.TempDir(t, "analyze-token-usage") |
| 387 | summary, err := analyzeTokenUsage(tmpDir, false) |
| 388 | require.NoError(t, err, "should not error when file not found") |
| 389 | assert.Nil(t, summary, "should return nil when no file found") |
| 390 | }) |
| 391 | |
| 392 | t.Run("parses file from sandbox path", func(t *testing.T) { |
| 393 | tmpDir := testutil.TempDir(t, "analyze-token-usage") |
| 394 | logsDir := filepath.Join(tmpDir, "sandbox", "firewall", "logs", "api-proxy-logs") |
| 395 | require.NoError(t, os.MkdirAll(logsDir, 0o755)) |
| 396 | tokenFile := filepath.Join(logsDir, "token-usage.jsonl") |
| 397 | content := `{"timestamp":"2026-04-01T17:56:38.042Z","request_id":"1","provider":"anthropic","model":"claude-sonnet-4-6","path":"/v1/messages","status":200,"streaming":true,"input_tokens":100,"output_tokens":200,"cache_read_tokens":5000,"cache_write_tokens":3000,"duration_ms":2500,"response_bytes":1500}` |
| 398 | require.NoError(t, os.WriteFile(tokenFile, []byte(content+"\n"), 0o644)) |
| 399 | |
| 400 | summary, err := analyzeTokenUsage(tmpDir, false) |
| 401 | require.NoError(t, err, "should parse without error") |
| 402 | require.NotNil(t, summary, "should return summary") |
| 403 | assert.Equal(t, 1, summary.TotalRequests, "should have 1 request") |
| 404 | assert.Equal(t, 100, summary.TotalInputTokens, "should have correct input tokens") |
| 405 | assert.InDelta(t, 1.575, summary.TotalAIC, 1e-9, "should compute AI Credits from model pricing") |
| 406 | }) |
| 407 | |
| 408 | t.Run("counts steering events from api-proxy events log", func(t *testing.T) { |
| 409 | tmpDir := testutil.TempDir(t, "analyze-token-steering-events") |
| 410 | logsDir := filepath.Join(tmpDir, "sandbox", "firewall", "logs", "api-proxy-logs") |
| 411 | require.NoError(t, os.MkdirAll(logsDir, 0o755)) |
| 412 | tokenFile := filepath.Join(logsDir, "token-usage.jsonl") |
| 413 | tokenContent := `{"timestamp":"2026-04-01T17:56:38.042Z","request_id":"1","provider":"anthropic","model":"claude-sonnet-4-6","path":"/v1/messages","status":200,"streaming":true,"input_tokens":100,"output_tokens":200,"cache_read_tokens":5000,"cache_write_tokens":3000,"duration_ms":2500,"response_bytes":1500}` |
| 414 | require.NoError(t, os.WriteFile(tokenFile, []byte(tokenContent+"\n"), 0o644)) |
| 415 | |
| 416 | eventsFile := filepath.Join(logsDir, "events.jsonl") |
| 417 | eventsContent := strings.Join([]string{ |
| 418 | `{"event":"token_steering","message":"[AWF TOKEN WARNING] You have used 80% of your effective token budget. Begin planning to wrap up your current work."}`, |
| 419 | `{"type":"token_steering","message":"[AWF TOKEN WARNING] You have used 90% of your effective token budget. Complete your current task and prepare final output."}`, |
| 420 | `{"event_name":"timeout_steering","message":"[AWF TIME WARNING] You have used 80% of your allotted run time. Begin planning to wrap up your current work."}`, |
| 421 | `{"eventName":"timeout_steering","message":"[AWF TIME WARNING] You have used 90% of your allotted run time. Complete your current task and prepare final output."}`, |
| 422 | `{"event":"request.forwarded"}`, |
| 423 | `{"event":"token_steering","message":"warn 95%"}`, |
| 424 | `{"event":"budget_steering","message":"[AWF TOKEN WARNING] non-spec event name"}`, |
| 425 | }, "\n") |
| 426 | require.NoError(t, os.WriteFile(eventsFile, []byte(eventsContent+"\n"), 0o644)) |
| 427 | |
| 428 | summary, err := analyzeTokenUsage(tmpDir, false) |
| 429 | require.NoError(t, err) |
| 430 | require.NotNil(t, summary) |
| 431 | assert.Equal(t, 4, summary.TotalSteeringEvents, "should count spec-compliant steering events from api-proxy events.jsonl") |
| 432 | }) |
| 433 | |
| 434 | t.Run("counts steering events from legacy firewall-audit-logs events file", func(t *testing.T) { |
| 435 | tmpDir := testutil.TempDir(t, "analyze-token-steering-events-legacy") |
| 436 | logsDir := filepath.Join(tmpDir, "firewall-audit-logs", "api-proxy-logs") |
| 437 | require.NoError(t, os.MkdirAll(logsDir, 0o755)) |
| 438 | tokenFile := filepath.Join(logsDir, "token-usage.jsonl") |
| 439 | tokenContent := `{"timestamp":"2026-04-01T17:56:38.042Z","request_id":"1","provider":"anthropic","model":"claude-sonnet-4-6","path":"/v1/messages","status":200,"streaming":true,"input_tokens":100,"output_tokens":200,"cache_read_tokens":5000,"cache_write_tokens":3000,"duration_ms":2500,"response_bytes":1500}` |
| 440 | require.NoError(t, os.WriteFile(tokenFile, []byte(tokenContent+"\n"), 0o644)) |
| 441 |
nothing calls this directly
no test coverage detected