Files
mats 2cf2cebf5c
Build and Publish / Metadata (push) Successful in 10s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 2m15s
fix
2026-09-20 11:39:20 +02:00

57 lines
2.7 KiB
Go

package triage
import "testing"
func TestClassify(t *testing.T) {
cases := []struct {
name string
in Input
want Category
}{
{"wp 500 is a probe not an outage", Input{Status: 500, Route: "/wp"}, ScannerProbe},
{"php 405 is a probe", Input{Status: 405, Route: "/index.php"}, ScannerProbe},
{"ses.env", Input{Status: 404, Route: "/ses.env"}, ScannerProbe},
{"yaml config 302", Input{Status: 302, Route: "/config/aws.yml"}, ScannerProbe},
{"traversal", Input{Status: 404, Route: "/api/w/admins/get_log_file/../../../../proc/self/environ"}, ScannerProbe},
{"credentials file", Input{Status: 404, Route: "/firebase-credentials.json"}, ScannerProbe},
{"matrix rooms is not OOM", Input{Status: 200, Route: "/_matrix/client/r0/rooms/x/messages"}, ExpectedLifecycle},
{"real api 404 stays stale", Input{Status: 404, Route: "/api/config"}, StaleReference},
{"env 404", Input{Status: 404, Route: "/.env"}, ScannerProbe},
{"git config 502", Input{Status: 502, Route: "/.git/config"}, ScannerProbe},
{"poller 401", Input{Status: 401, Route: "/api/repos/available"}, ClientCredentialIssue},
{"upstream 503", Input{Status: 503, Route: "/store/regions"}, DependencyUnreachable},
{"real 500", Input{Status: 500, Route: "/"}, ServiceDefect},
{"panic in message", Input{Message: "panic: nil pointer dereference"}, ServiceDefect},
{"timeout flag", Input{IsTimeout: true, Message: "query"}, CapacitySaturation},
{"dial error", Input{Message: "*websocket.dialerror: connection refused"}, DependencyUnreachable},
{"missing commit", Input{Status: 404, Route: "/mats/repo/commit/{id}"}, StaleReference},
{"cancellation", Input{IsCancellation: true, Message: "context canceled"}, ExpectedLifecycle},
{"health", Input{Kind: "span", Status: 200, Route: "/readyz"}, ExpectedLifecycle},
{"unknown", Input{Kind: "metric", Status: 418}, NeedsReview},
}
for _, c := range cases {
if got := Classify(c.in); got.Category != c.want {
t.Errorf("%s: got %s (%s), want %s", c.name, got.Category, got.Rule, c.want)
}
}
}
func TestProbeBeatsLifecycleFlags(t *testing.T) {
if got := Classify(Input{Route: "/.env", IsRetry: true}); got.Category != ScannerProbe {
t.Fatalf("got %s", got.Category)
}
}
func TestAIToolConfigPathsAreProbes(t *testing.T) {
for _, p := range []string{"/.cursorrules", "/.codex/auth.json", "/backup/.claude/credentials.json", "/.windsurfrules", "/.vscode/launch.json", "/.idea/WebServers.xml", "/x/.github/copilot-instructions.md", "/CLAUDE.md", "/mcp.json", "/.clinerules"} {
if !IsProbePath(p) {
t.Errorf("%s should be a probe", p)
}
}
for _, p := range []string{"/mcp", "/api/agents", "/api/sessions/{id}", "/api/continue"} {
if IsProbePath(p) {
t.Errorf("%s must not be a probe", p)
}
}
}