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 }}
run: pg-build-test

# 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
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,35 @@ testdeps: $(wildcard test/*/*.sql) $(wildcard test/*.sql) # Be careful not to in
# still fails loudly instead of looking identical to a deliberately empty one.
TEST_SCHEMA ?=
export PGOPTIONS := $(PGOPTIONS) -c count_nulls.test_schema=$(TEST_SCHEMA)

# 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