Skip to content

Commit 17019c0

Browse files
committed
Tighten TAP tests' tracking of postmaster state some more.
Commits 6c4a890 et al. had a couple of deficiencies: * The logic I added to Cluster::start to see if a PID file is present could be fooled by a stale PID file left over from a previous postmaster. To fix, if we're not sure whether we expect to find a running postmaster or not, validate the PID using "kill 0". * 017_shm.pl has a loop in which it just issues repeated Cluster::start calls; this will fail if some invocation fails but leaves self->_pid set. Per buildfarm results, the above fix is not enough to make this safe: we might have "validated" a PID for a postmaster that exits immediately after we look. Hence, match each failed start call with a stop call that will get us back to the self->_pid == undef state. Add a fail_ok option to Cluster::stop to make this work. Discussion: https://postgr.es/m/CA+hUKGKV6fOHvfiPt8=dOKzvswjAyLoFoJF1iQXMNpi7+hD1JQ@mail.gmail.com
1 parent 0a79fee commit 17019c0

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

src/test/perl/PostgresNode.pm

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -822,20 +822,37 @@ Note: if the node is already known stopped, this does nothing.
822822
However, if we think it's running and it's not, it's important for
823823
this to fail. Otherwise, tests might fail to detect server crashes.
824824
825+
With optional extra param fail_ok => 1, returns 0 for failure
826+
instead of bailing out.
827+
825828
=cut
826829

827830
sub stop
828831
{
829-
my ($self, $mode) = @_;
830-
my $port = $self->port;
832+
my ($self, $mode, %params) = @_;
831833
my $pgdata = $self->data_dir;
832834
my $name = $self->name;
835+
my $ret;
833836
$mode = 'fast' unless defined $mode;
834-
return unless defined $self->{_pid};
837+
return 1 unless defined $self->{_pid};
838+
835839
print "### Stopping node \"$name\" using mode $mode\n";
836-
TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-m', $mode, 'stop');
840+
$ret = TestLib::system_log('pg_ctl', '-D', $pgdata,
841+
'-m', $mode, 'stop');
842+
843+
if ($ret != 0)
844+
{
845+
print "# pg_ctl stop failed: $ret\n";
846+
847+
# Check to see if we still have a postmaster or not.
848+
$self->_update_pid(-1);
849+
850+
BAIL_OUT("pg_ctl stop failed") unless $params{fail_ok};
851+
return 0;
852+
}
853+
837854
$self->_update_pid(0);
838-
return;
855+
return 1;
839856
}
840857

841858
=pod
@@ -989,9 +1006,20 @@ sub _update_pid
9891006
if (open my $pidfile, '<', $self->data_dir . "/postmaster.pid")
9901007
{
9911008
chomp($self->{_pid} = <$pidfile>);
992-
print "# Postmaster PID for node \"$name\" is $self->{_pid}\n";
9931009
close $pidfile;
9941010

1011+
# If we aren't sure what to expect, validate the PID using kill().
1012+
# This protects against stale PID files left by crashed postmasters.
1013+
if ($is_running == -1 && kill(0, $self->{_pid}) == 0)
1014+
{
1015+
print
1016+
"# Stale postmaster.pid file for node \"$name\": PID $self->{_pid} no longer exists\n";
1017+
$self->{_pid} = undef;
1018+
return;
1019+
}
1020+
1021+
print "# Postmaster PID for node \"$name\" is $self->{_pid}\n";
1022+
9951023
# If we found a pidfile when there shouldn't be one, complain.
9961024
BAIL_OUT("postmaster.pid unexpectedly present") if $is_running == 0;
9971025
return;

src/test/recovery/t/017_shm.pl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ sub poll_start
196196
# Wait 0.1 second before retrying.
197197
usleep(100_000);
198198

199+
# Clean up in case the start attempt just timed out or some such.
200+
$node->stop('fast', fail_ok => 1);
201+
199202
$attempts++;
200203
}
201204

0 commit comments

Comments
 (0)