diff --git a/Makefile b/Makefile index e57011a..98b9c3f 100644 --- a/Makefile +++ b/Makefile @@ -2,3 +2,41 @@ include pgxntool/base.mk # Temporary hack testdeps: $(wildcard test/*/*.sql) $(wildcard test/*.sql) # Be careful not to include directories in this + +# Install the oldest historical version's full install script so the update +# test in test/build/upgrade.sql and test/deps.sql's update mode can +# CREATE EXTENSION count_nulls VERSION '0.9.6'. +# Not covered by base.mk's DATA wildcard, which only picks up upgrade scripts +# (sql/*--*--*.sql) and the current version file. +DATA += sql/count_nulls--0.9.6.sql + +# TEST_LOAD_SOURCE selects how test/deps.sql installs the extension for the +# WHOLE test suite: +# - fresh (default): CREATE EXTENSION count_nulls (current version). +# - update: CREATE EXTENSION at the oldest version we still ship a full +# install script for (0.9.6), then ALTER EXTENSION UPDATE to current. +# Running the SAME suite with the SAME expected output against the updated +# database proves it behaves identically to a fresh install. +# +# "update" (this) is extension-level (ALTER EXTENSION UPDATE); "upgrade" is +# cluster-level (pg_upgrade) and is a separate, not-yet-implemented axis. Don't +# conflate the two in variable names or comments. +# +# The mode is signalled to test/deps.sql via the count_nulls.test_load_mode +# placeholder GUC. pg_regress does not forward make variables, but the psql +# processes it spawns inherit the environment, so PGOPTIONS reaches deps.sql. +# It's exported unconditionally so deps.sql can read it without missing_ok +# and fail loudly if it didn't propagate, instead of silently defaulting to +# fresh and running the wrong suite. +TEST_LOAD_SOURCE ?= fresh +ifeq ($(filter $(TEST_LOAD_SOURCE),fresh update),) +$(error TEST_LOAD_SOURCE must be 'fresh' or 'update', got '$(TEST_LOAD_SOURCE)') +endif +export PGOPTIONS := $(PGOPTIONS) -c count_nulls.test_load_mode=$(TEST_LOAD_SOURCE) + +# Convenience wrapper: `make test-update` == `make test TEST_LOAD_SOURCE=update`. +# Must recurse (a fresh $(MAKE)) rather than depend on `test`, so the +# parse-time TEST_LOAD_SOURCE conditional above re-evaluates with update set. +.PHONY: test-update +test-update: + $(MAKE) test TEST_LOAD_SOURCE=update diff --git a/test/build/expected/upgrade.out b/test/build/expected/upgrade.out new file mode 100644 index 0000000..25fdbb1 --- /dev/null +++ b/test/build/expected/upgrade.out @@ -0,0 +1 @@ +\set ECHO none diff --git a/test/build/upgrade.sql b/test/build/upgrade.sql new file mode 100644 index 0000000..c5a5946 --- /dev/null +++ b/test/build/upgrade.sql @@ -0,0 +1,11 @@ +\set ECHO none +\i test/pgxntool/psql.sql +\t + +-- Sanity check: install the oldest available version and upgrade to current. +-- sql/count_nulls--0.9.6.sql is the oldest full install script we still ship +-- (0.9.0/0.9.2/0.9.5 only exist as upgrade diffs, not standalone installs). +BEGIN; +CREATE EXTENSION count_nulls VERSION '0.9.6'; +ALTER EXTENSION count_nulls UPDATE; +ROLLBACK; diff --git a/test/deps.sql b/test/deps.sql index 9705f9f..454be4b 100644 --- a/test/deps.sql +++ b/test/deps.sql @@ -5,4 +5,45 @@ CREATE SCHEMA IF NOT EXISTS :schema; SET search_path = :schema; SET client_min_messages = NOTICE; +/* + * Mode selection: 'fresh' installs the current version directly; 'update' + * installs the oldest version we still ship a full script for (0.9.6) and + * runs ALTER EXTENSION UPDATE. Since every test file loads this via + * test/load.sql, running the suite in each mode (make test / make + * test-update) exercises the SAME tests against a fresh vs. an updated + * install, with the same expected output either way. + * + * "update" here is extension-level (ALTER EXTENSION UPDATE); it is not + * "upgrade" (cluster-level pg_upgrade), a separate axis this doesn't cover. + * + * The Makefile always exports this GUC, so we read it without missing_ok: + * if it failed to propagate we want a loud error here, not a silent + * fall-through to 'fresh'. + */ +SELECT current_setting('count_nulls.test_load_mode') AS count_nulls_test_load_mode +\gset + +DO $$ +BEGIN + IF current_setting('count_nulls.test_load_mode') NOT IN ('fresh', 'update') THEN + RAISE EXCEPTION + 'count_nulls.test_load_mode must be ''fresh'' or ''update'', got ''%''' + , current_setting('count_nulls.test_load_mode') + ; + END IF; +END +$$; + +SELECT :'count_nulls_test_load_mode' = 'update' AS count_nulls_update_mode +\gset + +\if :count_nulls_update_mode +CREATE EXTENSION count_nulls VERSION '0.9.6'; +-- Suppress the "already installed, no update" NOTICE class of messages any +-- update script might emit. +SET client_min_messages = WARNING; +ALTER EXTENSION count_nulls UPDATE; +SET client_min_messages = NOTICE; +\else CREATE EXTENSION count_nulls; +\endif