]> granicus.if.org Git - postgresql/commitdiff
Improve TAP test function PostgresNode::poll_query_until().
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 2 Jul 2017 18:03:41 +0000 (14:03 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 2 Jul 2017 18:03:41 +0000 (14:03 -0400)
Add an optional "expected" argument to override the default assumption
that we're waiting for the query to return "t".  This allows replacing
a handwritten polling loop in recovery/t/007_sync_rep.pl with use of
poll_query_until(); AFAICS that's the only remaining ad-hoc polling
loop in our TAP tests.

Change poll_query_until() to probe ten times per second not once per
second.  Like some similar changes I've been making recently, the
one-second interval seems to be rooted in ancient traditions rather
than the actual likely wait duration on modern machines.  I'd consider
reducing it further if there were a convenient way to spawn just one
psql for the whole loop rather than one per probe attempt.

Discussion: https://postgr.es/m/12486.1498938782@sss.pgh.pa.us

src/test/perl/PostgresNode.pm
src/test/recovery/t/007_sync_rep.pl

index f4fa6009519c56cf8f29b83eedbba47ad4150b0f..4346423a0df99a75371c9f319bbd031277eb2aaf 100644 (file)
@@ -1213,36 +1213,43 @@ sub psql
 
 =pod
 
-=item $node->poll_query_until(dbname, query)
+=item $node->poll_query_until($dbname, $query [, $expected ])
 
-Run a query once a second, until it returns 't' (i.e. SQL boolean true).
-Continues polling if psql returns an error result. Times out after 180 seconds.
+Run B<$query> repeatedly, until it returns the B<$expected> result
+('t', or SQL boolean true, by default).
+Continues polling if B<psql> returns an error result.
+Times out after 180 seconds.
+Returns 1 if successful, 0 if timed out.
 
 =cut
 
 sub poll_query_until
 {
-       my ($self, $dbname, $query) = @_;
+       my ($self, $dbname, $query, $expected) = @_;
 
-       my $max_attempts = 180;
-       my $attempts     = 0;
+       $expected = 't' unless defined($expected);      # default value
+
+       my $cmd =
+               [ 'psql', '-XAt', '-c', $query, '-d', $self->connstr($dbname) ];
        my ($stdout, $stderr);
+       my $max_attempts = 180 * 10;
+       my $attempts     = 0;
 
        while ($attempts < $max_attempts)
        {
-               my $cmd =
-                 [ 'psql', '-XAt', '-c', $query, '-d', $self->connstr($dbname) ];
                my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr;
 
                chomp($stdout);
                $stdout =~ s/\r//g if $TestLib::windows_os;
-               if ($stdout eq "t")
+
+               if ($stdout eq $expected)
                {
                        return 1;
                }
 
-               # Wait a second before retrying.
-               sleep 1;
+               # Wait 0.1 second before retrying.
+               select undef, undef, undef, 0.1;
+
                $attempts++;
        }
 
index 8e3cc5e42e1e700e24719c7ff3a047979081f3cb..0f999f053594b6c8f6795a02d6e9aa99c4b4f465 100644 (file)
@@ -9,7 +9,7 @@ use Test::More tests => 11;
 my $check_sql =
 "SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;";
 
-# Check that sync_state of each standby is expected.
+# Check that sync_state of each standby is expected (waiting till it is).
 # If $setting is given, synchronous_standby_names is set to it and
 # the configuration file is reloaded before the test.
 sub test_sync_state
@@ -23,24 +23,7 @@ sub test_sync_state
                $self->reload;
        }
 
-       my $timeout_max = 30;
-       my $timeout     = 0;
-       my $result;
-
-       # A reload may take some time to take effect on busy machines,
-       # hence use a loop with a timeout to give some room for the test
-       # to pass.
-       while ($timeout < $timeout_max)
-       {
-               $result = $self->safe_psql('postgres', $check_sql);
-
-               last if ($result eq $expected);
-
-               $timeout++;
-               sleep 1;
-       }
-
-       is($result, $expected, $msg);
+       ok( $self->poll_query_until('postgres', $check_sql, $expected), $msg);
 }
 
 # Initialize master node