Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ jobs:
- name: Test on PostgreSQL ${{ matrix.pg }}, across every TEST_SCHEMA value
run: make test-schema-all

# Proves the in-place extension update path: CREATE EXTENSION at the
# oldest version we still ship a full install script for (0.9.6), then
# ALTER EXTENSION UPDATE (no pg_upgrade, same PostgreSQL), all within
# test/install/load.sql's own committed session (TEST_LOAD_SOURCE=update -
# see the Makefile) - then run the FULL suite against the updated
# database via the SAME expected output as a fresh install (see
# test/README.md for how the suite stays schema/load-mode invariant).
# No external script needed for this leg: unlike a real pg_upgrade
# (pg-upgrade-test), the update itself is just SQL, so test/install can
# do the whole thing inside one pg_regress invocation.
extension-update-test:
strategy:
matrix:
pg: [18, 17, 16, 15, 14, 13, 12, 11, 10]
name: ⬆️ Extension update test on PostgreSQL ${{ matrix.pg }}
runs-on: ubuntu-latest
container: pgxn/pgxn-tools
steps:
- name: Start PostgreSQL ${{ matrix.pg }}
run: pg-start ${{ matrix.pg }}
- name: Check out the repo
uses: actions/checkout@v4
- name: Install count_nulls
run: make install
- name: Update 0.9.6 -> current and run the suite
run: make verify-results TEST_LOAD_SOURCE=update

pg-tle-test:
strategy:
matrix:
Expand Down
36 changes: 34 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ TEST_SCHEMA ?=
export PGOPTIONS := $(PGOPTIONS) -c count_nulls.test_schema=$(TEST_SCHEMA)

# Every TEST_SCHEMA value the suite is tested against. A single source so
# test-schema-all and CI (once collapsed - see the "why not a CI matrix"
# note below) can't silently drift onto different sets.
# test-schema-all/test-update-schema-all and CI can't silently drift onto
# different sets.
TEST_SCHEMA_VALUES = "" Quoted

# TEST_SCHEMA is deliberately NOT a CI matrix dimension: unlike PostgreSQL
Expand All @@ -52,3 +52,35 @@ test-schema-all:
echo "=== TEST_SCHEMA=$$schema ==="; \
$(MAKE) test TEST_SCHEMA="$$schema" || exit 1; \
done

# TEST_LOAD_SOURCE selects how test/install/load.sql installs count_nulls
# for the WHOLE test run:
# - 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 -
# committed, since test/install runs outside any per-test rolled-back
# transaction (see pgxntool/README.asc's Update & Upgrade (U&U) Testing
# section for why the commit matters).
# - existing: count_nulls is already installed (a real `pg_upgrade` run,
# external to this invocation) - test/install only asserts it's present
# and current, it does not drop/create/update anything. Meant to be run
# with CONTRIB_TESTDB=<db> EXTRA_REGRESS_OPTS=--use-existing against a
# real database, not via a make wrapper here.
#
# "update" (this) is extension-level (ALTER EXTENSION UPDATE); "upgrade" is
# cluster-level (pg_upgrade) - 'existing' is how that axis is exercised.
#
# Propagated the same way as TEST_SCHEMA: via the count_nulls.test_load_mode
# GUC, exported unconditionally through PGOPTIONS, read without missing_ok.
TEST_LOAD_SOURCE ?= fresh
ifeq ($(filter $(TEST_LOAD_SOURCE),fresh update existing),)
$(error TEST_LOAD_SOURCE must be 'fresh', 'update' or 'existing', 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
61 changes: 61 additions & 0 deletions test/install/load.sql
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,65 @@ CREATE SCHEMA IF NOT EXISTS :"schema";
SET search_path = :"schema";
\endif

/*
* 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, committed (this file runs outside any
* per-test rolled-back transaction, unlike the old test/deps.sql approach -
* see pgxntool/README.asc's U&U section for why the commit matters);
* 'existing' asserts count_nulls is already installed (a real `pg_upgrade`
* run, external to this invocation) and touches nothing.
*
* Read without missing_ok, same reasoning as count_nulls.test_schema above.
*/
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', 'existing') THEN
RAISE EXCEPTION
'count_nulls.test_load_mode must be ''fresh'', ''update'' or ''existing'', got ''%'''
, current_setting('count_nulls.test_load_mode')
;
END IF;
END
$$;

SELECT :'count_nulls_test_load_mode' = 'update' AS count_nulls_update_mode
\gset
SELECT :'count_nulls_test_load_mode' = 'existing' AS count_nulls_existing_mode
\gset

\if :count_nulls_existing_mode
/*
* Already installed by something external to this pg_regress invocation
* (a real pg_upgrade run - see the pg-upgrade-test CI job). Only assert
* it's present and at the current version; do NOT drop/create/update it -
* the whole point of this mode is testing the REAL migrated objects.
*/
DO $$
DECLARE
v_installed text := (SELECT extversion FROM pg_extension WHERE extname = 'count_nulls');
v_default text := (SELECT default_version FROM pg_available_extensions WHERE name = 'count_nulls');
BEGIN
IF v_installed IS NULL THEN
RAISE EXCEPTION 'count_nulls.test_load_mode=existing but count_nulls is not installed';
END IF;
IF v_installed IS DISTINCT FROM v_default THEN
RAISE EXCEPTION 'count_nulls installed at % but default_version is %', v_installed, v_default;
END IF;
END
$$;
\elif :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
Loading