Add custom filtering rules to the TAP tests of pg_upgrade
authorMichael Paquier <[email protected]>
Tue, 27 Dec 2022 05:35:56 +0000 (14:35 +0900)
committerMichael Paquier <[email protected]>
Tue, 27 Dec 2022 05:35:56 +0000 (14:35 +0900)
002_pg_upgrade.pl gains support for a new environment variable called
"filter_rules", that can be used to point to a file that includes a
set of custom regular expressions that would be applied to the dumps of
the origin and target clusters when doing a cross-version test (aka when
defining olddump and oldinstall), to give the possibility to reshape
dynamically the dumps in the same way as the internals of the buildfarm
code so as the tests are able to pass in scenarios where one expects
them to even if pg_dump generates slightly-different outputs depending
on the versions involved.

This option is not used when pg_upgrade runs with the same version for
the origin and target clusters, and it is the last piece I see as
required to be able to plug-in more efficiently the TAP tests of
pg_upgrade with the buildfarm or just a CI.

Author: Anton A. Melnikov
Discussion: https://postgr.es/m/49f389ba-95ce-8a9b-09ae-f60650c0e7c7@inbox.ru

src/bin/pg_upgrade/TESTING
src/bin/pg_upgrade/t/002_pg_upgrade.pl

index 127dc30bbb3136fc5b2cf0dd3b60e22bfa1cb79d..98286231d77c6f0f6b1f11c8c357a7a388d0635f 100644 (file)
@@ -17,6 +17,21 @@ the creation of the dump):
 export olddump=...somewhere/dump.sql   (old version's dump)
 export oldinstall=...otherversion/     (old version's install base path)
 
+"filter_rules" is a variable that can be used to specify a file with custom
+filtering rules applied before comparing the dumps of the PostgreSQL
+instances near the end of the tests, in the shape of regular expressions
+valid for perl.  This is useful to enforce certain validation cases where
+pg_dump could create inconsistent outputs across major versions.
+For example:
+
+       # Remove all CREATE POLICY statements
+       s/^CREATE\sPOLICY.*//mgx
+       # Replace REFRESH with DROP for materialized views
+       s/^REFRESH\s(MATERIALIZED\sVIEW)/DROP $1/mgx
+
+Lines beginning with '#' and empty lines are ignored.  One rule can be
+defined per line.
+
 Finally, the tests can be done by running
 
        make check
index 4cc14693060e45b9a7907e8f7fee60f671d3d4b8..c066fd7d938563d45181ba11a5c18349789201df 100644 (file)
@@ -45,6 +45,31 @@ sub filter_dump
        # Remove empty lines.
        $dump_contents =~ s/^\n//mgx;
 
+       # Apply custom filtering rules, if any.
+       if (defined($ENV{filter_rules}))
+       {
+               my $filter_file = $ENV{filter_rules};
+               die "no file with custom filter rules found!" unless -e $filter_file;
+
+               open my $filter_handle, '<', $filter_file
+                 or die "could not open $filter_file";
+               while (<$filter_handle>)
+               {
+                       my $filter_line = $_;
+
+                       # Skip comments and empty lines
+                       next if ($filter_line =~ /^#/);
+                       next if ($filter_line =~ /^\s*$/);
+
+                       # Apply lines with filters.
+                       note "Applying custom rule $filter_line to $dump_file";
+                       my $filter = "\$dump_contents =~ $filter_line";
+                       ## no critic (ProhibitStringyEval)
+                       eval $filter;
+               }
+               close $filter_handle;
+       }
+
        my $dump_file_filtered = "${dump_file}_filtered";
        open(my $dh, '>', $dump_file_filtered)
          || die "opening $dump_file_filtered";