On Sun, Dec 5, 2021 at 4:16 AM Andrew Dunstan <and...@dunslane.net> wrote: > TAP tests are passed a path to pg_regress as $ENV{PG_REGRESS}. You > should be using that. On non-MSVC, the path to a non-installed psql is > in this case "$TESTDIR/../../bin/psql" - this should work for VPATH > builds as well as non-VPATH. On MSVC it's a bit harder - it's > "$top_builddir/$releasetype/psql" but we don't expose that. Perhaps we > should. c.f. commit f4ce6c4d3a
Thanks, that helped. Here's a new version that passes on Windows, Unix and Unix with VPATH. I also had to figure out where the DLLs are, and make sure that various output files go to the build directory, not source directory, if different, which I did by passing down another similar environment variable. Better ideas? (It confused me for some time that make follows the symlink and runs the perl code from inside the source directory.) This adds 2 whole minutes to the recovery check, when running with the Windows serial-only scripts on Cirrus CI (using Andres's CI patches). For Linux it adds ~20 seconds to the total of -j8 check-world. Hopefully that's time well spent, because it adds test coverage for all the redo routines, and hopefully soon we won't have to run 'em in series on Windows. Does anyone want to object to the concept of the "pg_user_files" directory or the developer-only GUC "allow_relative_tablespaces"? There's room for discussion about names; maybe initdb shouldn't create the directory unless you ask it to, or something.
From 6e4cbfea69ceb279b18d3312f37a77beb1f33506 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Tue, 25 May 2021 20:42:17 +1200 Subject: [PATCH v8 1/5] Allow restricted relative tablespace paths. Traditionally, tablespace paths provided to LOCATION had to be absolute, because relative paths risked colliding with PostgreSQL-managed files and generally blurring the boundary between system-managed and user-managed data. This commit adds a very small exception: it allows relative paths to be used, but only under a new directory "pg_user_files", and only if the developer-only option allow_relative_tablespaces is enabled. This is intended to be used in automated testing. Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com --- src/backend/commands/tablespace.c | 55 +++++++++++++++++++++++++++---- src/backend/utils/misc/guc.c | 12 +++++++ src/bin/initdb/initdb.c | 1 + src/common/string.c | 9 +++++ src/include/commands/tablespace.h | 2 ++ src/include/common/string.h | 1 + src/port/dirmod.c | 4 +++ 7 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 4b96eec9df..7e98ca5b76 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -70,6 +70,7 @@ #include "commands/tablecmds.h" #include "commands/tablespace.h" #include "common/file_perm.h" +#include "common/string.h" #include "miscadmin.h" #include "postmaster/bgwriter.h" #include "storage/fd.h" @@ -87,6 +88,7 @@ /* GUC variables */ char *default_tablespace = NULL; char *temp_tablespaces = NULL; +bool allow_relative_tablespaces = false; static void create_tablespace_directories(const char *location, @@ -267,11 +269,15 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) errmsg("tablespace location cannot contain single quotes"))); /* - * Allowing relative paths seems risky + * Allowing relative paths seems risky in general, but we'll allow it under + * pg_user_files if a developer-mode option is enabled, for the purpose + * of testing. * * this also helps us ensure that location is not empty or whitespace */ - if (!is_absolute_path(location)) + if (!is_absolute_path(location) && + (!allow_relative_tablespaces || + !pg_str_startswith(location, "pg_user_files/"))) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("tablespace location must be an absolute path"))); @@ -587,6 +593,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) static void create_tablespace_directories(const char *location, const Oid tablespaceoid) { + char buffer[MAXPGPATH]; char *linkloc; char *location_with_version_dir; struct stat st; @@ -602,11 +609,27 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) if (chmod(location, pg_dir_create_mode) != 0) { if (errno == ENOENT) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FILE), - errmsg("directory \"%s\" does not exist", location), - InRecovery ? errhint("Create this directory for the tablespace before " - "restarting the server.") : 0)); + { + /* + * We're prepared to create directories under pg_user_files on the + * fly, for the benefit of regression tests. + */ + if (pg_str_startswith(location, "pg_user_files/")) + { + Assert(allow_relative_tablespaces || InRecovery); + if (mkdir(location, pg_dir_create_mode) != 0) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FILE), + errmsg("could not create directory \"%s\"", + location))); + } + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FILE), + errmsg("directory \"%s\" does not exist", location), + InRecovery ? errhint("Create this directory for the tablespace before " + "restarting the server.") : 0)); + } else ereport(ERROR, (errcode_for_file_access(), @@ -651,6 +674,24 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) if (InRecovery) remove_tablespace_symlink(linkloc); + if (!is_absolute_path(location)) + { +#ifdef WIN32 + /* + * Our Windows junction-based symlink() emulation can't handle relative + * paths, so convert "pg_user_files" to an absolute path. + */ + snprintf(buffer, sizeof(buffer), "%s/%s", DataDir, location); +#else + /* + * Add a ".." prefix so that we have a path relative to the symlink, + * rather than DataDir. + */ + snprintf(buffer, sizeof(buffer), "../%s", location); +#endif + location = buffer; + } + /* * Create the symlink under PGDATA */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ee6a838b3a..ab11bee118 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -46,6 +46,7 @@ #include "catalog/storage.h" #include "commands/async.h" #include "commands/prepare.h" +#include "commands/tablespace.h" #include "commands/trigger.h" #include "commands/user.h" #include "commands/vacuum.h" @@ -1963,6 +1964,17 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"allow_relative_tablespaces", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Allows the tablespaces located under pg_user_files."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &allow_relative_tablespaces, + false, + NULL, NULL, NULL + }, + { {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS, gettext_noop("Enables backward compatibility mode for privilege checks on large objects."), diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 403adb0ee7..7c4b3e9626 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -225,6 +225,7 @@ static const char *const subdirs[] = { "pg_tblspc", "pg_stat", "pg_stat_tmp", + "pg_user_files", "pg_xact", "pg_logical", "pg_logical/snapshots", diff --git a/src/common/string.c b/src/common/string.c index 3aa378c051..7e7e34f1f5 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -24,6 +24,15 @@ #include "common/string.h" +/* + * Returns whether the string `str' has the prefix `start'. + */ +bool +pg_str_startswith(const char *str, const char *start) +{ + return strncmp(str, start, strlen(start)) == 0; +} + /* * Returns whether the string `str' has the postfix `end'. */ diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index 49cfc8479a..d286ced1c8 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -19,6 +19,8 @@ #include "lib/stringinfo.h" #include "nodes/parsenodes.h" +extern bool allow_relative_tablespaces; + /* XLOG stuff */ #define XLOG_TBLSPC_CREATE 0x00 #define XLOG_TBLSPC_DROP 0x10 diff --git a/src/include/common/string.h b/src/include/common/string.h index 8eb5271ec8..ddd384f6f9 100644 --- a/src/include/common/string.h +++ b/src/include/common/string.h @@ -21,6 +21,7 @@ typedef struct PromptInterruptContext } PromptInterruptContext; /* functions in src/common/string.c */ +extern bool pg_str_startswith(const char *str, const char *start); extern bool pg_str_endswith(const char *str, const char *end); extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base); diff --git a/src/port/dirmod.c b/src/port/dirmod.c index 763bc5f915..8787912d03 100644 --- a/src/port/dirmod.c +++ b/src/port/dirmod.c @@ -182,6 +182,10 @@ pgsymlink(const char *oldpath, const char *newpath) while ((p = strchr(p, '/')) != NULL) *p++ = '\\'; + /* collapse useless instances of "\.\" to "\" */ + while ((p = strstr(nativeTarget, "\\.\\")) != NULL) + memmove(p, p + 2, strlen(p + 2) + 1); + len = strlen(nativeTarget) * sizeof(WCHAR); reparseBuf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; reparseBuf->ReparseDataLength = len + 12; -- 2.30.2
From a60ada37f3ff7d311d56fe453b2abeadf0b350e5 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Wed, 4 Aug 2021 22:17:54 +1200 Subject: [PATCH v8 2/5] Use relative paths for tablespace regression test. Remove the machinery from pg_regress that manages the testtablespace directory. Instead, use a relative path. Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com --- src/test/regress/GNUmakefile | 3 +- .../tablespace.out} | 18 +++++++-- src/test/regress/pg_regress.c | 40 ------------------- .../tablespace.source => sql/tablespace.sql} | 19 +++++++-- src/tools/msvc/vcregress.pl | 2 - 5 files changed, 32 insertions(+), 50 deletions(-) rename src/test/regress/{output/tablespace.source => expected/tablespace.out} (97%) rename src/test/regress/{input/tablespace.source => sql/tablespace.sql} (95%) diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile index fe6e0c98aa..d014b4a35d 100644 --- a/src/test/regress/GNUmakefile +++ b/src/test/regress/GNUmakefile @@ -119,7 +119,7 @@ submake-contrib-spi: | submake-libpgport submake-generated-headers ## Run tests ## -REGRESS_OPTS = --dlpath=. --max-concurrent-tests=20 --make-testtablespace-dir \ +REGRESS_OPTS = --dlpath=. --max-concurrent-tests=20 \ $(EXTRA_REGRESS_OPTS) check: all @@ -163,5 +163,4 @@ clean distclean maintainer-clean: clean-lib rm -f pg_regress_main.o pg_regress.o pg_regress$(X) # things created by various check targets rm -f $(output_files) $(input_files) - rm -rf testtablespace rm -rf $(pg_regress_clean_files) diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/expected/tablespace.out similarity index 97% rename from src/test/regress/output/tablespace.source rename to src/test/regress/expected/tablespace.out index e7629d470e..7386693e05 100644 --- a/src/test/regress/output/tablespace.source +++ b/src/test/regress/expected/tablespace.out @@ -1,7 +1,19 @@ +-- Note: this test uses relative paths and expects the server to create the +-- directory on the fly, so that a streaming replica on the same system can +-- replay it. Normally we require absolute paths to directories that already +-- exist. +-- create a tablespace under a relative path +SET allow_relative_tablespaces = off; +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace'; -- fail +ERROR: tablespace location must be an absolute path +-- enable developer option allowing relative paths, with unacceptable prefix +SET allow_relative_tablespaces = on; +CREATE TABLESPACE regress_tblspacewith LOCATION 'xyz/testtablespace'; -- fail +ERROR: tablespace location must be an absolute path -- create a tablespace using WITH clause -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (some_nonexistent_parameter = true); -- fail +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (some_nonexistent_parameter = true); -- fail ERROR: unrecognized parameter "some_nonexistent_parameter" -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (random_page_cost = 3.0); -- ok +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (random_page_cost = 3.0); -- ok -- check to see the parameter was used SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; spcoptions @@ -12,7 +24,7 @@ SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; -- drop the tablespace so we can re-use the location DROP TABLESPACE regress_tblspacewith; -- create a tablespace we can use -CREATE TABLESPACE regress_tblspace LOCATION '@testtablespace@'; +CREATE TABLESPACE regress_tblspace LOCATION 'pg_user_files/testtablespace'; -- try setting and resetting some properties for the new tablespace ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true); -- fail diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index 2c8a600bad..7c1404dac1 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -477,7 +477,6 @@ replace_string(StringInfo string, const char *replace, const char *replacement) static void convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const char *dest_subdir, const char *suffix) { - char testtablespace[MAXPGPATH]; char indir[MAXPGPATH]; char outdir_sub[MAXPGPATH]; char **name; @@ -506,9 +505,6 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch if (!directory_exists(outdir_sub)) make_directory(outdir_sub); - /* We might need to replace @testtablespace@ */ - snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", outputdir); - /* finally loop on each file and do the replacement */ for (name = names; *name; name++) { @@ -554,7 +550,6 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch { replace_string(&line, "@abs_srcdir@", inputdir); replace_string(&line, "@abs_builddir@", outputdir); - replace_string(&line, "@testtablespace@", testtablespace); replace_string(&line, "@libdir@", dlpath); replace_string(&line, "@DLSUFFIX@", DLSUFFIX); fputs(line.data, outfile); @@ -587,32 +582,6 @@ convert_sourcefiles(void) convert_sourcefiles_in("output", outputdir, "expected", "out"); } -/* - * Clean out the test tablespace dir, or create it if it doesn't exist. - * - * On Windows, doing this cleanup here makes it possible to run the - * regression tests under a Windows administrative user account with the - * restricted token obtained when starting pg_regress. - */ -static void -prepare_testtablespace_dir(void) -{ - char testtablespace[MAXPGPATH]; - - snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", outputdir); - - if (directory_exists(testtablespace)) - { - if (!rmtree(testtablespace, true)) - { - fprintf(stderr, _("\n%s: could not remove test tablespace \"%s\"\n"), - progname, testtablespace); - exit(2); - } - } - make_directory(testtablespace); -} - /* * Scan resultmap file to find which platform-specific expected files to use. * @@ -2152,7 +2121,6 @@ help(void) printf(_(" --launcher=CMD use CMD as launcher of psql\n")); printf(_(" --load-extension=EXT load the named extension before running the\n")); printf(_(" tests; can appear multiple times\n")); - printf(_(" --make-testtablespace-dir create testtablespace directory\n")); printf(_(" --max-connections=N maximum number of concurrent connections\n")); printf(_(" (default is 0, meaning unlimited)\n")); printf(_(" --max-concurrent-tests=N maximum number of concurrent tests in schedule\n")); @@ -2211,12 +2179,10 @@ 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}, - {"make-testtablespace-dir", no_argument, NULL, 26}, {NULL, 0, NULL, 0} }; bool use_unix_sockets; - bool make_testtablespace_dir = false; _stringlist *sl; int c; int i; @@ -2342,9 +2308,6 @@ regression_main(int argc, char *argv[], case 25: max_concurrent_tests = atoi(optarg); break; - case 26: - make_testtablespace_dir = true; - break; default: /* getopt_long already emitted a complaint */ fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"), @@ -2397,9 +2360,6 @@ regression_main(int argc, char *argv[], unlimit_core_size(); #endif - if (make_testtablespace_dir) - prepare_testtablespace_dir(); - if (temp_instance) { FILE *pg_conf; diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/sql/tablespace.sql similarity index 95% rename from src/test/regress/input/tablespace.source rename to src/test/regress/sql/tablespace.sql index cb9774ecc8..6c79eb0333 100644 --- a/src/test/regress/input/tablespace.source +++ b/src/test/regress/sql/tablespace.sql @@ -1,6 +1,19 @@ +-- Note: this test uses relative paths and expects the server to create the +-- directory on the fly, so that a streaming replica on the same system can +-- replay it. Normally we require absolute paths to directories that already +-- exist. + +-- create a tablespace under a relative path +SET allow_relative_tablespaces = off; +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace'; -- fail + +-- enable developer option allowing relative paths, with unacceptable prefix +SET allow_relative_tablespaces = on; +CREATE TABLESPACE regress_tblspacewith LOCATION 'xyz/testtablespace'; -- fail + -- create a tablespace using WITH clause -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (some_nonexistent_parameter = true); -- fail -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (random_page_cost = 3.0); -- ok +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (some_nonexistent_parameter = true); -- fail +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (random_page_cost = 3.0); -- ok -- check to see the parameter was used SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; @@ -9,7 +22,7 @@ SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; DROP TABLESPACE regress_tblspacewith; -- create a tablespace we can use -CREATE TABLESPACE regress_tblspace LOCATION '@testtablespace@'; +CREATE TABLESPACE regress_tblspace LOCATION 'pg_user_files/testtablespace'; -- try setting and resetting some properties for the new tablespace ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl index 5975e7c9cd..bf66083f73 100644 --- a/src/tools/msvc/vcregress.pl +++ b/src/tools/msvc/vcregress.pl @@ -133,7 +133,6 @@ sub installcheck_internal "--bindir=../../../$Config/psql", "--schedule=${schedule}_schedule", "--max-concurrent-tests=20", - "--make-testtablespace-dir", "--encoding=SQL_ASCII", "--no-locale"); push(@args, $maxconn) if $maxconn; @@ -168,7 +167,6 @@ sub check "--bindir=", "--schedule=${schedule}_schedule", "--max-concurrent-tests=20", - "--make-testtablespace-dir", "--encoding=SQL_ASCII", "--no-locale", "--temp-instance=./tmp_check"); -- 2.30.2
From 5d76158609f6aa338fad7dd0ef872715582b0b08 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Tue, 5 Oct 2021 21:01:02 +1300 Subject: [PATCH v8 3/5] Test replay of regression tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new TAP test under src/test/recovery to run the standard regression tests while a streaming replica replays the WAL. This provides a basic workout for WAL decoding and redo code, and compares the replicated result. Optionally, enable (expensive) wal_consistency_checking if listed in the env variable PG_TEST_EXTRA. Reviewed-by: 綱川 貴之 (Takayuki Tsunakawa) <tsunakawa.ta...@fujitsu.com> Reviewed-by: Andres Freund <and...@anarazel.de> Reviewed-by: Andrew Dunstan <and...@dunslane.net> Reviewed-by: Tom Lane <t...@sss.pgh.pa.us> Reviewed-by: Anastasia Lubennikova <lubennikov...@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com --- doc/src/sgml/regress.sgml | 11 ++++ src/test/perl/PostgreSQL/Test/Cluster.pm | 2 +- src/test/recovery/Makefile | 6 +- src/test/recovery/t/027_stream_regress.pl | 75 +++++++++++++++++++++++ src/tools/msvc/vcregress.pl | 2 + 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/test/recovery/t/027_stream_regress.pl diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml index 724ef566e7..64fc81776d 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/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm index 9467a199c8..5cfa137cde 100644 --- a/src/test/perl/PostgreSQL/Test/Cluster.pm +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -460,7 +460,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/Makefile b/src/test/recovery/Makefile index 288c04b861..c557018b38 100644 --- a/src/test/recovery/Makefile +++ b/src/test/recovery/Makefile @@ -15,10 +15,14 @@ subdir = src/test/recovery top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -# required for 017_shm.pl +# required for 017_shm.pl and 027_stream_regress.pl REGRESS_SHLIB=$(abs_top_builddir)/src/test/regress/regress$(DLSUFFIX) export REGRESS_SHLIB +# required for 027_stream_regress.pl +REGRESS_OUTPUTDIR=$(abs_top_builddir)/src/test/recovery +export REGRESS_OUTPUTDIR + check: $(prove_check) diff --git a/src/test/recovery/t/027_stream_regress.pl b/src/test/recovery/t/027_stream_regress.pl new file mode 100644 index 0000000000..d656762d29 --- /dev/null +++ b/src/test/recovery/t/027_stream_regress.pl @@ -0,0 +1,75 @@ +# Run the standard regression tests with streaming replication +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More tests => 4; +use File::Basename; + +# Initialize primary node +my $node_primary = PostgreSQL::Test::Cluster->new('primary'); +$node_primary->init(allows_streaming => 1); + +# 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 = PostgreSQL::Test::Cluster->new('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; + +my $dlpath = PostgreSQL::Test::Utils::perl2host(dirname($ENV{REGRESS_SHLIB})); +my $outputdir = PostgreSQL::Test::Utils::perl2host($ENV{REGRESS_OUTPUTDIR}); + +# Run the regression tests against the primary. +system_or_bail($ENV{PG_REGRESS}, + "--dlpath=" . $dlpath, + "--bindir=", + "--port=" . $node_primary->port, + "--schedule=../regress/parallel_schedule", + "--inputdir=../regress", + "--outputdir=" . $outputdir); + +# Clobber all sequences with their next value, so that we don't have +# differences between nodes due to caching. +$node_primary->psql('regression', + "select setval(seqrelid, nextval(seqrelid)) from pg_sequence"); + +# Wait for standby to catch up +$node_primary->wait_for_catchup($node_standby_1, 'replay', + $node_primary->lsn('insert')); + +# Perform a logical dump of primary and standby, and check that they match +command_ok( + [ "pg_dump", '-f', $outputdir . '/primary.dump', '--no-sync', + '-p', $node_primary->port, 'regression' ], + "dump primary server"); +command_ok( + [ "pg_dump", '-f', $outputdir . '/standby.dump', '--no-sync', + '-p', $node_standby_1->port, 'regression' ], + "dump standby server"); +command_ok( + [ "diff", $outputdir . '/primary.dump', $outputdir . '/standby.dump' ], + "compare primary and standby dumps"); + +$node_standby_1->stop; +$node_primary->stop; diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl index bf66083f73..d002bdac9d 100644 --- a/src/tools/msvc/vcregress.pl +++ b/src/tools/msvc/vcregress.pl @@ -535,6 +535,8 @@ sub recoverycheck { InstallTemp(); + $ENV{REGRESS_OUTPUTDIR} = "$topdir/src/test/recovery"; + my $mstat = 0; my $dir = "$topdir/src/test/recovery"; my $status = tap_check($dir); -- 2.30.2