Fix test/install, add test-build, verify-results, docs#18
Fix test/install, add test-build, verify-results, docs#18jnasbyupgrade wants to merge 19 commits intoPostgres-Extensions:masterfrom
Conversation
- Add .claude/settings.json with references to test repos - Add CLAUDE.md documenting the meta-framework architecture - Include git commit guidelines Co-Authored-By: Claude <noreply@anthropic.com>
This ensures all projects using pgxntool will ignore Claude Code local configuration files Co-Authored-By: Claude <noreply@anthropic.com>
Add *.md to export-ignore to prevent markdown files (including CLAUDE.md) from being included in extension distributions Co-Authored-By: Claude <noreply@anthropic.com>
Add `.claude/commands/commit.md` with comprehensive commit workflow that will be shared with pgxntool-test via symlink. This ensures consistent commit standards across both repos. Document META.json generation process in `build_meta.sh` to explain why we generate from template (PGXN.org doesn't like empty optional fields) and future possibilities (could generate control files from template). Co-Authored-By: Claude <noreply@anthropic.com>
Add testing section to `CLAUDE.md` with critical rules: never use `make installcheck` directly, never run `make results` without verification, database connection requirements. Enhance `README.asc` to recommend `make test`, document `make results` verification workflow, and emphasize pgTap benefits. Co-Authored-By: Claude <noreply@anthropic.com>
… validation - Add `make_results.sh` script to handle copying results while respecting `output/*.source` files as source of truth - Update `base.mk` to properly handle ephemeral files from `.source` files: - Track `TEST_OUT_SOURCE_FILES` and `TEST_EXPECTED_FROM_SOURCE` - Add ephemeral files to `EXTRA_CLEAN` so `make clean` removes them - Create `test/results/` directory automatically - Remove rule that created `test/output/` directory (it's an optional input) - Add validation in `dist-only` target to ensure `.gitattributes` is committed before creating distribution (git archive only respects export-ignore for committed files) - Update `README.asc` and `CLAUDE.md` to document that development should be done from pgxntool-test repository Co-Authored-By: Claude <noreply@anthropic.com>
- Add `pgtle` make target to generate pg_tle registration SQL for extensions - Support pg_tle version ranges (1.0.0-1.5.0 and 1.5.0+) with appropriate API usage - Add `pgtle.sh` script to generate pg_tle SQL from extension control files and versioned SQL - Update `base.mk` to include pg_tle generation with proper dependencies on SQL files - Add pg_tle/ directory to EXTRA_CLEAN for `make clean` - Enhance `.claude/commands/commit.md` to require checking all 3 repos before committing - Add explicit guidance to commit all repos with changes together (no empty commits) - Document multi-repo commit workflow in steps - Update `CLAUDE.md` with pg_tle development context and documentation - Update `README.asc` and `README.html` with pg_tle usage documentation Co-Authored-By: Claude <noreply@anthropic.com>
Add "OPTIONAL TEST FEATURES" section documenting `test-build`, `test/install`, and `verify-results` configuration. Also clarify that `verify-results` works with all `pg_regress`-based tests, not just pgTap, and fix assignment to use `:=` to avoid recursion. Co-Authored-By: Claude <noreply@anthropic.com>
Replace local commit.md with reference to canonical version in pgxntool-test. All three repos (pgxntool, pgxntool-test, pgxntool-test-template) now share the same commit workflow. Co-Authored-By: Claude <noreply@anthropic.com>
Add new pg_tle version range to handle API changes in 1.4.0: - Split 1.0.0-1.5.0 range into 1.0.0-1.4.0 and 1.4.0-1.5.0 - Version 1.4.0 added uninstall function (backward-incompatible) - Version 1.5.0 added schema parameter (another boundary) - Update `base.mk` pattern rules for three version ranges - Update `pgtle.sh` documentation and logic for new range Extract shared utility functions into `lib.sh`: - Move `error()`, `die()`, and `debug()` functions from `pgtle.sh` - Update `pgtle.sh` and `setup.sh` to source `lib.sh` - Reduces code duplication and improves maintainability Refine `.gitattributes` export rules: - Add specific excludes: `CLAUDE.md`, `PLAN-*.md`, `.DS_Store` - Remove blanket `*.md` exclude (too broad) - Allows README.md and other docs to be included in distributions Add documentation about directory purity in `CLAUDE.md`: - Emphasize that pgxntool directory contains ONLY embedded files - Warn against adding temporary files or planning documents - Clarify that such files belong in pgxntool-test instead Co-Authored-By: Claude <noreply@anthropic.com>
Remove references to pgxntool-test-template (now consolidated): - Template files moved to pgxntool-test/template/ - Remove template directory from `.claude/settings.json` - Update `CLAUDE.md` for two-repository pattern Convert `.claude/commands/commit.md` to symlink: - Development happens in pgxntool-test, avoid duplication - Symlink: `commit.md -> ../../../pgxntool-test/.claude/commands/commit.md` Related changes in pgxntool-test: - Consolidate template files into pgxntool-test/template/ - Simplify commit workflow to two-phase (remove amend step) Co-Authored-By: Claude <noreply@anthropic.com>
Merges master's control.mk system and update-setup-files.sh while preserving test-build, test-install, and verify-results features from the build-test branch. Key changes: - Added control.mk.sh for parsing .control files - Added update-setup-files.sh for 3-way merging after pgxntool-sync - Added SETUP_FILES/SETUP_SYMLINKS config to lib.sh - Simplified meta.mk.sh (defers extension handling to control.mk.sh) - Used master's variable naming (TEST__SOURCE__*) - Preserved PGXNTOOL_ENABLE_TEST_BUILD feature - Preserved PGXNTOOL_ENABLE_TEST_INSTALL feature - Preserved PGXNTOOL_ENABLE_VERIFY_RESULTS feature Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enhancement request: Override mechanism for install/build file listsI'm planning to use the test/install support for pg_tle integration in my extensions monorepo. The auto-detection is great for the common case, but I need to control which files run and in what order. Two requests: 1. Documented override for test/install and test-build file lists
Suggested approach: Expose an intermediate variable that the schedule generation uses, documented as the public API for overriding: # Default: auto-detected from test/install/*.sql (unordered)
# Projects can override for ordering or conditional inclusion.
PGXNTOOL_INSTALL_TESTS ?= $(notdir $(basename $(TEST_INSTALL_SQL_FILES)))
$(PGXNTOOL_INSTALL_SCHEDULE):
@echo "# Auto-generated - DO NOT EDIT" > $@
@for f in $(PGXNTOOL_INSTALL_TESTS); do \
echo "test: ../install/$$f" >> $@; \
doneThen projects can do: include pgxntool/base.mk
# Explicit ordering + conditional pg_tle setup
PGXNTOOL_INSTALL_TESTS = extensions
ifdef PGTLE_MODE
PGXNTOOL_INSTALL_TESTS := pgtle-setup $(PGXNTOOL_INSTALL_TESTS)
endifSame pattern would be useful for test-build ( 2. Document new make targets to help with conflictsProjects that already hand-coded Suggestions:
|
…s, docs Replace broken separate-invocation test-install with schedule-based approach: install files now run in the same pg_regress invocation as regular tests via an auto-generated schedule file with ../install/ relative paths. State created by install files persists into the main test suite. - Add `test-build` feature for pre-test SQL validation via `test/build/` - Add `verify-results` safeguard preventing `make results` when tests fail - Add `.asc` to recognized asciidoc extensions - Document test-build, test/install, and verify-results in README - Update `_.gitignore` for auto-generated `test/install/schedule` - Remove `.claude/` directory (moved to pgxntool-test) Related changes in pgxntool-test: - Add install persistence test validating state survives across test phases - Rework `test-test-install.bats` for schedule-based approach - Add template marker files for install persistence validation Co-Authored-By: Claude <noreply@anthropic.com>
91da35b to
f36629c
Compare
README.asc
Outdated
| ---- | ||
| test/build/ | ||
| ├── *.sql # SQL test files (checked in) | ||
| ├── input/ # Optional: .source files for pg_regress processing |
There was a problem hiding this comment.
.source files would also be checked in
There was a problem hiding this comment.
Agreed. Will update the diagram to note that .source files in input/ are also checked in.
| # resolves install files from their original location without copying. | ||
| # | ||
| TEST_INSTALL_SQL_FILES = $(wildcard $(TESTDIR)/install/*.sql) | ||
| ifdef PGXNTOOL_ENABLE_TEST_INSTALL |
There was a problem hiding this comment.
This is almost the same code as for test/build; propose ways (in a comment) it could be refactored. We certainly want the code to remain clear, but I'm hoping we can remove some of the duplication.
See verify-results as well; it's pretty similar as well.
There was a problem hiding this comment.
The duplication is in the variable validation/normalization blocks (lines 98-115, 141-158, 175-188). All three follow the same pattern:
- If variable is set: normalize to lowercase, validate yes/no, error on bad value
- If not set: auto-detect (wildcard check or default)
Options for refactoring:
A. GNU Make call function — define the validation as a reusable template:
# $(1) = variable name, $(2) = file list or "yes" for default-enabled
define pgxntool_feature_detect
ifdef $(1)
$(1)_NORM = $$(strip $$(shell echo "$$($(1))" | tr '[:upper:]' '[:lower:]'))
ifneq ($$($(1)_NORM),yes)
ifneq ($$($(1)_NORM),no)
$$(error $(1) must be "yes" or "no", got "$$($(1))")
endif
endif
override $(1) := $$($(1)_NORM)
else
ifneq ($$(strip $(2)),)
$(1) = yes
else
$(1) = no
endif
endif
endef
$(eval $(call pgxntool_feature_detect,PGXNTOOL_ENABLE_TEST_BUILD,$(TEST_BUILD_FILES)))
$(eval $(call pgxntool_feature_detect,PGXNTOOL_ENABLE_TEST_INSTALL,$(TEST_INSTALL_SQL_FILES)))
$(eval $(call pgxntool_feature_detect,PGXNTOOL_ENABLE_VERIFY_RESULTS,yes))Pros: Eliminates all duplication, easy to add new features. Cons: $(eval $(call ...)) is less readable for people unfamiliar with GNU Make metaprogramming. Debugging errors from inside $(eval) can be confusing.
B. Keep inline but simplify — extract just the normalize+validate into a function, keep the auto-detect inline since each feature's detection logic differs slightly:
# Returns normalized yes/no or triggers error
define pgxntool_validate_yesno
$(strip $(if $(filter yes no,$(shell echo "$(1)" | tr '[:upper:]' '[:lower:]')),$(shell echo "$(1)" | tr '[:upper:]' '[:lower:]'),$(error $(2) must be "yes" or "no", got "$(1)")))
endefPros: Simpler, auto-detect logic stays visible. Cons: Still some repetition in the ifdef/else structure.
C. Leave as-is — the blocks are short, self-contained, and easy to understand. Each feature's config section is a complete unit you can read top-to-bottom.
I'd lean toward A since we already have three features and may add more. The $(eval $(call)) pattern is well-established in GNU Make. But readability is a real tradeoff — worth considering whether pgxntool users are likely to need to understand this code.
There was a problem hiding this comment.
Sounds good — will extract the normalize+validate into a function and keep the auto-detect logic inline.
base.mk
Outdated
| ifeq ($(PGXNTOOL_ENABLE_TEST_BUILD),yes) | ||
| TEST_DEPS += test-build | ||
| endif | ||
| TEST_DEPS += install |
There was a problem hiding this comment.
can't these two lines be combined with 267?
There was a problem hiding this comment.
Yes — can combine into TEST_DEPS += install installcheck on a single line. The conditional test-build += stays separate to preserve ordering (testdeps → test-build → install → installcheck).
base.mk
Outdated
| @for file in $(TEST_BUILD_SQL_FILES); do \ | ||
| cp "$$file" "$(TEST_BUILD_SQL_DIR)/$$(basename $$file)"; \ | ||
| done | ||
| @# Create empty expected files if needed |
There was a problem hiding this comment.
Need a comment on why we even need to do this
There was a problem hiding this comment.
pg_regress aborts with a confusing 'could not open file' error if the expected output file doesn't exist — it doesn't create one automatically. Without this, adding a new .sql file to test/build/ would fail before even running the SQL. Will add a comment explaining this.
README.asc
Outdated
| ├── expected/ # Expected output files (checked in) | ||
| │ └── *.out | ||
| └── sql/ # GENERATED - do not edit or check in | ||
| └── *.sql # Copied from *.sql above; generated from input/*.source |
- Combine TEST_DEPS lines: merge separate install/installcheck additions into a single line alongside testdeps in the initial assignment - Add pgtap mode to verify-results: new PGXNTOOL_VERIFY_RESULTS_MODE variable (default: pgtap) scans test/results/*.out for "not ok" and plan mismatch lines; also retains regression.diffs check as fallback. "diffs" mode preserves legacy behavior for non-pgtap projects. - Add comment explaining why empty expected files are created: pg_regress aborts immediately if expected/*.out is missing rather than running the test and showing a diff. - Extract test-build shell setup into pgxntool/run-test-build.sh: directory creation, SQL file copying, and empty expected file seeding are now in a dedicated script; base.mk only contains the make installcheck invocation and diffs check. - Replace PGXNTOOL_distclean with EXTRA_CLEAN: META.json, meta.mk, and control.mk are now listed in EXTRA_CLEAN (cleaned by PGXS make clean) instead of a custom distclean target. Removes the distclean: target and the clean: distclean prerequisite. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
For all three feature-enable variables (PGXNTOOL_ENABLE_TEST_BUILD, PGXNTOOL_ENABLE_TEST_INSTALL, PGXNTOOL_ENABLE_VERIFY_RESULTS), add a note in the doc comment that setting the variable to empty on the command line (e.g. PGXNTOOL_ENABLE_TEST_BUILD=) also disables the feature, the same as =no. This works because Make's ifdef sees an empty value as "not defined", so the validation block is skipped. But the Makefile's default assignment cannot override a command-line variable (even an empty one), so the feature-enable ifeq check sees "" and stays disabled. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lib.sh
Outdated
| shift | ||
| error "$@" | ||
| exit $exit_code | ||
| exit "$exit_code" |
There was a problem hiding this comment.
The die() function was added as a convenience for combining error output + exit. If it's not used or not pulling its weight, happy to remove it.
There was a problem hiding this comment.
No, I mean why are you wrapping $exit_code in ""?
There was a problem hiding this comment.
Fair point — exit only takes a numeric argument and $exit_code is always set from $1. The quoting is unnecessary here. Will remove.
| # | ||
| # META.json | ||
| # | ||
| PGXNTOOL_distclean += META.json |
There was a problem hiding this comment.
Should still be distclean (but I don't think we need a custom variable).
There was a problem hiding this comment.
Agreed. Will use standard distclean target directly instead of the PGXNTOOL_distclean variable.
| # meta.mk | ||
| # | ||
| # Build meta.mk, which contains PGXN distribution info from META.json | ||
| PGXNTOOL_distclean += meta.mk |
There was a problem hiding this comment.
Should still be distclean.
| # | ||
| # Find all control files first (needed for dependencies) | ||
| PGXNTOOL_CONTROL_FILES := $(wildcard *.control) | ||
| PGXNTOOL_distclean += control.mk |
There was a problem hiding this comment.
Should still be distclean.
|
|
||
| # Copy .sql files to sql/ directory for pg_regress | ||
| for file in "$BUILD_DIR"/*.sql; do | ||
| [ -f "$file" ] || continue |
There was a problem hiding this comment.
Why's this needed?
There was a problem hiding this comment.
Null-glob guard. If no .sql files exist in the directory, the glob *.sql expands to the literal string "$BUILD_DIR/*.sql". The [ -f "$file" ] check catches that and skips. Without it, the cp below would fail with "No such file".
There was a problem hiding this comment.
Please add a comment explaining that.
| # resolves install files from their original location without copying. | ||
| # | ||
| TEST_INSTALL_SQL_FILES = $(wildcard $(TESTDIR)/install/*.sql) | ||
| ifdef PGXNTOOL_ENABLE_TEST_INSTALL |
…ts, fix distclean Extract `pgxntool_validate_yesno` function to replace duplicated normalize+validate blocks in TEST_BUILD, TEST_INSTALL, and VERIFY_RESULTS feature detection (~12 lines each → 1 line each). Add pgtap failure detection to verify-results: scans result files for `^not ok` (excluding `# TODO`) and `Looks like you planned` mismatches before allowing `make results` to proceed. Restore `PGXNTOOL_distclean` accumulator variable for distclean target and document it in README. PGXS doesn't provide special distclean support, so we roll our own. Remove `clean: distclean` dependency — distclean files (META.json, meta.mk, control.mk) should survive `make clean`. Other fixes: - Combine `TEST_DEPS += install` and `installcheck` into single line - Add comment explaining pg_regress touch rule for missing expected files - Remove quotes from `exit` in `die()` (`lib.sh`) - README: add distclean section, fix tree diagram, add inline comments Related changes in pgxntool-test: - Simplify template SQL (CTAS for install marker, block comments) - Add working `template/test/build/` files - Redesign test-build, test-install, verify-results, and doc tests Co-Authored-By: Claude <noreply@anthropic.com>
test-build: Useful error messages for SQL syntax errors
When
CREATE EXTENSIONfails due to a syntax error, PostgreSQL reports acryptic error with limited context. test-build runs your extension SQL directly
through pg_regress first, so errors show the exact file, line, and position —
cutting debugging time significantly.
Place SQL files in
test/build/to enable. Auto-detects based on file presence.test/install: Run expensive setup once instead of per-test
Extensions that install dependencies or load fixtures in every test file pay
that cost once per test. test/install runs setup SQL once before the entire
suite, and all regular tests share the resulting database state. This can
dramatically speed up test suites.
Place SQL files in
test/install/to enable. Auto-detects based on file presence.invocation (database state persists across phases)
.sqlfiles astest/install/*.outverify-results: Prevent blessing incorrect test output
make resultsnow refuses to run when tests are failing. Prevents accidentallyupdating expected files with wrong output. Disable with
PGXNTOOL_ENABLE_VERIFY_RESULTS=no.Other changes
.ascas a recognized asciidoc extensionCompanion PR: Postgres-Extensions/pgxntool-test#7