From f7d199cefdec98bcdc5f580e5175ce09cb1299b2 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Fri, 23 Apr 2021 15:37:09 +1200 Subject: [PATCH] Test replay of regression tests. Add a new TAP test under src/test/recovery that runs the regression tests with wal_consistency_checking=all. --- src/test/recovery/Makefile | 3 + src/test/recovery/t/025_stream_rep_regress.pl | 67 +++++++++++++++++++ src/test/regress/pg_regress.c | 27 ++++++++ 3 files changed, 97 insertions(+) create mode 100644 src/test/recovery/t/025_stream_rep_regress.pl diff --git a/src/test/recovery/Makefile b/src/test/recovery/Makefile index 96442ceb4e..7dfcbae4b5 100644 --- a/src/test/recovery/Makefile +++ b/src/test/recovery/Makefile @@ -18,6 +18,9 @@ include $(top_builddir)/src/Makefile.global check: $(prove_check) +# Tell the TAP tests how to invoke make. +export MAKE + installcheck: $(prove_installcheck) 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..a7dbe54322 --- /dev/null +++ b/src/test/recovery/t/025_stream_rep_regress.pl @@ -0,0 +1,67 @@ +# Run the standard regression tests with streaming replication +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 3; + +# 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' ]); +$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; + +# Create some content on primary and check its presence in standby 1 +$node_primary->safe_psql('postgres', + "CREATE TABLE tab_int AS SELECT generate_series(1,1002) AS a"); + +# Wait for standby to catch up +$node_primary->wait_for_catchup($node_standby_1, 'replay', + $node_primary->lsn('insert')); + +my $result = + $node_standby_1->safe_psql('postgres', "SELECT count(*) FROM tab_int"); +print "standby 1: $result\n"; +is($result, qq(1002), 'check streamed content on standby 1'); + +# 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($ENV{MAKE}, '-C', '../regress', 'installcheck', + 'PGPORT=' . $node_primary->port, + 'EXTRA_REGRESS_OPTS=--skip-tests=tablespace --outputdir=' . TestLib::tempdir); + +# Wait for standby to catch up and do a sanity check +$node_primary->safe_psql('postgres', "INSERT INTO tab_int VALUES (42)"); +$node_primary->wait_for_catchup($node_standby_1, 'replay', + $node_primary->lsn('insert')); +$result = + $node_standby_1->safe_psql('postgres', "SELECT count(*) FROM tab_int"); +print "standby 1: $result\n"; +is($result, qq(1003), 'check streamed content on standby 1'); + +$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