Hi, while working on installcheck support with meson, that currently running installcheck-world fails regularly with meson and occasionally with make.
A way to quite reliably reproduce this with make is make -s -j48 -C contrib/ USE_MODULE_DB=1 installcheck-adminpack-recurse installcheck-passwordcheck-recurse that will fail with diffs like: diff -du10 /home/andres/src/postgresql/contrib/passwordcheck/expected/passwordcheck.out /home/andres/build/postgres/dev-assert/vpath/contrib/passwordcheck/res> --- /home/andres/src/postgresql/contrib/passwordcheck/expected/passwordcheck.out 2022-10-03 15:56:57.900326662 -0700 +++ /home/andres/build/postgres/dev-assert/vpath/contrib/passwordcheck/results/passwordcheck.out 2022-10-03 15:56:59.930329973 -0700 @@ -1,19 +1,22 @@ LOAD 'passwordcheck'; CREATE USER regress_user1; -- ok ALTER USER regress_user1 PASSWORD 'a_nice_long_password'; +ERROR: tuple concurrently deleted -- error: too short ALTER USER regress_user1 PASSWORD 'tooshrt'; -ERROR: password is too short +ERROR: role "regress_user1" does not exist -- error: contains user name ALTER USER regress_user1 PASSWORD 'xyzregress_user1'; -ERROR: password must not contain user name +ERROR: role "regress_user1" does not exist -- error: contains only letters LOAD 'passwordcheck'; CREATE USER regress_user1; -- ok ALTER USER regress_user1 PASSWORD 'a_nice_long_password'; +ERROR: tuple concurrently deleted -- error: too short ALTER USER regress_user1 PASSWORD 'tooshrt'; -ERROR: password is too short +ERROR: role "regress_user1" does not exist -- error: contains user name That's not surprising, given the common name of "regress_user1". The attached patch fixes a number of instances of this issue. With it I got through ~5 iterations of installcheck-world on ac, and >30 iterations with meson. There's a few further roles that seem to pose some danger goign forward: ./contrib/file_fdw/sql/file_fdw.sql:CREATE ROLE regress_no_priv_user LOGIN; -- has priv but no user mapping ./contrib/postgres_fdw/sql/postgres_fdw.sql:CREATE ROLE regress_view_owner SUPERUSER; ./contrib/postgres_fdw/sql/postgres_fdw.sql:CREATE ROLE regress_nosuper NOSUPERUSER; ./contrib/passwordcheck/sql/passwordcheck.sql:CREATE USER regress_passwordcheck_user1; ./contrib/citext/sql/create_index_acl.sql:CREATE ROLE regress_minimal; ./src/test/modules/test_rls_hooks/sql/test_rls_hooks.sql:CREATE ROLE regress_r1; ./src/test/modules/test_rls_hooks/sql/test_rls_hooks.sql:CREATE ROLE regress_s1; ./src/test/modules/test_oat_hooks/sql/test_oat_hooks.sql:CREATE ROLE regress_role_joe; ./src/test/modules/test_oat_hooks/sql/test_oat_hooks.sql:CREATE USER regress_test_user; ./src/test/modules/unsafe_tests/sql/rolenames.sql:CREATE ROLE regress_testrol0 SUPERUSER LOGIN; ./src/test/modules/unsafe_tests/sql/rolenames.sql:CREATE ROLE regress_testrolx SUPERUSER LOGIN; ./src/test/modules/unsafe_tests/sql/rolenames.sql:CREATE ROLE regress_testrol2 SUPERUSER; ./src/test/modules/unsafe_tests/sql/rolenames.sql:CREATE ROLE regress_testrol1 SUPERUSER LOGIN IN ROLE regress_testrol2; ./src/test/modules/unsafe_tests/sql/rolenames.sql:CREATE ROLE regress_role_haspriv; ./src/test/modules/unsafe_tests/sql/rolenames.sql:CREATE ROLE regress_role_nopriv; ./src/test/modules/unsafe_tests/sql/guc_privs.sql:CREATE ROLE regress_admin SUPERUSER; ./src/test/modules/test_ddl_deparse/sql/alter_function.sql:CREATE ROLE regress_alter_function_role; BTW, shouldn't src/test/modules/unsafe_tests use the PG_TEST_EXTRA mechanism somehow? Seems not great to run it as part of installcheck-world, if we don't want to run it as part of installcheck. A second issue I noticed is that advisory_lock.sql often fails, because the pg_locks queries don't restrict to the current database. Patch attached. I haven't seen that with autoconf installcheck-world, presumably because of this: # There are too many interdependencies between the subdirectories, so # don't attempt parallel make here. .NOTPARALLEL: With those two patches applied, I got through 10 iterations of running all regress / isolation tests concurrently with meson without failures. I attached the meson patch as well, but just because I used it to to get to these patches. Greetings, Andres Freund
>From fee4e186f18134df929618bbd00cc1519149f144 Mon Sep 17 00:00:00 2001 From: Andres Freund <and...@anarazel.de> Date: Sun, 25 Sep 2022 16:49:51 -0700 Subject: [PATCH v2 1/3] tests: Rename conflicting role names These cause problems when running installcheck concurrently. --- src/pl/plperl/expected/plperl_setup.out | 30 +++++++++---------- src/pl/plperl/sql/plperl_setup.sql | 30 +++++++++---------- contrib/adminpack/expected/adminpack.out | 20 ++++++------- contrib/adminpack/sql/adminpack.sql | 20 ++++++------- .../passwordcheck/expected/passwordcheck.out | 16 +++++----- contrib/passwordcheck/sql/passwordcheck.sql | 16 +++++----- 6 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/pl/plperl/expected/plperl_setup.out b/src/pl/plperl/expected/plperl_setup.out index 5234febefd6..5537a95ccc2 100644 --- a/src/pl/plperl/expected/plperl_setup.out +++ b/src/pl/plperl/expected/plperl_setup.out @@ -4,9 +4,9 @@ -- Before going ahead with the to-be-tested installations, verify that -- a non-superuser is allowed to install plperl (but not plperlu) when -- suitable permissions have been granted. -CREATE USER regress_user1; -CREATE USER regress_user2; -SET ROLE regress_user1; +CREATE USER regress_plperl_user1; +CREATE USER regress_plperl_user2; +SET ROLE regress_plperl_user1; CREATE EXTENSION plperl; -- fail ERROR: permission denied to create extension "plperl" HINT: Must have CREATE privilege on current database to create this extension. @@ -16,18 +16,18 @@ HINT: Must be superuser to create this extension. RESET ROLE; DO $$ begin - execute format('grant create on database %I to regress_user1', + execute format('grant create on database %I to regress_plperl_user1', current_database()); end; $$; -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; CREATE EXTENSION plperl; CREATE EXTENSION plperlu; -- fail ERROR: permission denied to create extension "plperlu" HINT: Must be superuser to create this extension. CREATE SCHEMA plperl_setup_scratch; SET search_path = plperl_setup_scratch; -GRANT ALL ON SCHEMA plperl_setup_scratch TO regress_user2; +GRANT ALL ON SCHEMA plperl_setup_scratch TO regress_plperl_user2; CREATE FUNCTION foo1() returns int language plperl as '1;'; SELECT foo1(); foo1 @@ -38,15 +38,15 @@ SELECT foo1(); -- Must reconnect to avoid failure with non-MULTIPLICITY Perl interpreters \c - SET search_path = plperl_setup_scratch; -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; -- Should be able to change privileges on the language revoke all on language plperl from public; -SET ROLE regress_user2; +SET ROLE regress_plperl_user2; CREATE FUNCTION foo2() returns int language plperl as '2;'; -- fail ERROR: permission denied for language plperl -SET ROLE regress_user1; -grant usage on language plperl to regress_user2; -SET ROLE regress_user2; +SET ROLE regress_plperl_user1; +grant usage on language plperl to regress_plperl_user2; +SET ROLE regress_plperl_user2; CREATE FUNCTION foo2() returns int language plperl as '2;'; SELECT foo2(); foo2 @@ -54,7 +54,7 @@ SELECT foo2(); 2 (1 row) -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; -- Should be able to drop the extension, but not the language per se DROP LANGUAGE plperl CASCADE; ERROR: cannot drop language plperl because extension plperl requires it @@ -65,9 +65,9 @@ DETAIL: drop cascades to function foo1() drop cascades to function foo2() -- Clean up RESET ROLE; -DROP OWNED BY regress_user1; -DROP USER regress_user1; -DROP USER regress_user2; +DROP OWNED BY regress_plperl_user1; +DROP USER regress_plperl_user1; +DROP USER regress_plperl_user2; -- Now install the versions that will be used by subsequent test scripts. CREATE EXTENSION plperl; CREATE EXTENSION plperlu; diff --git a/src/pl/plperl/sql/plperl_setup.sql b/src/pl/plperl/sql/plperl_setup.sql index a89cf56617e..0eac9156294 100644 --- a/src/pl/plperl/sql/plperl_setup.sql +++ b/src/pl/plperl/sql/plperl_setup.sql @@ -6,10 +6,10 @@ -- a non-superuser is allowed to install plperl (but not plperlu) when -- suitable permissions have been granted. -CREATE USER regress_user1; -CREATE USER regress_user2; +CREATE USER regress_plperl_user1; +CREATE USER regress_plperl_user2; -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; CREATE EXTENSION plperl; -- fail CREATE EXTENSION plperlu; -- fail @@ -18,18 +18,18 @@ RESET ROLE; DO $$ begin - execute format('grant create on database %I to regress_user1', + execute format('grant create on database %I to regress_plperl_user1', current_database()); end; $$; -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; CREATE EXTENSION plperl; CREATE EXTENSION plperlu; -- fail CREATE SCHEMA plperl_setup_scratch; SET search_path = plperl_setup_scratch; -GRANT ALL ON SCHEMA plperl_setup_scratch TO regress_user2; +GRANT ALL ON SCHEMA plperl_setup_scratch TO regress_plperl_user2; CREATE FUNCTION foo1() returns int language plperl as '1;'; SELECT foo1(); @@ -38,25 +38,25 @@ SELECT foo1(); \c - SET search_path = plperl_setup_scratch; -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; -- Should be able to change privileges on the language revoke all on language plperl from public; -SET ROLE regress_user2; +SET ROLE regress_plperl_user2; CREATE FUNCTION foo2() returns int language plperl as '2;'; -- fail -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; -grant usage on language plperl to regress_user2; +grant usage on language plperl to regress_plperl_user2; -SET ROLE regress_user2; +SET ROLE regress_plperl_user2; CREATE FUNCTION foo2() returns int language plperl as '2;'; SELECT foo2(); -SET ROLE regress_user1; +SET ROLE regress_plperl_user1; -- Should be able to drop the extension, but not the language per se DROP LANGUAGE plperl CASCADE; @@ -64,9 +64,9 @@ DROP EXTENSION plperl CASCADE; -- Clean up RESET ROLE; -DROP OWNED BY regress_user1; -DROP USER regress_user1; -DROP USER regress_user2; +DROP OWNED BY regress_plperl_user1; +DROP USER regress_plperl_user1; +DROP USER regress_plperl_user2; -- Now install the versions that will be used by subsequent test scripts. CREATE EXTENSION plperl; diff --git a/contrib/adminpack/expected/adminpack.out b/contrib/adminpack/expected/adminpack.out index 76aafe6316a..6bcf2217f25 100644 --- a/contrib/adminpack/expected/adminpack.out +++ b/contrib/adminpack/expected/adminpack.out @@ -36,10 +36,10 @@ SELECT pg_read_file('test_file1'); -- disallowed file paths for non-superusers and users who are -- not members of pg_write_server_files -CREATE ROLE regress_user1; -GRANT pg_read_all_settings TO regress_user1; -GRANT EXECUTE ON FUNCTION pg_file_write(text,text,bool) TO regress_user1; -SET ROLE regress_user1; +CREATE ROLE regress_adminpack_user1; +GRANT pg_read_all_settings TO regress_adminpack_user1; +GRANT EXECUTE ON FUNCTION pg_file_write(text,text,bool) TO regress_adminpack_user1; +SET ROLE regress_adminpack_user1; SELECT pg_file_write('../test_file0', 'test0', false); ERROR: path must be in or below the current directory SELECT pg_file_write('/tmp/test_file0', 'test0', false); @@ -53,9 +53,9 @@ SELECT pg_file_write(current_setting('data_directory') || '/test_file4', 'test4' SELECT pg_file_write(current_setting('data_directory') || '/../test_file4', 'test4', false); ERROR: absolute path not allowed RESET ROLE; -REVOKE EXECUTE ON FUNCTION pg_file_write(text,text,bool) FROM regress_user1; -REVOKE pg_read_all_settings FROM regress_user1; -DROP ROLE regress_user1; +REVOKE EXECUTE ON FUNCTION pg_file_write(text,text,bool) FROM regress_adminpack_user1; +REVOKE pg_read_all_settings FROM regress_adminpack_user1; +DROP ROLE regress_adminpack_user1; -- sync SELECT pg_file_sync('test_file1'); -- sync file pg_file_sync @@ -153,8 +153,8 @@ SELECT pg_file_unlink('test_file4'); (1 row) -- superuser checks -CREATE USER regress_user1; -SET ROLE regress_user1; +CREATE USER regress_adminpack_user1; +SET ROLE regress_adminpack_user1; SELECT pg_file_write('test_file0', 'test0', false); ERROR: permission denied for function pg_file_write SELECT pg_file_sync('test_file0'); @@ -167,6 +167,6 @@ ERROR: permission denied for function pg_file_unlink SELECT pg_logdir_ls(); ERROR: permission denied for function pg_logdir_ls RESET ROLE; -DROP USER regress_user1; +DROP USER regress_adminpack_user1; -- no further tests for pg_logdir_ls() because it depends on the -- server's logging setup diff --git a/contrib/adminpack/sql/adminpack.sql b/contrib/adminpack/sql/adminpack.sql index 918d0bdc65e..5776c9af0d1 100644 --- a/contrib/adminpack/sql/adminpack.sql +++ b/contrib/adminpack/sql/adminpack.sql @@ -14,20 +14,20 @@ SELECT pg_read_file('test_file1'); -- disallowed file paths for non-superusers and users who are -- not members of pg_write_server_files -CREATE ROLE regress_user1; +CREATE ROLE regress_adminpack_user1; -GRANT pg_read_all_settings TO regress_user1; -GRANT EXECUTE ON FUNCTION pg_file_write(text,text,bool) TO regress_user1; +GRANT pg_read_all_settings TO regress_adminpack_user1; +GRANT EXECUTE ON FUNCTION pg_file_write(text,text,bool) TO regress_adminpack_user1; -SET ROLE regress_user1; +SET ROLE regress_adminpack_user1; SELECT pg_file_write('../test_file0', 'test0', false); SELECT pg_file_write('/tmp/test_file0', 'test0', false); SELECT pg_file_write(current_setting('data_directory') || '/test_file4', 'test4', false); SELECT pg_file_write(current_setting('data_directory') || '/../test_file4', 'test4', false); RESET ROLE; -REVOKE EXECUTE ON FUNCTION pg_file_write(text,text,bool) FROM regress_user1; -REVOKE pg_read_all_settings FROM regress_user1; -DROP ROLE regress_user1; +REVOKE EXECUTE ON FUNCTION pg_file_write(text,text,bool) FROM regress_adminpack_user1; +REVOKE pg_read_all_settings FROM regress_adminpack_user1; +DROP ROLE regress_adminpack_user1; -- sync SELECT pg_file_sync('test_file1'); -- sync file @@ -59,8 +59,8 @@ SELECT pg_file_unlink('test_file4'); -- superuser checks -CREATE USER regress_user1; -SET ROLE regress_user1; +CREATE USER regress_adminpack_user1; +SET ROLE regress_adminpack_user1; SELECT pg_file_write('test_file0', 'test0', false); SELECT pg_file_sync('test_file0'); @@ -69,7 +69,7 @@ SELECT pg_file_unlink('test_file0'); SELECT pg_logdir_ls(); RESET ROLE; -DROP USER regress_user1; +DROP USER regress_adminpack_user1; -- no further tests for pg_logdir_ls() because it depends on the diff --git a/contrib/passwordcheck/expected/passwordcheck.out b/contrib/passwordcheck/expected/passwordcheck.out index e04cda6bd95..2027681daf6 100644 --- a/contrib/passwordcheck/expected/passwordcheck.out +++ b/contrib/passwordcheck/expected/passwordcheck.out @@ -1,19 +1,19 @@ LOAD 'passwordcheck'; -CREATE USER regress_user1; +CREATE USER regress_passwordcheck_user1; -- ok -ALTER USER regress_user1 PASSWORD 'a_nice_long_password'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short -ALTER USER regress_user1 PASSWORD 'tooshrt'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; ERROR: password is too short -- error: contains user name -ALTER USER regress_user1 PASSWORD 'xyzregress_user1'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'xyzregress_passwordcheck_user1'; ERROR: password must not contain user name -- error: contains only letters -ALTER USER regress_user1 PASSWORD 'alessnicelongpassword'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'alessnicelongpassword'; ERROR: password must contain both letters and nonletters -- encrypted ok (password is "secret") -ALTER USER regress_user1 PASSWORD 'md51a44d829a20a23eac686d9f0d258af13'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'md592350e12ac34e52dd598f90893bb3ae7'; -- error: password is user name -ALTER USER regress_user1 PASSWORD 'md5e589150ae7d28f93333afae92b36ef48'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'md507a112732ed9f2087fa90b192d44e358'; ERROR: password must not equal user name -DROP USER regress_user1; +DROP USER regress_passwordcheck_user1; diff --git a/contrib/passwordcheck/sql/passwordcheck.sql b/contrib/passwordcheck/sql/passwordcheck.sql index d98796ac494..1fbd6b0e96e 100644 --- a/contrib/passwordcheck/sql/passwordcheck.sql +++ b/contrib/passwordcheck/sql/passwordcheck.sql @@ -1,23 +1,23 @@ LOAD 'passwordcheck'; -CREATE USER regress_user1; +CREATE USER regress_passwordcheck_user1; -- ok -ALTER USER regress_user1 PASSWORD 'a_nice_long_password'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short -ALTER USER regress_user1 PASSWORD 'tooshrt'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; -- error: contains user name -ALTER USER regress_user1 PASSWORD 'xyzregress_user1'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'xyzregress_passwordcheck_user1'; -- error: contains only letters -ALTER USER regress_user1 PASSWORD 'alessnicelongpassword'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'alessnicelongpassword'; -- encrypted ok (password is "secret") -ALTER USER regress_user1 PASSWORD 'md51a44d829a20a23eac686d9f0d258af13'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'md592350e12ac34e52dd598f90893bb3ae7'; -- error: password is user name -ALTER USER regress_user1 PASSWORD 'md5e589150ae7d28f93333afae92b36ef48'; +ALTER USER regress_passwordcheck_user1 PASSWORD 'md507a112732ed9f2087fa90b192d44e358'; -DROP USER regress_user1; +DROP USER regress_passwordcheck_user1; -- 2.37.3.542.gdd3f6c4cae
>From 36db621755bd4e31e9431e432c7bdc3823f71db5 Mon Sep 17 00:00:00 2001 From: Andres Freund <and...@anarazel.de> Date: Mon, 3 Oct 2022 16:30:36 -0700 Subject: [PATCH v2 2/3] test: Restrict pg_locks queries in advisory_locks.sql to current database Otherwise testing an existing installation can fail, if there are other locks, e.g. from one of the isolation tests. Author: Reviewed-by: Discussion: https://postgr.es/m/ Backpatch: --- src/test/regress/expected/advisory_lock.out | 31 ++++++++++---------- src/test/regress/sql/advisory_lock.sql | 32 +++++++++++---------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/test/regress/expected/advisory_lock.out b/src/test/regress/expected/advisory_lock.out index 2a2df6f7e4b..02e07765ac2 100644 --- a/src/test/regress/expected/advisory_lock.out +++ b/src/test/regress/expected/advisory_lock.out @@ -1,6 +1,7 @@ -- -- ADVISORY LOCKS -- +SELECT oid AS datoid FROM pg_database WHERE datname = current_database() \gset BEGIN; SELECT pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), @@ -11,7 +12,7 @@ SELECT (1 row) SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -28,7 +29,7 @@ SELECT pg_advisory_unlock_all(); (1 row) -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 4 @@ -49,7 +50,7 @@ WARNING: you don't own a lock of type ShareLock -- automatically release xact locks at commit COMMIT; -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 0 @@ -66,7 +67,7 @@ SELECT (1 row) SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -86,7 +87,7 @@ SELECT ROLLBACK; SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -111,7 +112,7 @@ WARNING: you don't own a lock of type ShareLock t | f | t | f | t | f | t | f (1 row) -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 0 @@ -128,7 +129,7 @@ SELECT (1 row) SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -148,7 +149,7 @@ SELECT ROLLBACK; SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -165,7 +166,7 @@ SELECT pg_advisory_unlock_all(); (1 row) -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 0 @@ -184,7 +185,7 @@ SELECT (1 row) SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -195,7 +196,7 @@ SELECT locktype, classid, objid, objsubid, mode, granted (4 rows) COMMIT; -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 0 @@ -213,7 +214,7 @@ SELECT (1 row) SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -233,7 +234,7 @@ SELECT t | t | t | t | t | t | t | t (1 row) -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 0 @@ -251,7 +252,7 @@ SELECT (1 row) SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; locktype | classid | objid | objsubid | mode | granted ----------+---------+-------+----------+---------------+--------- @@ -267,7 +268,7 @@ SELECT pg_advisory_unlock_all(); (1 row) -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; count ------- 0 diff --git a/src/test/regress/sql/advisory_lock.sql b/src/test/regress/sql/advisory_lock.sql index 57c47c0faca..8513ab8e98f 100644 --- a/src/test/regress/sql/advisory_lock.sql +++ b/src/test/regress/sql/advisory_lock.sql @@ -2,6 +2,8 @@ -- ADVISORY LOCKS -- +SELECT oid AS datoid FROM pg_database WHERE datname = current_database() \gset + BEGIN; SELECT @@ -9,14 +11,14 @@ SELECT pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2); SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; -- pg_advisory_unlock_all() shouldn't release xact locks SELECT pg_advisory_unlock_all(); -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; -- can't unlock xact locks @@ -28,7 +30,7 @@ SELECT -- automatically release xact locks at commit COMMIT; -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; BEGIN; @@ -39,7 +41,7 @@ SELECT pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2); SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; SELECT @@ -49,7 +51,7 @@ SELECT ROLLBACK; SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; @@ -60,7 +62,7 @@ SELECT pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2); -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; BEGIN; @@ -71,7 +73,7 @@ SELECT pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2); SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; SELECT @@ -81,14 +83,14 @@ SELECT ROLLBACK; SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; -- releasing all session locks SELECT pg_advisory_unlock_all(); -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; BEGIN; @@ -102,12 +104,12 @@ SELECT pg_advisory_xact_lock_shared(2, 2), pg_advisory_xact_lock_shared(2, 2); SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; COMMIT; -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; -- grabbing session locks multiple times @@ -118,7 +120,7 @@ SELECT pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2); SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; SELECT @@ -127,7 +129,7 @@ SELECT pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2); -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; -- .. and releasing them all at once @@ -138,9 +140,9 @@ SELECT pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2); SELECT locktype, classid, objid, objsubid, mode, granted - FROM pg_locks WHERE locktype = 'advisory' + FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid ORDER BY classid, objid, objsubid; SELECT pg_advisory_unlock_all(); -SELECT count(*) FROM pg_locks WHERE locktype = 'advisory'; +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = :datoid; -- 2.37.3.542.gdd3f6c4cae
>From 5f546b4d05747eff04d81dc15437de27bbaad7fb Mon Sep 17 00:00:00 2001 From: Andres Freund <and...@anarazel.de> Date: Sun, 25 Sep 2022 16:57:01 -0700 Subject: [PATCH v2 3/3] wip: meson: Add installcheck equivalent run all tests that support running against existing server: $ meson test --setup running run just the main pg_regress tests against existing server: $ meson test --setup running main-running/regress --- contrib/basic_archive/meson.build | 1 + contrib/pg_freespacemap/meson.build | 3 + contrib/pg_stat_statements/meson.build | 4 + contrib/pg_walinspect/meson.build | 3 + contrib/test_decoding/meson.build | 5 ++ src/interfaces/ecpg/test/meson.build | 1 + src/test/isolation/meson.build | 1 + src/test/modules/commit_ts/meson.build | 3 + src/test/modules/snapshot_too_old/meson.build | 3 + src/test/modules/test_oat_hooks/meson.build | 1 + src/test/modules/test_pg_dump/meson.build | 2 + src/test/modules/worker_spi/meson.build | 4 +- src/test/regress/meson.build | 1 + .cirrus.yml | 15 ++++ meson.build | 87 ++++++++++++++++--- 15 files changed, 120 insertions(+), 14 deletions(-) diff --git a/contrib/basic_archive/meson.build b/contrib/basic_archive/meson.build index b67cbef60bd..0600c04940b 100644 --- a/contrib/basic_archive/meson.build +++ b/contrib/basic_archive/meson.build @@ -19,5 +19,6 @@ tests += { 'regress_args': [ '--temp-config', files('basic_archive.conf'), ], + 'runningcheck': false, }, } diff --git a/contrib/pg_freespacemap/meson.build b/contrib/pg_freespacemap/meson.build index f795014d7ca..a8703660c73 100644 --- a/contrib/pg_freespacemap/meson.build +++ b/contrib/pg_freespacemap/meson.build @@ -25,5 +25,8 @@ tests += { 'regress_args': [ '--temp-config', files('pg_freespacemap.conf') ], + # Disabled because these tests require "autovacuum=off", which + # typical runningcheck users do not have (e.g. buildfarm clients). + 'runningcheck': false, }, } diff --git a/contrib/pg_stat_statements/meson.build b/contrib/pg_stat_statements/meson.build index ac117d2fc1d..07c5d5d4442 100644 --- a/contrib/pg_stat_statements/meson.build +++ b/contrib/pg_stat_statements/meson.build @@ -31,5 +31,9 @@ tests += { 'pg_stat_statements', ], 'regress_args': ['--temp-config', files('pg_stat_statements.conf')], + # Disabled because these tests require + # "shared_preload_libraries=pg_stat_statements", which typical + # runningcheck users do not have (e.g. buildfarm clients). + 'runningcheck': false, }, } diff --git a/contrib/pg_walinspect/meson.build b/contrib/pg_walinspect/meson.build index d6b27877dd0..15a052ec879 100644 --- a/contrib/pg_walinspect/meson.build +++ b/contrib/pg_walinspect/meson.build @@ -22,6 +22,9 @@ tests += { 'sql': [ 'pg_walinspect', ], + # Disabled because these tests require "wal_level=replica", which + # some runningcheck users do not have (e.g. buildfarm clients). 'regress_args': ['--temp-config', files('walinspect.conf')], + 'runningcheck': false, }, } diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build index dd7cb0101ad..48b9c866a43 100644 --- a/contrib/test_decoding/meson.build +++ b/contrib/test_decoding/meson.build @@ -37,6 +37,9 @@ tests += { 'regress_args': [ '--temp-config', files('logical.conf'), ], + # Disabled because these tests require "wal_level=logical", which + # typical runningcheck users do not have (e.g. buildfarm clients). + 'runningcheck': false, }, 'isolation': { 'specs': [ @@ -54,6 +57,8 @@ tests += { 'regress_args': [ '--temp-config', files('logical.conf'), ], + # see above + 'runningcheck': false, }, 'tap': { 'tests': [ diff --git a/src/interfaces/ecpg/test/meson.build b/src/interfaces/ecpg/test/meson.build index f0ace641f0c..21331501a5a 100644 --- a/src/interfaces/ecpg/test/meson.build +++ b/src/interfaces/ecpg/test/meson.build @@ -79,6 +79,7 @@ tests += { 'test_kwargs': { 'depends': ecpg_test_dependencies, }, + 'dbname': 'ecpg1_regression,ecpg2_regression', 'regress_args': ecpg_regress_args, }, } diff --git a/src/test/isolation/meson.build b/src/test/isolation/meson.build index c7656fd4609..6c748b08209 100644 --- a/src/test/isolation/meson.build +++ b/src/test/isolation/meson.build @@ -54,5 +54,6 @@ tests += { 'priority': 40, 'timeout': 1000, }, + 'dbname': 'isolation_regression', }, } diff --git a/src/test/modules/commit_ts/meson.build b/src/test/modules/commit_ts/meson.build index 60cb12164d2..fa86e70e880 100644 --- a/src/test/modules/commit_ts/meson.build +++ b/src/test/modules/commit_ts/meson.build @@ -6,6 +6,9 @@ tests += { 'sql': [ 'commit_timestamp', ], + # Disabled because these tests require "track_commit_timestamp = on", + # which typical runningcheck users do not have (e.g. buildfarm clients). + 'runningcheck': false, }, 'tap': { 'tests': [ diff --git a/src/test/modules/snapshot_too_old/meson.build b/src/test/modules/snapshot_too_old/meson.build index efd3f1f113b..5094b52949b 100644 --- a/src/test/modules/snapshot_too_old/meson.build +++ b/src/test/modules/snapshot_too_old/meson.build @@ -10,5 +10,8 @@ tests += { 'sto_using_hash_index', ], 'regress_args': ['--temp-config', files('sto.conf')], + # Disabled because these tests require "old_snapshot_threshold" >= 0, which + # typical runningcheck users do not have (e.g. buildfarm clients). + 'runningcheck': false, }, } diff --git a/src/test/modules/test_oat_hooks/meson.build b/src/test/modules/test_oat_hooks/meson.build index 5faf0459777..b2faab98a5f 100644 --- a/src/test/modules/test_oat_hooks/meson.build +++ b/src/test/modules/test_oat_hooks/meson.build @@ -14,5 +14,6 @@ tests += { 'test_oat_hooks', ], 'regress_args': ['--no-locale', '--encoding=UTF8'], + 'runningcheck': false, }, } diff --git a/src/test/modules/test_pg_dump/meson.build b/src/test/modules/test_pg_dump/meson.build index 41021829f3a..73f1fcf9428 100644 --- a/src/test/modules/test_pg_dump/meson.build +++ b/src/test/modules/test_pg_dump/meson.build @@ -13,6 +13,8 @@ tests += { 'sql': [ 'test_pg_dump', ], + # doesn't delete its user + 'runningcheck': false, }, 'tap': { 'tests': [ diff --git a/src/test/modules/worker_spi/meson.build b/src/test/modules/worker_spi/meson.build index 32acad883b2..5491248f16f 100644 --- a/src/test/modules/worker_spi/meson.build +++ b/src/test/modules/worker_spi/meson.build @@ -21,6 +21,8 @@ tests += { 'sql': [ 'worker_spi', ], - 'regress_args': ['--temp-config', files('dynamic.conf'), '--dbname=contrib_regression'], + 'dbname': 'contrib_regression', + 'regress_args': ['--temp-config', files('dynamic.conf')], + 'runningcheck': false, }, } diff --git a/src/test/regress/meson.build b/src/test/regress/meson.build index 03de591b0c7..18a5e1acf7c 100644 --- a/src/test/regress/meson.build +++ b/src/test/regress/meson.build @@ -67,5 +67,6 @@ tests += { 'priority': 50, 'timeout': 1000, }, + 'dbname': 'regression', }, } diff --git a/.cirrus.yml b/.cirrus.yml index 531cfe96f65..e5416371049 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -122,6 +122,21 @@ task: meson test $MTEST_ARGS --num-processes ${TEST_JOBS} EOF + # test runningcheck, freebsd chosen because it's currently fast enough + test_running_script: | + su postgres <<-EOF + set -e + ulimit -c unlimited + meson test $MTEST_ARGS --quiet --suite setup + export LD_LIBRARY_PATH="$(pwd)/build/tmp_install/usr/local/pgsql/lib/:$LD_LIBRARY_PATH" + mkdir -p build/testrun + build/tmp_install/usr/local/pgsql/bin/initdb -N build/runningcheck --no-instructions -A trust + echo "include '$(pwd)/src/tools/ci/pg_ci_base.conf'" >> build/runningcheck/postgresql.conf + build/tmp_install/usr/local/pgsql/bin/pg_ctl -c -o '-c fsync=off' -D build/runningcheck -l build/testrun/runningcheck.log start + meson test $MTEST_ARGS --num-processes ${TEST_JOBS} --setup running + build/tmp_install/usr/local/pgsql/bin/pg_ctl -D build/runningcheck stop + EOF + on_failure: <<: *on_failure_meson cores_script: src/tools/ci/cores_backtrace.sh freebsd /tmp/cores diff --git a/meson.build b/meson.build index 253994931e8..48e6a108bfe 100644 --- a/meson.build +++ b/meson.build @@ -2820,6 +2820,18 @@ endif # Test Generation ############################################################### +# when using a meson version understanding exclude_suites, define a 'default' +# test setup that excludes tests running against a pre-existing install and a +# 'running' setup that conflicts with creation of the temporary installation +# and tap tests (which don't support running against a running server). +running_suites = [] +install_suites = [] +if meson.version().version_compare('>=0.57') + runningcheck = true +else + runningcheck = false +endif + testwrap = files('src/tools/testwrap') foreach test_dir : tests @@ -2827,7 +2839,6 @@ foreach test_dir : tests testwrap, '--basedir', meson.build_root(), '--srcdir', test_dir['sd'], - '--testgroup', test_dir['name'], ] foreach kind, v : test_dir @@ -2840,41 +2851,51 @@ foreach test_dir : tests if kind in ['regress', 'isolation', 'ecpg'] if kind == 'regress' runner = pg_regress + fallback_dbname = 'regression_@0@' elif kind == 'isolation' runner = pg_isolation_regress + fallback_dbname = 'isolation_regression_@0@' elif kind == 'ecpg' runner = pg_regress_ecpg + fallback_dbname = 'ecpg_regression_@0@' endif - test_output = test_result_dir / test_dir['name'] / kind + test_group = test_dir['name'] + test_group_running = test_dir['name'] + '-running' - test_command = [ + test_output = test_result_dir / test_group / kind + test_output_running = test_result_dir / test_group_running/ kind + + # Unless specified by the test, choose a non-conflicting database name, + # to avoid conflicts when running against existing server. + dbname = t.get('dbname', + fallback_dbname.format(test_dir['name'])) + + test_command_base = [ runner.full_path(), '--inputdir', t.get('inputdir', test_dir['sd']), '--expecteddir', t.get('expecteddir', test_dir['sd']), - '--outputdir', test_output, - '--temp-instance', test_output / 'tmp_check', '--bindir', '', '--dlpath', test_dir['bd'], '--max-concurrent-tests=20', - '--port', testport.to_string(), + '--dbname', dbname, ] + t.get('regress_args', []) + test_selection = [] if t.has_key('schedule') - test_command += ['--schedule', t['schedule'],] + test_selection += ['--schedule', t['schedule'],] endif if kind == 'isolation' - test_command += t.get('specs', []) + test_selection += t.get('specs', []) else - test_command += t.get('sql', []) + test_selection += t.get('sql', []) endif env = test_env env.prepend('PATH', temp_install_bindir, test_dir['bd']) test_kwargs = { - 'suite': [test_dir['name']], 'priority': 10, 'timeout': 1000, 'depends': test_deps + t.get('deps', []), @@ -2883,12 +2904,41 @@ foreach test_dir : tests test(test_dir['name'] / kind, python, - args: testwrap_base + [ + args: [ + testwrap_base, + '--testgroup', test_group, '--testname', kind, - '--', test_command, + '--', + test_command_base, + '--outputdir', test_output, + '--temp-instance', test_output / 'tmp_check', + '--port', testport.to_string(), + test_selection, ], + suite: test_group, kwargs: test_kwargs, ) + install_suites += test_dir['name'] + + # some tests can't support running against running DB + if runningcheck and t.get('runningcheck', true) + test(test_group_running / kind, + python, + args: [ + testwrap_base, + '--testgroup', test_group_running, + '--testname', kind, + '--', + test_command_base, + '--outputdir', test_output_running, + test_selection, + ], + is_parallel: t.get('runningcheck-parallel', true), + suite: test_group_running, + kwargs: test_kwargs, + ) + running_suites += test_group_running + endif testport += 1 elif kind == 'tap' @@ -2911,9 +2961,10 @@ foreach test_dir : tests env.set(name, value) endforeach + suite = test_dir['name'] test_kwargs = { 'protocol': 'tap', - 'suite': [test_dir['name']], + 'suite': suite, 'timeout': 1000, 'depends': test_deps + t.get('deps', []), 'env': env, @@ -2933,12 +2984,14 @@ foreach test_dir : tests python, kwargs: test_kwargs, args: testwrap_base + [ + '--testgroup', test_dir['name'], '--testname', onetap_p, '--', test_command, test_dir['sd'] / onetap, ], ) endforeach + install_suites += suite else error('unknown kind @0@ of test in @1@'.format(kind, test_dir['sd'])) endif @@ -2947,6 +3000,14 @@ foreach test_dir : tests endforeach # directories with tests +# repeat condition so meson realizes version dependency +if meson.version().version_compare('>=0.57') + add_test_setup('default', + is_default: true, + exclude_suites: running_suites) + add_test_setup('running', + exclude_suites: ['setup'] + install_suites) +endif ############################################################### -- 2.37.3.542.gdd3f6c4cae