2 # Copyright (c) 2021-2024, PostgreSQL Global Development Group
5 use warnings FATAL
=> 'all';
7 use PostgreSQL
::Test
::Cluster
;
8 use PostgreSQL
::Test
::Utils
;
11 my $tempdir = PostgreSQL
::Test
::Utils
::tempdir
;
13 ###############################################################
14 # This structure is based off of the src/bin/pg_dump/t test
16 ###############################################################
17 # Definition of the pg_dump runs to make.
19 # Each of these runs are named and those names are used below
20 # to define how each test should (or shouldn't) treat a result
23 # compile_option indicates if the commands run depend on a compilation
24 # option, if any. This can be used to control if tests should be
25 # skipped when a build dependency is not satisfied.
27 # test_key indicates that a given run should simply use the same
28 # set of like/unlike tests as another run, and which run that is.
30 # dump_cmd is the pg_dump command to run, which is an array of
31 # the full command and arguments to run. Note that this is run
32 # using $node->command_ok(), so the port does not need to be
33 # specified and is pulled from $PGPORT, which is set by the
34 # PostgreSQL::Test::Cluster system.
36 # restore_cmd is the pg_restore command to run, if any. Note
37 # that this should generally be used when the pg_dump goes to
38 # a non-text file and that the restore can then be used to
39 # generate a text file to run through the tests from the
40 # non-text file generated by pg_dump.
42 # TODO: Have pg_restore actually restore to an independent
43 # database and then pg_dump *that* database (or something along
44 # those lines) to validate that part of the process.
49 'pg_dump', '--no-sync',
50 "--file=$tempdir/binary_upgrade.sql", '--schema-only',
51 '--binary-upgrade', '--dbname=postgres',
56 'pg_dump', "--file=$tempdir/clean.sql",
65 "--file=$tempdir/clean_if_exists.sql",
68 '--encoding=UTF8', # no-op, just tests that option is accepted
76 "--file=$tempdir/createdb.sql",
78 '-R', # no-op, just for testing
86 "--file=$tempdir/data_only.sql",
88 '-v', # no-op, just make sure it works
93 dump_cmd
=> [ 'pg_dump', '-f', "$tempdir/defaults.sql", 'postgres', ],
95 defaults_custom_format
=> {
96 test_key
=> 'defaults',
97 compile_option
=> 'gzip',
99 'pg_dump', '--no-sync', '-Fc', '-Z6',
100 "--file=$tempdir/defaults_custom_format.dump", 'postgres',
104 "--file=$tempdir/defaults_custom_format.sql",
105 "$tempdir/defaults_custom_format.dump",
108 defaults_dir_format
=> {
109 test_key
=> 'defaults',
111 'pg_dump', '--no-sync', '-Fd',
112 "--file=$tempdir/defaults_dir_format", 'postgres',
116 "--file=$tempdir/defaults_dir_format.sql",
117 "$tempdir/defaults_dir_format",
120 defaults_parallel
=> {
121 test_key
=> 'defaults',
123 'pg_dump', '--no-sync', '-Fd', '-j2',
124 "--file=$tempdir/defaults_parallel", 'postgres',
128 "--file=$tempdir/defaults_parallel.sql",
129 "$tempdir/defaults_parallel",
132 defaults_tar_format
=> {
133 test_key
=> 'defaults',
135 'pg_dump', '--no-sync', '-Ft',
136 "--file=$tempdir/defaults_tar_format.tar", 'postgres',
140 "--file=$tempdir/defaults_tar_format.sql",
141 "$tempdir/defaults_tar_format.tar",
147 '--exclude-table=regress_table_dumpable',
148 "--file=$tempdir/exclude_table.sql",
152 extension_schema
=> {
154 'pg_dump', '--schema=public',
155 "--file=$tempdir/extension_schema.sql", 'postgres',
158 pg_dumpall_globals
=> {
160 'pg_dumpall', '--no-sync',
161 "--file=$tempdir/pg_dumpall_globals.sql", '-g',
166 'pg_dump', '--no-sync',
167 "--file=$tempdir/no_privs.sql", '-x',
173 'pg_dump', '--no-sync',
174 "--file=$tempdir/no_owner.sql", '-O',
179 # regress_dump_login_role shouldn't need SELECT rights on internal
180 # (undumped) extension tables
181 privileged_internals
=> {
183 'pg_dump', '--no-sync',
184 "--file=$tempdir/privileged_internals.sql",
185 # these two tables are irrelevant to the test case
186 '--exclude-table=regress_pg_dump_schema.external_tab',
187 '--exclude-table=regress_pg_dump_schema.extdependtab',
188 '--username=regress_dump_login_role', 'postgres',
194 'pg_dump', '--no-sync', "--file=$tempdir/schema_only.sql",
198 section_pre_data
=> {
200 'pg_dump', '--no-sync',
201 "--file=$tempdir/section_pre_data.sql", '--section=pre-data',
207 'pg_dump', '--no-sync',
208 "--file=$tempdir/section_data.sql", '--section=data',
212 section_post_data
=> {
214 'pg_dump', '--no-sync', "--file=$tempdir/section_post_data.sql",
215 '--section=post-data', 'postgres',
220 'pg_dump', '--no-sync', "--file=$tempdir/with_extension.sql",
221 '--extension=test_pg_dump', 'postgres',
224 exclude_extension
=> {
226 'pg_dump', '--no-sync',
227 "--file=$tempdir/exclude_extension.sql",
228 '--exclude-extension=test_pg_dump', 'postgres',
231 exclude_extension_filter
=> {
235 "--file=$tempdir/exclude_extension_filter.sql",
236 "--filter=$tempdir/exclude_extension_filter.txt",
241 # plpgsql in the list blocks the dump of extension test_pg_dump
242 without_extension
=> {
244 'pg_dump', '--no-sync', "--file=$tempdir/without_extension.sql",
245 '--extension=plpgsql', 'postgres',
249 # plpgsql in the list of extensions blocks the dump of extension
250 # test_pg_dump. "public" is the schema used by the extension
251 # test_pg_dump, but none of its objects should be dumped.
252 without_extension_explicit_schema
=> {
256 "--file=$tempdir/without_extension_explicit_schema.sql",
257 '--extension=plpgsql',
263 # plpgsql in the list of extensions blocks the dump of extension
264 # test_pg_dump, but not the dump of objects not dependent on the
265 # extension located on a schema maintained by the extension.
266 without_extension_internal_schema
=> {
270 "--file=$tempdir/without_extension_internal_schema.sql",
271 '--extension=plpgsql',
272 '--schema=regress_pg_dump_schema',
277 ###############################################################
278 # Definition of the tests to run.
280 # Each test is defined using the log message that will be used.
282 # A regexp should be defined for each test which provides the
283 # basis for the test. That regexp will be run against the output
284 # file of each of the runs which the test is to be run against
285 # and the success of the result will depend on if the regexp
286 # result matches the expected 'like' or 'unlike' case.
287 # The runs listed as 'like' will be checked if they match the
288 # regexp and, if so, the test passes. All runs which are not
289 # listed as 'like' will be checked to ensure they don't match
290 # the regexp; if they do, the test will fail.
292 # The below hashes provide convenience sets of runs. Individual
293 # runs can be excluded from a general hash by placing that run
294 # into the 'unlike' section.
296 # There can then be a 'create_sql' and 'create_order' for a
297 # given test. The 'create_sql' commands are collected up in
298 # 'create_order' and then run against the database prior to any
299 # of the pg_dump runs happening. This is what "seeds" the
300 # system with objects to be dumped out.
302 # Building of this hash takes a bit of time as all of the regexps
303 # included in it are compiled. This greatly improves performance
304 # as the regexps are used for each run the test applies to.
306 # Tests which are considered 'full' dumps by pg_dump, but there
307 # are flags used to exclude specific items (ACLs, LOs, etc).
311 clean_if_exists
=> 1,
317 privileged_internals
=> 1,
319 exclude_extension
=> 1,
320 exclude_extension_filter
=> 1,
321 without_extension
=> 1);
324 'ALTER EXTENSION test_pg_dump' => {
327 'ALTER EXTENSION test_pg_dump ADD TABLE regress_pg_dump_table_added;',
329 \QCREATE TABLE public
.regress_pg_dump_table_added
(\E
330 \n\s
+\Qcol1 integer NOT NULL
,\E
331 \n\s
+\Qcol2 integer\E
333 like
=> { binary_upgrade
=> 1, },
336 'CREATE EXTENSION test_pg_dump' => {
338 create_sql
=> 'CREATE EXTENSION test_pg_dump;',
340 \QCREATE EXTENSION IF NOT EXISTS test_pg_dump WITH SCHEMA public
;\E
345 section_pre_data
=> 1,
349 exclude_extension
=> 1,
350 exclude_extension_filter
=> 1,
351 without_extension
=> 1
355 'CREATE ROLE regress_dump_test_role' => {
357 create_sql
=> 'CREATE ROLE regress_dump_test_role;',
358 regexp
=> qr/^CREATE ROLE regress_dump_test_role;\n/m,
359 like
=> { pg_dumpall_globals
=> 1, },
362 'CREATE ROLE regress_dump_login_role' => {
364 create_sql
=> 'CREATE ROLE regress_dump_login_role LOGIN;',
366 \QCREATE ROLE regress_dump_login_role
;\E
367 \n\QALTER ROLE regress_dump_login_role WITH \E
.*\Q LOGIN \E
.*;
369 like
=> { pg_dumpall_globals
=> 1, },
372 'GRANT ALTER SYSTEM ON PARAMETER full_page_writes TO regress_dump_test_role'
376 'GRANT ALTER SYSTEM ON PARAMETER full_page_writes TO regress_dump_test_role;',
379 qr/^GRANT ALTER SYSTEM ON PARAMETER full_page_writes TO regress_dump_test_role;/m,
380 like
=> { pg_dumpall_globals
=> 1, },
383 'GRANT ALL ON PARAMETER Custom.Knob TO regress_dump_test_role WITH GRANT OPTION'
387 'GRANT SET, ALTER SYSTEM ON PARAMETER Custom.Knob TO regress_dump_test_role WITH GRANT OPTION;',
389 # "set" plus "alter system" is "all" privileges on parameters
390 qr/^GRANT ALL ON PARAMETER "custom.knob" TO regress_dump_test_role WITH GRANT OPTION;/m,
391 like
=> { pg_dumpall_globals
=> 1, },
394 'GRANT ALL ON PARAMETER DateStyle TO regress_dump_test_role' => {
397 'GRANT ALL ON PARAMETER "DateStyle" TO regress_dump_test_role WITH GRANT OPTION; REVOKE GRANT OPTION FOR ALL ON PARAMETER DateStyle FROM regress_dump_test_role;',
399 # The revoke simplifies the ultimate grant so as to not include "with grant option"
400 qr/^GRANT ALL ON PARAMETER datestyle TO regress_dump_test_role;/m,
401 like
=> { pg_dumpall_globals
=> 1, },
404 'CREATE SCHEMA public' => {
405 regexp
=> qr/^CREATE SCHEMA public;/m,
407 extension_schema
=> 1,
408 without_extension_explicit_schema
=> 1,
412 'CREATE SEQUENCE regress_pg_dump_table_col1_seq' => {
414 \QCREATE SEQUENCE public
.regress_pg_dump_table_col1_seq\E
416 \n\s
+\QSTART WITH
1\E
417 \n\s
+\QINCREMENT BY
1\E
422 like
=> { binary_upgrade
=> 1, },
425 'CREATE TABLE regress_pg_dump_table_added' => {
428 'CREATE TABLE regress_pg_dump_table_added (col1 int not null, col2 int);',
430 \QCREATE TABLE public
.regress_pg_dump_table_added
(\E
431 \n\s
+\Qcol1 integer NOT NULL
,\E
432 \n\s
+\Qcol2 integer\E
434 like
=> { binary_upgrade
=> 1, },
437 'CREATE SEQUENCE regress_pg_dump_seq' => {
439 \QCREATE SEQUENCE public
.regress_pg_dump_seq\E
440 \n\s
+\QSTART WITH
1\E
441 \n\s
+\QINCREMENT BY
1\E
446 like
=> { binary_upgrade
=> 1, },
449 'SETVAL SEQUENCE regress_seq_dumpable' => {
451 create_sql
=> qq{SELECT nextval
('regress_seq_dumpable');},
453 \QSELECT pg_catalog
.setval
('public.regress_seq_dumpable', 1, true
);\E
459 extension_schema
=> 1,
462 exclude_extension
=> 1,
463 exclude_extension_filter
=> 1,
464 without_extension
=> 1,
468 'CREATE TABLE regress_pg_dump_table' => {
470 \QCREATE TABLE public
.regress_pg_dump_table
(\E
471 \n\s
+\Qcol1 integer NOT NULL
,\E
472 \n\s
+\Qcol2 integer
,\E
473 \n\s
+\QCONSTRAINT regress_pg_dump_table_col2_check
CHECK ((col2
> 0))\E
475 like
=> { binary_upgrade
=> 1, },
478 'COPY public.regress_table_dumpable (col1)' => {
480 \QCOPY public
.regress_table_dumpable
(col1
) FROM stdin
;\E
486 extension_schema
=> 1,
491 exclude_extension
=> 1,
492 exclude_extension_filter
=> 1,
493 without_extension
=> 1,
497 'REVOKE ALL ON FUNCTION wgo_then_no_access' => {
500 DO $$BEGIN EXECUTE format(
501 'REVOKE ALL ON FUNCTION wgo_then_no_access()
502 FROM pg_signal_backend, public, %I',
504 FROM pg_user JOIN pg_proc ON proowner = usesysid
505 WHERE proname = 'wgo_then_no_access')); END$$;},
507 \QREVOKE ALL ON FUNCTION public.wgo_then_no_access() FROM PUBLIC;\E
508 \n\QREVOKE ALL ON FUNCTION public.wgo_then_no_access() FROM \E.*;
509 \n\QREVOKE ALL ON FUNCTION public.wgo_then_no_access() FROM pg_signal_backend;\E
514 section_pre_data => 1,
518 exclude_extension => 1,
519 exclude_extension_filter => 1,
520 without_extension => 1,
524 'REVOKE GRANT OPTION FOR UPDATE ON SEQUENCE wgo_then_regular' => {
526 create_sql => 'REVOKE GRANT OPTION FOR UPDATE ON SEQUENCE
527 wgo_then_regular FROM pg_signal_backend;',
529 \QREVOKE ALL ON SEQUENCE public.wgo_then_regular FROM pg_signal_backend;\E
530 \n\QGRANT SELECT,UPDATE ON SEQUENCE public.wgo_then_regular TO pg_signal_backend;\E
531 \n\QGRANT USAGE ON SEQUENCE public.wgo_then_regular TO pg_signal_backend WITH GRANT OPTION;\E
536 section_pre_data => 1,
540 exclude_extension => 1,
541 exclude_extension_filter => 1,
542 without_extension => 1,
546 'CREATE ACCESS METHOD regress_test_am' => {
548 \QCREATE ACCESS METHOD regress_test_am TYPE INDEX HANDLER bthandler;\E
550 like => { binary_upgrade => 1, },
553 'COMMENT ON EXTENSION test_pg_dump' => {
555 \QCOMMENT ON EXTENSION test_pg_dump \E
556 \QIS 'Test pg_dump with an extension';\E
561 section_pre_data => 1,
564 exclude_extension => 1,
565 exclude_extension_filter => 1,
566 without_extension => 1,
570 'GRANT SELECT regress_pg_dump_table_added pre-ALTER EXTENSION' => {
573 'GRANT SELECT ON regress_pg_dump_table_added TO regress_dump_test_role;',
575 \QGRANT SELECT ON TABLE public.regress_pg_dump_table_added TO regress_dump_test_role;\E
577 like => { binary_upgrade => 1, },
580 'REVOKE SELECT regress_pg_dump_table_added post-ALTER EXTENSION' => {
583 'REVOKE SELECT ON regress_pg_dump_table_added FROM regress_dump_test_role;',
585 \QREVOKE SELECT ON TABLE public.regress_pg_dump_table_added FROM regress_dump_test_role;\E
590 section_pre_data => 1,
594 exclude_extension => 1,
595 exclude_extension_filter => 1,
596 without_extension => 1,
600 'GRANT SELECT ON TABLE regress_pg_dump_table' => {
602 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
603 \QGRANT SELECT ON TABLE public.regress_pg_dump_table TO regress_dump_test_role;\E\n
604 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
606 like => { binary_upgrade => 1, },
609 'GRANT SELECT(col1) ON regress_pg_dump_table' => {
611 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
612 \QGRANT SELECT(col1) ON TABLE public.regress_pg_dump_table TO PUBLIC;\E\n
613 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
615 like => { binary_upgrade => 1, },
618 'GRANT SELECT(col2) ON regress_pg_dump_table TO regress_dump_test_role'
621 create_sql => 'GRANT SELECT(col2) ON regress_pg_dump_table
622 TO regress_dump_test_role;',
624 \QGRANT SELECT(col2) ON TABLE public.regress_pg_dump_table TO regress_dump_test_role;\E
629 section_pre_data => 1,
633 exclude_extension => 1,
634 exclude_extension_filter => 1,
635 without_extension => 1
639 'GRANT USAGE ON regress_pg_dump_table_col1_seq TO regress_dump_test_role'
642 create_sql => 'GRANT USAGE ON SEQUENCE regress_pg_dump_table_col1_seq
643 TO regress_dump_test_role;',
645 \QGRANT USAGE ON SEQUENCE public.regress_pg_dump_table_col1_seq TO regress_dump_test_role;\E
650 section_pre_data => 1,
654 exclude_extension => 1,
655 exclude_extension_filter => 1,
656 without_extension => 1,
660 'GRANT USAGE ON regress_pg_dump_seq TO regress_dump_test_role' => {
662 \QGRANT USAGE ON SEQUENCE public.regress_pg_dump_seq TO regress_dump_test_role;\E
664 like => { binary_upgrade => 1, },
667 'REVOKE SELECT(col1) ON regress_pg_dump_table' => {
669 create_sql => 'REVOKE SELECT(col1) ON regress_pg_dump_table
672 \QREVOKE SELECT(col1) ON TABLE public.regress_pg_dump_table FROM PUBLIC;\E
677 section_pre_data => 1,
681 exclude_extension => 1,
682 exclude_extension_filter => 1,
683 without_extension => 1,
687 # Objects included in extension part of a schema created by this extension */
688 'CREATE TABLE regress_pg_dump_schema.test_table' => {
690 \QCREATE TABLE regress_pg_dump_schema.test_table (\E
691 \n\s+\Qcol1 integer,\E
692 \n\s+\Qcol2 integer,\E
693 \n\s+\QCONSTRAINT test_table_col2_check CHECK ((col2 > 0))\E
695 like => { binary_upgrade => 1, },
698 'GRANT SELECT ON regress_pg_dump_schema.test_table' => {
700 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
701 \QGRANT SELECT ON TABLE regress_pg_dump_schema.test_table TO regress_dump_test_role;\E\n
702 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
704 like => { binary_upgrade => 1, },
707 'CREATE SEQUENCE regress_pg_dump_schema.test_seq' => {
709 \QCREATE SEQUENCE regress_pg_dump_schema.test_seq\E
710 \n\s+\QSTART WITH 1\E
711 \n\s+\QINCREMENT BY 1\E
716 like => { binary_upgrade => 1, },
719 'GRANT USAGE ON regress_pg_dump_schema.test_seq' => {
721 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
722 \QGRANT USAGE ON SEQUENCE regress_pg_dump_schema.test_seq TO regress_dump_test_role;\E\n
723 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
725 like => { binary_upgrade => 1, },
728 'CREATE TYPE regress_pg_dump_schema.test_type' => {
730 \QCREATE TYPE regress_pg_dump_schema.test_type AS (\E
731 \n\s+\Qcol1 integer\E
733 like => { binary_upgrade => 1, },
736 'GRANT USAGE ON regress_pg_dump_schema.test_type' => {
738 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
739 \QGRANT ALL ON TYPE regress_pg_dump_schema.test_type TO regress_dump_test_role;\E\n
740 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
742 like => { binary_upgrade => 1, },
745 'CREATE FUNCTION regress_pg_dump_schema.test_func' => {
747 \QCREATE FUNCTION regress_pg_dump_schema.test_func() RETURNS integer\E
748 \n\s+\QLANGUAGE sql\E
750 like => { binary_upgrade => 1, },
753 'GRANT ALL ON regress_pg_dump_schema.test_func' => {
755 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
756 \QGRANT ALL ON FUNCTION regress_pg_dump_schema.test_func() TO regress_dump_test_role;\E\n
757 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
759 like => { binary_upgrade => 1, },
762 'CREATE AGGREGATE regress_pg_dump_schema.test_agg' => {
764 \QCREATE AGGREGATE regress_pg_dump_schema.test_agg(smallint) (\E
765 \n\s+\QSFUNC = int2_sum,\E
766 \n\s+\QSTYPE = bigint\E
768 like => { binary_upgrade => 1, },
771 'GRANT ALL ON regress_pg_dump_schema.test_agg' => {
773 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\E\n
774 \QGRANT ALL ON FUNCTION regress_pg_dump_schema.test_agg(smallint) TO regress_dump_test_role;\E\n
775 \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E
777 like => { binary_upgrade => 1, },
780 'ALTER INDEX pkey DEPENDS ON extension' => {
783 'CREATE TABLE regress_pg_dump_schema.extdependtab (col1 integer primary key, col2 int);
784 CREATE INDEX ON regress_pg_dump_schema.extdependtab (col2);
785 ALTER INDEX regress_pg_dump_schema.extdependtab_col2_idx DEPENDS ON EXTENSION test_pg_dump;
786 ALTER INDEX regress_pg_dump_schema.extdependtab_pkey DEPENDS ON EXTENSION test_pg_dump;',
788 \QALTER INDEX regress_pg_dump_schema.extdependtab_pkey DEPENDS ON EXTENSION test_pg_dump;\E\n
790 like => {%pgdump_runs},
793 extension_schema => 1,
794 pg_dumpall_globals => 1,
795 privileged_internals => 1,
797 section_pre_data => 1,
798 # Excludes this schema as extension is not listed.
799 without_extension_explicit_schema => 1,
803 'ALTER INDEX idx DEPENDS ON extension' => {
805 \QALTER INDEX regress_pg_dump_schema.extdependtab_col2_idx DEPENDS ON EXTENSION test_pg_dump;\E\n
807 like => {%pgdump_runs},
810 extension_schema => 1,
811 pg_dumpall_globals => 1,
812 privileged_internals => 1,
814 section_pre_data => 1,
815 # Excludes this schema as extension is not listed.
816 without_extension_explicit_schema => 1,
820 # Objects not included in extension, part of schema created by extension
821 'CREATE TABLE regress_pg_dump_schema.external_tab' => {
823 create_sql => 'CREATE TABLE regress_pg_dump_schema.external_tab
826 \QCREATE TABLE regress_pg_dump_schema.external_tab (\E
827 \n\s+\Qcol1 integer\E
832 section_pre_data => 1,
833 # Excludes the extension and keeps the schema's data.
834 without_extension_internal_schema => 1,
836 unlike => { privileged_internals => 1 },
839 #########################################
840 # Create a PG instance to test actually dumping from
842 my $node = PostgreSQL::Test::Cluster->new('main');
843 $node->init('auth_extra' => [ '--create-role', 'regress_dump_login_role' ]);
846 my $port = $node->port;
848 my $supports_gzip = check_pg_config("#define HAVE_LIBZ 1");
850 #########################################
851 # Set up schemas, tables, etc, to be dumped.
853 # Build up the create statements
858 if ($tests{$a}->{create_order} and $tests{$b}->{create_order})
860 $tests{$a}->{create_order} <=> $tests{$b}->{create_order};
862 elsif ($tests{$a}->{create_order})
866 elsif ($tests{$b}->{create_order})
876 if ($tests{$test}->{create_sql})
878 $create_sql .= $tests{$test}->{create_sql};
882 # Send the combined set of commands to psql
883 $node->safe_psql('postgres', $create_sql);
885 #########################################
886 # Create filter file for exclude_extension_filter test
890 open $filterfile, '>', "$tempdir/exclude_extension_filter.txt"
891 or die "unable to open filter file for writing";
892 print $filterfile "exclude extension test_pg_dump\n";
895 #########################################
898 foreach my $run (sort keys %pgdump_runs)
903 # Skip command-level tests for gzip if there is no support for it.
904 if ( defined($pgdump_runs{$run}->{compile_option})
905 && $pgdump_runs{$run}->{compile_option} eq 'gzip'
908 note "$run: skipped due to no gzip support";
912 $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} },
913 "$run: pg_dump runs");
915 if ($pgdump_runs{$run}->{restore_cmd})
917 $node->command_ok(\@{ $pgdump_runs{$run}->{restore_cmd} },
918 "$run: pg_restore runs");
921 if ($pgdump_runs{$run}->{test_key})
923 $test_key = $pgdump_runs{$run}->{test_key};
926 my $output_file = slurp_file("$tempdir/${run}.sql");
928 #########################################
929 # Run all tests where this run is included
930 # as either a 'like' or 'unlike' test.
932 foreach my $test (sort keys %tests)
934 # Check for proper test definitions
936 # There should be a "like" list, even if it is empty. (This
937 # makes the test more self-documenting.)
938 if (!defined($tests{$test}->{like}))
940 die "missing \"like\" in test \"$test\"";
942 # Check for useless entries in "unlike" list. Runs that are
943 # not listed in "like" don't need to be excluded in "unlike".
944 if ($tests{$test}->{unlike}->{$test_key}
945 && !defined($tests{$test}->{like}->{$test_key}))
947 die "useless \"unlike\" entry \"$test_key\" in test \"$test\"";
950 # Run the test listed as a like, unless it is specifically noted
951 # as an unlike (generally due to an explicit exclusion or similar).
952 if ($tests{$test}->{like}->{$test_key}
953 && !defined($tests{$test}->{unlike}->{$test_key}))
955 if (!ok($output_file =~ $tests{$test}->{regexp},
956 "$run: should dump $test"))
958 diag("Review $run results in $tempdir");
963 if (!ok($output_file !~ $tests{$test}->{regexp},
964 "$run: should not dump $test"))
966 diag("Review $run results in $tempdir");
972 #########################################
973 # Stop the database instance, which will be removed at the end of the tests.