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
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Explicit, not auto-detected: fail loudly if test/install/ ever ends up
# empty by accident, rather than silently falling back to per-test install.
PGXNTOOL_ENABLE_TEST_INSTALL = yes

include pgxntool/base.mk

# Temporary hack
Expand Down
38 changes: 37 additions & 1 deletion test/core/functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,36 @@ END
$body$;
*/

/*
* search_path guard: not a correctness assertion about count_nulls itself,
* but a guard against some OTHER test in this suite accidentally mutating
* search_path (e.g. via a stray SET) and leaking that mutation into every
* test that runs afterward. At this phase there's no TEST_SCHEMA concept
* yet, so the expected search_path for this test session is already a
* static, hardcoded literal - it's set two lines above (SET SEARCH_PATH =
* _null_count_test, tap) - so there's nothing to capture at runtime; just
* compare current_setting('search_path') against that known literal. A
* plain exception is enough here - pgTAP's runner reports any exception
* raised by a teardown__ function as "Test died: ..." against the test it
* ran after, no ok()/is() needed.
*
* SEE ALSO: test__check_ncs in test/sql/extension_tests.sql, which checks
* WHERE count_nulls actually landed (a different risk than this check).
*/
CREATE FUNCTION _null_count_test.teardown__search_path_unchanged
() RETURNS SETOF text LANGUAGE plpgsql AS $body$
DECLARE
v_current text := current_setting('search_path');
BEGIN
IF v_current IS DISTINCT FROM '_null_count_test, tap' THEN
RAISE EXCEPTION
'search_path was left dirty by the preceding test: expected %, got %'
, '_null_count_test, tap', v_current;
END IF;
RETURN;
END
$body$;

/*
* function definition
*/
Expand Down Expand Up @@ -219,6 +249,12 @@ BEGIN
END
$body$;

SET SEARCH_PATH = _null_count_test, tap, :schema;
/*
* No explicit target schema to restore in phase 1 (count_nulls installs
* with no schema targeting at all - see test/install/load.sql), so this
* just re-states the same search_path already set at the top of this file.
* A later schema-targeting phase may need this to do more.
*/
SET SEARCH_PATH = _null_count_test, tap;

-- vi: expandtab sw=2 ts=2
24 changes: 16 additions & 8 deletions test/deps.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
-- Add any test dependency statements here
-- IF NOT EXISTS will emit NOTICEs, which is annoying
SET client_min_messages = WARNING;
CREATE SCHEMA IF NOT EXISTS :schema;
SET search_path = :schema;
SET client_min_messages = NOTICE;

