Ok, here's a new version incorporating feedback so far.

1.  Invoke pg_regress directly (no make).

2.  Use PG_TEST_EXTRA="wal_consistency_checking" as a way to opt in to
the more expensive test.

3.  Use parallel schedule rather than serial.  It's faster but also
the non-determinism might discover more things.  This required
changing the TAP test max_connections setting from 10 to 25.

4.  Remove some extraneous print statements and
check-if-data-is-replicated-using-SELECT tests that are technically
not needed (I had copied those from 001_stream_rep.pl).
From c14c839be91b4b7b534c899370a5f450f118fed3 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.mu...@gmail.com>
Date: Fri, 23 Apr 2021 15:37:09 +1200
Subject: [PATCH v2] Test replay of regression tests.

Add a new TAP test under src/test/recovery to run the standard
regression tests with a streaming replica replaying the WAL.  This
provides a basic workout for WAL decoding and redo code.

Optionally, enable (expensive) wal_consistency_checking if configured in
PG_TEST_EXTRA.

For now, skip the tablespace tests with a new option to pg_regress,
until we have way to run them with a replica on the same file system.

Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com
---
 doc/src/sgml/regress.sgml                     | 11 ++++
 src/test/perl/PostgresNode.pm                 |  2 +-
 src/test/recovery/t/025_stream_rep_regress.pl | 62 +++++++++++++++++++
 src/test/regress/pg_regress.c                 | 27 ++++++++
 4 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 src/test/recovery/t/025_stream_rep_regress.pl

diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
index cb401a45b3..7a10c83d8a 100644
--- a/doc/src/sgml/regress.sgml
+++ b/doc/src/sgml/regress.sgml
@@ -289,6 +289,17 @@ make check-world PG_TEST_EXTRA='kerberos ldap ssl'
       </para>
      </listitem>
     </varlistentry>
+
+    <varlistentry>
+     <term><literal>wal_consistency_checking</literal></term>
+     <listitem>
+      <para>
+       Uses <literal>wal_consistency_checking=all</literal> while running
+       some of the tests under <filename>src/test/recovery</filename>.  Not
+       enabled by default because it is resource intensive.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
 
    Tests for features that are not supported by the current build
diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index 0eb8df5fbf..9fdf1eb060 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/PostgresNode.pm
@@ -482,7 +482,7 @@ sub init
 		print $conf "hot_standby = on\n";
 		# conservative settings to ensure we can run multiple postmasters:
 		print $conf "shared_buffers = 1MB\n";
-		print $conf "max_connections = 10\n";
+		print $conf "max_connections = 25\n";
 		# limit disk space consumption, too:
 		print $conf "max_wal_size = 128MB\n";
 	}
diff --git a/src/test/recovery/t/025_stream_rep_regress.pl b/src/test/recovery/t/025_stream_rep_regress.pl
new file mode 100644
index 0000000000..8b125a1d67
--- /dev/null
+++ b/src/test/recovery/t/025_stream_rep_regress.pl
@@ -0,0 +1,62 @@
+# Run the standard regression tests with streaming replication
+use strict;
+use warnings;
+use PostgresNode;
+use TestLib;
+use Test::More tests => 2;
+
+# Initialize primary node
+my $node_primary = get_new_node('primary');
+# A specific role is created to perform some tests related to replication,
+# and it needs proper authentication configuration.
+$node_primary->init(
+	allows_streaming => 1,
+	auth_extra       => [ '--create-role', 'repl_role' ]);
+
+# WAL consistency checking is resource intensive so require opt-in with the
+# PG_TEST_EXTRA environment variable.
+if ($ENV{PG_TEST_EXTRA} &&
+	$ENV{PG_TEST_EXTRA} =~ m/\bwal_consistency_checking\b/) {
+	$node_primary->append_conf('postgresql.conf',
+		'wal_consistency_checking = all');
+}
+
+$node_primary->start;
+is( $node_primary->psql(
+        'postgres',
+        qq[SELECT pg_create_physical_replication_slot('standby_1');]),
+    0,
+    'physical slot created on primary');
+my $backup_name = 'my_backup';
+
+# Take backup
+$node_primary->backup($backup_name);
+
+# Create streaming standby linking to primary
+my $node_standby_1 = get_new_node('standby_1');
+$node_standby_1->init_from_backup($node_primary, $backup_name,
+	has_streaming => 1);
+$node_standby_1->append_conf('postgresql.conf',
+    "primary_slot_name = standby_1");
+$node_standby_1->start;
+
+# XXX The tablespace tests don't currently work when the standby shares a
+# filesystem with the primary, due to colliding absolute paths.  We'll skip
+# that for now.
+
+# Run the regression tests against the primary.
+system_or_bail("../regress/pg_regress",
+			   "--port=" . $node_primary->port,
+			   "--schedule=../regress/parallel_schedule",
+			   "--dlpath=../regress",
+			   "--inputdir=../regress",
+			   "--skip-tests=tablespace");
+
+# Wait for standby to catch up
+$node_primary->wait_for_catchup($node_standby_1, 'replay',
+	$node_primary->lsn('insert'));
+
+ok(1, "caught up");
+
+$node_standby_1->stop;
+$node_primary->stop;
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index b7d80bd9bb..b75eccfa7c 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -83,6 +83,7 @@ static int	max_connections = 0;
 static int	max_concurrent_tests = 0;
 static char *encoding = NULL;
 static _stringlist *schedulelist = NULL;
