(t *testing.T)
| 95 | } |
| 96 | |
| 97 | func TestRedactErrorForLog(t *testing.T) { |
| 98 | // A DuckDB-style error that echoes the offending SQL verbatim, including |
| 99 | // the credential literal — the exact leak this guards. |
| 100 | secretErr := "Parser Error: syntax error at or near \"BOGUS\"\n" + |
| 101 | "LINE 1: ... (TYPE s3, KEY_ID 'AKIABAD', SECRET '" + secretLiteral + "' BOGUS)" |
| 102 | |
| 103 | tests := []struct { |
| 104 | name string |
| 105 | query string |
| 106 | errMsg string |
| 107 | // want is the exact output; if empty, only assert the literal is gone. |
| 108 | want string |
| 109 | }{ |
| 110 | { |
| 111 | name: "empty error passes through", |
| 112 | query: "CREATE SECRET foo (TYPE s3, SECRET '" + secretLiteral + "')", |
| 113 | errMsg: "", |
| 114 | want: "", |
| 115 | }, |
| 116 | { |
| 117 | name: "non-secret query keeps its error verbatim", |
| 118 | query: "SELECT * FROM missing", |
| 119 | errMsg: "Catalog Error: Table with name missing does not exist", |
| 120 | want: "Catalog Error: Table with name missing does not exist", |
| 121 | }, |
| 122 | { |
| 123 | name: "secret-head query redacts error echoing the literal", |
| 124 | query: "CREATE SECRET foo (TYPE s3, KEY_ID 'AKIABAD', SECRET '" + secretLiteral + "' BOGUS)", |
| 125 | errMsg: secretErr, |
| 126 | want: redactedErrorPlaceholder, |
| 127 | }, |
| 128 | { |
| 129 | name: "non-leading secret DDL redacts error", |
| 130 | query: "SELECT 1; CREATE PERSISTENT SECRET foo (TYPE s3, SECRET '" + secretLiteral + "')", |
| 131 | errMsg: secretErr, |
| 132 | want: redactedErrorPlaceholder, |
| 133 | }, |
| 134 | { |
| 135 | name: "drop secret error passes through (no credential material)", |
| 136 | query: "DROP PERSISTENT SECRET foo", |
| 137 | errMsg: "Invalid Input Error: secret foo not found", |
| 138 | want: "Invalid Input Error: secret foo not found", |
| 139 | }, |
| 140 | } |
| 141 | |
| 142 | for _, tt := range tests { |
| 143 | t.Run(tt.name, func(t *testing.T) { |
| 144 | got := RedactErrorForLog(tt.query, tt.errMsg) |
| 145 | if tt.want != "" && got != tt.want { |
| 146 | t.Fatalf("RedactErrorForLog(%q, %q) = %q, want %q", tt.query, tt.errMsg, got, tt.want) |
| 147 | } |
| 148 | if tt.want == "" && got != "" { |
| 149 | t.Fatalf("RedactErrorForLog(%q, \"\") = %q, want empty", tt.query, got) |
| 150 | } |
| 151 | if strings.Contains(got, secretLiteral) { |
| 152 | t.Fatalf("secret literal leaked in redacted error: %q", got) |
| 153 | } |
| 154 | }) |
nothing calls this directly
no test coverage detected