CREATE EXTENSION count_nulls;
/*
* Intentionally empty. test/install/load.sql now installs count_nulls once,
* committed, before test/sql/ runs (see its header comment), so this
* per-test file no longer has anything to do.
*
* Can't be deleted: pgxntool/test/pgxntool/setup.sql (vendored, never
* hand-edited) unconditionally does `\i test/deps.sql`, so every test
* session's setup would fail without it. It's also one of only two files
* (.gitignore, test/deps.sql) that pgxntool's subtree-sync reconciliation
* tracks and 3-way-merges on every `git subtree pull`.
*
* Kept for future use: add per-test dependency statements here again if a
* genuine need arises - e.g. relaying a value into the per-test session via
* a psql variable - same role this file played before test/install took
* over installing count_nulls.
*/
94 changes: 46 additions & 48 deletions test/expected/extension_tests.out
Original file line number Diff line number Diff line change
@@ -1,87 +1,85 @@
\set ECHO none
# Subtest: _null_count_test.test__check_ncs()
ok 1
ok 2 - schema schema_to_load_count_nulls should not be in search path
1..2
ok 1 - ncs() resolves to the schema count_nulls actually installed in
1..1
ok 1 - _null_count_test.test__check_ncs
# Subtest: _null_count_test.test__definition()
ok 1 - ensure null_count({anyarray}) is not in search_path
ok 2 - Function schema_to_load_count_nulls.null_count(anyarray) should return integer
ok 3 - Function schema_to_load_count_nulls.null_count(anyarray) should not be strict
ok 4 - Function schema_to_load_count_nulls.null_count(anyarray) should be IMMUTABLE
ok 2 - Function public.null_count(anyarray) should return integer
ok 3 - Function public.null_count(anyarray) should not be strict
ok 4 - Function public.null_count(anyarray) should be IMMUTABLE
ok 5 - ensure null_count({json}) is not in search_path
ok 6 - Function schema_to_load_count_nulls.null_count(json) should return integer
ok 7 - Function schema_to_load_count_nulls.null_count(json) should not be strict
ok 8 - Function schema_to_load_count_nulls.null_count(json) should be IMMUTABLE
ok 6 - Function public.null_count(json) should return integer
ok 7 - Function public.null_count(json) should not be strict
ok 8 - Function public.null_count(json) should be IMMUTABLE
ok 9 - ensure null_count({jsonb}) is not in search_path
ok 10 - Function schema_to_load_count_nulls.null_count(jsonb) should return integer
ok 11 - Function schema_to_load_count_nulls.null_count(jsonb) should not be strict
ok 12 - Function schema_to_load_count_nulls.null_count(jsonb) should be IMMUTABLE
ok 10 - Function public.null_count(jsonb) should return integer
ok 11 - Function public.null_count(jsonb) should not be strict
ok 12 - Function public.null_count(jsonb) should be IMMUTABLE
ok 13 - ensure not_null_count({anyarray}) is not in search_path
ok 14 - Function schema_to_load_count_nulls.not_null_count(anyarray) should return integer
ok 15 - Function schema_to_load_count_nulls.not_null_count(anyarray) should not be strict
ok 16 - Function schema_to_load_count_nulls.not_null_count(anyarray) should be IMMUTABLE
ok 14 - Function public.not_null_count(anyarray) should return integer
ok 15 - Function public.not_null_count(anyarray) should not be strict
ok 16 - Function public.not_null_count(anyarray) should be IMMUTABLE
ok 17 - ensure not_null_count({json}) is not in search_path
ok 18 - Function schema_to_load_count_nulls.not_null_count(json) should return integer
ok 19 - Function schema_to_load_count_nulls.not_null_count(json) should not be strict
ok 20 - Function schema_to_load_count_nulls.not_null_count(json) should be IMMUTABLE
ok 18 - Function public.not_null_count(json) should return integer
ok 19 - Function public.not_null_count(json) should not be strict
ok 20 - Function public.not_null_count(json) should be IMMUTABLE
ok 21 - ensure not_null_count({jsonb}) is not in search_path
ok 22 - Function schema_to_load_count_nulls.not_null_count(jsonb) should return integer
ok 23 - Function schema_to_load_count_nulls.not_null_count(jsonb) should not be strict
ok 24 - Function schema_to_load_count_nulls.not_null_count(jsonb) should be IMMUTABLE
ok 25 - Function schema_to_load_count_nulls.null_count_trigger() should return trigger
ok 26 - Function schema_to_load_count_nulls.null_count_trigger() should not be strict
ok 27 - Function schema_to_load_count_nulls.null_count_trigger() should be IMMUTABLE
ok 28 - Function schema_to_load_count_nulls.not_null_count_trigger() should return trigger
ok 29 - Function schema_to_load_count_nulls.not_null_count_trigger() should not be strict
ok 30 - Function schema_to_load_count_nulls.not_null_count_trigger() should be IMMUTABLE
ok 22 - Function public.not_null_count(jsonb) should return integer
ok 23 - Function public.not_null_count(jsonb) should not be strict
ok 24 - Function public.not_null_count(jsonb) should be IMMUTABLE
ok 25 - Function public.null_count_trigger() should return trigger
ok 26 - Function public.null_count_trigger() should not be strict
ok 27 - Function public.null_count_trigger() should be IMMUTABLE
ok 28 - Function public.not_null_count_trigger() should return trigger
ok 29 - Function public.not_null_count_trigger() should not be strict
ok 30 - Function public.not_null_count_trigger() should be IMMUTABLE
1..30
ok 2 - _null_count_test.test__definition
# Subtest: _null_count_test.test__functionality()
ok 1 - Test schema_to_load_count_nulls.null_count(a, b, c)
ok 2 - Test schema_to_load_count_nulls.null_count(json)
ok 3 - Test schema_to_load_count_nulls.null_count(jsonb)
ok 4 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.not_null_count_trigger( NULL )
ok 5 - Test schema_to_load_count_nulls.not_null_count_trigger( NULL )
ok 1 - Test public.null_count(a, b, c)
ok 2 - Test public.null_count(json)
ok 3 - Test public.null_count(jsonb)
ok 4 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.not_null_count_trigger( NULL )
ok 5 - Test public.not_null_count_trigger( NULL )
ok 6 - DROP TRIGGER "test trigger"
ok 7 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.not_null_count_trigger( )
ok 8 - Test schema_to_load_count_nulls.not_null_count_trigger( )
ok 7 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.not_null_count_trigger( )
ok 8 - Test public.not_null_count_trigger( )
ok 9 - DROP TRIGGER "test trigger"
ok 10 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.null_count_trigger( NULL )
ok 11 - Test schema_to_load_count_nulls.null_count_trigger( NULL )
ok 10 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.null_count_trigger( NULL )
ok 11 - Test public.null_count_trigger( NULL )
ok 12 - DROP TRIGGER "test trigger"
ok 13 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.null_count_trigger( )
ok 14 - Test schema_to_load_count_nulls.null_count_trigger( )
ok 13 - CREATE TRIGGER "test trigger" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.null_count_trigger( )
ok 14 - Test public.null_count_trigger( )
ok 15 - DROP TRIGGER "test trigger"
ok 16 - CREATE TRIGGER "null_BEFORE_error_message" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.null_count_trigger(1, 'error_message')
ok 16 - CREATE TRIGGER "null_BEFORE_error_message" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.null_count_trigger(1, 'error_message')
ok 17 - Test "null_BEFORE_error_message"
ok 18 - DROP TRIGGER "null_BEFORE_error_message"
ok 19 - CREATE TRIGGER "null_AFTER_error_message" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.null_count_trigger(1, 'error_message')
ok 19 - CREATE TRIGGER "null_AFTER_error_message" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.null_count_trigger(1, 'error_message')
ok 20 - Test "null_AFTER_error_message"
ok 21 - DROP TRIGGER "null_AFTER_error_message"
ok 22 - CREATE TRIGGER "not_null_BEFORE_error_message" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.not_null_count_trigger(1, 'error_message')
ok 22 - CREATE TRIGGER "not_null_BEFORE_error_message" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.not_null_count_trigger(1, 'error_message')
ok 23 - Test "not_null_BEFORE_error_message"
ok 24 - DROP TRIGGER "not_null_BEFORE_error_message"
ok 25 - CREATE TRIGGER "not_null_AFTER_error_message" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.not_null_count_trigger(1, 'error_message')
ok 25 - CREATE TRIGGER "not_null_AFTER_error_message" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.not_null_count_trigger(1, 'error_message')
ok 26 - Test "not_null_AFTER_error_message"
ok 27 - DROP TRIGGER "not_null_AFTER_error_message"
ok 28 - CREATE TRIGGER "null_BEFORE_" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.null_count_trigger(1, NULL)
ok 28 - CREATE TRIGGER "null_BEFORE_" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.null_count_trigger(1, NULL)
ok 29 - Test "null_BEFORE_"
ok 30 - DROP TRIGGER "null_BEFORE_"
ok 31 - CREATE TRIGGER "null_AFTER_" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.null_count_trigger(1, NULL)
ok 31 - CREATE TRIGGER "null_AFTER_" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.null_count_trigger(1, NULL)
ok 32 - Test "null_AFTER_"
ok 33 - DROP TRIGGER "null_AFTER_"
ok 34 - CREATE TRIGGER "not_null_BEFORE_" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.not_null_count_trigger(1, NULL)
ok 34 - CREATE TRIGGER "not_null_BEFORE_" BEFORE INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.not_null_count_trigger(1, NULL)
ok 35 - Test "not_null_BEFORE_"
ok 36 - DROP TRIGGER "not_null_BEFORE_"
ok 37 - CREATE TRIGGER "not_null_AFTER_" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE schema_to_load_count_nulls.not_null_count_trigger(1, NULL)
ok 37 - CREATE TRIGGER "not_null_AFTER_" AFTER INSERT ON test_data FOR EACH ROW EXECUTE PROCEDURE public.not_null_count_trigger(1, NULL)
ok 38 - Test "not_null_AFTER_"
ok 39 - DROP TRIGGER "not_null_AFTER_"
1..39
ok 3 - _null_count_test.test__functionality
# Subtest: _null_count_test.test__shutdown__drop_all()
ok 1
ok 2
1..2
1..1
ok 4 - _null_count_test.test__shutdown__drop_all
1..4
12 changes: 0 additions & 12 deletions test/expected/sanity.out

This file was deleted.

71 changes: 0 additions & 71 deletions test/expected/simple.out

This file was deleted.

2 changes: 2 additions & 0 deletions test/install/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
load.out
install.out.diff
14 changes: 14 additions & 0 deletions test/install/load.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Installs count_nulls once, committed, before the main test/sql/ schedule
* runs (see pgxntool/README.asc's "test/install" and "Update & Upgrade (U&U)
* Testing" sections) - so every file under test/sql/ finds it already
* present instead of each one installing (and dropping) it per-test.
*
* This file's own output is NOT tracked as expected output (see
* test/install/.gitignore): pg_regress resolves both its expected and
* actual-result paths to test/install/load.out, so the diff is always
* self-identical regardless of content. Correctness here comes from this
* file failing loudly (aborting the session) if something's wrong, not
* from a textual comparison - matching cat_tools' test/install/load.sql.
*/
CREATE EXTENSION count_nulls;
Loading
Loading