Skip to content

Test install foundation: TEST_LOAD_SOURCE modes, dependency guard - #19

Merged
jnasbyupgrade merged 8 commits into
masterfrom
test-install-foundation
Aug 8, 2026
Merged

Test install foundation: TEST_LOAD_SOURCE modes, dependency guard#19
jnasbyupgrade merged 8 commits into
masterfrom
test-install-foundation

Conversation

@jnasbyupgrade

@jnasbyupgrade jnasbyupgrade commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds test/install/load.sql (pgxntool's test/install feature): installs extension_drop ONCE, committed, before the pgTAP suite runs, instead of every test file reinstalling it via test/deps.sql.
  • TEST_LOAD_SOURCE (Makefile) selects fresh (default) / update / existing install mode, propagated to load.sql via a GUC over PGOPTIONS.
  • Adds test/sql/dependency_guard.sql: proves non-CASCADE DROP EXTENSION is blocked by the dependency guard.
  • test/deps.sql simplified: no longer creates a schema or installs the extension (that's load.sql's job now).
  • test/sql/simple.sql: removed a SET search_path line that was dead code once installs moved to the ambient/public path (search_path always includes public, so it couldn't prove anything test/sql/schema.sql doesn't already cover for the custom-schema path).
  • test/sql/schema.sql: added the minimal preamble (drop the committed install, recreate in its own schema) needed because load.sql now pre-installs into public before this file runs.

Previously this PR also included a schema-name mixed-case/quoting-robustness rename to test/sql/schema.sql -- that's unrelated to this PR's actual purpose (the test/install foundation) and has been split out to #34, which this PR is now rebased on top of.

Test plan

  • make test passes (load, dependency_guard, schema, simple, build)
  • make lint clean

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 22edf953-5274-4098-8ded-9383100dc240

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jnasbyupgrade
jnasbyupgrade changed the base branch from fix-cat-tools-install to master August 4, 2026 22:38
@jnasbyupgrade
jnasbyupgrade changed the base branch from master to fix-cat-tools-install August 4, 2026 22:39
@jnasbyupgrade
jnasbyupgrade force-pushed the fix-cat-tools-install branch from f08db32 to ef2e29d Compare August 5, 2026 23:08
@jnasbyupgrade
jnasbyupgrade force-pushed the test-install-foundation branch 2 times, most recently from 43749f2 to 187577a Compare August 6, 2026 17:13
@jnasbyupgrade
jnasbyupgrade changed the base branch from fix-cat-tools-install to pin-cat-tools-0.3.0-tag August 6, 2026 17:13
@jnasbyupgrade
jnasbyupgrade changed the base branch from pin-cat-tools-0.3.0-tag to master August 6, 2026 20:54
@jnasbyupgrade
jnasbyupgrade changed the base branch from master to pin-cat-tools-0.3.0-tag August 6, 2026 20:55
@jnasbyupgrade
jnasbyupgrade force-pushed the pin-cat-tools-0.3.0-tag branch from b9a135c to 1efc4de Compare August 6, 2026 21:04
@jnasbyupgrade
jnasbyupgrade force-pushed the test-install-foundation branch from 3fcef44 to 8f4e50d Compare August 6, 2026 21:05
@jnasbyupgrade
jnasbyupgrade marked this pull request as ready for review August 6, 2026 22:10
@jnasbyupgrade
jnasbyupgrade force-pushed the test-install-foundation branch from 8f4e50d to 67855c7 Compare August 6, 2026 23:03
@jnasbyupgrade
jnasbyupgrade changed the base branch from pin-cat-tools-0.3.0-tag to migrate-test-build August 6, 2026 23:03
@jnasbyupgrade
jnasbyupgrade force-pushed the test-install-foundation branch from dad617f to 5645da3 Compare August 7, 2026 21:38
@jnasbyupgrade jnasbyupgrade changed the title Test install foundation: TEST_LOAD_SOURCE modes, dependency guard, schema quoting rename Test install foundation: TEST_LOAD_SOURCE modes, dependency guard Aug 7, 2026
@jnasbyupgrade
jnasbyupgrade changed the base branch from migrate-test-build to schema-quoting-robustness August 7, 2026 21:38
@jnasbyupgrade
jnasbyupgrade force-pushed the schema-quoting-robustness branch from 692336e to 5a8e081 Compare August 7, 2026 21:55
@jnasbyupgrade
jnasbyupgrade force-pushed the test-install-foundation branch from 5645da3 to 2925fca Compare August 7, 2026 21:56
jnasbyupgrade and others added 4 commits August 7, 2026 17:13
…, quoting-requiring schema test

Builds the U&U (update & upgrade) test infrastructure that doesn't require a
real second extension_drop version or pg_upgrade CI to already exist:

- PGXNTOOL_ENABLE_TEST_INSTALL = yes, with test/install/load.sql as the
  committed-once installer for the extension (no test roles exist for this
  extension, so unlike cat_tools there's nothing role-related to add).
- TEST_LOAD_SOURCE (fresh/update/existing) GUC/make-var switch, parse-time
  validated, exported unconditionally, read in load.sql without missing_ok.
  `existing` mode is fully exercised locally (verified against a real,
  already-installed database, including the failure path when the extension
  is genuinely absent). `update` mode is wired up and structurally verified
  end-to-end, but extension_drop has no real prior released version to
  update FROM yet -- the Makefile refuses to run it without TEST_UPDATE_FROM
  set explicitly, and no CI leg exercises it in this repo today.
- Dependency guard (test/sql/dependency_guard.sql): a view depending on
  extension_drop__commands' row type blocks a non-CASCADE DROP EXTENSION;
  proven by actually attempting the drop and asserting failure, not assumed.
- test/sql/schema.sql's custom-schema test names renamed to mixed case
  (requires identifier quoting), reusing its existing coverage rather than
  adding a new schema-testing dimension.
- ci.yml: run `make test && make verify-results` instead of pg-build-test,
  so a real regression actually fails the build (pgxntool's
  .IGNORE: installcheck otherwise reports green regardless of test results,
  per RELEASE.md's existing note about PRs #6/#7).

Moving the extension's own installation into test/install/load.sql required
adapting every test file that used to install it per-test in a rolled-back
transaction (test/deps.sql, test/sql/simple.sql, test/sql/schema.sql,
test/sql/zzz_build.sql) to work against the new committed-once install
instead, since an extension name is a database-wide singleton.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…redate this branch

CI on this branch showed the switch to `make test && make verify-results`
surfacing real pgTAP failures on PostgreSQL 9.3/9.6 (cat_tools/extension_drop
never actually install there). Checked PR #10's own baseline CI
(#10, run
30665031257): PG 9.3 and 9.6 already report "3 of 3 tests failed" in the raw
job log there too, just silently reported as a passing check because
pg-build-test's underlying `make test` hits pgxntool's
`.IGNORE: installcheck` the same way. So this isn't a regression from this
PR's own changes -- it's the exact masking problem RELEASE.md already
documents, just now applying to a different, older part of the PG matrix
than the PRs (#6/#7) it originally cites. Reverting the ci.yml step back to
pg-build-test here keeps this PR scoped to test/install infrastructure;
fixing cat_tools's install path on pre-PG10 belongs to whoever owns that
dependency setup (PR #10 or a follow-up), not this PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two comments described what test/deps.sql or this file's CASCADE logic
used to be responsible for, instead of just stating current behavior.
That kind of history belongs in commit messages/PR descriptions, not
in comments that will rot as the code moves on.
…/deps.sql

simple.sql exercises the public/ambient install path, where 'public' is
always on search_path -- so its SET search_path line couldn't move the
extension's schema off the path and never proved anything; schema.sql
already covers that property for the custom-schema path, which is the
only path that needs to. The deps.sql comment was fully redundant with
test/install/load.sql's own comment about what schema.sql tests.
…mmand

Comments describing a branch were placed after the \if/\else/\endif
that opens it, reading as if they described the code above instead of
below. Move each comment to precede its command, and add the missing
one-line rationale to the fresh/update \if pair, which had it on
neither side.
@jnasbyupgrade
jnasbyupgrade force-pushed the test-install-foundation branch from 2925fca to 03b0355 Compare August 7, 2026 22:14
@jnasbyupgrade
jnasbyupgrade changed the base branch from schema-quoting-robustness to master August 7, 2026 22:14
@jnasbyupgrade

Copy link
Copy Markdown
Contributor Author

@claude review

@claude

claude Bot commented Aug 8, 2026

Copy link
Copy Markdown

Claude finished @jnasbyupgrade's task in 3m 12s —— View job


Claude is reviewing this PR

  • Gather context (diff, changed files, repo CLAUDE.md)
  • Review Makefile TEST_LOAD_SOURCE changes
  • Review test/install/load.sql
  • Review test/sql/dependency_guard.sql
  • Review test/deps.sql / test/sql/schema.sql / test/sql/simple.sql changes
  • Post review feedback
    · branch test-install-foundation

Review

Traced the full execution path (pgxntool/base.mk's existing test/install schedule feature → Makefileload.sql → each test/sql/*.sql file) rather than just reading files in isolation, since the whole point of this PR is that state now persists across files. It holds together correctly:

  • Sequencing is sound. REGRESS is built from a plain sorted file list (pgxntool/base.mk:72), not a schedule with multiple names per line, so test/sql/*.sql runs strictly sequentially: dependency_guard.sqlschema.sqlsimple.sql. Each file's pgTAP transaction is rolled back on exit (finish.sql's # TRANSACTION INTENTIONALLY LEFT OPEN!), so schema.sql's non-CASCADE DROP EXTENSION extension_drop; (test/sql/schema.sql:22) never collides with dependency_guard.sql's guard view — that view never escapes its own rolled-back transaction.
  • test/deps.sql simplification is safe. Confirmed no other test file reads :TEST_SCHEMA/:"TEST_SCHEMA" expecting deps.sql to have set it — schema.sql sets its own copy locally (test/sql/schema.sql:2). Removing the old schema-creation/install block from deps.sql doesn't strand anything.
  • Makefile TEST_LOAD_SOURCE validation logic is correct$(filter $(TEST_LOAD_SOURCE),fresh update existing) works here (empty for a typo, non-empty for a valid mode) because TEST_LOAD_SOURCE is a single word with no % wildcard, so argument order doesn't change the result. One nit: this reverses the conventional Make idiom $(filter <patterns>,<text>) (normally the static list comes first), which could read as backwards/confusing to a future maintainer even though it's correct today. Not worth a fix, just flagging.
  • load.sql's three modes (fresh/update/existing) are internally consistent, the existing-mode assertions (extension present + version matches default_version) actually protect against a silent no-op, and the PR is upfront that update mode has no real historical version to exercise yet (documented in both the Makefile and load.sql, and enforced — TEST_UPDATE_FROM is required, no unsafe default).
  • dependency_guard.sql proves a real property (non-CASCADE DROP EXTENSION fails via 2BP01) rather than just asserting the SQL exists, and correctly uses the 4-arg throws_ok form to check the actual SQLSTATE rather than string-matching the message.
  • CI is green on this PR (make test + make lint).

No functional issues found. This is a well-reasoned, well-documented change — the inline comments carry real rationale (e.g. why dependency_guard.sql's view types on extension_drop__commands's row rather than a column, why test/install/.gitignore excludes load.out) rather than restating the code.

@jnasbyupgrade
jnasbyupgrade merged commit 454f0ba into master Aug 8, 2026
9 checks passed
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

Claude finished @jnasbyupgrade's task in 4m 3s —— View job


Claude finished reviewing PR #19

  • Gather context (diff, changed files, repo CLAUDE.md)
  • Re-verify PR content against CLAUDE.md's schema-independence rules
  • Post review feedback

· branch test-install-foundation


Review

This PR was already reviewed once in this thread and merged. I independently re-pulled and re-read the actual changed content (Makefile, test/install/load.sql, test/sql/dependency_guard.sql, test/deps.sql, test/sql/schema.sql, test/sql/simple.sql) rather than assuming the prior pass — findings below confirm the earlier review and add one more check specific to this repo's CLAUDE.md.

Sequencing / mechanics — same conclusion as before, re-verified: test/install/load.sql installs extension_drop once, committed, before the pgTAP suite runs; each test/sql/*.sql file's transaction rolls back on exit, so schema.sql's non-CASCADE DROP EXTENSION never collides with dependency_guard.sql's guard view. test/deps.sql no longer creates a schema or installs the extension — confirmed no other file depends on it having done so.

dependency_guard.sql correctly uses the 4-arg throws_ok(sql, sqlstate, message, description) form to check 2BP01 rather than string-matching, and asserts both that the drop is blocked and that the extension/guard view survive the attempt — a real behavioral proof, not just "the SQL exists."

CLAUDE.md schema-independence check — this repo's CLAUDE.md sets a specific, easy-to-get-wrong bar: at least one tested leg must install into a schema verifiably absent from search_path at assertion time, via CREATE EXTENSION ... SCHEMA, with a mixed-case/quoting-sensitive name. Reading test/sql/schema.sql end to end:

  • TEST_SCHEMA_2 (_Test_Ed_2, mixed-case → requires quoting) is installed via CREATE EXTENSION extension_drop SCHEMA %I while TEST_SCHEMA is still in search_path — not by mutating search_path first.
  • search_path is then explicitly reset to exclude TEST_SCHEMA_2 ("Ensure test schema 2 isn't in search_path") before extension_drop__update()/extension_drop__get() are exercised against it via fully-qualified %I.function() calls.

That satisfies both conditions in CLAUDE.md (verifiable absence at assertion time + quoting-sensitive name) for this leg. The minimal preamble this PR itself adds to schema.sql (drop the committed load.sql install, recreate locally) is consistent with that existing structure and doesn't disturb it.

Makefile TEST_LOAD_SOURCE validation — confirmed still correct: $(filter $(TEST_LOAD_SOURCE),fresh update existing) works because TEST_LOAD_SOURCE is a single word with no % wildcard. Same nit as before: this reverses the conventional $(filter <patterns>,<text>) idiom (static list normally comes first), which could read as backwards to a future maintainer even though it's correct today. Not worth a fix.

load.sql's three modes (fresh/update/existing) remain internally consistent; existing mode's assertions (presence + version match) genuinely guard against a silent no-op; update mode is honestly documented as wired-up-but-unexercised since extension_drop has no real second released version yet, and TEST_UPDATE_FROM has no unsafe default.

No functional issues found on re-verification. The CLAUDE.md schema-independence property this repo cares about specifically is upheld by the existing test/sql/schema.sql structure that this PR builds on top of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant