You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Captured responses live in per-connection temp tables that vanish with the
test's rollback and connection close — impossible to examine in a query
editor afterwards, and re-issuing the request from an .http file cannot
reproduce a response that depended on the test's uncommitted transactional
fixtures.
New setting ResponseTempTable.DebugTable (default null = off): when set
(e.g. "_responses_debug"), every captured response is ALSO mirrored into a
PERMANENT table with that name, written on a separate autocommit pooled
connection — immune to rollbacks and connection closes, append-only so
parallel test files cannot collide. The temp-table semantics (assertions,
naming, transactions) are completely unchanged.
ONE table covers the whole run: each HTTP block adds one row with
captured_at, test_file, block (that block's response-table name — Name, a
MultiNamePattern ordinal, or the # @response name), method, path, status,
body, content_type, headers, is_success. Recreated at the start of every
run, so it always holds the LAST run. Enabling it prints a loud warning
(debugging aid — do not enable in CI); mirror inserts are best-effort (a
failure logs a warning, never fails the test). In the fresh-test-database
workflow combine with Keep, or teardown drops the database and mirror.
Note: the naive alternative ("Permanent": true on the response table) was
rejected — parallel tests would collide on one permanent name, and CREATE
TABLE is transactional, so the rollback would erase the table exactly when
it was needed.
Config synced (appsettings.json, ConfigTemplate.cs, ConfigDefaults.cs,
ConfigSchemaGenerator.cs). Full suite green (2394). Live-verified on
example 19: all three block-naming schemes distinguishable in one query,
including the response body of a rolled-back fixture; rerun leaves exactly
the last run's rows. Changelog + docs updated.
Copy file name to clipboardExpand all lines: NpgsqlRestClient/ConfigSchemaGenerator.cs
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -266,6 +266,7 @@ public static partial class ConfigSchemaGenerator
266
266
["TestRunner:LoggerName"]="SourceContext name for the runner's own log channel; set its level independently under Log:MinimalLevels (defaults to Information).\nDiscovery/parsing log at Debug, each query and HTTP invocation at Verbose, `raise notice` by severity. The console PASS/FAIL report is separate.",
267
267
["TestRunner:ResponseTempTable:Name"]="Temp table name used when a test file has exactly ONE HTTP block.\nEach HTTP block gets its own fresh temp table (created without IF NOT EXISTS, so a duplicate name fails the test); writes are pg_temp-qualified. Per-block override: `# @response <name>`.",
268
268
["TestRunner:ResponseTempTable:MultiNamePattern"]="Temp table name pattern used when a test file has 2+ HTTP blocks.\n{n} is the 1-based block ordinal, e.g. \"_response_{n}\" => _response_1, _response_2, …",
269
+
["TestRunner:ResponseTempTable:DebugTable"]="Debugging aid: when set (e.g. \"_responses_debug\"), every captured response is ALSO mirrored into a PERMANENT table with this name — written on a separate autocommit connection, so it survives the test's rollback and connection close and can be examined in a query editor after the run.\nRecreated at the start of every run (holds the LAST run). ONE table covers everything: each HTTP block adds one row, with the block column recording that block's response-table name (Name, MultiNamePattern ordinal, or the # @response name) alongside test_file, method, path, status, body, content_type, headers, is_success, captured_at. Temp-table semantics unchanged. Do not enable in CI. Null (default) = off.",
269
270
["TestRunner:ResponseTempTable:Columns"]="Maps each response component to a column name. A null or empty name omits that column.",
270
271
["TestRunner:Steps"]="Named, reusable steps (name → step; same shape as Setup/Teardown entries). Reference them by name in Setup/Teardown, or from an individual test file's leading header comments:\n-- @setup StepName [StepName ...] (runs before that file); -- @teardown StepName [StepName ...] (runs after that file, always, best-effort); -- @connection Name (runs that file on a named ConnectionStrings entry).\nAnnotations are repeatable; names may be whitespace- or comma-separated and run in the order written.\nTest files can also reuse SQL scripts in place with psql-style includes: `\\i file` (cwd-relative) or `\\ir file` (relative to the including file) — executed on the test's connection, inside its transaction.",
271
272
["TestRunner:Setup"]="Run-once setup, BEFORE endpoint discovery. Steps run in the EXACT order written.\nEach entry is a step NAME from \"Steps\", or an inline object: { \"Command\": \"...\", \"WorkingDirectory\": \"...\" } (OS shell); { \"Sql\": \"...\" } | { \"SqlFile\": \"...\" } which run on the test connection, or set \"ConnectionName\" to run on another ConnectionStrings entry (e.g. an admin connection that runs `create database`).",
thrownewInvalidOperationException($"invalid ResponseTempTable.DebugTable name '{table}'");
970
+
}
971
+
if(_debugTableWarnedisfalse)
972
+
{
973
+
_debugTableWarned=true;
974
+
_out.Line($"WARNING: ResponseTempTable.DebugTable is enabled — every captured response is written to the PERMANENT table \"{table}\" (debugging aid; do not enable in CI)",ConsoleColor.Yellow);
975
+
_log?.LogWarning("ResponseTempTable.DebugTable enabled: mirroring responses into permanent table {Table}",table);
**Debugging captured responses** — temp tables vanish with the test's rollback and connection, so you cannot inspect them afterwards (and re-issuing the request from an `.http` file cannot reproduce a response that depended on the test's uncommitted fixtures). Set **`ResponseTempTable.DebugTable`** (e.g. `"_responses_debug"`; default `null` = off) and every captured response is **also mirrored into a permanent table** — written on a separate autocommit connection, immune to rollbacks, recreated at the start of every run so it always holds the last run. One table covers everything: each HTTP block adds one row, with `test_file`, `block` (that block's response-table name — `_response`, a `_response_{n}` ordinal, or the `# @response` name), `method`, `path`, `status`, `body`, `content_type`, `headers`, `is_success`, and `captured_at` — so after a run you can open a query editor and dig into any response with jsonb operators. The temp-table semantics are unchanged; enabling it prints a loud warning (debugging aid — do not enable in CI). In the fresh-test-database workflow combine it with `Keep: true`, or teardown drops the database and the mirror with it.
127
+
126
128
### Reusing scripts: `\i` and `\ir` includes
127
129
128
130
Shared SQL — fixture inserts, utility scripts — can be spliced into any test with psql's include syntax on its own line:
@@ -287,6 +289,7 @@ The runner logs through its own channel — **`NpgsqlRestTest`** (configurable v
287
289
"ResponseTempTable": {
288
290
"Name":"_response", // table name when a file has ONE HTTP block
289
291
"MultiNamePattern":"_response_{n}",// name pattern for 2+ blocks; {n} = 1-based block position
292
+
"DebugTable":null, // debugging aid: ALSO mirror every response into this PERMANENT table (survives rollback; last run; not for CI)
0 commit comments