Improve TAP test function PostgresNode::poll_query_until().
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
This commit is contained in:
parent
2dca03439f
commit
de3de0afd7
@ -1213,36 +1213,43 @@ sub psql
|
|||||||
|
|
||||||
=pod
|
=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).
|
Run B<$query> repeatedly, until it returns the B<$expected> result
|
||||||
Continues polling if psql returns an error result. Times out after 180 seconds.
|
('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
|
=cut
|
||||||
|
|
||||||
sub poll_query_until
|
sub poll_query_until
|
||||||
{
|
{
|
||||||
my ($self, $dbname, $query) = @_;
|
my ($self, $dbname, $query, $expected) = @_;
|
||||||
|
|
||||||
my $max_attempts = 180;
|
$expected = 't' unless defined($expected); # default value
|
||||||
my $attempts = 0;
|
|
||||||
|
my $cmd =
|
||||||
|
[ 'psql', '-XAt', '-c', $query, '-d', $self->connstr($dbname) ];
|
||||||
my ($stdout, $stderr);
|
my ($stdout, $stderr);
|
||||||
|
my $max_attempts = 180 * 10;
|
||||||
|
my $attempts = 0;
|
||||||
|
|
||||||
while ($attempts < $max_attempts)
|
while ($attempts < $max_attempts)
|
||||||
{
|
{
|
||||||
my $cmd =
|
|
||||||
[ 'psql', '-XAt', '-c', $query, '-d', $self->connstr($dbname) ];
|
|
||||||
my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr;
|
my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr;
|
||||||
|
|
||||||
chomp($stdout);
|
chomp($stdout);
|
||||||
$stdout =~ s/\r//g if $TestLib::windows_os;
|
$stdout =~ s/\r//g if $TestLib::windows_os;
|
||||||
if ($stdout eq "t")
|
|
||||||
|
if ($stdout eq $expected)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Wait a second before retrying.
|
# Wait 0.1 second before retrying.
|
||||||
sleep 1;
|
select undef, undef, undef, 0.1;
|
||||||
|
|
||||||
$attempts++;
|
$attempts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use Test::More tests => 11;
|
|||||||
my $check_sql =
|
my $check_sql =
|
||||||
"SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;";
|
"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
|
# If $setting is given, synchronous_standby_names is set to it and
|
||||||
# the configuration file is reloaded before the test.
|
# the configuration file is reloaded before the test.
|
||||||
sub test_sync_state
|
sub test_sync_state
|
||||||
@ -23,24 +23,7 @@ sub test_sync_state
|
|||||||
$self->reload;
|
$self->reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $timeout_max = 30;
|
ok( $self->poll_query_until('postgres', $check_sql, $expected), $msg);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Initialize master node
|
# Initialize master node
|
||||||
|
Loading…
x
Reference in New Issue
Block a user