Support retaining data dirs on successful TAP tests

This moves the data directories from using temporary directories with
randomness in the directory name to a static name, to make it easier to
debug.  The data directory will be retained if tests fail or the test
code dies/exits with failure, and is automatically removed on the next
make check.

If the environment variable PG_TEST_NOCLEAN is defined, the data
directories will be retained regardless of test or exit status.

Author: Daniel Gustafsson <daniel@yesql.se>
This commit is contained in:
Peter Eisentraut 2017-09-05 12:22:33 -04:00
parent 5e8304fdce
commit 90627cf98a
7 changed files with 61 additions and 15 deletions

View File

@ -362,12 +362,14 @@ endef
ifeq ($(enable_tap_tests),yes) ifeq ($(enable_tap_tests),yes)
define prove_installcheck define prove_installcheck
rm -rf $(CURDIR)/tmp_check/log rm -rf '$(CURDIR)'/tmp_check
$(MKDIR_P) '$(CURDIR)'/tmp_check
cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
endef endef
define prove_check define prove_check
rm -rf $(CURDIR)/tmp_check/log rm -rf '$(CURDIR)'/tmp_check
$(MKDIR_P) '$(CURDIR)'/tmp_check
cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl)
endef endef

View File

@ -114,9 +114,10 @@ sub check_query
sub setup_cluster sub setup_cluster
{ {
my $extra_name = shift;
# Initialize master, data checksums are mandatory # Initialize master, data checksums are mandatory
$node_master = get_new_node('master'); $node_master = get_new_node('master' . ($extra_name ? "_${extra_name}" : ''));
$node_master->init(allows_streaming => 1); $node_master->init(allows_streaming => 1);
} }
@ -130,7 +131,9 @@ sub start_master
sub create_standby sub create_standby
{ {
$node_standby = get_new_node('standby'); my $extra_name = shift;
$node_standby = get_new_node('standby' . ($extra_name ? "_${extra_name}" : ''));
$node_master->backup('my_backup'); $node_master->backup('my_backup');
$node_standby->init_from_backup($node_master, 'my_backup'); $node_standby->init_from_backup($node_master, 'my_backup');
my $connstr_master = $node_master->connstr(); my $connstr_master = $node_master->connstr();

View File

@ -9,7 +9,7 @@ sub run_test
{ {
my $test_mode = shift; my $test_mode = shift;
RewindTest::setup_cluster(); RewindTest::setup_cluster($test_mode);
RewindTest::start_master(); RewindTest::start_master();
# Create a test table and insert a row in master. # Create a test table and insert a row in master.
@ -28,7 +28,7 @@ sub run_test
master_psql("CHECKPOINT"); master_psql("CHECKPOINT");
RewindTest::create_standby(); RewindTest::create_standby($test_mode);
# Insert additional data on master that will be replicated to standby # Insert additional data on master that will be replicated to standby
master_psql("INSERT INTO tbl1 values ('in master, before promotion')"); master_psql("INSERT INTO tbl1 values ('in master, before promotion')");

View File

@ -9,13 +9,13 @@ sub run_test
{ {
my $test_mode = shift; my $test_mode = shift;
RewindTest::setup_cluster(); RewindTest::setup_cluster($test_mode);
RewindTest::start_master(); RewindTest::start_master();
# Create a database in master. # Create a database in master.
master_psql('CREATE DATABASE inmaster'); master_psql('CREATE DATABASE inmaster');
RewindTest::create_standby(); RewindTest::create_standby($test_mode);
# Create another database, the creation is replicated to the standby # Create another database, the creation is replicated to the standby
master_psql('CREATE DATABASE beforepromotion'); master_psql('CREATE DATABASE beforepromotion');

View File

@ -14,7 +14,7 @@ sub run_test
{ {
my $test_mode = shift; my $test_mode = shift;
RewindTest::setup_cluster(); RewindTest::setup_cluster($test_mode);
RewindTest::start_master(); RewindTest::start_master();
my $test_master_datadir = $node_master->data_dir; my $test_master_datadir = $node_master->data_dir;
@ -27,7 +27,7 @@ sub run_test
append_to_file "$test_master_datadir/tst_both_dir/both_subdir/both_file3", append_to_file "$test_master_datadir/tst_both_dir/both_subdir/both_file3",
"in both3"; "in both3";
RewindTest::create_standby(); RewindTest::create_standby($test_mode);
# Create different subdirs and files in master and standby # Create different subdirs and files in master and standby
my $test_standby_datadir = $node_standby->data_dir; my $test_standby_datadir = $node_standby->data_dir;

View File

@ -26,7 +26,7 @@ sub run_test
my $master_xlogdir = "${TestLib::tmp_check}/xlog_master"; my $master_xlogdir = "${TestLib::tmp_check}/xlog_master";
rmtree($master_xlogdir); rmtree($master_xlogdir);
RewindTest::setup_cluster(); RewindTest::setup_cluster($test_mode);
my $test_master_datadir = $node_master->data_dir; my $test_master_datadir = $node_master->data_dir;
@ -43,7 +43,7 @@ sub run_test
master_psql("CHECKPOINT"); master_psql("CHECKPOINT");
RewindTest::create_standby(); RewindTest::create_standby($test_mode);
# Insert additional data on master that will be replicated to standby # Insert additional data on master that will be replicated to standby
master_psql("INSERT INTO tbl1 values ('in master, before promotion')"); master_psql("INSERT INTO tbl1 values ('in master, before promotion')");

View File

@ -86,6 +86,7 @@ use Config;
use Cwd; use Cwd;
use Exporter 'import'; use Exporter 'import';
use File::Basename; use File::Basename;
use File::Path qw(rmtree);
use File::Spec; use File::Spec;
use File::Temp (); use File::Temp ();
use IPC::Run; use IPC::Run;
@ -100,7 +101,7 @@ our @EXPORT = qw(
get_new_node get_new_node
); );
our ($test_localhost, $test_pghost, $last_port_assigned, @all_nodes); our ($test_localhost, $test_pghost, $last_port_assigned, @all_nodes, $died);
# Windows path to virtual file system root # Windows path to virtual file system root
@ -149,11 +150,13 @@ sub new
my $self = { my $self = {
_port => $pgport, _port => $pgport,
_host => $pghost, _host => $pghost,
_basedir => TestLib::tempdir("data_" . $name), _basedir => "$TestLib::tmp_check/t_${testname}_${name}_data",
_name => $name, _name => $name,
_logfile => "$TestLib::log_path/${testname}_${name}.log" }; _logfile => "$TestLib::log_path/${testname}_${name}.log" };
bless $self, $class; bless $self, $class;
mkdir $self->{_basedir} or
BAIL_OUT("could not create data directory \"$self->{_basedir}\": $!");
$self->dump_info; $self->dump_info;
return $self; return $self;
@ -928,9 +931,24 @@ sub get_new_node
return $node; return $node;
} }
# Retain the errno on die() if set, else assume a generic errno of 1.
# This will instruct the END handler on how to handle artifacts left
# behind from tests.
$SIG{__DIE__} = sub
{
if ($!)
{
$died = $!;
}
else
{
$died = 1;
}
};
# Automatically shut down any still-running nodes when the test script exits. # Automatically shut down any still-running nodes when the test script exits.
# Note that this just stops the postmasters (in the same order the nodes were # Note that this just stops the postmasters (in the same order the nodes were
# created in). Temporary PGDATA directories are deleted, in an unspecified # created in). Any temporary directories are deleted, in an unspecified
# order, later when the File::Temp objects are destroyed. # order, later when the File::Temp objects are destroyed.
END END
{ {
@ -941,6 +959,13 @@ END
foreach my $node (@all_nodes) foreach my $node (@all_nodes)
{ {
$node->teardown_node; $node->teardown_node;
# skip clean if we are requested to retain the basedir
next if defined $ENV{'PG_TEST_NOCLEAN'};
# clean basedir on clean test invocation
$node->clean_node
if TestLib::all_tests_passing() && !defined $died && !$exit_code;
} }
$? = $exit_code; $? = $exit_code;
@ -959,6 +984,22 @@ sub teardown_node
my $self = shift; my $self = shift;
$self->stop('immediate'); $self->stop('immediate');
}
=pod
=item $node->clean_node()
Remove the base directory of the node if the node has been stopped.
=cut
sub clean_node
{
my $self = shift;
rmtree $self->{_basedir} unless defined $self->{_pid};
} }
=pod =pod