package metrics import ( "strings" "testing" ) // Part E — sanitization. Red-proof: gutting RedactLine (return s unchanged) must fail // every case here with the secret visible in the failure message. func TestRedactLine_SpecPatterns(t *testing.T) { in := "password=hunter2 token: abc Bearer xyz" got := RedactLine(in) want := "password=[REDACTED] token: [REDACTED] Bearer [REDACTED]" if got != want { t.Fatalf("RedactLine(%q) = %q, want %q", in, got, want) } for _, secret := range []string{"hunter2", "abc", "xyz"} { if strings.Contains(got, secret) { t.Fatalf("secret %q shipped: %q", secret, got) } } } func TestRedactLine_Hex64(t *testing.T) { hex64 := strings.Repeat("ab12", 16) // 64 hex chars — restic repo password shape in := "repo unlock with " + hex64 + " done" got := RedactLine(in) if strings.Contains(got, hex64) { t.Fatalf("64-hex secret shipped: %q", got) } if !strings.Contains(got, "[REDACTED-HEX64]") { t.Fatalf("expected [REDACTED-HEX64] marker, got %q", got) } } func TestRedactLine_Variants(t *testing.T) { cases := []struct{ in, want string }{ {"authorization: Bearer eyJhbGciOi.payload.sig", "authorization: [REDACTED]"}, {"api_key=sk-live-123", "api_key=[REDACTED]"}, {"API-KEY: verysecret", "API-KEY: [REDACTED]"}, {"apikey=whatever", "apikey=[REDACTED]"}, {"PASSWD: root123", "PASSWD: [REDACTED]"}, {"client secret=s3cr3t", "client secret=[REDACTED]"}, } for _, c := range cases { if got := RedactLine(c.in); got != c.want { t.Errorf("RedactLine(%q) = %q, want %q", c.in, got, c.want) } } } // Benign lines must pass through byte-identical — support usefulness over aggression. func TestRedactLine_BenignUntouched(t *testing.T) { cases := []string{ "connection refused to 10.0.0.5:5432", "GET /api/keys 200 12ms", // "api/keys" is not "api_key" "tokenizer initialized in 40ms", // "token" not followed by separator+value "ERROR: NFS mount /mnt/media gone", // the CWA shape — must stay readable "deadbeef", // short hex, not 64 } for _, c := range cases { if got := RedactLine(c); got != c { t.Errorf("benign line mangled: %q -> %q", c, got) } } }