The load-bearing invariant: a failed CREATE SECRET must NOT leak its credential into the Errors-page ring — neither via the stored query nor the error message (engine errors echo the offending SQL). logQueryError redacts both at capture.
(t *testing.T)
| 45 | // into the Errors-page ring — neither via the stored query nor the error message |
| 46 | // (engine errors echo the offending SQL). logQueryError redacts both at capture. |
| 47 | func TestLogQueryErrorCapturesRedactedSecret(t *testing.T) { |
| 48 | installFakeQueryTracker(t) |
| 49 | s := &Server{recentErrors: newRecentErrorRing(0)} |
| 50 | c := &clientConn{server: s, orgID: "acme", username: "root", pid: 1000, workerID: 42, ctx: context.Background()} |
| 51 | |
| 52 | const cred = "topsecretAKIA" |
| 53 | query := "CREATE SECRET s (TYPE S3, KEY_ID 'AKIAEXAMPLE', SECRET '" + cred + "')" |
| 54 | // DuckDB echoes the offending SQL (incl. the literal) in its error text. |
| 55 | engineErr := errors.New("Parser Error: syntax error at or near \"" + cred + "\"\nLINE 1: " + query) |
| 56 | |
| 57 | c.logQueryError(query, engineErr) |
| 58 | |
| 59 | got := s.RecentErrors(10) |
| 60 | if len(got) != 1 { |
| 61 | t.Fatalf("ring len = %d, want 1", len(got)) |
| 62 | } |
| 63 | e := got[0] |
| 64 | if strings.Contains(e.Query, cred) { |
| 65 | t.Errorf("stored Query leaks credential: %q", e.Query) |
| 66 | } |
| 67 | if strings.Contains(e.Message, cred) { |
| 68 | t.Errorf("stored Message leaks credential: %q", e.Message) |
| 69 | } |
| 70 | if e.OrgID != "acme" || e.Username != "root" || e.WorkerID != 42 || e.PID != 1000 { |
| 71 | t.Errorf("metadata not captured: %+v", e) |
| 72 | } |
| 73 | // A syntax error is user-attributable (42601); the point of this test is the |
| 74 | // redaction above — just assert classification was captured. |
| 75 | if e.Category == "" || e.SQLState == "" { |
| 76 | t.Errorf("classification missing: category=%q sqlstate=%q", e.Category, e.SQLState) |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | // A non-secret query is stored verbatim (redaction is a no-op) so triage keeps |
| 81 | // full fidelity for ordinary errors. |
nothing calls this directly
no test coverage detected