Add fresh/update/existing-mode extension test infrastructure - #18
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
9815294 to
dd00649
Compare
d6e9f75 to
500d867
Compare
|
Claude finished @jnasbyupgrade's task in 6m 11s —— View job Claude's Review of PR #18Tasks
Reviewed this diff against SummaryThis is a careful, well-scoped PR. I cross-checked the highest-risk piece —
The moved FindingsNone. No correctness, security, or maintainability issues found in this diff. The scope is honestly and precisely bounded to what the PR description claims (local test/Makefile machinery only, CI wiring for |
500d867 to
204b288
Compare
|
Claude finished @jnasbyupgrade's task in 2m 19s —— View job Claude's Review of PR #18 (re-run after synchronize)Tasks
Reviewed against
No issues found in this delta. CI is green on both PostgreSQL matrix legs for the current head commit. |
204b288 to
b01fa75
Compare
|
Claude finished @jnasbyupgrade's task in 1m 0s —— View job Claude's Review of PR #18 (re-run after synchronize)Tasks
Reviewed against
CI is green on both PostgreSQL matrix legs for the current head commit. No new issues found. SummaryNo outstanding findings across the full stack of reviews on this PR. The diff remains a careful, well-scoped implementation of |
b01fa75 to
4a37b00
Compare
|
Claude finished @jnasbyupgrade's task in 3m 19s —— View job Claude's Code Review of PR #18Ran the Tasks
Scope of this passThree prior reviews already exist in this thread covering everything through commit
Verified by hand:
FindingsNone. This commit closes a real gap the PR's own tooling was built to catch, is scoped correctly, and the full 0.1.0-vs-current diff cross-check turned up no other missed cases of the same bug class. |
4a37b00 to
82818b4
Compare
|
Claude finished @jnasbyupgrade's task in 2m 23s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Reviewed against Tasks
Scope of this passFour prior reviews in this thread already cover everything through commit
The commit message claims this mirrors
CI is green on both PostgreSQL matrix legs for the current head commit ( FindingsNone. This commit is a correct, well-verified generalization of the same session-setting-ownership principle already applied to the fresh-install script on the base branch, and the apparent gap (no relocated suppression for the update path) turns out to already be covered by pre-existing code in |
…ript, test/install/load.sql three-mode loader, dependency-guard anchor, and a permanent schema-qualification pgTAP assertion Implements advanced-extension-testing.md checklist items 1-6 on top of PR #17 (reconcile-object-functions): - PGXNTOOL_ENABLE_TEST_INSTALL / PGXNTOOL_ENABLE_VERIFY_RESULTS set explicitly; TEST_LOAD_SOURCE (fresh/update/existing) + TEST_UPDATE_FROM/TO make vars, parse-time validated, propagated as placeholder GUCs via PGOPTIONS; `make test-update` wrapper. - test/install/load.sql: single committed-once installer for the extension, covering all three load modes, including a drop-first reset (with pg_temp.drop_role() for the extension's own global roles) and an existing-mode presence/version assertion. - sql/object_reference--0.1.0--stable.sql: hand-authored update script (there was previously no update path at all from the only real historical release to current). Recreates every function/view that changed via the same private-helper-schema bootstrap/teardown convention the fresh install uses, so the update path is verified byte-for-byte structurally identical to a fresh install (function bodies, comments, ACLs, table/view columns). - Makefile: DATA += sql/object_reference--0.1.0.sql (pgxntool#48 workaround, needed for CREATE EXTENSION ... VERSION '0.1.0' to work at all); a conditional count_nulls install step for the update-mode floor only (0.1.0's own install script still needs it, even though current object_reference no longer requires it). - test/finish.sql: one permanent pgTAP assertion (modeled on pg_count_nulls'/extension_tools' own schema-qualification checks) proving object_reference/_object_reference are never resolved via search_path. - Moved the pre-existing raw-source-load sanity check (test/sql/zzz_build.sql) to test/build/, pgxntool's own test-build feature: it needs a schema-free database to create `object_reference` manually in, which the committed-once installer above no longer provides in the shared main-suite database. Dependency-guard anchor for a future existing-mode CI job: a view typed on _object_reference.object's row type (object_reference-owned, never dropped or redefined by the update script) blocks a non-CASCADE DROP EXTENSION; manually proven to block the drop (and to keep blocking it after the update path) as part of this PR's own verification, not committed as CI machinery yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
test/build/zzz_build.sql (moved there in the previous commit) enables pgxntool's test-build feature, whose run-test-build.sh syncs test/build/*.sql into test/build/sql/ via rsync -- not present in the pgxn/pgxn-tools image, causing every PG-matrix leg to fail with "rsync: command not found". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
0.1.0 and stable are byte-identical for this function's body once the linter's annotation (PR #16's own, separate content) isn't part of this branch -- the CREATE OR REPLACE was a no-op here. Verified via bin/test_existing's structural diff (clean) and a full local run (7/7 pgTAP files, dump/restore, test-build).
Same stale 1..29 header issue as u-and-u-extension-update-ci: picked up the corrected plan count from reconcile-object-functions but not the regenerated total including this branch's own schema-qualification assertion (test 30). Regenerated via make results, not hand-edited. Co-Authored-By: Claude <noreply@anthropic.com>
Mirrors reconcile-object-functions' fresh-install changes in this hand-authored 0.1.0->stable update script: - object_oid is dropped (not backfilled+kept) alongside the reg* columns it used to collapse -- with no reg* columns left after this update, it's pure redundant storage of objid. objid_must_match and the two view recreations' object_oid passthrough go with it. - SET LOCAL client_min_messages, not plain SET -- this script runs inside ALTER EXTENSION UPDATE's implicit transaction, so LOCAL reverts automatically once it commits. Verified structurally clean and functionally correct: make test TEST_LOAD_SOURCE=update (the real 0.1.0 -> stable update path) passes all 8 tests. Co-Authored-By: Claude <noreply@anthropic.com>
Same CODE_STYLE.md fix as reconcile-object-functions' commit for sql/object_reference.sql, applied to this update script's identical client_min_messages explanation. Co-Authored-By: Claude <noreply@anthropic.com>
The earlier removal of this re-declaration assumed 0.1.0's body and current source were byte-identical for this function. They aren't: 0.1.0 still has a dead, commented-out CREATE TEMP TABLE ... AS attempt in the EXCEPTION handler that current source has since dropped. Functionally inert either way, but pg_get_functiondef() returns comments verbatim, so an updated install's function body would literally differ from a fresh install's -- caught by bin/test_existing's structural diff (planted expressly to catch this class of divergence). Recreated with the current, comment-free body; confirmed structurally identical to a fresh install afterward. Co-Authored-By: Claude <noreply@anthropic.com>
Same reasoning as reconcile-object-functions' identical change to sql/object_reference.sql: a shipped script (this one runs for real on every ALTER EXTENSION UPDATE) shouldn't unilaterally change a session setting on its caller's behalf, even scoped via SET LOCAL. Verified no test depends on the quieter output -- make test/verify-results in both fresh and update (TEST_LOAD_SOURCE=update) modes still pass cleanly. Co-Authored-By: Claude <noreply@anthropic.com>
82818b4 to
27d1c18
Compare
|
Claude finished @jnasbyupgrade's task in 1m 22s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Tasks
Scope of this passThis synchronize is a rebase, not new content. PR #17 ( Verified this is a pure rebase, not a content change:
CI is green: the FindingsNone. No new content to review — this synchronize only reflects |
The assertion's own description doesn't need to echo current_schemas() -- a failure already tells you which schema(s) shouldn't be there, and pgtap's own diagnostic output shows the assertion context. Dropped the format()/%s interpolation. test/expected/*.out regenerated via make results (every test file's last line changed since this is a description string, not just a pass/ fail check). Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @jnasbyupgrade's task in 1m 15s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Reviewed against Tasks
Scope of this passSix prior reviews in this thread already cover everything through commit
Verified by hand:
CI is green on the current head commit ( FindingsNone. This is a small, well-justified robustness fix (removing environment-dependent output from a committed |
The zzz_ prefix only existed to force this test to run last alphabetically; pgxntool's test-build feature now runs it as its own separate installcheck target, so ordering no longer applies.
|
Claude finished @jnasbyupgrade's task in 1m 14s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Reviewed against Tasks
Scope of this passSeven prior reviews in this thread already cover everything through commit
Verified by hand:
CI is green: the FindingsNone. This is a pure, well-justified rename with no functional or behavioral change, correctly aligned with pgxntool's own naming convention for this feature. |
pgTAP's set_hasnt() asserts a set has none of a given set of values, which is exactly what the search_path check needs, and reports which schema leaked into search_path on failure instead of just failing. Split into two assertions, one per schema, so a failure names the specific schema.
|
Claude finished @jnasbyupgrade's task in 1m 24s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Reviewed against Tasks
Scope of this passEight prior reviews in this thread already cover everything through commit
Verified by hand:
CI is green: the FindingsNone. This is a small, well-executed test-quality improvement (better failure diagnostics via pgTAP's dedicated set-comparison function) with correctly regenerated plan counts and expected output across all six affected test files. |
…lication_role The header comment re-derived this file's whole change history from a diff instead of just orienting a reader; cut it down to the one thing worth knowing up front, the __object_reference helper schema. Event triggers obey session_replication_role the same way row/statement triggers do (they're created ENABLE, i.e. origin-scoped, by default), so SET LOCAL session_replication_role = replica for the structural section replaces three explicit ALTER EVENT TRIGGER ... DISABLE statements and needs no matching re-enable: it reverts automatically at the end of the transaction this whole script runs in, covering the final helper-schema cleanup too instead of racing to re-enable before it.
|
Claude finished @jnasbyupgrade's task in 4m 10s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Reviewed against Tasks
Scope of this passNine prior reviews in this thread already cover everything through commit
The technical premise checks out: event triggers do respect Finding
Concretely: a DBA running This directly contradicts the principle this same PR just established in commit The old three-statement CI is green: the |
…tion_role explicitly A SET LOCAL inside an extension update script is not scoped to the script itself: it persists into the rest of the caller's transaction if ALTER EXTENSION UPDATE isn't the only statement in it (confirmed against a manual test with an explicit surrounding transaction). Assuming the prior value was 'origin' and relying on the transaction to revert it was therefore wrong on two counts. Save the actual prior value in a placeholder GUC before disabling, and restore that exact value explicitly once the structural section and its cleanup are done.
|
Claude finished @jnasbyupgrade's task in 1m 44s —— View job Claude's Code Review of PR #18 (re-run after synchronize)Reviewed against Tasks
Scope of this passTen prior reviews in this thread already cover everything through commit
Verified by hand:
CI is green: the FindingsNone. This commit correctly and completely resolves the session-scoping issue flagged in the previous review pass, following the same placeholder-GUC convention already established elsewhere in this codebase. |
Adds the local test/Makefile machinery for testing this extension's own version-update path (`ALTER EXTENSION ... UPDATE`) — not a PostgreSQL major-version `pg_upgrade`, which is unrelated, separate, later work: `TEST_LOAD_SOURCE=fresh|update|existing` plus `TEST_UPDATE_FROM`/`TEST_UPDATE_TO` make vars, a single committed installer covering all three modes, a hand-authored `0.1.0` → `stable` update script, and one permanent pgTAP assertion proving the extension's own SQL never relies on an ambient `search_path`. CI wiring that actually drives `update`/`existing` mode in an automated job is a separate, later PR — CI here just keeps running the normal fresh-mode suite.
Adds the local test/Makefile machinery for fresh/update/existing-mode testing:
TEST_LOAD_SOURCE=fresh|update|existingplusTEST_UPDATE_FROM/TEST_UPDATE_TOmake vars, a single committed installer covering all three modes, a hand-authored0.1.0→stableupdate script, and one permanent pgTAP assertion proving the extension's own SQL never relies on an ambientsearch_path. CI wiring that actually drivesupdate/existingmode in an automated job is a separate, later PR — CI here just keeps running the normal fresh-mode suite.test/install/load.sql: single, committed-once installer covering all three load modes — a drop-first reset (including apg_temp.drop_role()helper for the extension's own global roles) for fresh/update, and a presence+version assertion for existing.sql/object_reference--0.1.0--stable.sql: hand-authored update script. Every function/view it recreates goes through the same private-helper-schema bootstrap/teardown convention the fresh install itself uses, rather than hand-writtenDROP/CREATE/REVOKE/GRANT/COMMENT, so the update path can't silently diverge from what a fresh install actually produces. The view drop order matters:_object_v/_object_v__for_updateare dropped before the_object_oidtable's column changes, sincepg_regresswon't allow dropping a column a view still selects. The extension's own event triggers (already active from the 0.1.0 base) are suppressed for the structural portion of the script viasession_replication_role = replica—zzz__object_reference_drop's body queries_object_reference._object_v, which would error the instant the script's ownDROP VIEWran against it otherwise — and the caller's actual prior value (not an assumed default) is restored afterward, sinceALTER EXTENSION UPDATEisn't guaranteed to be the only statement in its transaction.test/finish.sql: the one permanent assertion thatobject_reference/_object_referenceare absent from the resolvedsearch_path, checked at the end of every test file — proof that nothing in the suite accidentally relies on an ambient search path to resolve the extension's own objects.test/build/build.sql(moved fromtest/sql/, and dropped its historicalzzz_ordering prefix): the raw-source-load sanity check now runs under pgxntool'stest-buildfeature, in its own separate database — it collides with the real extension now installed viatest/install/load.sqlin the shared main-suite database otherwise._object_reference.object's own row type, referenced from a guard view. Confirmed to block a non-CASCADEDROP EXTENSION(withCASCADEcorrectly dropping both) on a fresh install, and confirmed to survive the update path unchanged and still block a non-CASCADE drop afterward.Verified locally (CI doesn't yet exercise
update/existingmode, per above):make test TEST_LOAD_SOURCE=updateandmake test TEST_LOAD_SOURCE=existingagainst both a correctly-updated and a deliberately-stale database pass/fail as expected, and a structural comparison of every recreated function/view (bodies viapg_get_functiondef, table/view columns, comments, ACLs) between the update path and a fresh install is byte-for-byte identical.Co-Authored-By: Claude noreply@anthropic.com