Make PostgreSQL::Test::Cluster compatible with all live branches
authorAndrew Dunstan <andrew@dunslane.net>
Wed, 30 Mar 2022 15:07:05 +0000 (11:07 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Wed, 30 Mar 2022 15:25:11 +0000 (11:25 -0400)
We do this via a subclass for any branch older than the minimum known
to be compatible with the main package (currently release 12).

This should be useful for constructing cross-version tests.

In theory this could be extended back any number of versions, with
varying degrees of compatibility.

Reviewed by Michael Paquier and Dagfinn Ilmari MannsÃ¥ker

Discussion: https://postgr.es/m/a3efd19a-d5c9-fdf2-6094-4cde056a2708@dunslane.net

src/test/perl/PostgreSQL/Test/Cluster.pm

index b6e33516110a15324a3a435bc06a02baa9eb8e7d..fa0ef12d72ea26c5cd089a323d3b9e98cc7e693a 100644 (file)
@@ -111,6 +111,10 @@ use Scalar::Util qw(blessed);
 our ($use_tcp, $test_localhost, $test_pghost, $last_host_assigned,
        $last_port_assigned, @all_nodes, $died);
 
+# the minimum version we believe to be compatible with this package without
+# subclassing.
+our $min_compat = 12;
+
 INIT
 {
 
@@ -1063,7 +1067,7 @@ sub enable_streaming
 
        print "### Enabling streaming replication for node \"$name\"\n";
        $self->append_conf(
-               'postgresql.conf', qq(
+               $self->_recovery_file, qq(
 primary_conninfo='$root_connstr'
 ));
        $self->set_standby_mode();
@@ -1092,7 +1096,7 @@ sub enable_restoring
          : qq{cp "$path/%f" "%p"};
 
        $self->append_conf(
-               'postgresql.conf', qq(
+               $self->_recovery_file, qq(
 restore_command = '$copy_command'
 ));
        if ($standby)
@@ -1106,6 +1110,8 @@ restore_command = '$copy_command'
        return;
 }
 
+sub _recovery_file { return "postgresql.conf"; }
+
 =pod
 
 =item $node->set_recovery_mode()
@@ -1305,15 +1311,29 @@ sub new
 
        $node->dump_info;
 
-       # Add node to list of nodes
-       push(@all_nodes, $node);
-
        $node->_set_pg_version;
 
-       my $v = $node->{_pg_version};
+       my $ver = $node->{_pg_version};
 
-       carp("PostgreSQL::Test::Cluster isn't fully compatible with version " . $v)
-         if $v < 12;
+       # Use a subclass as defined below (or elsewhere) if this version
+       # isn't fully compatible. Warn if the version is too old and thus we don't
+       # have a subclass of this class.
+       if (ref $ver && $ver < $min_compat)
+    {
+               my $maj      = $ver->major(separator => '_');
+               my $subclass = $class . "::V_$maj";
+               if ($subclass->isa($class))
+               {
+                       bless $node, $subclass;
+               }
+               else
+               {
+                       carp "PostgreSQL::Test::Cluster isn't fully compatible with version $ver";
+               }
+    }
+
+       # Add node to list of nodes
+       push(@all_nodes, $node);
 
        return $node;
 }
@@ -2602,8 +2622,12 @@ sub wait_for_catchup
          . "_lsn to pass "
          . $target_lsn . " on "
          . $self->name . "\n";
+       # Before release 12 walreceiver just set the application name to
+       # "walreceiver"
        my $query =
-         qq[SELECT '$target_lsn' <= ${mode}_lsn AND state = 'streaming' FROM pg_catalog.pg_stat_replication WHERE application_name = '$standby_name';];
+         qq[SELECT '$target_lsn' <= ${mode}_lsn AND state = 'streaming'
+         FROM pg_catalog.pg_stat_replication
+         WHERE application_name IN ('$standby_name', 'walreceiver')];
        $self->poll_query_until('postgres', $query)
          or croak "timed out waiting for catchup";
        print "done\n";
@@ -2890,4 +2914,41 @@ sub corrupt_page_checksum
 
 =cut
 
+##########################################################################
+
+package PostgreSQL::Test::Cluster::V_11; ## no critic (ProhibitMultiplePackages)
+
+use parent -norequire, qw(PostgreSQL::Test::Cluster);
+
+# https://www.postgresql.org/docs/11/release-11.html
+
+# max_wal_senders + superuser_reserved_connections must be < max_connections
+# uses recovery.conf
+
+sub _recovery_file { return "recovery.conf"; }
+
+sub set_standby_mode
+{
+    my $self = shift;
+    $self->append_conf("recovery.conf", "standby_mode = on\n");
+}
+
+sub init
+{
+    my ($self, %params) = @_;
+    $self->SUPER::init(%params);
+    $self->adjust_conf('postgresql.conf', 'max_wal_senders',
+                      $params{allows_streaming} ? 5 : 0);
+}
+
+##########################################################################
+
+package PostgreSQL::Test::Cluster::V_10; ## no critic (ProhibitMultiplePackages)
+
+use parent -norequire, qw(PostgreSQL::Test::Cluster::V_11);
+
+# https://www.postgresql.org/docs/10/release-10.html
+
+########################################################################
+
 1;