Skip to content
Draft
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
22 changes: 17 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,22 @@ jobs:
# is what actually proves that works from a plain clone.
run: make lint

# Fresh install, across the PG matrix. Every TEST_SCHEMA value (empty -
# no schema targeting at all - and 'Quoted', a name requiring SQL
# identifier quoting) is exercised too, via `make test-schema-all`'s
# in-Makefile loop rather than a CI matrix dimension - a schema name is
# Fresh install, then the in-place extension update path, both across the
# PG matrix. The update leg CREATE EXTENSIONs at the oldest version we
# still ship a full install script for (0.9.6), then ALTER EXTENSION
# UPDATEs to current (no pg_upgrade, same PostgreSQL) and reruns the
# suite - a single job rather than a dedicated one, since a load mode is
# just an input the same assertions run against, not a real environment
# difference (same reasoning as TEST_SCHEMA below), and the per-version
# container/checkout setup would otherwise be duplicated across two jobs
# with the same PG matrix. Every TEST_SCHEMA value (empty - no schema
# targeting at all - and 'Quoted', a name requiring SQL identifier
# quoting) is exercised too, via `make test-schema-all`'s in-Makefile
# loop rather than a CI matrix dimension - a schema name is just an
# input the same assertions run against, not a real environment
# difference, so crossing it into the matrix would only multiply job
# count for no added confidence (see the Makefile's TEST_SCHEMA_VALUES
# comment). Both legs pass against the SAME
# comment). Every leg passes against the SAME
# test/expected/extension_tests.out (see test/README.md for how the
# suite keeps its output schema-invariant).
test:
Expand All @@ -41,6 +49,10 @@ jobs:
uses: actions/checkout@v4
- name: Test on PostgreSQL ${{ matrix.pg }}, across every TEST_SCHEMA value
run: make test-schema-all
- 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:
Expand Down
36 changes: 34 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,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 @@ -57,3 +57,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 @@ -34,4 +34,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