From e93813f4ba4289df8485c142df8606fd57882c74 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Tue, 25 Apr 2017 15:59:48 +0200
Subject: [PATCH] Support retaining datadir on successful TAP tests

This moves the datadirs from using tempdirs with randomness in
the directory name to a static name to make it easier to clean
up as well as debug.  The datadir will be retained in case the
the tests fail or the testcode dies/exits with failure, and is
automatically removed on make check.  In case PG_TESTS_NOCLEAN
is defined the datadirs will be retained regardless of test or
exit status.

Additionally, a new make target 'check-clean' is added to the
directories containing TAP tests to allow for cleaning retained
datadirs.
---
 src/Makefile.global.in          | 11 ++++++++--
 src/bin/initdb/Makefile         |  3 +++
 src/bin/pg_basebackup/Makefile  |  3 +++
 src/bin/pg_config/Makefile      |  3 +++
 src/bin/pg_controldata/Makefile |  3 +++
 src/bin/pg_ctl/Makefile         |  3 +++
 src/bin/pg_dump/Makefile        |  3 +++
 src/bin/pg_rewind/Makefile      |  3 +++
 src/bin/pgbench/Makefile        |  3 +++
 src/bin/scripts/Makefile        |  3 +++
 src/test/perl/PostgresNode.pm   | 47 ++++++++++++++++++++++++++++++++++++++---
 11 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index b83f09f..579b40a 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -359,18 +359,25 @@ endef
 ifeq ($(enable_tap_tests),yes)
 
 define prove_installcheck
-rm -rf $(CURDIR)/tmp_check/log
+rm -rf $(CURDIR)/tmp_check/
+mkir -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)
 endef
 
 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)
 endef
 
+define prove_clean
+rm -rf $(CURDIR)/tmp_check/t_*_data
+endef
+
 else
 prove_installcheck = @echo "TAP tests not enabled"
 prove_check = $(prove_installcheck)
+prove_clean = $(prove_installcheck)
 endif
 
 # Installation.
diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile
index eaed050..f73f9a3 100644
--- a/src/bin/initdb/Makefile
+++ b/src/bin/initdb/Makefile
@@ -66,3 +66,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/pg_basebackup/Makefile b/src/bin/pg_basebackup/Makefile
index f0c3be8..5fe5b4f 100644
--- a/src/bin/pg_basebackup/Makefile
+++ b/src/bin/pg_basebackup/Makefile
@@ -58,3 +58,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile
index c410087..8d7e97a 100644
--- a/src/bin/pg_config/Makefile
+++ b/src/bin/pg_config/Makefile
@@ -40,3 +40,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/pg_controldata/Makefile b/src/bin/pg_controldata/Makefile
index fd87daa..ce93c84 100644
--- a/src/bin/pg_controldata/Makefile
+++ b/src/bin/pg_controldata/Makefile
@@ -40,3 +40,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/pg_ctl/Makefile b/src/bin/pg_ctl/Makefile
index f5ec088..83bb153 100644
--- a/src/bin/pg_ctl/Makefile
+++ b/src/bin/pg_ctl/Makefile
@@ -43,3 +43,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index b58636e..3f347ed 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -48,6 +48,9 @@ check:
 installcheck:
 	$(prove_installcheck)
 
+check-clean:
+	$(prove_clean)
+
 uninstall:
 	rm -f $(addprefix '$(DESTDIR)$(bindir)'/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))
 
diff --git a/src/bin/pg_rewind/Makefile b/src/bin/pg_rewind/Makefile
index 828ae01..0074648 100644
--- a/src/bin/pg_rewind/Makefile
+++ b/src/bin/pg_rewind/Makefile
@@ -52,3 +52,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/pgbench/Makefile b/src/bin/pgbench/Makefile
index 1503d00..af72189 100644
--- a/src/bin/pgbench/Makefile
+++ b/src/bin/pgbench/Makefile
@@ -48,3 +48,6 @@ check:
 
 installcheck:
 	$(prove_installcheck)
+
+check-clean:
+	$(prove_clean)
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
index 45ac492..a0268dd 100644
--- a/src/bin/scripts/Makefile
+++ b/src/bin/scripts/Makefile
@@ -59,5 +59,8 @@ clean distclean maintainer-clean:
 check:
 	$(prove_check)
 
+check-clean:
+	$(prove_clean)
+
 installcheck:
 	$(prove_installcheck)
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index 51cbec8..2eed791 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/PostgresNode.pm
@@ -86,6 +86,7 @@ use Config;
 use Cwd;
 use Exporter 'import';
 use File::Basename;
+use File::Path;
 use File::Spec;
 use File::Temp ();
 use IPC::Run;
@@ -99,7 +100,7 @@ our @EXPORT = qw(
   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
 
@@ -148,11 +149,13 @@ sub new
 	my $self = {
 		_port    => $pgport,
 		_host    => $pghost,
-		_basedir => TestLib::tempdir("data_" . $name),
+		_basedir => "$TestLib::tmp_check/t_${testname}_${name}_data",
 		_name    => $name,
 		_logfile => "$TestLib::log_path/${testname}_${name}.log" };
 
 	bless $self, $class;
+	BAIL_OUT("unable to create datadir \"$self->{_basedir}\"")
+		unless mkdir $self->{_basedir};
 	$self->dump_info;
 
 	return $self;
@@ -921,9 +924,24 @@ sub get_new_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.
 # 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.
 END
 {
@@ -934,6 +952,13 @@ END
 	foreach my $node (@all_nodes)
 	{
 		$node->teardown_node;
+
+		# skip clean if we are requested to retain the basedir
+		next if (defined $ENV{'PG_TESTS_NOCLEAN'});
+
+		# clean basedir on clean test invocation
+		$node->clean_node
+			unless (!TestLib::all_tests_passing() || defined $died || $exit_code);
 	}
 
 	$? = $exit_code;
@@ -952,6 +977,22 @@ sub teardown_node
 	my $self = shift;
 
 	$self->stop('immediate');
+
+}
+
+=pod
+
+=item $node->clean_node()
+
+Remove the base directory of the node iff the node has been stopped
+
+=cut
+
+sub clean_node
+{
+	my $self = shift;
+
+	rmtree $self->{_basedir} unless defined $self->{_pid};
 }
 
 =pod
-- 
2.6.4 (Apple Git-63)