+static _stringlist *skip_tests = NULL;
 static _stringlist *extra_tests = NULL;
 static char *temp_instance = NULL;
 static _stringlist *temp_configs = NULL;
@@ -203,6 +204,22 @@ split_to_stringlist(const char *s, const char *delim, _stringlist **listhead)
 	free(sc);
 }
 
+/*
+ * Test if a string is in a list.
+ */
+static bool
+string_in_stringlist(const char *s, _stringlist *list)
+{
+	while (list)
+	{
+		if (strcmp(list->str, s) == 0)
+			return true;
+		list = list->next;
+	}
+
+	return false;
+}
+
 /*
  * Print a progress banner on stdout.
  */
@@ -1662,7 +1679,11 @@ run_schedule(const char *schedule, test_start_function startfunc,
 		if (scbuf[0] == '\0' || scbuf[0] == '#')
 			continue;
 		if (strncmp(scbuf, "test: ", 6) == 0)
+		{
 			test = scbuf + 6;
+			if (string_in_stringlist(test, skip_tests))
+				continue;
+		}
 		else if (strncmp(scbuf, "ignore: ", 8) == 0)
 		{
 			c = scbuf + 8;
@@ -1860,6 +1881,7 @@ run_schedule(const char *schedule, test_start_function startfunc,
 	}
 
 	free_stringlist(&ignorelist);
+	free_stringlist(&skip_tests);
 
 	fclose(scf);
 }
@@ -2065,6 +2087,7 @@ help(void)
 	printf(_("      --outputdir=DIR           place output files in DIR (default \".\")\n"));
 	printf(_("      --schedule=FILE           use test ordering schedule from FILE\n"));
 	printf(_("                                (can be used multiple times to concatenate)\n"));
+	printf(_("      --skip-tests=LIST         comma-separated list of tests to skip\n"));
 	printf(_("      --temp-instance=DIR       create a temporary instance in DIR\n"));
 	printf(_("      --use-existing            use an existing installation\n"));
 	printf(_("  -V, --version                 output version information, then exit\n"));
@@ -2116,6 +2139,7 @@ regression_main(int argc, char *argv[],
 		{"load-extension", required_argument, NULL, 22},
 		{"config-auth", required_argument, NULL, 24},
 		{"max-concurrent-tests", required_argument, NULL, 25},
+		{"skip-tests", required_argument, NULL, 26},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -2245,6 +2269,9 @@ regression_main(int argc, char *argv[],
 			case 25:
 				max_concurrent_tests = atoi(optarg);
 				break;
+			case 26:
+				split_to_stringlist(optarg, ",", &skip_tests);
+				break;
 			default:
 				/* getopt_long already emitted a complaint */
 				fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"),
-- 
2.30.2

Reply via email to