Skip to content

Commit 2ab8876

Browse files
committed
Add fresh/update/existing-mode extension test infrastructure (#18)
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.
1 parent c04df7d commit 2ab8876

21 files changed

Lines changed: 1043 additions & 14 deletions

‎.github/workflows/ci.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ jobs:
129129
run: pg-start ${{ matrix.pg }}
130130
- name: Check out the repo
131131
uses: actions/checkout@v4
132+
# pgxntool's test-build feature (test/build/build.sql) syncs
133+
# test/build/*.sql into test/build/sql/ via rsync (run-test-build.sh),
134+
# which the pgxn/pgxn-tools image doesn't ship.
135+
- name: Install rsync
136+
run: apt-get install -y rsync
132137
- name: Test on PostgreSQL ${{ matrix.pg }}
133138
# `make test` alone never fails this step: pgxntool/base.mk (as
134139
# vendored here, 2.2.0) marks its underlying installcheck .IGNORE,

‎Makefile‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,90 @@
1+
# Committed-once install of the extension (test/install/load.sql), run before
2+
# the main pgTAP suite in its own pg_regress session so its state persists
3+
# (committed) into every per-test file. Must be set (and set to exactly
4+
# "yes"/"no", not auto-detected) BEFORE base.mk is included below, since
5+
# base.mk reads it at parse time.
6+
PGXNTOOL_ENABLE_TEST_INSTALL = yes
7+
8+
# Safeguard for `make results`: refuses to copy test/results/*.out over
9+
# test/expected/*.out while a real regression is showing. This is already
10+
# pgxntool's own default, but set it explicitly so that stays true even if a
11+
# future pgxntool default ever changes.
12+
PGXNTOOL_ENABLE_VERIFY_RESULTS = yes
13+
14+
# TEST_LOAD_SOURCE selects how test/install/load.sql installs the extension:
15+
# - fresh (default): CREATE EXTENSION object_reference (current version).
16+
# - update: CREATE EXTENSION at TEST_UPDATE_FROM (default 0.1.0, the only
17+
# real historical PGXN release) then ALTER EXTENSION UPDATE -- to
18+
# TEST_UPDATE_TO if set, otherwise to the current default_version
19+
# ("stable"). Running the SAME suite with the SAME expected output
20+
# against the updated database verifies it behaves identically to a
21+
# fresh install.
22+
# - existing: the extension is ALREADY installed in the target database (by
23+
# a binary pg_upgrade, or an ALTER EXTENSION UPDATE done outside the
24+
# suite). load.sql does not touch it; it only asserts presence + current
25+
# version. Pair with CONTRIB_TESTDB=<db> and
26+
# EXTRA_REGRESS_OPTS=--use-existing so pg_regress runs against that
27+
# database instead of dropping and recreating a throwaway one.
28+
#
29+
# The mode (and the update from/to versions) are signalled to load.sql via
30+
# placeholder GUCs. pg_regress does not forward make variables, but the psql
31+
# processes it spawns inherit the environment, so PGOPTIONS reaches load.sql.
32+
#
33+
# The GUCs are exported UNCONDITIONALLY, so load.sql can read them WITHOUT
34+
# missing_ok and fail loudly if they did not propagate. Relying on an absent
35+
# GUC to mean "fresh" is unsafe: a silent break anywhere in the
36+
# make -> PGOPTIONS -> env -> psql chain would quietly run the wrong mode.
37+
#
38+
# TEST_LOAD_SOURCE must be exactly `fresh`, `update` or `existing`; anything
39+
# else is a hard error at parse time (so e.g. `make test
40+
# TEST_LOAD_SOURCE=typo` fails fast rather than defaulting).
41+
TEST_LOAD_SOURCE ?= fresh
42+
ifeq ($(filter $(TEST_LOAD_SOURCE),fresh update existing),)
43+
$(error TEST_LOAD_SOURCE must be 'fresh', 'update' or 'existing', got '$(TEST_LOAD_SOURCE)')
44+
endif
45+
46+
# update-mode version range (read by load.sql only in update mode). Empty
47+
# TEST_UPDATE_TO means "update to the current default_version" (stable).
48+
TEST_UPDATE_FROM ?= 0.1.0
49+
TEST_UPDATE_TO ?=
50+
51+
export PGOPTIONS := $(PGOPTIONS) -c object_reference.test_load_mode=$(TEST_LOAD_SOURCE) -c object_reference.test_update_from=$(TEST_UPDATE_FROM) -c object_reference.test_update_to=$(TEST_UPDATE_TO)
52+
53+
# Convenience wrapper: `make test-update` == `make test TEST_LOAD_SOURCE=update`.
54+
# Must recurse (a fresh $(MAKE)) rather than depend on `test`, so the
55+
# parse-time TEST_LOAD_SOURCE conditional above re-evaluates with update set.
56+
.PHONY: test-update
57+
test-update:
58+
$(MAKE) test TEST_LOAD_SOURCE=update
59+
160
include pgxntool/base.mk
261

362
testdeps: $(wildcard test/*.sql test/helpers/*.sql) # Be careful not to include directories in this
463
testdeps: test_factory
564

665
install: cat_tools
766

67+
# 0.1.0 (TEST_UPDATE_FROM's default -- the update-mode floor, see above) needs
68+
# count_nulls too: its install script's _object_oid.null_count trigger calls
69+
# count_nulls' not_null_count_trigger(), and object_reference.control's
70+
# `requires` (cat_tools only -- count_nulls was dropped once the reg*
71+
# pseudotype removal made that trigger unnecessary) no longer CASCADEs it in.
72+
# Only needed for update-mode testing against that floor -- current
73+
# object_reference has no runtime dependency on count_nulls at all -- so this
74+
# is conditional, not folded into the unconditional `install: cat_tools` above.
75+
ifeq ($(TEST_LOAD_SOURCE),update)
76+
install: count_nulls
77+
endif
78+
79+
.PHONY: count_nulls
80+
count_nulls: $(DESTDIR)$(datadir)/extension/count_nulls.control
81+
$(DESTDIR)$(datadir)/extension/count_nulls.control:
82+
pgxn install count_nulls
83+
84+
# Clean the cruft pg_regress writes into test/install/ (the self-comparing
85+
# result .out and its diff), which is listed in test/install/.gitignore.
86+
extra_clean += $(addprefix test/install/,$(shell grep -v '^\#' test/install/.gitignore 2>/dev/null))
87+
888
test: dump_test
989
extra_clean += $(wildcard test/dump/*.log)
1090
dump_test: test/dump/run.sh test/helpers/object_table.sql $(wildcard test/dump/*.sql)

0 commit comments

Comments
 (0)