Supporting TAP tests with MSVC and Windows

Started by Michael Paquieralmost 11 years ago23 messages
#1Michael Paquier
michael.paquier@gmail.com
1 attachment(s)

Hi all,
(Adding Peter and Heikki in CC for awareness)

Please find attached a WIP patch to support TAP tests with MSVC. The
tests can be kicked with this command:
vcregress tapcheck

There are a couple of things to note with this patch, and I would like
to have some input for some of those things:
1) I have tweaked some code paths to configure a node correctly, with
for example listen_addresses = 'localhost', or disabling local
settings in pg_hba.conf. Does that sound fine?
2) tapcheck does not check if IPC::Run is installed or not. Should we
add a check in the code for that? If yes, should we bypass the test or
fail?
3) Temporary installation needs to be done in the top directory,
actually out of src/, because Install.pm scans the contents of src/ to
fetch for example the .samples files and this leads to bad
interactions. Using this location has as well the advantage to install
the binaries for all the tests only once.
4) pg_rewind tests are disabled for now, I am waiting for the outcome
of 5519F169.8030406@gmx.net
5) ssl tests are disabled for now (haven't looked at that yet). They
should be tested if possible. Still need some investigation.
6) the command to access pg_regress is passed using an environment
variable TESTREGRESS.
7) TAP tests use sometimes top_builddir directly. I think that's ugly,
and if there are no objections I think that we should change it to use
a dedicated environment variable like TESTTOP or similar.
8) Some commands have needed some tweaks because option parsing on
Windows is... Well... sometimes broken. For example those things do
not work on Windows:
createdb foobar3 -E win1252
initdb PGDATA -X XLOGDIR
Note that modifying those commands does not change the test coverage.
9) @Peter: IPC::Run is not reliable when using h->results, by
switching to (h->full_results)[0] I was able to get results reliably
from a child process.
10) This patch needs to have IPC::Run installed. You need to install
it from CPAN, that's the same deal as for OSX.
11) Windows does not support symlink, so some tests of pg_basebackup
cannot be executed. I can live with this restriction.

I think that's all for now. I'll add this patch to the 2015-06 commit fest.
Regards,
--
Michael

Attachments:

20150402_tap_tests_msvc.patchtext/x-patch; charset=US-ASCII; name=20150402_tap_tests_msvc.patchDownload
diff --git a/.gitignore b/.gitignore
index 8d3af50..3cd37fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,6 @@ lib*.pc
 /pgsql.sln.cache
 /Debug/
 /Release/
+
+# Generated by tests
+/tmp_check/
diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index 9b77648..d3d8f5f 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -438,6 +438,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress contribcheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 149b3d1..091ec0e 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -1,10 +1,26 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 19;
 
 my $tempdir = TestLib::tempdir;
 
+sub cleanup_tempdir
+{
+	my $tempdir = shift;
+
+	if ($Config{osname} eq "MSWin32")
+	{
+		system_or_bail "rd /s /q $tempdir";
+		mkdir $tempdir;
+	}
+	else
+	{
+		system_or_bail "rm -rf '$tempdir'/*";
+	}
+}
+
 program_help_ok('initdb');
 program_version_ok('initdb');
 program_options_handling_ok('initdb');
@@ -18,27 +34,26 @@ command_fails([ 'initdb', '-S', "$tempdir/data3" ],
 mkdir "$tempdir/data4" or BAIL_OUT($!);
 command_ok([ 'initdb', "$tempdir/data4" ], 'existing empty data directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
-
-command_ok([ 'initdb', "$tempdir/data", '-X', "$tempdir/pgxlog" ],
-	'separate xlog directory');
+cleanup_tempdir $tempdir;
 
-system_or_bail "rm -rf '$tempdir'/*";
+command_ok([ 'initdb', '-D', "$tempdir/data", '-X', "$tempdir/pgxlog" ],
+		   'separate xlog directory');
+cleanup_tempdir $tempdir;
 command_fails(
 	[ 'initdb', "$tempdir/data", '-X', 'pgxlog' ],
 	'relative xlog directory not allowed');
 
-system_or_bail "rm -rf '$tempdir'/*";
+cleanup_tempdir $tempdir;
 mkdir "$tempdir/pgxlog";
-command_ok([ 'initdb', "$tempdir/data", '-X', "$tempdir/pgxlog" ],
+command_ok([ 'initdb', '-D', "$tempdir/data", '-X', "$tempdir/pgxlog" ],
 	'existing empty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+cleanup_tempdir $tempdir;
 mkdir "$tempdir/pgxlog";
 mkdir "$tempdir/pgxlog/lost+found";
-command_fails([ 'initdb', "$tempdir/data", '-X', "$tempdir/pgxlog" ],
+command_fails([ 'initdb', '-D', "$tempdir/data", '-X', "$tempdir/pgxlog" ],
 	'existing nonempty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
-command_ok([ 'initdb', "$tempdir/data", '-T', 'german' ],
+cleanup_tempdir $tempdir;
+command_ok([ 'initdb', '-D', "$tempdir/data", '-T', 'german' ],
 	'select default dictionary');
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 7e9a776..130f41a 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 26 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -18,7 +19,11 @@ command_fails(
 	'pg_basebackup fails because of hba');
 
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
+# Windows builds do not support local connections
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+}
 print HBA "host replication all 127.0.0.1/32 trust\n";
 print HBA "host replication all ::1/128 trust\n";
 close HBA;
@@ -61,49 +66,53 @@ unlink "$tempdir/pgdata/$superlongname";
 # for the tablespace directories, which hopefully won't run afoul of
 # the 99 character length limit.
 my $shorter_tempdir = tempdir_short . "/tempdir";
-symlink "$tempdir", $shorter_tempdir;
 
-mkdir "$tempdir/tblspc1";
-psql 'postgres', "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
-psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
-	'tar format with tablespaces');
-ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
-my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
-is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
-	'plain format with tablespaces fails without tablespace mapping');
-
-command_ok(
-	[   'pg_basebackup',    '-D',
-		"$tempdir/backup1", '-Fp',
-		"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
-	'plain format with tablespaces succeeds with tablespace mapping');
-ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
-opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
-ok( (   grep
-		{
-			-l "$tempdir/backup1/pg_tblspc/$_"
-			  and readlink "$tempdir/backup1/pg_tblspc/$_" eq
-			  "$tempdir/tbackup/tblspc1"
-		  } readdir($dh)),
-	"tablespace symlink was updated");
-closedir $dh;
-
-mkdir "$tempdir/tbl=spc2";
-psql 'postgres', "DROP TABLE test1;";
-psql 'postgres', "DROP TABLESPACE tblspc1;";
-psql 'postgres', "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
-command_ok(
-	[   'pg_basebackup',    '-D',
-		"$tempdir/backup3", '-Fp',
-		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
-	'mapping tablespace with = sign in path');
-ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
-psql 'postgres', "DROP TABLESPACE tblspc2;";
+# Windows does not support symlink
+if ($Config{osname} ne "MSWin32")
+{
+	symlink "$tempdir", $shorter_tempdir;
+
+	mkdir "$tempdir/tblspc1";
+	psql 'postgres', "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
+	psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
+			   'tar format with tablespaces');
+	ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
+	my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
+	is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
+
+	command_fails(
+		[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
+		'plain format with tablespaces fails without tablespace mapping');
+
+	command_ok(
+		[   'pg_basebackup',    '-D',
+			"$tempdir/backup1", '-Fp',
+			"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
+		'plain format with tablespaces succeeds with tablespace mapping');
+	ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
+	opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
+	ok( (   grep
+			{
+				-l "$tempdir/backup1/pg_tblspc/$_"
+					and readlink "$tempdir/backup1/pg_tblspc/$_" eq
+					"$tempdir/tbackup/tblspc1"
+			} readdir($dh)),
+		"tablespace symlink was updated");
+	closedir $dh;
+
+	mkdir "$tempdir/tbl=spc2";
+	psql 'postgres', "DROP TABLE test1;";
+	psql 'postgres', "DROP TABLESPACE tblspc1;";
+	psql 'postgres', "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
+	command_ok(
+		[   'pg_basebackup',    '-D',
+			"$tempdir/backup3", '-Fp',
+			"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
+		'mapping tablespace with = sign in path');
+	ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
+	psql 'postgres', "DROP TABLESPACE tblspc2;";
+}
 
 command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 17309e8..f5b61cf 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,11 +1,15 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
 my $tempdir = TestLib::tempdir;
 my $tempdir_short = TestLib::tempdir_short;
 
+my $pg_regress = ($Config{osname} eq "MSWin32") ?
+	$ENV{TESTREGRESS} : "$ENV{top_builddir}/src/test/regress/pg_regress";
+
 program_help_ok('pg_ctl');
 program_version_ok('pg_ctl');
 program_options_handling_ok('pg_ctl');
@@ -15,12 +19,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[   "$pg_regress", '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = 'localhost'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index b8cbbda..ffea71f 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = 'localhost'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/scripts/t/010_clusterdb.pl b/src/bin/scripts/t/010_clusterdb.pl
index cb9d04b..f125625 100644
--- a/src/bin/scripts/t/010_clusterdb.pl
+++ b/src/bin/scripts/t/010_clusterdb.pl
@@ -15,12 +15,12 @@ issues_sql_like(
 	qr/statement: CLUSTER;/,
 	'SQL CLUSTER run');
 
-command_fails([ 'clusterdb', '-t', 'nonexistent', 'postgres' ],
+command_fails([ 'clusterdb', '-t', 'nonexistent', '-d', 'postgres' ],
 	'fails with nonexistent table');
 
 psql 'postgres',
 'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a); CLUSTER test1 USING test1x';
 issues_sql_like(
-	[ 'clusterdb', 'postgres', '-t', 'test1' ],
+	[ 'clusterdb', '-d', 'postgres', '-t', 'test1' ],
 	qr/statement: CLUSTER test1;/,
 	'cluster specific table');
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 40fbc92..7395381 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,9 +15,11 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
-	[ 'createdb', 'foobar2', '-l', 'C', '-E', 'LATIN1', '-T', 'template0' ],
-	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
+	[ 'createdb', '-l', 'C', '-E', "$encoding", '-T', 'template0', 'foobar2' ],
+	qr/statement: CREATE DATABASE foobar2 ENCODING '$encoding'/,
 	'create database with encoding');
 
 command_fails([ 'createdb', 'foobar1' ], 'fails if database already exists');
diff --git a/src/bin/scripts/t/090_reindexdb.pl b/src/bin/scripts/t/090_reindexdb.pl
index d24088e..f80a79e 100644
--- a/src/bin/scripts/t/090_reindexdb.pl
+++ b/src/bin/scripts/t/090_reindexdb.pl
@@ -20,18 +20,18 @@ issues_sql_like(
 psql 'postgres',
   'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a);';
 issues_sql_like(
-	[ 'reindexdb', 'postgres', '-t', 'test1' ],
+	[ 'reindexdb', '-d', 'postgres', '-t', 'test1' ],
 	qr/statement: REINDEX TABLE test1;/,
 	'reindex specific table');
 issues_sql_like(
-	[ 'reindexdb', 'postgres', '-i', 'test1x' ],
+	[ 'reindexdb', '-d', 'postgres', '-i', 'test1x' ],
 	qr/statement: REINDEX INDEX test1x;/,
 	'reindex specific index');
 issues_sql_like(
-	[ 'reindexdb', 'postgres', '-S', 'pg_catalog' ],
+	[ 'reindexdb', '-d', 'postgres', '-S', 'pg_catalog' ],
 	qr/statement: REINDEX SCHEMA pg_catalog;/,
 	'reindex specific schema');
 issues_sql_like(
-	[ 'reindexdb', 'postgres', '-s' ],
+	[ 'reindexdb', '-d', 'postgres', '-s' ],
 	qr/statement: REINDEX SYSTEM postgres;/,
 	'reindex system tables');
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 003cd9a..26de1ac 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -73,9 +74,19 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-				   '--config-auth', $pgdata);
+
+	if ($Config{osname} eq "MSWin32")
+	{
+		system_or_bail("initdb -D $pgdata -A trust -N > NUL");
+		system_or_bail("$ENV{TESTREGRESS}",
+					   '--config-auth', $pgdata);
+	}
+	else
+	{
+		system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
+		system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+					   '--config-auth', $pgdata);
+	}
 }
 
 my ($test_server_datadir, $test_server_logfile);
@@ -87,10 +98,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "localhost" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-	  "--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -99,7 +112,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "localhost" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -158,7 +171,7 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	is(($h->full_results)[0], $expected, $test_name);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index bd3dd2c..affe92b 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -31,7 +33,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -77,6 +79,7 @@ my %command = (
 	ECPGCHECK      => \&ecpgcheck,
 	CONTRIBCHECK   => \&contribcheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -162,6 +165,59 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	# Temporary installation cannot be located deeper in src/ because
+	# of interferences with Install.pm scanning its content. So install
+	# it just once for all the tests.
+	my $tmp_root = "$topdir/tmp_check";
+	(mkdir $tmp_root || die $!) unless -d $tmp_root;
+	my $tmp_install = "$tmp_root/install";
+	Install($tmp_install, "all", $config);
+	my @args = (
+		"prove",
+		"--verbose",
+		"t/*.pl");
+
+	# XXX: Check existence of IPC::Run in environment?
+
+	# Set environment variables common to all the tests
+	my ($bindir, $libdir, $oldsrc, $newsrc) =
+	  ("$tmp_install/bin", "$tmp_install/lib", $topdir, $topdir);
+
+	$ENV{PATH} = "$bindir;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+	$ENV{top_builddir} = "$topdir";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach(@$tap_dirs)
+	{
+		next if /pg_rewind/;
+		next if /ssl/;
+
+		my $dir = dirname($_);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		$ENV{PGHOST} = 'localhost';
+		$ENV{PGPORT} ||= 50432;
+		system(@args);
+	}
+}
+
 sub plcheck
 {
 	chdir "../../pl";
#2Noah Misch
noah@leadboat.com
In reply to: Michael Paquier (#1)
Re: Supporting TAP tests with MSVC and Windows

Each Windows patch should cover all Windows build systems; patches that fix a
problem in the src/tools/msvc build while leaving it broken in the GNU make
build are a bad trend. In this case, I expect you'll need few additional
changes to cover both.

On Thu, Apr 02, 2015 at 06:30:02PM +0900, Michael Paquier wrote:

2) tapcheck does not check if IPC::Run is installed or not. Should we
add a check in the code for that? If yes, should we bypass the test or
fail?

The src/tools/msvc build system officially requires ActivePerl, and I seem to
recall ActivePerl installs IPC::Run by default. A check is optional.

7) TAP tests use sometimes top_builddir directly. I think that's ugly,
and if there are no objections I think that we should change it to use
a dedicated environment variable like TESTTOP or similar.

I sense nothing ugly about a top_builddir reference, but see below.

--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
+# Windows builds do not support local connections
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+}
print HBA "host replication all 127.0.0.1/32 trust\n";
print HBA "host replication all ::1/128 trust\n";
close HBA;

Test suites that run as part of "make check-world", including all src/bin TAP
suites, _must not_ enable trust authentication on Windows. To do so would
reintroduce CVE-2014-0067. (The standard alternative is to call "pg_regress
--config-auth", which switches a data directory to SSPI authentication.)
Suites not in check-world, though not obligated to follow that rule, will have
a brighter future if they do so anyway.

--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -73,9 +74,19 @@ sub tempdir_short
sub standard_initdb
{
my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-				   '--config-auth', $pgdata);
+
+	if ($Config{osname} eq "MSWin32")
+	{
+		system_or_bail("initdb -D $pgdata -A trust -N > NUL");
+		system_or_bail("$ENV{TESTREGRESS}",
+					   '--config-auth', $pgdata);
+	}
+	else
+	{
+		system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
+		system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+					   '--config-auth', $pgdata);
+	}
}

Make all build systems set TESTREGRESS, and use it unconditionally.

That's not a complete review, just some highlights.

Thanks,
nm

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Michael Paquier
michael.paquier@gmail.com
In reply to: Noah Misch (#2)
Re: Supporting TAP tests with MSVC and Windows

Thanks for your input, Noah.

On Fri, Apr 3, 2015 at 3:22 PM, Noah Misch <noah@leadboat.com> wrote:

Each Windows patch should cover all Windows build systems; patches that fix a
problem in the src/tools/msvc build while leaving it broken in the GNU make
build are a bad trend. In this case, I expect you'll need few additional
changes to cover both.

Yes I am planning to do more tests with MinGW as well, once I got the
patch in a more advanced state in May/June. For Cygwin, I am not much
familiar with it yet, but I am sure I'll come up with something.

On Thu, Apr 02, 2015 at 06:30:02PM +0900, Michael Paquier wrote:

2) tapcheck does not check if IPC::Run is installed or not. Should we
add a check in the code for that? If yes, should we bypass the test or
fail?

The src/tools/msvc build system officially requires ActivePerl, and I seem to
recall ActivePerl installs IPC::Run by default. A check is optional.

I recall installing ActivePerl for my own box some time ago. It is
5.16, so now it is outdated, but the package manager does not contain
IPC::Run and I had to install it by hand.

Test suites that run as part of "make check-world", including all src/bin TAP
suites, _must not_ enable trust authentication on Windows. To do so would
reintroduce CVE-2014-0067. (The standard alternative is to call "pg_regress
--config-auth", which switches a data directory to SSPI authentication.)
Suites not in check-world, though not obligated to follow that rule, will have
a brighter future if they do so anyway.

OK. I'll rework this part.

--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -73,9 +74,19 @@ sub tempdir_short
sub standard_initdb
{
my $pgdata = shift;
-     system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-     system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-                                '--config-auth', $pgdata);
+
+     if ($Config{osname} eq "MSWin32")
+     {
+             system_or_bail("initdb -D $pgdata -A trust -N > NUL");
+             system_or_bail("$ENV{TESTREGRESS}",
+                                        '--config-auth', $pgdata);
+     }
+     else
+     {
+             system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
+             system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+                                        '--config-auth', $pgdata);
+     }
}

Make all build systems set TESTREGRESS, and use it unconditionally.

Yeah, that would be better.

That's not a complete review, just some highlights.

Thanks again.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#3)
1 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

(Thanks Noah for pointing out that the patch did not reach the MLs..)

On Fri, Apr 3, 2015 at 3:40 PM, Michael Paquier wrote:

That's not a complete review, just some highlights.

Thanks again.

Here is a v2 with the following changes:
- Use an environment variable to define where pg_regress is located.
- Use SSPI to access a node in the tests, to secure the test environment.
- Rebase on latest HEAD
- SSL tests are run only if build is configured with openssl

A couple of things to note:
- pg_rewind tests are still disabled, waiting for the outcome of
5519F169.8030406@gmx.net. They will need some tweaks.
- SSL tests can work if an equivalent of cp is available, like
something installed with msysgit... IMO the scripts in src/test/ssl
should be patched to be made more portable (see
/messages/by-id/CAB7nPqQivFxnSjPwkyapa8=HTGm0hfDNvdGcM3=hkK6fPT0+Pg@mail.gmail.com)
- I tested the scripts with MinGW and this patch and got them working.
As prove can fail because of a bad perl interpreter, pointing to
/usr/bin/perl, it is necessary to enforce "PROVE = c:\Perl64\bin\perl
c:\Perl64\bin\prove" or similar. That's not beautiful, but it works,
and the t/ scripts need no further modifications. At least I checked
that.
Regards,
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From 28bda0ccb13f3d2c53170dbf10fb8fd6fb087b36 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Wed, 8 Apr 2015 23:07:33 -0700
Subject: [PATCH] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 .gitignore                                     |  3 +
 doc/src/sgml/install-windows.sgml              |  1 +
 src/Makefile.global.in                         |  2 +-
 src/bin/initdb/t/001_initdb.pl                 | 27 +++++++--
 src/bin/pg_basebackup/t/010_pg_basebackup.pl   | 79 ++++++++++++++++----------
 src/bin/pg_controldata/t/001_pg_controldata.pl |  5 +-
 src/bin/pg_ctl/t/001_start_stop.pl             | 14 ++++-
 src/bin/pg_ctl/t/002_status.pl                 | 12 +++-
 src/bin/scripts/t/020_createdb.pl              |  3 +
 src/test/perl/TestLib.pm                       | 14 +++--
 src/tools/msvc/vcregress.pl                    | 53 ++++++++++++++++-
 11 files changed, 163 insertions(+), 50 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8d3af50..3cd37fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,6 @@ lib*.pc
 /pgsql.sln.cache
 /Debug/
 /Release/
+
+# Generated by tests
+/tmp_check/
diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index 9b77648..d3d8f5f 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -438,6 +438,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress contribcheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 7c39d82..b5c2f0e 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -323,7 +323,7 @@ endef
 define prove_check
 $(MKDIR_P) tmp_check/log
 $(MAKE) -C $(top_builddir) DESTDIR='$(CURDIR)'/tmp_check/install install >'$(CURDIR)'/tmp_check/log/install.log 2>&1
-cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(CURDIR)/tmp_check/install$(libdir)) top_builddir='$(CURDIR)/$(top_builddir)' PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(CURDIR)/tmp_check/install$(libdir)) top_builddir='$(CURDIR)/$(top_builddir)' PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index d12be84..ae3a6b2 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -1,10 +1,26 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 19;
 
 my $tempdir = TestLib::tempdir;
 
+sub cleanup_tempdir
+{
+	my $tempdir = shift;
+
+	if ($Config{osname} eq "MSWin32")
+	{
+		system_or_bail "rd /s /q $tempdir";
+		mkdir $tempdir;
+	}
+	else
+	{
+		system_or_bail "rm -rf '$tempdir'/*";
+	}
+}
+
 program_help_ok('initdb');
 program_version_ok('initdb');
 program_options_handling_ok('initdb');
@@ -18,27 +34,26 @@ command_fails([ 'initdb', '-S', "$tempdir/data3" ],
 mkdir "$tempdir/data4" or BAIL_OUT($!);
 command_ok([ 'initdb', "$tempdir/data4" ], 'existing empty data directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
-
+cleanup_tempdir $tempdir;
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'separate xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+cleanup_tempdir $tempdir;
 command_fails(
 	[ 'initdb', "$tempdir/data", '-X', 'pgxlog' ],
 	'relative xlog directory not allowed');
 
-system_or_bail "rm -rf '$tempdir'/*";
+cleanup_tempdir $tempdir;
 mkdir "$tempdir/pgxlog";
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing empty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+cleanup_tempdir $tempdir;
 mkdir "$tempdir/pgxlog";
 mkdir "$tempdir/pgxlog/lost+found";
 command_fails([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing nonempty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+cleanup_tempdir $tempdir;
 command_ok([ 'initdb', '-T', 'german', "$tempdir/data" ],
 	'select default dictionary');
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 7e9a776..4cb1b5a 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 26 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -17,10 +18,20 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup" ],
 	'pg_basebackup fails because of hba');
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
 
@@ -56,6 +67,39 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 			  'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+mkdir "$tempdir/$superlongname";
+psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			  'pg_basebackup tar with long symlink target fails');
+psql 'postgres', "DROP TABLESPACE tblspc3;";
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -102,31 +146,4 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
-mkdir "$tempdir/$superlongname";
-psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-			  'pg_basebackup tar with long symlink target fails');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 17309e8..66f67f3 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index b8cbbda..480a02e 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 003cd9a..094265e 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -73,8 +74,9 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+	my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+	system_or_bail("initdb -D $pgdata -A trust -N > $null_ptr");
+	system_or_bail($ENV{TESTREGRESS},
 				   '--config-auth', $pgdata);
 }
 
@@ -87,10 +89,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-	  "--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -99,7 +103,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -158,7 +162,7 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	is(($h->full_results)[0], $expected, $test_name);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index bd3dd2c..5e080ec 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -31,7 +33,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -77,6 +79,7 @@ my %command = (
 	ECPGCHECK      => \&ecpgcheck,
 	CONTRIBCHECK   => \&contribcheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -162,6 +165,54 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	# Temporary installation cannot be located deeper in src/ because
+	# of interferences with Install.pm scanning its content. So install
+	# it just once for all the tests.
+	my $tmp_root = "$topdir/tmp_check";
+	(mkdir $tmp_root || die $!) unless -d $tmp_root;
+	my $tmp_install = "$tmp_root/install";
+	Install($tmp_install, "all", $config);
+	my @args = (
+		"prove",
+		"--verbose",
+		"t/*.pl");
+
+	# Set environment variables common to all the tests
+	my ($bindir, $libdir, $oldsrc, $newsrc) =
+	  ("$tmp_install/bin", "$tmp_install/lib", $topdir, $topdir);
+
+	$ENV{PATH} = "$bindir;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/pg_rewind\//);
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+	}
+}
+
 sub plcheck
 {
 	chdir "../../pl";
-- 
2.3.5

#5Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#4)
2 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Fri, Apr 10, 2015 at 11:29 AM, Michael Paquier wrote:

Here is a v2 with the following changes:
- Use an environment variable to define where pg_regress is located.
- Use SSPI to access a node in the tests, to secure the test environment.
- Rebase on latest HEAD
- SSL tests are run only if build is configured with openssl

A couple of things to note:
- pg_rewind tests are still disabled, waiting for the outcome of
5519F169.8030406@gmx.net. They will need some tweaks.
- SSL tests can work if an equivalent of cp is available, like
something installed with msysgit... IMO the scripts in src/test/ssl
should be patched to be made more portable (see
/messages/by-id/CAB7nPqQivFxnSjPwkyapa8=HTGm0hfDNvdGcM3=hkK6fPT0+Pg@mail.gmail.com)
- I tested the scripts with MinGW and this patch and got them working.
As prove can fail because of a bad perl interpreter, pointing to
/usr/bin/perl, it is necessary to enforce "PROVE = c:\Perl64\bin\perl
c:\Perl64\bin\prove" or similar. That's not beautiful, but it works,
and the t/ scripts need no further modifications. At least I checked
that.

And here is v3 with support for pg_rewind tests. One thing that I
noticed with this stuff is that the log redirection fails on Windows
with "cannot access file because it is used by another process",
because of system_or_bail that is used by a set of pg_ctl commands in
RewindTest.pm to stop, start and promote the test servers. I am
attaching a second patch switching those calls from system_or_bail to
IPC's run(), making the log capture method completely consistent
across platforms. In the first patch log redirection is done to NUL to
make the test work even if log output is lost, the split is done for
clarity and those patches should be applied together.

Note as well that this patch uses the following patches fixing
independent issues:
- Replace use of rm in initdb tests by rmtree:
/messages/by-id/CAB7nPqQqzjSHxnCPYCO5vr2dmELt8DqedETqRZmj7TMNqb5Bkg@mail.gmail.com
- Add --debug for pg_rewind remote mode:
/messages/by-id/CAB7nPqSMRFZcfB-b6Un8KvnJKWNLi+qckkXgsy1Fu4dQBif=gw@mail.gmail.com
- Improve sleep processing of pg_rewind, windows being sometimes
susceptible about that as well...
/messages/by-id/CAB7nPqSQfTfge-whbpRD99BEbJOX3Z+Pepwa+TUBxA0fDtuVyg@mail.gmail.com
Regards,
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From 88cbadb55a89593f56fb40a6b496771dbc7b2cf9 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sun, 19 Apr 2015 21:46:02 +0900
Subject: [PATCH 1/2] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 .gitignore                                     |   3 +
 doc/src/sgml/install-windows.sgml              |   1 +
 src/Makefile.global.in                         |   2 +-
 src/bin/initdb/t/001_initdb.pl                 |  18 ++--
 src/bin/pg_basebackup/t/010_pg_basebackup.pl   |  79 +++++++++-------
 src/bin/pg_controldata/t/001_pg_controldata.pl |   5 +-
 src/bin/pg_ctl/t/001_start_stop.pl             |  14 ++-
 src/bin/pg_ctl/t/002_status.pl                 |  12 ++-
 src/bin/pg_rewind/RewindTest.pm                | 119 ++++++++++++++++++++-----
 src/bin/scripts/t/020_createdb.pl              |   3 +
 src/test/perl/TestLib.pm                       |  25 ++++--
 src/tools/msvc/vcregress.pl                    |  54 ++++++++++-
 12 files changed, 263 insertions(+), 72 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8d3af50..3cd37fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,6 @@ lib*.pc
 /pgsql.sln.cache
 /Debug/
 /Release/
+
+# Generated by tests
+/tmp_check/
diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 4b06fc2..b27ed78 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -324,7 +324,7 @@ endef
 define prove_check
 $(MKDIR_P) tmp_check/log
 $(MAKE) -C $(top_builddir) DESTDIR='$(CURDIR)'/tmp_check/install install >'$(CURDIR)'/tmp_check/log/install.log 2>&1
-cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(CURDIR)/tmp_check/install$(libdir)) top_builddir='$(CURDIR)/$(top_builddir)' PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(CURDIR)/tmp_check/install$(libdir)) top_builddir='$(CURDIR)/$(top_builddir)' PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index d12be84..0865107 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -1,6 +1,8 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
+use File::Path qw(rmtree);
 use Test::More tests => 19;
 
 my $tempdir = TestLib::tempdir;
@@ -18,27 +20,31 @@ command_fails([ 'initdb', '-S', "$tempdir/data3" ],
 mkdir "$tempdir/data4" or BAIL_OUT($!);
 command_ok([ 'initdb', "$tempdir/data4" ], 'existing empty data directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
-
+rmtree($tempdir);
+mkdir $tempdir;
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'separate xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 command_fails(
 	[ 'initdb', "$tempdir/data", '-X', 'pgxlog' ],
 	'relative xlog directory not allowed');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 mkdir "$tempdir/pgxlog";
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing empty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 mkdir "$tempdir/pgxlog";
 mkdir "$tempdir/pgxlog/lost+found";
 command_fails([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing nonempty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 command_ok([ 'initdb', '-T', 'german', "$tempdir/data" ],
 	'select default dictionary');
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 7e9a776..4cb1b5a 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 26 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -17,10 +18,20 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup" ],
 	'pg_basebackup fails because of hba');
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
 
@@ -56,6 +67,39 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 			  'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+mkdir "$tempdir/$superlongname";
+psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			  'pg_basebackup tar with long symlink target fails');
+psql 'postgres', "DROP TABLESPACE tblspc3;";
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -102,31 +146,4 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
-mkdir "$tempdir/$superlongname";
-psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-			  'pg_basebackup tar with long symlink target fails');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 17309e8..66f67f3 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index b8cbbda..480a02e 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index e6a5b9b..87f407a 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -38,6 +38,7 @@ use warnings;
 use TestLib;
 use Test::More;
 
+use Config;
 use File::Copy;
 use File::Path qw(remove_tree);
 use IPC::Run qw(run start);
@@ -64,11 +65,9 @@ our @EXPORT = qw(
 
 
 # Adjust these paths for your environment
-my $testroot = "./tmp_check";
-our $test_master_datadir="$testroot/data_master";
-our $test_standby_datadir="$testroot/data_standby";
-
-mkdir $testroot;
+my $testroot;
+our $test_master_datadir;
+our $test_standby_datadir;
 
 # Log files are created here
 mkdir "regress_log";
@@ -78,6 +77,7 @@ my $port_master=$ENV{PGPORT};
 my $port_standby=$port_master + 1;
 
 my $log_path;
+my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master="port=$port_master";
@@ -137,7 +137,12 @@ sub init_rewind_test
 	my $testname = shift;
 	my $test_mode = shift;
 
-	$log_path="regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
+
+	$testroot = TestLib::tempdir;
+	$test_master_datadir="$testroot/data_master";
+	$test_standby_datadir="$testroot/data_standby";
 
 	remove_tree $log_path;
 }
@@ -164,15 +169,30 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file("$test_master_datadir/pg_hba.conf", qq(
+	if ($Config{osname} eq "MSWin32")
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
+host replication all 127.0.0.1/32 sspi include_realm=1 map=regress
+host replication all ::1/128 sspi include_realm=1 map=regress
+));
+	}
+	else
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
 local replication all trust
 ));
+	}
+
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST} = ($Config{osname} eq "MSWin32") ?
+		"127.0.0.1" : $tempdir_short;
 }
 
 sub create_standby
@@ -181,18 +201,43 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1");
+	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
-primary_conninfo='$connstr_master'
+primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_standby" :
+		"-k $tempdir_short --listen-addresses='' -p $port_standby";
+
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
 
-	# sleep a bit to make sure the standby has caught up.
-	sleep 1;
+	# Wait until the standby has caught up with the primary by comparing
+	# WAL positions on both nodes. Note that this is fine
+	my $max_attempts = 30;
+	my $attempts = 0;
+	while ($attempts < $max_attempts)
+	{
+		# Wait a bit before proceeding.
+		sleep 1;
+		$attempts++;
+
+		my $query = "SELECT pg_current_xlog_location() = replay_location FROM pg_stat_replication WHERE application_name = 'rewind_standby';";
+		my $cmd = ['psql', '-At', '-c', "$query", '-d', "$connstr_master" ];
+		my ($res, $stdout, $stderr) = command_result($cmd);
+		chomp($stdout);
+		if ($stdout eq "t")
+		{
+			last;
+		}
+	}
+	if ($attempts == $max_attempts)
+	{
+		die "Maximum number of attempts reached when waiting for standby to catch up";
+	}
 }
 
 sub promote_standby
@@ -201,9 +246,31 @@ sub promote_standby
 	# up standby
 
 	# Now promote slave and insert some new data on master, this will put
-	# the master out-of-sync with the standby.
-	system_or_bail("pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1");
-	sleep 2;
+	# the master out-of-sync with the standby. Be sure that we leave here
+	# with a standby actually ready for the next operations.
+	system_or_bail("pg_ctl -w -D $test_standby_datadir promote $log_redirect");
+	my $max_attempts = 30;
+	my $attempts = 0;
+	while ($attempts < $max_attempts)
+	{
+		# Wait a bit before proceeding, promotion may have not taken effect
+		# in such a short time.
+		sleep 1;
+		$attempts++;
+
+		my $query = "SELECT pg_is_in_recovery()";
+		my $cmd = ['psql', '-At', '-c', "$query", '-d', "$connstr_standby" ];
+		my ($res, $stdout, $stderr) = command_result($cmd);
+		chomp($stdout);
+		if ($stdout eq "f")
+		{
+			last;
+		}
+	}
+	if ($attempts == $max_attempts)
+	{
+		die "Maximum number of attempts reached when waiting for promotion of standby";
+	}
 }
 
 sub run_pg_rewind
@@ -211,7 +278,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -226,7 +293,7 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail("pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1");
+		system_or_bail("pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect");
 		my $result =
 			run(['pg_rewind',
 				 "--debug",
@@ -240,6 +307,7 @@ sub run_pg_rewind
 		# Do rewind using a remote connection as source
 		my $result =
 			run(['pg_rewind',
+				 "--debug",
 				 "--source-server", "port=$port_standby dbname=postgres",
 				 "--target-pgdata=$test_master_datadir"],
 				'>>', $log_path, '2>&1');
@@ -259,8 +327,12 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to check the result
 }
@@ -268,13 +340,16 @@ recovery_target_timeline='latest'
 # Clean up after the test. Stop both servers, if they're still running.
 sub clean_rewind_test
 {
+	my $null_redirect = ($Config{osname} eq "MSWin32") ?
+		"2> nul" : "2> /dev/null";
+
 	if ($test_master_datadir)
 	{
-		system "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_master_datadir -w -s -m immediate stop $null_redirect";
 	}
 	if ($test_standby_datadir)
 	{
-		system "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_standby_datadir -w -s -m immediate stop $null_redirect";
 	}
 }
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 003cd9a..8714024 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -16,6 +17,7 @@ our @EXPORT = qw(
   command_ok
   command_fails
   command_exit_is
+  command_result
   program_help_ok
   program_version_ok
   program_options_handling_ok
@@ -73,8 +75,9 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+	my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+	system_or_bail("initdb -D $pgdata -A trust -N > $null_ptr");
+	system_or_bail($ENV{TESTREGRESS},
 				   '--config-auth', $pgdata);
 }
 
@@ -87,10 +90,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-	  "--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -99,7 +104,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -158,7 +163,17 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
+}
+
+sub command_result
+{
+	my ($cmd) = @_;
+	my ($stdout, $stderr);
+	my $result = run $cmd, '>', \$stdout, '2>', \$stderr;
+	return ($result, $stdout, $stderr);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index c3143ac..1cc5495 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -31,7 +33,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -78,6 +80,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -163,6 +166,55 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	# Temporary installation cannot be located deeper in src/ because
+	# of interferences with Install.pm scanning its content. So install
+	# it just once for all the tests.
+	my $tmp_root = "$topdir/tmp_check";
+	(mkdir $tmp_root || die $!) unless -d $tmp_root;
+	my $tmp_install = "$tmp_root/install";
+	Install($tmp_install, "all", $config);
+	my @args = (
+		"prove",
+		"--verbose",
+		"t/*.pl");
+
+	# Set environment variables common to all the tests
+	my ($bindir, $libdir, $oldsrc, $newsrc) =
+	  ("$tmp_install/bin", "$tmp_install/lib", $topdir, $topdir);
+
+	$ENV{PATH} = "$bindir;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir "../../pl";
-- 
2.3.5

0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchtext/x-patch; charset=US-ASCII; name=0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchDownload
From d30daa883ab27a0acda7c12235608cdaa77e4c77 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sun, 19 Apr 2015 21:47:43 +0900
Subject: [PATCH 2/2] Prefer IPC's run to system_or_bail in pg_rewind tests

This facilitates log capture on Windows, the former method making tests
failing on Windows when multiple processes try to access this log file.
---
 src/bin/pg_rewind/RewindTest.pm | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index 87f407a..f86f64e 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -77,7 +77,6 @@ my $port_master=$ENV{PGPORT};
 my $port_standby=$port_master + 1;
 
 my $log_path;
-my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master="port=$port_master";
@@ -138,7 +137,6 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
-	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	$testroot = TestLib::tempdir;
 	$test_master_datadir="$testroot/data_master";
@@ -187,7 +185,8 @@ local replication all trust
 		"--listen-addresses=127.0.0.1 -p $port_master" :
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
@@ -201,7 +200,8 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	run(['pg_basebackup', '-D', "$test_standby_datadir",
+		 '-p', "$port_master", '-x'], '>>', $log_path, '2>&1');
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
@@ -213,7 +213,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_standby";
 
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	# Wait until the standby has caught up with the primary by comparing
 	# WAL positions on both nodes. Note that this is fine
@@ -248,7 +249,8 @@ sub promote_standby
 	# Now promote slave and insert some new data on master, this will put
 	# the master out-of-sync with the standby. Be sure that we leave here
 	# with a standby actually ready for the next operations.
-	system_or_bail("pg_ctl -w -D $test_standby_datadir promote $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", 'promote'],
+		'>>', $log_path, '2>&1');
 	my $max_attempts = 30;
 	my $attempts = 0;
 	while ($attempts < $max_attempts)
@@ -278,7 +280,8 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-m',
+		 'fast', 'stop'], '>>', $log_path, '2>&1');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -293,7 +296,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail("pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect");
+		run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-m',
+			 'fast', 'stop'], '>>', $log_path, '2>&1');
 		my $result =
 			run(['pg_rewind',
 				 "--debug",
@@ -332,7 +336,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to check the result
 }
-- 
2.3.5

#6Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#5)
2 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Sun, Apr 19, 2015 at 10:01 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

Note as well that this patch uses the following patches fixing
independent issues:
...

Attached is v4. I added a switch in config.pl to be consistent with
./configure and --enable-tap-tests.
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From f532bbd2522b3a1784038d9863325d055fc445bf Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Mon, 20 Apr 2015 04:57:37 -0700
Subject: [PATCH 1/2] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 .gitignore                                     |   3 +
 doc/src/sgml/install-windows.sgml              |   1 +
 src/Makefile.global.in                         |   2 +-
 src/bin/initdb/t/001_initdb.pl                 |  18 ++--
 src/bin/pg_basebackup/t/010_pg_basebackup.pl   |  79 +++++++++-------
 src/bin/pg_controldata/t/001_pg_controldata.pl |   5 +-
 src/bin/pg_ctl/t/001_start_stop.pl             |  14 ++-
 src/bin/pg_ctl/t/002_status.pl                 |  12 ++-
 src/bin/pg_rewind/RewindTest.pm                | 119 ++++++++++++++++++++-----
 src/bin/scripts/t/020_createdb.pl              |   3 +
 src/test/perl/TestLib.pm                       |  25 ++++--
 src/tools/msvc/Solution.pm                     |   1 +
 src/tools/msvc/config_default.pl               |   1 +
 src/tools/msvc/vcregress.pl                    |  60 ++++++++++++-
 14 files changed, 271 insertions(+), 72 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8d3af50..3cd37fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,6 @@ lib*.pc
 /pgsql.sln.cache
 /Debug/
 /Release/
+
+# Generated by tests
+/tmp_check/
diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 4b06fc2..b27ed78 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -324,7 +324,7 @@ endef
 define prove_check
 $(MKDIR_P) tmp_check/log
 $(MAKE) -C $(top_builddir) DESTDIR='$(CURDIR)'/tmp_check/install install >'$(CURDIR)'/tmp_check/log/install.log 2>&1
-cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(CURDIR)/tmp_check/install$(libdir)) top_builddir='$(CURDIR)/$(top_builddir)' PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(CURDIR)/tmp_check/install$(libdir)) top_builddir='$(CURDIR)/$(top_builddir)' PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index d12be84..0865107 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -1,6 +1,8 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
+use File::Path qw(rmtree);
 use Test::More tests => 19;
 
 my $tempdir = TestLib::tempdir;
@@ -18,27 +20,31 @@ command_fails([ 'initdb', '-S', "$tempdir/data3" ],
 mkdir "$tempdir/data4" or BAIL_OUT($!);
 command_ok([ 'initdb', "$tempdir/data4" ], 'existing empty data directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
-
+rmtree($tempdir);
+mkdir $tempdir;
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'separate xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 command_fails(
 	[ 'initdb', "$tempdir/data", '-X', 'pgxlog' ],
 	'relative xlog directory not allowed');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 mkdir "$tempdir/pgxlog";
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing empty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 mkdir "$tempdir/pgxlog";
 mkdir "$tempdir/pgxlog/lost+found";
 command_fails([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing nonempty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 command_ok([ 'initdb', '-T', 'german', "$tempdir/data" ],
 	'select default dictionary');
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 7e9a776..4cb1b5a 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 26 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -17,10 +18,20 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup" ],
 	'pg_basebackup fails because of hba');
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
 
@@ -56,6 +67,39 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 			  'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+mkdir "$tempdir/$superlongname";
+psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			  'pg_basebackup tar with long symlink target fails');
+psql 'postgres', "DROP TABLESPACE tblspc3;";
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -102,31 +146,4 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
-mkdir "$tempdir/$superlongname";
-psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-			  'pg_basebackup tar with long symlink target fails');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 17309e8..66f67f3 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index b8cbbda..480a02e 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index e6a5b9b..87f407a 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -38,6 +38,7 @@ use warnings;
 use TestLib;
 use Test::More;
 
+use Config;
 use File::Copy;
 use File::Path qw(remove_tree);
 use IPC::Run qw(run start);
@@ -64,11 +65,9 @@ our @EXPORT = qw(
 
 
 # Adjust these paths for your environment
-my $testroot = "./tmp_check";
-our $test_master_datadir="$testroot/data_master";
-our $test_standby_datadir="$testroot/data_standby";
-
-mkdir $testroot;
+my $testroot;
+our $test_master_datadir;
+our $test_standby_datadir;
 
 # Log files are created here
 mkdir "regress_log";
@@ -78,6 +77,7 @@ my $port_master=$ENV{PGPORT};
 my $port_standby=$port_master + 1;
 
 my $log_path;
+my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master="port=$port_master";
@@ -137,7 +137,12 @@ sub init_rewind_test
 	my $testname = shift;
 	my $test_mode = shift;
 
-	$log_path="regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
+
+	$testroot = TestLib::tempdir;
+	$test_master_datadir="$testroot/data_master";
+	$test_standby_datadir="$testroot/data_standby";
 
 	remove_tree $log_path;
 }
@@ -164,15 +169,30 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file("$test_master_datadir/pg_hba.conf", qq(
+	if ($Config{osname} eq "MSWin32")
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
+host replication all 127.0.0.1/32 sspi include_realm=1 map=regress
+host replication all ::1/128 sspi include_realm=1 map=regress
+));
+	}
+	else
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
 local replication all trust
 ));
+	}
+
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST} = ($Config{osname} eq "MSWin32") ?
+		"127.0.0.1" : $tempdir_short;
 }
 
 sub create_standby
@@ -181,18 +201,43 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1");
+	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
-primary_conninfo='$connstr_master'
+primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_standby" :
+		"-k $tempdir_short --listen-addresses='' -p $port_standby";
+
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
 
-	# sleep a bit to make sure the standby has caught up.
-	sleep 1;
+	# Wait until the standby has caught up with the primary by comparing
+	# WAL positions on both nodes. Note that this is fine
+	my $max_attempts = 30;
+	my $attempts = 0;
+	while ($attempts < $max_attempts)
+	{
+		# Wait a bit before proceeding.
+		sleep 1;
+		$attempts++;
+
+		my $query = "SELECT pg_current_xlog_location() = replay_location FROM pg_stat_replication WHERE application_name = 'rewind_standby';";
+		my $cmd = ['psql', '-At', '-c', "$query", '-d', "$connstr_master" ];
+		my ($res, $stdout, $stderr) = command_result($cmd);
+		chomp($stdout);
+		if ($stdout eq "t")
+		{
+			last;
+		}
+	}
+	if ($attempts == $max_attempts)
+	{
+		die "Maximum number of attempts reached when waiting for standby to catch up";
+	}
 }
 
 sub promote_standby
@@ -201,9 +246,31 @@ sub promote_standby
 	# up standby
 
 	# Now promote slave and insert some new data on master, this will put
-	# the master out-of-sync with the standby.
-	system_or_bail("pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1");
-	sleep 2;
+	# the master out-of-sync with the standby. Be sure that we leave here
+	# with a standby actually ready for the next operations.
+	system_or_bail("pg_ctl -w -D $test_standby_datadir promote $log_redirect");
+	my $max_attempts = 30;
+	my $attempts = 0;
+	while ($attempts < $max_attempts)
+	{
+		# Wait a bit before proceeding, promotion may have not taken effect
+		# in such a short time.
+		sleep 1;
+		$attempts++;
+
+		my $query = "SELECT pg_is_in_recovery()";
+		my $cmd = ['psql', '-At', '-c', "$query", '-d', "$connstr_standby" ];
+		my ($res, $stdout, $stderr) = command_result($cmd);
+		chomp($stdout);
+		if ($stdout eq "f")
+		{
+			last;
+		}
+	}
+	if ($attempts == $max_attempts)
+	{
+		die "Maximum number of attempts reached when waiting for promotion of standby";
+	}
 }
 
 sub run_pg_rewind
@@ -211,7 +278,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -226,7 +293,7 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail("pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1");
+		system_or_bail("pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect");
 		my $result =
 			run(['pg_rewind',
 				 "--debug",
@@ -240,6 +307,7 @@ sub run_pg_rewind
 		# Do rewind using a remote connection as source
 		my $result =
 			run(['pg_rewind',
+				 "--debug",
 				 "--source-server", "port=$port_standby dbname=postgres",
 				 "--target-pgdata=$test_master_datadir"],
 				'>>', $log_path, '2>&1');
@@ -259,8 +327,12 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to check the result
 }
@@ -268,13 +340,16 @@ recovery_target_timeline='latest'
 # Clean up after the test. Stop both servers, if they're still running.
 sub clean_rewind_test
 {
+	my $null_redirect = ($Config{osname} eq "MSWin32") ?
+		"2> nul" : "2> /dev/null";
+
 	if ($test_master_datadir)
 	{
-		system "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_master_datadir -w -s -m immediate stop $null_redirect";
 	}
 	if ($test_standby_datadir)
 	{
-		system "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_standby_datadir -w -s -m immediate stop $null_redirect";
 	}
 }
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 003cd9a..8714024 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -16,6 +17,7 @@ our @EXPORT = qw(
   command_ok
   command_fails
   command_exit_is
+  command_result
   program_help_ok
   program_version_ok
   program_options_handling_ok
@@ -73,8 +75,9 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+	my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+	system_or_bail("initdb -D $pgdata -A trust -N > $null_ptr");
+	system_or_bail($ENV{TESTREGRESS},
 				   '--config-auth', $pgdata);
 }
 
@@ -87,10 +90,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-	  "--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -99,7 +104,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -158,7 +163,17 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
+}
+
+sub command_result
+{
+	my ($cmd) = @_;
+	my ($stdout, $stderr);
+	my $result = run $cmd, '>', \$stdout, '2>', \$stderr;
+	return ($result, $stdout, $stderr);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 764ba1e..e40f138 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -622,6 +622,7 @@ sub GetFakeConfigure
 	$cfg .= ' --enable-integer-datetimes'
 	  if ($self->{options}->{integer_datetimes});
 	$cfg .= ' --enable-nls' if ($self->{options}->{nls});
+	$cfg .= ' --enable-tap-tests' if ($self->{options}->{taptest});
 	$cfg .= ' --with-ldap'  if ($self->{options}->{ldap});
 	$cfg .= ' --without-zlib' unless ($self->{options}->{zlib});
 	$cfg .= ' --with-extra-version' if ($self->{options}->{extraver});
diff --git a/src/tools/msvc/config_default.pl b/src/tools/msvc/config_default.pl
index 0bee0c0..5a575e0 100644
--- a/src/tools/msvc/config_default.pl
+++ b/src/tools/msvc/config_default.pl
@@ -14,6 +14,7 @@ our $config = {
 	  # wal_blocksize => 8,     # --with-wal-blocksize, 8kB by default
 	  # wal_segsize => 16,      # --with-wal-segsize, 16MB by default
 	ldap     => 1,       # --with-ldap
+	taptest  => undef,   # --enable-tap-tests
 	extraver => undef,   # --with-extra-version=<string>
 	nls      => undef,   # --enable-nls=<path>
 	tcl      => undef,   # --with-tls=<path>
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index c3143ac..144b9ff 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -31,7 +33,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -78,6 +80,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -163,6 +166,61 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	if (!defined($config->{taptest}))
+	{
+		print "TAP tests not enabled\n";
+		exit 0;
+	}
+
+	# Temporary installation cannot be located deeper in src/ because
+	# of interferences with Install.pm scanning its content. So install
+	# it just once for all the tests.
+	my $tmp_root = "$topdir/tmp_check";
+	(mkdir $tmp_root || die $!) unless -d $tmp_root;
+	my $tmp_install = "$tmp_root/install";
+	Install($tmp_install, "all", $config);
+	my @args = (
+		"prove",
+		"--verbose",
+		"t/*.pl");
+
+	# Set environment variables common to all the tests
+	my ($bindir, $libdir, $oldsrc, $newsrc) =
+	  ("$tmp_install/bin", "$tmp_install/lib", $topdir, $topdir);
+
+	$ENV{PATH} = "$bindir;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir "../../pl";
-- 
2.3.5

0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchtext/x-patch; charset=US-ASCII; name=0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchDownload
From 4c80410bb9fa05b117c1cf5c2f2c28437c1e240e Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sun, 19 Apr 2015 21:47:43 +0900
Subject: [PATCH 2/2] Prefer IPC's run to system_or_bail in pg_rewind tests

This facilitates log capture on Windows, the former method making tests
failing on Windows when multiple processes try to access this log file.
---
 src/bin/pg_rewind/RewindTest.pm | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index 87f407a..f86f64e 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -77,7 +77,6 @@ my $port_master=$ENV{PGPORT};
 my $port_standby=$port_master + 1;
 
 my $log_path;
-my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master="port=$port_master";
@@ -138,7 +137,6 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
-	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	$testroot = TestLib::tempdir;
 	$test_master_datadir="$testroot/data_master";
@@ -187,7 +185,8 @@ local replication all trust
 		"--listen-addresses=127.0.0.1 -p $port_master" :
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
@@ -201,7 +200,8 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	run(['pg_basebackup', '-D', "$test_standby_datadir",
+		 '-p', "$port_master", '-x'], '>>', $log_path, '2>&1');
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
@@ -213,7 +213,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_standby";
 
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	# Wait until the standby has caught up with the primary by comparing
 	# WAL positions on both nodes. Note that this is fine
@@ -248,7 +249,8 @@ sub promote_standby
 	# Now promote slave and insert some new data on master, this will put
 	# the master out-of-sync with the standby. Be sure that we leave here
 	# with a standby actually ready for the next operations.
-	system_or_bail("pg_ctl -w -D $test_standby_datadir promote $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", 'promote'],
+		'>>', $log_path, '2>&1');
 	my $max_attempts = 30;
 	my $attempts = 0;
 	while ($attempts < $max_attempts)
@@ -278,7 +280,8 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-m',
+		 'fast', 'stop'], '>>', $log_path, '2>&1');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -293,7 +296,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail("pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect");
+		run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-m',
+			 'fast', 'stop'], '>>', $log_path, '2>&1');
 		my $result =
 			run(['pg_rewind',
 				 "--debug",
@@ -332,7 +336,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to check the result
 }
-- 
2.3.5

#7Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#6)
2 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Mon, Apr 20, 2015 at 9:01 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

On Sun, Apr 19, 2015 at 10:01 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

Note as well that this patch uses the following patches fixing
independent issues:
...

Attached is v4. I added a switch in config.pl to be consistent with
./configure and --enable-tap-tests.

Attached is v5, rebased on HEAD (2c47fe16) after conflicts with
dcae5fac and 54a16df0.
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From 9c348d985a3da0098be9d9f64a14e936068117a0 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Mon, 20 Apr 2015 04:57:37 -0700
Subject: [PATCH 1/2] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 doc/src/sgml/install-windows.sgml              |  1 +
 src/Makefile.global.in                         |  2 +-
 src/bin/initdb/t/001_initdb.pl                 | 18 ++++--
 src/bin/pg_basebackup/t/010_pg_basebackup.pl   | 79 ++++++++++++++++----------
 src/bin/pg_controldata/t/001_pg_controldata.pl |  5 +-
 src/bin/pg_ctl/t/001_start_stop.pl             | 14 ++++-
 src/bin/pg_ctl/t/002_status.pl                 | 12 +++-
 src/bin/pg_rewind/RewindTest.pm                | 56 ++++++++++++++----
 src/bin/scripts/t/020_createdb.pl              |  3 +
 src/test/perl/TestLib.pm                       | 16 ++++--
 src/tools/msvc/Solution.pm                     |  1 +
 src/tools/msvc/config_default.pl               |  1 +
 src/tools/msvc/vcregress.pl                    | 48 +++++++++++++++-
 13 files changed, 195 insertions(+), 61 deletions(-)

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 81cae94..f030dac 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -338,7 +338,7 @@ cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPOR
 endef
 
 define prove_check
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index d12be84..0865107 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -1,6 +1,8 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
+use File::Path qw(rmtree);
 use Test::More tests => 19;
 
 my $tempdir = TestLib::tempdir;
@@ -18,27 +20,31 @@ command_fails([ 'initdb', '-S', "$tempdir/data3" ],
 mkdir "$tempdir/data4" or BAIL_OUT($!);
 command_ok([ 'initdb', "$tempdir/data4" ], 'existing empty data directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
-
+rmtree($tempdir);
+mkdir $tempdir;
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'separate xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 command_fails(
 	[ 'initdb', "$tempdir/data", '-X', 'pgxlog' ],
 	'relative xlog directory not allowed');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 mkdir "$tempdir/pgxlog";
 command_ok([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing empty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 mkdir "$tempdir/pgxlog";
 mkdir "$tempdir/pgxlog/lost+found";
 command_fails([ 'initdb', '-X', "$tempdir/pgxlog", "$tempdir/data" ],
 	'existing nonempty xlog directory');
 
-system_or_bail "rm -rf '$tempdir'/*";
+rmtree($tempdir);
+mkdir $tempdir;
 command_ok([ 'initdb', '-T', 'german', "$tempdir/data" ],
 	'select default dictionary');
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 7e9a776..4cb1b5a 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 26 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -17,10 +18,20 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup" ],
 	'pg_basebackup fails because of hba');
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
 
@@ -56,6 +67,39 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 			  'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+mkdir "$tempdir/$superlongname";
+psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			  'pg_basebackup tar with long symlink target fails');
+psql 'postgres', "DROP TABLESPACE tblspc3;";
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -102,31 +146,4 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
-mkdir "$tempdir/$superlongname";
-psql 'postgres', "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-			  'pg_basebackup tar with long symlink target fails');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 17309e8..66f67f3 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index b8cbbda..480a02e 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index a5f7d08..088a021 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -38,6 +38,7 @@ use warnings;
 use TestLib;
 use Test::More;
 
+use Config;
 use File::Copy;
 use File::Path qw(remove_tree);
 use IPC::Run qw(run start);
@@ -80,6 +81,7 @@ my $port_master=$ENV{PGPORT};
 my $port_standby=$port_master + 1;
 
 my $log_path;
+my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master="port=$port_master";
@@ -170,7 +172,12 @@ sub init_rewind_test
 	my $testname = shift;
 	my $test_mode = shift;
 
-	$log_path="regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
+
+	$testroot = TestLib::tempdir;
+	$test_master_datadir="$testroot/data_master";
+	$test_standby_datadir="$testroot/data_standby";
 
 	remove_tree $log_path;
 }
@@ -197,15 +204,30 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file("$test_master_datadir/pg_hba.conf", qq(
+	if ($Config{osname} eq "MSWin32")
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
+host replication all 127.0.0.1/32 sspi include_realm=1 map=regress
+host replication all ::1/128 sspi include_realm=1 map=regress
+));
+	}
+	else
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
 local replication all trust
 ));
+	}
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1");
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST} = ($Config{osname} eq "MSWin32") ?
+		"127.0.0.1" : $tempdir_short;
 }
 
 sub create_standby
@@ -214,15 +236,19 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1");
+	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_standby" :
+		"-k $tempdir_short --listen-addresses='' -p $port_standby";
+
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -249,7 +275,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -264,7 +290,7 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail("pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1");
+		system_or_bail("pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect");
 		my $result =
 			run(['pg_rewind',
 				 "--debug",
@@ -278,6 +304,7 @@ sub run_pg_rewind
 		# Do rewind using a remote connection as source
 		my $result =
 			run(['pg_rewind',
+				 "--debug",
 				 "--source-server", "port=$port_standby dbname=postgres",
 				 "--target-pgdata=$test_master_datadir"],
 				'>>', $log_path, '2>&1');
@@ -297,8 +324,12 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to check the result
 }
@@ -306,13 +337,16 @@ recovery_target_timeline='latest'
 # Clean up after the test. Stop both servers, if they're still running.
 sub clean_rewind_test
 {
+	my $null_redirect = ($Config{osname} eq "MSWin32") ?
+		"2> nul" : "2> /dev/null";
+
 	if ($test_master_datadir)
 	{
-		system "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_master_datadir -w -s -m immediate stop $null_redirect";
 	}
 	if ($test_standby_datadir)
 	{
-		system "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_standby_datadir -w -s -m immediate stop $null_redirect";
 	}
 }
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 003cd9a..9394bb6 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -73,8 +74,9 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
+	my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+	system_or_bail("initdb -D $pgdata -A trust -N > $null_ptr");
+	system_or_bail($ENV{TESTREGRESS},
 				   '--config-auth', $pgdata);
 }
 
@@ -87,10 +89,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-	  "--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -99,7 +103,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -158,7 +162,9 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 764ba1e..e40f138 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -622,6 +622,7 @@ sub GetFakeConfigure
 	$cfg .= ' --enable-integer-datetimes'
 	  if ($self->{options}->{integer_datetimes});
 	$cfg .= ' --enable-nls' if ($self->{options}->{nls});
+	$cfg .= ' --enable-tap-tests' if ($self->{options}->{taptest});
 	$cfg .= ' --with-ldap'  if ($self->{options}->{ldap});
 	$cfg .= ' --without-zlib' unless ($self->{options}->{zlib});
 	$cfg .= ' --with-extra-version' if ($self->{options}->{extraver});
diff --git a/src/tools/msvc/config_default.pl b/src/tools/msvc/config_default.pl
index 0bee0c0..5a575e0 100644
--- a/src/tools/msvc/config_default.pl
+++ b/src/tools/msvc/config_default.pl
@@ -14,6 +14,7 @@ our $config = {
 	  # wal_blocksize => 8,     # --with-wal-blocksize, 8kB by default
 	  # wal_segsize => 16,      # --with-wal-segsize, 16MB by default
 	ldap     => 1,       # --with-ldap
+	taptest  => undef,   # --enable-tap-tests
 	extraver => undef,   # --with-extra-version=<string>
 	nls      => undef,   # --enable-nls=<path>
 	tcl      => undef,   # --with-tls=<path>
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index 0153f05..9336514 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,49 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	if (!defined($config->{taptest}))
+	{
+		print "TAP tests not enabled\n";
+		exit 0;
+	}
+
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.3.6

0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchtext/x-patch; charset=US-ASCII; name=0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchDownload
From ad498861ef5355ac78b9bbd35d37f5a04698213d Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sun, 19 Apr 2015 21:47:43 +0900
Subject: [PATCH 2/2] Prefer IPC's run to system_or_bail in pg_rewind tests

This facilitates log capture on Windows, the former method making tests
failing on Windows when multiple processes try to access this log file.
---
 src/bin/pg_rewind/RewindTest.pm | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index 088a021..93994ef 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -81,7 +81,6 @@ my $port_master=$ENV{PGPORT};
 my $port_standby=$port_master + 1;
 
 my $log_path;
-my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master="port=$port_master";
@@ -173,7 +172,6 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
-	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	$testroot = TestLib::tempdir;
 	$test_master_datadir="$testroot/data_master";
@@ -222,7 +220,8 @@ local replication all trust
 		"--listen-addresses=127.0.0.1 -p $port_master" :
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
@@ -236,7 +235,8 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	run(['pg_basebackup', '-D', "$test_standby_datadir",
+		 '-p', "$port_master", '-x'], '>>', $log_path, '2>&1');
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
@@ -248,7 +248,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_standby";
 
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -265,7 +266,8 @@ sub promote_standby
 	# Now promote slave and insert some new data on master, this will put
 	# the master out-of-sync with the standby. Wait until the standby is
 	# out of recovery mode, and is ready to accept read-write connections.
-	system_or_bail("pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", 'promote'],
+		'>>', $log_path, '2>&1');
 	poll_query_until("SELECT NOT pg_is_in_recovery()", $connstr_standby)
 		or die "Timed out while waiting for promotion of standby";
 }
@@ -275,7 +277,8 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-m',
+		 'fast', 'stop'], '>>', $log_path, '2>&1');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -290,7 +293,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail("pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect");
+		run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-m',
+			 'fast', 'stop'], '>>', $log_path, '2>&1');
 		my $result =
 			run(['pg_rewind',
 				 "--debug",
@@ -329,7 +333,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to check the result
 }
-- 
2.3.6

#8Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#7)
2 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Fri, Apr 24, 2015 at 11:26 AM, Michael Paquier
<michael.paquier@gmail.com> wrote:

On Mon, Apr 20, 2015 at 9:01 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

On Sun, Apr 19, 2015 at 10:01 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

Note as well that this patch uses the following patches fixing
independent issues:
...

Attached is v4. I added a switch in config.pl to be consistent with
./configure and --enable-tap-tests.

Attached is v5, rebased on HEAD (2c47fe16) after conflicts with
dcae5fac and 54a16df0.

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-diff; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From 5879da14bbf20b5ac66b78f8beab09114bb2fa96 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Mon, 20 Apr 2015 04:57:37 -0700
Subject: [PATCH 1/2] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 doc/src/sgml/install-windows.sgml              |  1 +
 src/Makefile.global.in                         |  2 +-
 src/bin/initdb/t/001_initdb.pl                 |  1 +
 src/bin/pg_basebackup/t/010_pg_basebackup.pl   | 67 ++++++++++++++++----------
 src/bin/pg_controldata/t/001_pg_controldata.pl |  5 +-
 src/bin/pg_ctl/t/001_start_stop.pl             | 14 ++++--
 src/bin/pg_ctl/t/002_status.pl                 | 12 ++++-
 src/bin/pg_rewind/RewindTest.pm                | 66 +++++++++++++++----------
 src/bin/scripts/t/020_createdb.pl              |  3 ++
 src/test/perl/TestLib.pm                       | 18 ++++---
 src/tools/msvc/Solution.pm                     |  1 +
 src/tools/msvc/config_default.pl               |  1 +
 src/tools/msvc/vcregress.pl                    | 48 +++++++++++++++++-
 13 files changed, 175 insertions(+), 64 deletions(-)

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index c583b44..563d1d1 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -336,7 +336,7 @@ cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPOR
 endef
 
 define prove_check
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 299dcf5..095cbf3 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -4,6 +4,7 @@
 
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 14;
 
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 3476ea6..112f3a1 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 25 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -17,10 +18,20 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup" ],
 	'pg_basebackup fails because of hba');
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
 
@@ -56,6 +67,33 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 	'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -101,29 +139,8 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
 
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
 mkdir "$tempdir/$superlongname";
 psql 'postgres',
   "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 6c9ec5c..c73fb2c 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index 0558854..12da210 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index 5219ec9..ae07b1b 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -38,6 +38,7 @@ use warnings;
 use TestLib;
 use Test::More;
 
+use Config;
 use File::Copy;
 use File::Path qw(remove_tree);
 use IPC::Run qw(run start);
@@ -80,6 +81,7 @@ my $port_master  = $ENV{PGPORT};
 my $port_standby = $port_master + 1;
 
 my $log_path;
+my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master  = "port=$port_master";
@@ -177,6 +179,7 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	remove_tree $log_path;
 }
@@ -204,18 +207,30 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file(
-		"$test_master_datadir/pg_hba.conf", qq(
+	if ($Config{osname} eq "MSWin32")
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
+host replication all 127.0.0.1/32 sspi include_realm=1 map=regress
+host replication all ::1/128 sspi include_realm=1 map=regress
+));
+	}
+	else
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
 local replication all trust
 ));
+	}
 
-	system_or_bail(
-"pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1"
-	);
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST} = $tempdir_short;
+	$ENV{PGHOST} = ($Config{osname} eq "MSWin32") ?
+		"127.0.0.1" : $tempdir_short;
 }
 
 sub create_standby
@@ -225,19 +240,19 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail(
-"pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1");
-	append_to_file(
-		"$test_standby_datadir/recovery.conf", qq(
+	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_standby" :
+		"-k $tempdir_short --listen-addresses='' -p $port_standby";
+
 	# Start standby
-	system_or_bail(
-"pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1"
-	);
+	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -274,8 +289,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail(
-		"pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -295,7 +309,7 @@ sub run_pg_rewind
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
 		system_or_bail(
-			"pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1"
+			"pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect"
 		);
 		my $result = run(
 			[   'pg_rewind',
@@ -309,10 +323,10 @@ sub run_pg_rewind
 	}
 	elsif ($test_mode eq "remote")
 	{
-
 		# Do rewind using a remote connection as source
 		my $result = run(
 			[   'pg_rewind',
+				"--debug",
 				"--source-server",
 				"port=$port_standby dbname=postgres",
 				"--target-pgdata=$test_master_datadir" ],
@@ -323,7 +337,6 @@ sub run_pg_rewind
 	}
 	else
 	{
-
 		# Cannot come here normally
 		die("Incorrect test mode specified");
 	}
@@ -341,10 +354,12 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
 	# Restart the master to check that rewind went correctly
-	system_or_bail(
-"pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1"
-	);
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to check the result
 }
@@ -352,15 +367,16 @@ recovery_target_timeline='latest'
 # Clean up after the test. Stop both servers, if they're still running.
 sub clean_rewind_test
 {
+	my $null_redirect = ($Config{osname} eq "MSWin32") ?
+		"2> nul" : "2> /dev/null";
+
 	if ($test_master_datadir)
 	{
-		system
-		  "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_master_datadir -w -s -m immediate stop $null_redirect";
 	}
 	if ($test_standby_datadir)
 	{
-		system
-		  "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_standby_datadir -w -s -m immediate stop $null_redirect";
 	}
 }
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index ef42366..e228aa9 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -77,9 +78,10 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+	system_or_bail("initdb -D $pgdata -A trust -N > $null_ptr");
+	system_or_bail($ENV{TESTREGRESS},
+				   '--config-auth', $pgdata);
 }
 
 my ($test_server_datadir, $test_server_logfile);
@@ -91,10 +93,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-"--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -103,7 +107,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -162,7 +166,9 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 6b16e69..8abc81d 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -619,6 +619,7 @@ sub GetFakeConfigure
 	$cfg .= ' --enable-integer-datetimes'
 	  if ($self->{options}->{integer_datetimes});
 	$cfg .= ' --enable-nls' if ($self->{options}->{nls});
+	$cfg .= ' --enable-tap-tests' if ($self->{options}->{taptest});
 	$cfg .= ' --with-ldap'  if ($self->{options}->{ldap});
 	$cfg .= ' --without-zlib' unless ($self->{options}->{zlib});
 	$cfg .= ' --with-extra-version' if ($self->{options}->{extraver});
diff --git a/src/tools/msvc/config_default.pl b/src/tools/msvc/config_default.pl
index b9f2ff4..5b8c8cd 100644
--- a/src/tools/msvc/config_default.pl
+++ b/src/tools/msvc/config_default.pl
@@ -14,6 +14,7 @@ our $config = {
 	# wal_blocksize => 8,     # --with-wal-blocksize, 8kB by default
 	# wal_segsize => 16,      # --with-wal-segsize, 16MB by default
 	ldap     => 1,        # --with-ldap
+	taptest  => undef,    # --enable-tap-tests
 	extraver => undef,    # --with-extra-version=<string>
 	nls      => undef,    # --enable-nls=<path>
 	tcl      => undef,    # --with-tls=<path>
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index ddb628d..778bf1e 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,49 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	if (!defined($config->{taptest}))
+	{
+		print "TAP tests not enabled\n";
+		exit 0;
+	}
+
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.4.1

0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchtext/x-diff; charset=US-ASCII; name=0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchDownload
From 681b1f0437e2a7cfa75137da9e75174bcc059858 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sun, 19 Apr 2015 21:47:43 +0900
Subject: [PATCH 2/2] Prefer IPC's run to system_or_bail in pg_rewind tests

This facilitates log capture on Windows, the former method making tests
failing on Windows when multiple processes try to access this log file.
---
 src/bin/pg_rewind/RewindTest.pm | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index ae07b1b..39be3db 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -81,7 +81,6 @@ my $port_master  = $ENV{PGPORT};
 my $port_standby = $port_master + 1;
 
 my $log_path;
-my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master  = "port=$port_master";
@@ -179,7 +178,6 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
-	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	remove_tree $log_path;
 }
@@ -225,7 +223,8 @@ local replication all trust
 		"--listen-addresses=127.0.0.1 -p $port_master" :
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
@@ -240,7 +239,8 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	run(['pg_basebackup', '-D', "$test_standby_datadir",
+		 '-p', "$port_master", '-x'], '>>', $log_path, '2>&1');
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
@@ -252,7 +252,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_standby";
 
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -270,8 +271,8 @@ sub promote_standby
 	# Now promote slave and insert some new data on master, this will put
 	# the master out-of-sync with the standby. Wait until the standby is
 	# out of recovery mode, and is ready to accept read-write connections.
-	system_or_bail(
-		"pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", 'promote'],
+		'>>', $log_path, '2>&1');
 	poll_query_until("SELECT NOT pg_is_in_recovery()", $connstr_standby)
 	  or die "Timed out while waiting for promotion of standby";
 
@@ -289,7 +290,8 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-m',
+		 'fast', 'stop'], '>>', $log_path, '2>&1');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -305,12 +307,10 @@ sub run_pg_rewind
 	# Now run pg_rewind
 	if ($test_mode eq "local")
 	{
-
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail(
-			"pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect"
-		);
+		run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-m',
+			 'fast', 'stop'], '>>', $log_path, '2>&1');
 		my $result = run(
 			[   'pg_rewind',
 				"--debug",
@@ -359,7 +359,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to check the result
 }
-- 
2.4.1

#9Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#8)
2 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Tue, May 26, 2015 at 3:39 PM, Michael Paquier wrote:

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.

Attached is v7, rebased on 0b157a0.
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From 4b960b29446c01ca2f1a44f0e545835d99ab87e6 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Mon, 20 Apr 2015 04:57:37 -0700
Subject: [PATCH 1/2] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 doc/src/sgml/install-windows.sgml              |  1 +
 src/Makefile.global.in                         |  2 +-
 src/bin/initdb/t/001_initdb.pl                 |  1 +
 src/bin/pg_basebackup/t/010_pg_basebackup.pl   | 67 ++++++++++++++++----------
 src/bin/pg_controldata/t/001_pg_controldata.pl |  5 +-
 src/bin/pg_ctl/t/001_start_stop.pl             | 14 ++++--
 src/bin/pg_ctl/t/002_status.pl                 | 12 ++++-
 src/bin/pg_rewind/RewindTest.pm                | 66 +++++++++++++++----------
 src/bin/scripts/t/020_createdb.pl              |  3 ++
 src/test/perl/TestLib.pm                       | 18 ++++---
 src/tools/msvc/Solution.pm                     |  1 +
 src/tools/msvc/config_default.pl               |  1 +
 src/tools/msvc/vcregress.pl                    | 48 +++++++++++++++++-
 13 files changed, 175 insertions(+), 64 deletions(-)

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index c583b44..563d1d1 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -336,7 +336,7 @@ cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPOR
 endef
 
 define prove_check
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 299dcf5..095cbf3 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -4,6 +4,7 @@
 
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 14;
 
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index c8c9250..3fd297b 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 25 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -25,10 +26,20 @@ if (open BADCHARS, ">>$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
 	close BADCHARS;
 }
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
 
@@ -64,6 +75,33 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 	'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -109,29 +147,8 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
 
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
 mkdir "$tempdir/$superlongname";
 psql 'postgres',
   "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl
index a4180e7..fc18a3a 100644
--- a/src/bin/pg_controldata/t/001_pg_controldata.pl
+++ b/src/bin/pg_controldata/t/001_pg_controldata.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -11,6 +12,8 @@ program_options_handling_ok('pg_controldata');
 command_fails(['pg_controldata'], 'pg_controldata without arguments fails');
 command_fails([ 'pg_controldata', 'nonexistent' ],
 	'pg_controldata with nonexistent directory fails');
-system_or_bail "initdb -D '$tempdir'/data -A trust >/dev/null";
+
+my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+system_or_bail "initdb -D $tempdir/data -A trust > $null_ptr";
 command_like([ 'pg_controldata', "$tempdir/data" ],
 	qr/checkpoint/, 'pg_controldata produces output');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index 6c9ec5c..c73fb2c 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index 0558854..12da210 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index 5219ec9..ae07b1b 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -38,6 +38,7 @@ use warnings;
 use TestLib;
 use Test::More;
 
+use Config;
 use File::Copy;
 use File::Path qw(remove_tree);
 use IPC::Run qw(run start);
@@ -80,6 +81,7 @@ my $port_master  = $ENV{PGPORT};
 my $port_standby = $port_master + 1;
 
 my $log_path;
+my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master  = "port=$port_master";
@@ -177,6 +179,7 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
+	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	remove_tree $log_path;
 }
@@ -204,18 +207,30 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file(
-		"$test_master_datadir/pg_hba.conf", qq(
+	if ($Config{osname} eq "MSWin32")
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
+host replication all 127.0.0.1/32 sspi include_realm=1 map=regress
+host replication all ::1/128 sspi include_realm=1 map=regress
+));
+	}
+	else
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
 local replication all trust
 ));
+	}
 
-	system_or_bail(
-"pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1"
-	);
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST} = $tempdir_short;
+	$ENV{PGHOST} = ($Config{osname} eq "MSWin32") ?
+		"127.0.0.1" : $tempdir_short;
 }
 
 sub create_standby
@@ -225,19 +240,19 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail(
-"pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1");
-	append_to_file(
-		"$test_standby_datadir/recovery.conf", qq(
+	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_standby" :
+		"-k $tempdir_short --listen-addresses='' -p $port_standby";
+
 	# Start standby
-	system_or_bail(
-"pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1"
-	);
+	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -274,8 +289,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail(
-		"pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1");
+	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -295,7 +309,7 @@ sub run_pg_rewind
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
 		system_or_bail(
-			"pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1"
+			"pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect"
 		);
 		my $result = run(
 			[   'pg_rewind',
@@ -309,10 +323,10 @@ sub run_pg_rewind
 	}
 	elsif ($test_mode eq "remote")
 	{
-
 		# Do rewind using a remote connection as source
 		my $result = run(
 			[   'pg_rewind',
+				"--debug",
 				"--source-server",
 				"port=$port_standby dbname=postgres",
 				"--target-pgdata=$test_master_datadir" ],
@@ -323,7 +337,6 @@ sub run_pg_rewind
 	}
 	else
 	{
-
 		# Cannot come here normally
 		die("Incorrect test mode specified");
 	}
@@ -341,10 +354,12 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
 	# Restart the master to check that rewind went correctly
-	system_or_bail(
-"pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1"
-	);
+	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
 
 	#### Now run the test-specific parts to check the result
 }
@@ -352,15 +367,16 @@ recovery_target_timeline='latest'
 # Clean up after the test. Stop both servers, if they're still running.
 sub clean_rewind_test
 {
+	my $null_redirect = ($Config{osname} eq "MSWin32") ?
+		"2> nul" : "2> /dev/null";
+
 	if ($test_master_datadir)
 	{
-		system
-		  "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_master_datadir -w -s -m immediate stop $null_redirect";
 	}
 	if ($test_standby_datadir)
 	{
-		system
-		  "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null";
+		system "pg_ctl -D $test_standby_datadir -w -s -m immediate stop $null_redirect";
 	}
 }
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index ef42366..e228aa9 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -77,9 +78,10 @@ sub tempdir_short
 sub standard_initdb
 {
 	my $pgdata = shift;
-	system_or_bail("initdb -D '$pgdata' -A trust -N >/dev/null");
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	my $null_ptr = ($Config{osname} eq "MSWin32") ? "NUL" : "/dev/null";
+	system_or_bail("initdb -D $pgdata -A trust -N > $null_ptr");
+	system_or_bail($ENV{TESTREGRESS},
+				   '--config-auth', $pgdata);
 }
 
 my ($test_server_datadir, $test_server_logfile);
@@ -91,10 +93,12 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	standard_initdb "$tempdir/pgdata";
 	$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
 	  "$tempdir/logfile", '-o',
-"--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
+	  "--fsync=off -k $tempdir_short --listen-addresses=$listen_addresses --log-statement=all",
 	  'start';
 
 	if ($ret != 0)
@@ -103,7 +107,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -162,7 +166,9 @@ sub command_exit_is
 	my $h = start $cmd, '>', File::Spec->devnull(), '2>',
 	  File::Spec->devnull();
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 6b16e69..8abc81d 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -619,6 +619,7 @@ sub GetFakeConfigure
 	$cfg .= ' --enable-integer-datetimes'
 	  if ($self->{options}->{integer_datetimes});
 	$cfg .= ' --enable-nls' if ($self->{options}->{nls});
+	$cfg .= ' --enable-tap-tests' if ($self->{options}->{taptest});
 	$cfg .= ' --with-ldap'  if ($self->{options}->{ldap});
 	$cfg .= ' --without-zlib' unless ($self->{options}->{zlib});
 	$cfg .= ' --with-extra-version' if ($self->{options}->{extraver});
diff --git a/src/tools/msvc/config_default.pl b/src/tools/msvc/config_default.pl
index b9f2ff4..5b8c8cd 100644
--- a/src/tools/msvc/config_default.pl
+++ b/src/tools/msvc/config_default.pl
@@ -14,6 +14,7 @@ our $config = {
 	# wal_blocksize => 8,     # --with-wal-blocksize, 8kB by default
 	# wal_segsize => 16,      # --with-wal-segsize, 16MB by default
 	ldap     => 1,        # --with-ldap
+	taptest  => undef,    # --enable-tap-tests
 	extraver => undef,    # --with-extra-version=<string>
 	nls      => undef,    # --enable-nls=<path>
 	tcl      => undef,    # --with-tls=<path>
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index ddb628d..778bf1e 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,49 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	if (!defined($config->{taptest}))
+	{
+		print "TAP tests not enabled\n";
+		exit 0;
+	}
+
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.4.4

0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchtext/x-patch; charset=US-ASCII; name=0002-Prefer-IPC-s-run-to-system_or_bail-in-pg_rewind-test.patchDownload
From 3b5d6c9c77261110ecc555587b40212b5cd52e55 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sun, 19 Apr 2015 21:47:43 +0900
Subject: [PATCH 2/2] Prefer IPC's run to system_or_bail in pg_rewind tests

This facilitates log capture on Windows, the former method making tests
failing on Windows when multiple processes try to access this log file.
---
 src/bin/pg_rewind/RewindTest.pm | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index ae07b1b..39be3db 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -81,7 +81,6 @@ my $port_master  = $ENV{PGPORT};
 my $port_standby = $port_master + 1;
 
 my $log_path;
-my $log_redirect;
 my $tempdir_short;
 
 my $connstr_master  = "port=$port_master";
@@ -179,7 +178,6 @@ sub init_rewind_test
 	my $test_mode = shift;
 
 	$log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}";
-	$log_redirect = ($Config{osname} eq "MSWin32") ? "> nul" : ">>$log_path 2>&1";
 
 	remove_tree $log_path;
 }
@@ -225,7 +223,8 @@ local replication all trust
 		"--listen-addresses=127.0.0.1 -p $port_master" :
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
@@ -240,7 +239,8 @@ sub create_standby
 	remove_tree $test_standby_datadir;
 
 	# Base backup is taken with xlog files included
-	system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x $log_redirect");
+	run(['pg_basebackup', '-D', "$test_standby_datadir",
+		 '-p', "$port_master", '-x'], '>>', $log_path, '2>&1');
 	append_to_file("$test_standby_datadir/recovery.conf", qq(
 primary_conninfo='$connstr_master application_name=rewind_standby'
 standby_mode=on
@@ -252,7 +252,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_standby";
 
 	# Start standby
-	system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -270,8 +271,8 @@ sub promote_standby
 	# Now promote slave and insert some new data on master, this will put
 	# the master out-of-sync with the standby. Wait until the standby is
 	# out of recovery mode, and is ready to accept read-write connections.
-	system_or_bail(
-		"pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1");
+	run(['pg_ctl', '-w', '-D', "$test_standby_datadir", 'promote'],
+		'>>', $log_path, '2>&1');
 	poll_query_until("SELECT NOT pg_is_in_recovery()", $connstr_standby)
 	  or die "Timed out while waiting for promotion of standby";
 
@@ -289,7 +290,8 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail("pg_ctl -w -D $test_master_datadir -m fast stop $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-m',
+		 'fast', 'stop'], '>>', $log_path, '2>&1');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -305,12 +307,10 @@ sub run_pg_rewind
 	# Now run pg_rewind
 	if ($test_mode eq "local")
 	{
-
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail(
-			"pg_ctl -w -D $test_standby_datadir -m fast stop $log_redirect"
-		);
+		run(['pg_ctl', '-w', '-D', "$test_standby_datadir", '-m',
+			 'fast', 'stop'], '>>', $log_path, '2>&1');
 		my $result = run(
 			[   'pg_rewind',
 				"--debug",
@@ -359,7 +359,8 @@ recovery_target_timeline='latest'
 		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
 	# Restart the master to check that rewind went correctly
-	system_or_bail("pg_ctl -w -D $test_master_datadir -o \"$ctl_options\" start $log_redirect");
+	run(['pg_ctl', '-w', '-D', "$test_master_datadir", '-o',
+		 "$ctl_options", 'start'], '>>', $log_path, '2>&1');
 
 	#### Now run the test-specific parts to check the result
 }
-- 
2.4.4

#10Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#9)
1 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Thu, Jun 25, 2015 at 1:40 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

On Tue, May 26, 2015 at 3:39 PM, Michael Paquier wrote:

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.

Attached is v7, rebased on 0b157a0.

Attached is v8, rebased on 1ea0620, meaning that it includes all the
fancy improvements in log capture for TAP tests.
--
Michael

Attachments:

0001-Add-support-for-TAP-tests-on-Windows.patchtext/x-diff; charset=US-ASCII; name=0001-Add-support-for-TAP-tests-on-Windows.patchDownload
From e8db0a990ec02ddb5bdf2fd95d42b297360ecd55 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Thu, 9 Jul 2015 06:46:13 -0700
Subject: [PATCH] Add support for TAP tests on Windows

Nodes initialized by the TAP tests use SSPI to securely perform the
tests, and test scripts are patched in a couple of places to support
Windows grammar. In the case of MSVC, tests can be run with this
command:
vcregress tapcheck
---
 doc/src/sgml/install-windows.sgml            |  1 +
 src/Makefile.global.in                       |  2 +-
 src/bin/pg_basebackup/t/010_pg_basebackup.pl | 67 +++++++++++++++++-----------
 src/bin/pg_ctl/t/001_start_stop.pl           | 14 ++++--
 src/bin/pg_ctl/t/002_status.pl               | 12 ++++-
 src/bin/pg_rewind/RewindTest.pm              | 56 ++++++++++++++++-------
 src/bin/scripts/t/020_createdb.pl            |  3 ++
 src/test/perl/TestLib.pm                     | 19 +++++---
 src/tools/msvc/Solution.pm                   |  1 +
 src/tools/msvc/clean.bat                     |  8 ++++
 src/tools/msvc/config_default.pl             |  1 +
 src/tools/msvc/vcregress.pl                  | 48 +++++++++++++++++++-
 12 files changed, 176 insertions(+), 56 deletions(-)

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 8d1250d..4b9c529 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -338,7 +338,7 @@ endef
 
 define prove_check
 rm -rf $(srcdir)/tmp_check/log
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' TESTREGRESS='$(top_builddir)/src/test/regress/pg_regress' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index e47c3a0..59e8cb4 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,8 +1,9 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
-use Test::More tests => 35;
+use Test::More tests => ($Config{osname} eq "MSWin32") ? 25 : 35;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -25,10 +26,20 @@ if (open BADCHARS, ">>$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
 	close BADCHARS;
 }
 
+# Use SSPI on Windows, node has been initialized already accordingly
+# by pg_regress --config-auth.
 open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print HBA "local replication all trust\n";
+	print HBA "host replication all 127.0.0.1/32 trust\n";
+	print HBA "host replication all ::1/128 trust\n";
+}
+else
+{
+	print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+}
 close HBA;
 system_or_bail 'pg_ctl', '-D', "$tempdir/pgdata", 'reload';
 
@@ -64,6 +75,33 @@ command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
 	'pg_basebackup tar with long name fails');
 unlink "$tempdir/pgdata/$superlongname";
 
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+	'-T with empty old directory fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+	'-T with empty new directory fails');
+command_fails(
+	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
+		"-T/foo=/bar=/baz" ],
+	'-T with multiple = fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+	'-T with old directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+	'-T with new directory not absolute fails');
+command_fails(
+	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+	'-T with invalid format fails');
+
+# Windows does not support symlink, which is what the rest of the tests
+# need, so simply leave.
+if ($Config{osname} eq "MSWin32")
+{
+	exit 0;
+}
+
 # Create a temporary directory in the system location and symlink it
 # to our physical temp location.  That way we can use shorter names
 # for the tablespace directories, which hopefully won't run afoul of
@@ -109,29 +147,8 @@ command_ok(
 		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
 	'mapping tablespace with = sign in path');
 ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
 psql 'postgres', "DROP TABLESPACE tblspc2;";
 
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
-	'-T with empty old directory fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
-	'-T with empty new directory fails');
-command_fails(
-	[   'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
-		"-T/foo=/bar=/baz" ],
-	'-T with multiple = fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
-	'-T with old directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
-	'-T with new directory not absolute fails');
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
-	'-T with invalid format fails');
-
 mkdir "$tempdir/$superlongname";
 psql 'postgres',
   "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index bcceb57..bebcd6e 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{TESTREGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index ec0a2a7..f68cd62 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 3;
 
@@ -11,8 +12,15 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 
 standard_initdb "$tempdir/data";
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} eq "MSWin32")
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
+else
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
 close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index e57b417..8923d9b 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -38,6 +38,7 @@ use warnings;
 use TestLib;
 use Test::More;
 
+use Config;
 use File::Copy;
 use File::Path qw(remove_tree);
 use IPC::Run qw(run start);
@@ -195,19 +196,32 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file(
-		"$test_master_datadir/pg_hba.conf", qq(
+	if ($Config{osname} eq "MSWin32")
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
+host replication all 127.0.0.1/32 sspi include_realm=1 map=regress
+host replication all ::1/128 sspi include_realm=1 map=regress
+));
+	}
+	else
+	{
+		append_to_file("$test_master_datadir/pg_hba.conf", qq(
 local replication all trust
 ));
+	}
+
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
 
-	system_or_bail('pg_ctl' , '-w',
-				   '-D' , $test_master_datadir,
-				   "-o", "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+	system_or_bail('pg_ctl', '-w',
+				   '-D', $test_master_datadir,
+				   '-o', $ctl_options, 'start');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST} = $tempdir_short;
+	$ENV{PGHOST} = ($Config{osname} eq "MSWin32") ?
+		"127.0.0.1" : $tempdir_short;
 }
 
 sub create_standby
@@ -226,10 +240,13 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_standby" :
+		"-k $tempdir_short --listen-addresses='' -p $port_standby";
+
 	# Start standby
 	system_or_bail('pg_ctl', '-w', '-D', $test_standby_datadir,
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_standby",
-				   'start');
+				   '-o', $ctl_options, 'start');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -265,7 +282,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail('pg_ctl', '-D', $test_master_datadir, 'stop', '-m', 'fast');
+	system_or_bail('pg_ctl', '-D', $test_master_datadir, '-m', 'fast', 'stop');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -283,8 +300,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail('pg_ctl', '-D', $test_standby_datadir, 'stop',
-					   '-m', 'fast');
+		system_or_bail('pg_ctl', '-D', $test_standby_datadir,
+					   '-m', 'fast', 'stop');
 		command_ok(['pg_rewind',
 					"--debug",
 					"--source-pgdata=$test_standby_datadir",
@@ -295,6 +312,7 @@ sub run_pg_rewind
 	{
 		# Do rewind using a remote connection as source
 		command_ok(['pg_rewind',
+					"--debug",
 					"--source-server",
 					"port=$port_standby dbname=postgres",
 					"--target-pgdata=$test_master_datadir"],
@@ -302,7 +320,6 @@ sub run_pg_rewind
 	}
 	else
 	{
-
 		# Cannot come here normally
 		die("Incorrect test mode specified");
 	}
@@ -320,10 +337,13 @@ standby_mode=on
 recovery_target_timeline='latest'
 ));
 
+	my $ctl_options = ($Config{osname} eq "MSWin32") ?
+		"--listen-addresses=127.0.0.1 -p $port_master" :
+		"-k $tempdir_short --listen-addresses='' -p $port_master";
+
 	# Restart the master to check that rewind went correctly
 	system_or_bail('pg_ctl', '-w', '-D', $test_master_datadir,
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+				   '-o', $ctl_options, 'start');
 
 	#### Now run the test-specific parts to check the result
 }
@@ -334,12 +354,14 @@ sub clean_rewind_test
 	if ($test_master_datadir)
 	{
 		system
-		  'pg_ctl', '-D', $test_master_datadir, '-m', 'immediate', 'stop';
+			'pg_ctl', '-D', $test_master_datadir, '-m',
+			'immediate', 'stop';
 	}
 	if ($test_standby_datadir)
 	{
 		system
-		  'pg_ctl', '-D', $test_standby_datadir, '-m', 'immediate', 'stop';
+			'pg_ctl', '-D', $test_standby_datadir, '-m',
+			'immediate', 'stop';
 	}
 }
 
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index a44283c..7e769e4 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 13;
 
@@ -14,6 +15,8 @@ issues_sql_like(
 	[ 'createdb', 'foobar1' ],
 	qr/statement: CREATE DATABASE foobar1/,
 	'SQL CREATE DATABASE run');
+
+my $encoding = ($Config{osname} eq "MSWin32") ? "win1252" : "LATIN1" ;
 issues_sql_like(
 	[ 'createdb', '-l', 'C', '-E', 'LATIN1', '-T', 'template0', 'foobar2' ],
 	qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 0193d57..02f29f7 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,6 +3,7 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
@@ -90,7 +91,6 @@ if (!$ENV{PGPORT})
 
 $ENV{PGPORT} = int($ENV{PGPORT}) % 65536;
 
-
 #
 # Helper functions
 #
@@ -116,8 +116,8 @@ sub standard_initdb
 {
 	my $pgdata = shift;
 	system_or_bail('initdb', '-D', "$pgdata", '-A' , 'trust', '-N');
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	system_or_bail($ENV{TESTREGRESS},
+				   '--config-auth', $pgdata);
 }
 
 my ($test_server_datadir, $test_server_logfile);
@@ -129,12 +129,15 @@ sub start_test_server
 
 	my $tempdir_short = tempdir_short;
 
+	my $listen_addresses = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : "''";
+
 	print("### Starting test server in $tempdir\n");
 	standard_initdb "$tempdir/pgdata";
 	$ret = system_log('pg_ctl', '-D', "$tempdir/pgdata", '-w', '-l',
 	  "$tempdir/logfile", '-o',
-"--fsync=off -k \"$tempdir_short\" --listen-addresses='' --log-statement=all",
-					'start');
+	  "--fsync=off --listen-addresses=$listen_addresses --log-statement=all",
+	  'start');
+
 	if ($ret != 0)
 	{
 		print "# pg_ctl failed; logfile:\n";
@@ -142,7 +145,7 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -216,7 +219,9 @@ sub command_exit_is
 	print("# Running: " . join(" ", @{$cmd}) ."\n");
 	my $h = start $cmd;
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 6b16e69..8abc81d 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -619,6 +619,7 @@ sub GetFakeConfigure
 	$cfg .= ' --enable-integer-datetimes'
 	  if ($self->{options}->{integer_datetimes});
 	$cfg .= ' --enable-nls' if ($self->{options}->{nls});
+	$cfg .= ' --enable-tap-tests' if ($self->{options}->{taptest});
 	$cfg .= ' --with-ldap'  if ($self->{options}->{ldap});
 	$cfg .= ' --without-zlib' unless ($self->{options}->{zlib});
 	$cfg .= ' --with-extra-version' if ($self->{options}->{extraver});
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index fbe3cc6..50c361e 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -88,6 +88,14 @@ if exist src\test\regress\regress.dll del /q src\test\regress\regress.dll
 if exist src\test\regress\refint.dll del /q src\test\regress\refint.dll
 if exist src\test\regress\autoinc.dll del /q src\test\regress\autoinc.dll
 
+if exist src\test\ssl\tmp_check rd /s /q src\test\ssl\tmp_check
+if exist src\bin\initdb\tmp_check rd /s /q src\bin\initdb\tmp_check
+if exist src\bin\pg_basebackup\tmp_check rd /s /q src\bin\pg_basebackup\tmp_check
+if exist src\bin\pg_config\tmp_check rd /s /q src\bin\pg_config\tmp_check
+if exist src\bin\pg_ctl\tmp_check rd /s /q src\bin\pg_ctl\tmp_check
+if exist src\bin\pg_rewind\tmp_check rd /s /q src\bin\pg_rewind\tmp_check
+if exist src\bin\scripts\tmp_check rd /s /q src\bin\scripts\tmp_check
+
 REM Clean up datafiles built with contrib
 REM cd contrib
 REM for /r %%f in (*.sql) do if exist %%f.in del %%f
diff --git a/src/tools/msvc/config_default.pl b/src/tools/msvc/config_default.pl
index b9f2ff4..5b8c8cd 100644
--- a/src/tools/msvc/config_default.pl
+++ b/src/tools/msvc/config_default.pl
@@ -14,6 +14,7 @@ our $config = {
 	# wal_blocksize => 8,     # --with-wal-blocksize, 8kB by default
 	# wal_segsize => 16,      # --with-wal-segsize, 16MB by default
 	ldap     => 1,        # --with-ldap
+	taptest  => undef,    # --enable-tap-tests
 	extraver => undef,    # --with-extra-version=<string>
 	nls      => undef,    # --enable-nls=<path>
 	tcl      => undef,    # --with-tls=<path>
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index 6196383..4dcc155 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,49 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	if (!defined($config->{taptest}))
+	{
+		print "TAP tests not enabled\n";
+		exit 0;
+	}
+
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{TESTREGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.4.5

#11Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Michael Paquier (#9)
1 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On 06/25/2015 07:40 AM, Michael Paquier wrote:

On Tue, May 26, 2015 at 3:39 PM, Michael Paquier wrote:

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.

Attached is v7, rebased on 0b157a0.

Thanks! I fiddled with this a bit more, to centralize more of the
platform-dependent stuff to RewindTest.pm. Also, Windows doesn't have
"cat" and "touch" if you haven't installed MinGW, so I replaced those
calls with built-in perl code.

Can you double-check that the attached still works in your environment?
It works for me now.

Note: I had some trouble installing IPC::Run on my system, with
ActiveState Perl and MSVC. There is no PPM package of that for Windows,
so I had to do "cpan install IPC::Run". That downloaded the MinGW C
compiler and make utility, which took a while. But some of the IPC::Run
regression tests failed, and the installation was aborted. I forced my
way through that "notest install IPC::Run". The next obstacle was that
"vcregress <anything>" no longer worked. It complained about finding
some function in the Install module. Turns out that when it installed
the C compiler and make utility, it also installed a module called
"install" from cpan, which has the same name as the PostgreSQL
Install.pm module. We really should rename our module. I got through
that by manually removing the system install.pm module from the perl
installation's site directory. But after that, it worked great :-).

We need to put some instructions in the docs on how to install IPC::Run
on Windows. I can write up something unless you're eager to.

- Heikki

Attachments:

0001-Make-TAP-tests-work-on-Windows.patchapplication/x-patch; name=0001-Make-TAP-tests-work-on-Windows.patchDownload
From 1793f273cb2d849c9fc63483ab485fba29c114d6 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Fri, 24 Jul 2015 17:39:24 +0300
Subject: [PATCH] Make TAP tests work on Windows.

On Windows, use listen_address=127.0.0.1 to allow connections. We were
already using "pg_regress --config-auth" to set up HBA appropriately.
The standard_initdb helper function now sets up the server's
unix_socket_directories or listen_addresses in the config file, so that
they don't need to be specified in the pg_ctl command line anymore. That
way, the pg_ctl invocations in test programs don't need to differ between
Windows and Unix.

Add another helper function to configure the server's pg_hba.conf to
allow replication connections. The configuration is done similarly to
pg_regress --config-auth: trust on domain sockets on Unix, and SSPI
authentication on Windows.

Replace calls to "cat" and "touch" programs with built-in perl code.

Add "vcregress tapcheck" command for launching the tests on Windows.

Michael Paquier

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..2047790 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index e2f7211..59c9eed 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -339,7 +339,7 @@ endef
 
 define prove_check
 rm -rf $(srcdir)/tmp_check/log
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index e47c3a0..40b6b76 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,6 +1,7 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
 use Test::More tests => 35;
 
@@ -25,11 +26,7 @@ if (open BADCHARS, ">>$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
 	close BADCHARS;
 }
 
-open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
-close HBA;
+configure_hba_for_replication "$tempdir/pgdata";
 system_or_bail 'pg_ctl', '-D', "$tempdir/pgdata", 'reload';
 
 command_fails(
@@ -57,61 +54,7 @@ command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft' ],
 	'tar format');
 ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
 
-my $superlongname = "superlongname_" . ("x" x 100);
-
-system_or_bail 'touch', "$tempdir/pgdata/$superlongname";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
-	'pg_basebackup tar with long name fails');
-unlink "$tempdir/pgdata/$superlongname";
-
-# Create a temporary directory in the system location and symlink it
-# to our physical temp location.  That way we can use shorter names
-# for the tablespace directories, which hopefully won't run afoul of
-# the 99 character length limit.
-my $shorter_tempdir = tempdir_short . "/tempdir";
-symlink "$tempdir", $shorter_tempdir;
-
-mkdir "$tempdir/tblspc1";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
-psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
-	'tar format with tablespaces');
-ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
-my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
-is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
-	'plain format with tablespaces fails without tablespace mapping');
-
-command_ok(
-	[   'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
-		"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
-	'plain format with tablespaces succeeds with tablespace mapping');
-ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
-opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
-ok( (   grep {
-			-l "$tempdir/backup1/pg_tblspc/$_"
-			  and readlink "$tempdir/backup1/pg_tblspc/$_" eq
-			  "$tempdir/tbackup/tblspc1"
-		  } readdir($dh)),
-	"tablespace symlink was updated");
-closedir $dh;
-
-mkdir "$tempdir/tbl=spc2";
-psql 'postgres', "DROP TABLE test1;";
-psql 'postgres', "DROP TABLESPACE tblspc1;";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
-command_ok(
-	[   'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
-		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
-	'mapping tablespace with = sign in path');
-ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
-psql 'postgres', "DROP TABLESPACE tblspc2;";
-
+# Test incorrect arguments
 command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
 	'-T with empty old directory fails');
@@ -132,9 +75,72 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
 	'-T with invalid format fails');
 
-mkdir "$tempdir/$superlongname";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-	'pg_basebackup tar with long symlink target');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
+# Tar format doesn't support filenames longer than 100 bytes.
+my $superlongname = "superlongname_" . ("x" x 100);
+my $superlongpath = "$tempdir/pgdata/$superlongname";
+
+open FILE, ">$superlongpath" or die "unable to create file $superlongpath";
+close FILE;
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
+	'pg_basebackup tar with long name fails');
+unlink "$tempdir/pgdata/$superlongname";
+
+# The following tests test symlinks. Windows doesn't have symlinks, so
+# skip on Windows.
+SKIP: {
+    skip "symlinks not supported on Windows", 10 if ($Config{osname} eq "MSWin32");
+
+	# Create a temporary directory in the system location and symlink it
+	# to our physical temp location.  That way we can use shorter names
+	# for the tablespace directories, which hopefully won't run afoul of
+	# the 99 character length limit.
+	my $shorter_tempdir = tempdir_short . "/tempdir";
+	symlink "$tempdir", $shorter_tempdir;
+
+	mkdir "$tempdir/tblspc1";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
+	psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
+			   'tar format with tablespaces');
+	ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
+	my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
+	is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
+
+	command_fails(
+		[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
+		'plain format with tablespaces fails without tablespace mapping');
+
+	command_ok(
+		[   'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
+			"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
+		'plain format with tablespaces succeeds with tablespace mapping');
+	ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
+	opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
+	ok( (   grep {
+		-l "$tempdir/backup1/pg_tblspc/$_"
+			and readlink "$tempdir/backup1/pg_tblspc/$_" eq
+			"$tempdir/tbackup/tblspc1"
+			} readdir($dh)),
+		"tablespace symlink was updated");
+	closedir $dh;
+
+	mkdir "$tempdir/tbl=spc2";
+	psql 'postgres', "DROP TABLE test1;";
+	psql 'postgres', "DROP TABLESPACE tblspc1;";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
+	command_ok(
+		[   'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
+			"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
+		'mapping tablespace with = sign in path');
+	ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
+	psql 'postgres', "DROP TABLESPACE tblspc2;";
+
+	mkdir "$tempdir/$superlongname";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			   'pg_basebackup tar with long symlink target');
+	psql 'postgres', "DROP TABLESPACE tblspc3;";
+}
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index bcceb57d..4f65af5 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -15,13 +15,9 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{PG_REGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
-open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
-close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index ec0a2a7..31f7c72 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -10,10 +10,6 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 	4, 'pg_ctl status with nonexistent directory');
 
 standard_initdb "$tempdir/data";
-open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
-close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
 	3, 'pg_ctl status with server not running');
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index db5e90b..7fd8af2 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -195,19 +195,14 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file(
-		"$test_master_datadir/pg_hba.conf", qq(
-local replication all trust
-));
+	configure_hba_for_replication $test_master_datadir;
 
-	system_or_bail('pg_ctl' , '-w',
-				   '-D' , $test_master_datadir,
-				   "-o", "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+	system_or_bail('pg_ctl', '-w',
+				   '-D', $test_master_datadir,
+				   '-o', "-p $port_master", 'start');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST} = $tempdir_short;
 }
 
 sub create_standby
@@ -228,8 +223,7 @@ recovery_target_timeline='latest'
 
 	# Start standby
 	system_or_bail('pg_ctl', '-w', '-D', $test_standby_datadir,
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_standby",
-				   'start');
+				   '-o', "-p $port_standby", 'start');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -265,7 +259,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail('pg_ctl', '-D', $test_master_datadir, 'stop', '-m', 'fast');
+	system_or_bail('pg_ctl', '-D', $test_master_datadir, '-m', 'fast', 'stop');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -283,8 +277,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail('pg_ctl', '-D', $test_standby_datadir, 'stop',
-					   '-m', 'fast');
+		system_or_bail('pg_ctl', '-D', $test_standby_datadir,
+					   '-m', 'fast', 'stop');
 		command_ok(['pg_rewind',
 					"--debug",
 					"--source-pgdata=$test_standby_datadir",
@@ -303,7 +297,6 @@ sub run_pg_rewind
 	}
 	else
 	{
-
 		# Cannot come here normally
 		die("Incorrect test mode specified");
 	}
@@ -323,8 +316,7 @@ recovery_target_timeline='latest'
 
 	# Restart the master to check that rewind went correctly
 	system_or_bail('pg_ctl', '-w', '-D', $test_master_datadir,
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+				   '-o', "-p $port_master", 'start');
 
 	#### Now run the test-specific parts to check the result
 }
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 0193d57..4d0dd45 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,11 +3,13 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
   tempdir_short
   standard_initdb
+  configure_hba_for_replication
   start_test_server
   restart_test_server
   psql
@@ -112,29 +114,83 @@ sub tempdir_short
 	return File::Temp::tempdir(CLEANUP => 1);
 }
 
+# Initialize a new cluster for testing.
+#
+# The PGHOST environment variable is set to connect to the new cluster.
+#
+# Authentication is set up so that only the current OS user can access the
+# cluster. On Unix, we use Unix domain socket connections, with the socket in
+# a directory that's only accessible to the current user to ensure that.
+# On Windows, we use SSPI authentication to ensure the same (by pg_regress
+# --config-auth).
 sub standard_initdb
 {
 	my $pgdata = shift;
 	system_or_bail('initdb', '-D', "$pgdata", '-A' , 'trust', '-N');
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata);
+
+	my $tempdir_short = tempdir_short;
+
+	open CONF, ">>$pgdata/postgresql.conf";
+	print CONF "\n# Added by TestLib.pm)\n";
+	if ($Config{osname} eq "MSWin32")
+	{
+		print CONF "listen_addresses = '127.0.0.1'\n";
+	}
+	else
+	{
+		print CONF "unix_socket_directories = '$tempdir_short'\n";
+	}
+	close CONF;
+
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
+}
+
+# Set up the cluster to allow replication connections, in the same way that
+# standard_initdb does for normal connections.
+sub configure_hba_for_replication
+{
+	my $pgdata = shift;
+
+	open HBA, ">>$pgdata/pg_hba.conf";
+	print HBA "\n# Allow replication (set up by TestLib.pm)\n";
+	if ($Config{osname} ne "MSWin32")
+	{
+		print HBA "local replication all trust\n";
+	}
+	else
+	{
+		print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+		print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";
+	}
+	close HBA;
 }
 
 my ($test_server_datadir, $test_server_logfile);
 
+
+# Initialize a new cluster for testing, and start it.
+#
+# The first argument is a temporary directory to create the cluster in.
+# If the second argument is true, the cluster configured to accept
+# replication connections.
 sub start_test_server
 {
-	my ($tempdir) = @_;
+	my $tempdir = shift;
+	my $replication = shift;
 	my $ret;
 
-	my $tempdir_short = tempdir_short;
-
 	print("### Starting test server in $tempdir\n");
 	standard_initdb "$tempdir/pgdata";
-	$ret = system_log('pg_ctl', '-D', "$tempdir/pgdata", '-w', '-l',
-	  "$tempdir/logfile", '-o',
-"--fsync=off -k \"$tempdir_short\" --listen-addresses='' --log-statement=all",
-					'start');
+	if ($replication)
+	{
+		configure_for_replication("$tempdir/pgdata");
+	}
+
+	$ret = system_log('pg_ctl', '-D', "$tempdir/pgdata", '-w',
+	  '-l', "$tempdir/logfile", '-o', "--fsync=off --log-statement=all",
+	  'start');
+
 	if ($ret != 0)
 	{
 		print "# pg_ctl failed; logfile:\n";
@@ -142,7 +198,6 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -216,7 +271,9 @@ sub command_exit_is
 	print("# Running: " . join(" ", @{$cmd}) ."\n");
 	my $h = start $cmd;
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
@@ -269,7 +326,12 @@ sub issues_sql_like
 	truncate $test_server_logfile, 0;
 	my $result = run_log($cmd);
 	ok($result, "@$cmd exit code 0");
-	my $log = `cat '$test_server_logfile'`;
+
+	# read the server log file into variable
+	open SERVERLOG, '<', $test_server_logfile or die "Could not open server log file $test_server_logfile: $!";
+	my $log = do { local $/; <SERVERLOG> };
+	close SERVERLOG;
+
 	like($log, $expected_sql, "$test_name: SQL found in server log");
 }
 
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index fbe3cc6..50c361e 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -88,6 +88,14 @@ if exist src\test\regress\regress.dll del /q src\test\regress\regress.dll
 if exist src\test\regress\refint.dll del /q src\test\regress\refint.dll
 if exist src\test\regress\autoinc.dll del /q src\test\regress\autoinc.dll
 
+if exist src\test\ssl\tmp_check rd /s /q src\test\ssl\tmp_check
+if exist src\bin\initdb\tmp_check rd /s /q src\bin\initdb\tmp_check
+if exist src\bin\pg_basebackup\tmp_check rd /s /q src\bin\pg_basebackup\tmp_check
+if exist src\bin\pg_config\tmp_check rd /s /q src\bin\pg_config\tmp_check
+if exist src\bin\pg_ctl\tmp_check rd /s /q src\bin\pg_ctl\tmp_check
+if exist src\bin\pg_rewind\tmp_check rd /s /q src\bin\pg_rewind\tmp_check
+if exist src\bin\scripts\tmp_check rd /s /q src\bin\scripts\tmp_check
+
 REM Clean up datafiles built with contrib
 REM cd contrib
 REM for /r %%f in (*.sql) do if exist %%f.in del %%f
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index 6196383..b02f0e6 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,43 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\// && !defined($config->{openssl}));
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.1.4

#12Andrew Dunstan
andrew@dunslane.net
In reply to: Heikki Linnakangas (#11)
Re: Supporting TAP tests with MSVC and Windows

On 07/24/2015 01:27 PM, Heikki Linnakangas wrote:

On 06/25/2015 07:40 AM, Michael Paquier wrote:

On Tue, May 26, 2015 at 3:39 PM, Michael Paquier wrote:

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.

Attached is v7, rebased on 0b157a0.

Thanks! I fiddled with this a bit more, to centralize more of the
platform-dependent stuff to RewindTest.pm. Also, Windows doesn't have
"cat" and "touch" if you haven't installed MinGW, so I replaced those
calls with built-in perl code.

Can you double-check that the attached still works in your
environment? It works for me now.

Note: I had some trouble installing IPC::Run on my system, with
ActiveState Perl and MSVC. There is no PPM package of that for
Windows, so I had to do "cpan install IPC::Run". That downloaded the
MinGW C compiler and make utility, which took a while. But some of the
IPC::Run regression tests failed, and the installation was aborted. I
forced my way through that "notest install IPC::Run". The next
obstacle was that "vcregress <anything>" no longer worked. It
complained about finding some function in the Install module. Turns
out that when it installed the C compiler and make utility, it also
installed a module called "install" from cpan, which has the same name
as the PostgreSQL Install.pm module. We really should rename our
module. I got through that by manually removing the system install.pm
module from the perl installation's site directory. But after that, it
worked great :-).

We need to put some instructions in the docs on how to install
IPC::Run on Windows. I can write up something unless you're eager to.

AFAIK all you need to do is put Run.pm in the right place. It doesn't
need any building, IIRC, and the current version can be got from
<http://cpansearch.perl.org/src/TODDR/IPC-Run-0.94/lib/IPC/Run.pm&gt;

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Michael Paquier
michael.paquier@gmail.com
In reply to: Andrew Dunstan (#12)
Re: Supporting TAP tests with MSVC and Windows

On Sat, Jul 25, 2015 at 3:27 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

On 07/24/2015 01:27 PM, Heikki Linnakangas wrote:

On 06/25/2015 07:40 AM, Michael Paquier wrote:

On Tue, May 26, 2015 at 3:39 PM, Michael Paquier wrote:

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.

Attached is v7, rebased on 0b157a0.

Thanks! I fiddled with this a bit more, to centralize more of the
platform-dependent stuff to RewindTest.pm. Also, Windows doesn't have "cat"
and "touch" if you haven't installed MinGW, so I replaced those calls with
built-in perl code.

Can you double-check that the attached still works in your environment? It
works for me now.

Note: I had some trouble installing IPC::Run on my system, with
ActiveState Perl and MSVC. There is no PPM package of that for Windows, so I
had to do "cpan install IPC::Run". That downloaded the MinGW C compiler and
make utility, which took a while. But some of the IPC::Run regression tests
failed, and the installation was aborted. I forced my way through that
"notest install IPC::Run". The next obstacle was that "vcregress <anything>"
no longer worked. It complained about finding some function in the Install
module. Turns out that when it installed the C compiler and make utility, it
also installed a module called "install" from cpan, which has the same name
as the PostgreSQL Install.pm module. We really should rename our module. I
got through that by manually removing the system install.pm module from the
perl installation's site directory. But after that, it worked great :-).

We need to put some instructions in the docs on how to install IPC::Run on
Windows. I can write up something unless you're eager to.

AFAIK all you need to do is put Run.pm in the right place. It doesn't need
any building, IIRC, and the current version can be got from
<http://cpansearch.perl.org/src/TODDR/IPC-Run-0.94/lib/IPC/Run.pm&gt;

Yeah, that's exactly what I did myself and put it in a path of
PERL5LIB, and it just worked.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#14Noah Misch
noah@leadboat.com
In reply to: Heikki Linnakangas (#11)
Re: Supporting TAP tests with MSVC and Windows

On Fri, Jul 24, 2015 at 08:27:42PM +0300, Heikki Linnakangas wrote:

On 06/25/2015 07:40 AM, Michael Paquier wrote:

Attached is v7, rebased on 0b157a0.

Thanks! I fiddled with this a bit more, to centralize more of the
platform-dependent stuff to RewindTest.pm. Also, Windows doesn't have "cat"
and "touch" if you haven't installed MinGW, so I replaced those calls with
built-in perl code.

My main priority for this patch is to not reintroduce CVE-2014-0067. The
patch is operating in a security minefield:

--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -15,13 +15,9 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{PG_REGRESS}, '--config-auth',
"$tempdir/data" ],
'configure authentication');
-open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
-close CONF;
command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
'pg_ctl start -w');

Since this series of tests doesn't use standard_initdb, the deleted lines
remain necessary.

@@ -303,7 +297,6 @@ sub run_pg_rewind
}
else
{
-
# Cannot come here normally

Unrelated change.

sub standard_initdb
{
my $pgdata = shift;
system_or_bail('initdb', '-D', "$pgdata", '-A' , 'trust', '-N');
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata);
+
+	my $tempdir_short = tempdir_short;
+
+	open CONF, ">>$pgdata/postgresql.conf";
+	print CONF "\n# Added by TestLib.pm)\n";
+	if ($Config{osname} eq "MSWin32")
+	{
+		print CONF "listen_addresses = '127.0.0.1'\n";
+	}
+	else
+	{
+		print CONF "unix_socket_directories = '$tempdir_short'\n";

This second branch needs listen_addresses=''; it doesn't help to secure the
socket directory if the server still listens on localhost.

+sub configure_hba_for_replication
+{
+	my $pgdata = shift;
+
+	open HBA, ">>$pgdata/pg_hba.conf";
+	print HBA "\n# Allow replication (set up by TestLib.pm)\n";
+	if ($Config{osname} ne "MSWin32")
+	{
+		print HBA "local replication all trust\n";
+	}
+	else
+	{
+		print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+		print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";

The second line will make the server fail to start on non-IPv6 systems. You
shouldn't need it if the clients always connect to 127.0.0.1, not "localhost".

+ configure_for_replication("$tempdir/pgdata");

That function name appears nowhere else.

+sub tapcheck
+{
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.

This target shall not run the SSL suite, for the same reason check-world shall
not run it. We could offer a distinct vcregress.pl target for TAP suites
excluded from check-world.

nm

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Michael Paquier
michael.paquier@gmail.com
In reply to: Heikki Linnakangas (#11)
Re: Supporting TAP tests with MSVC and Windows

On Sat, Jul 25, 2015 at 2:27 AM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

On 06/25/2015 07:40 AM, Michael Paquier wrote:

On Tue, May 26, 2015 at 3:39 PM, Michael Paquier wrote:

Here is v6, a rebased version on HEAD (79f2b5d). There were some
conflicts with the indentation and some other patches related to
pg_rewind and initdb's tests.

Attached is v7, rebased on 0b157a0.

Thanks! I fiddled with this a bit more, to centralize more of the
platform-dependent stuff to RewindTest.pm. Also, Windows doesn't have "cat"
and "touch" if you haven't installed MinGW, so I replaced those calls with
built-in perl code.

Can you double-check that the attached still works in your environment? It
works for me now.

Sure, I'll double check and update your last version as necessary.

We need to put some instructions in the docs on how to install IPC::Run on
Windows. I can write up something unless you're eager to.

I'll do it. That's fine, but it is going to be closer to a ninja
version of what you did.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Michael Paquier
michael.paquier@gmail.com
In reply to: Noah Misch (#14)
1 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Sat, Jul 25, 2015 at 4:14 PM, Noah Misch <noah@leadboat.com> wrote:

On Fri, Jul 24, 2015 at 08:27:42PM +0300, Heikki Linnakangas wrote:

On 06/25/2015 07:40 AM, Michael Paquier wrote:

Attached is v7, rebased on 0b157a0.

Thanks! I fiddled with this a bit more, to centralize more of the
platform-dependent stuff to RewindTest.pm. Also, Windows doesn't have "cat"
and "touch" if you haven't installed MinGW, so I replaced those calls with
built-in perl code.

My main priority for this patch is to not reintroduce CVE-2014-0067. The
patch is operating in a security minefield:

Thanks!

--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -15,13 +15,9 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
command_ok(
-     [   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+     [ $ENV{PG_REGRESS}, '--config-auth',
"$tempdir/data" ],
'configure authentication');
-open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
-close CONF;
command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
'pg_ctl start -w');

Since this series of tests doesn't use standard_initdb, the deleted lines
remain necessary.

Added with a switch on $config{osname}.

@@ -303,7 +297,6 @@ sub run_pg_rewind
}
else
{
-
# Cannot come here normally

Unrelated change.

Removed.

sub standard_initdb
{
my $pgdata = shift;
system_or_bail('initdb', '-D', "$pgdata", '-A' , 'trust', '-N');
-     system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-             '--config-auth', $pgdata);
+     system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata);
+
+     my $tempdir_short = tempdir_short;
+
+     open CONF, ">>$pgdata/postgresql.conf";
+     print CONF "\n# Added by TestLib.pm)\n";
+     if ($Config{osname} eq "MSWin32")
+     {
+             print CONF "listen_addresses = '127.0.0.1'\n";
+     }
+     else
+     {
+             print CONF "unix_socket_directories = '$tempdir_short'\n";

This second branch needs listen_addresses=''; it doesn't help to secure the
socket directory if the server still listens on localhost.

Yep. Agreed.

+sub configure_hba_for_replication
+{
+     my $pgdata = shift;
+
+     open HBA, ">>$pgdata/pg_hba.conf";
+     print HBA "\n# Allow replication (set up by TestLib.pm)\n";
+     if ($Config{osname} ne "MSWin32")
+     {
+             print HBA "local replication all trust\n";
+     }
+     else
+     {
+             print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+             print HBA "host replication all ::1/128 sspi include_realm=1 map=regress\n";

The second line will make the server fail to start on non-IPv6 systems. You
shouldn't need it if the clients always connect to 127.0.0.1, not "localhost".

Done.

+ configure_for_replication("$tempdir/pgdata");

That function name appears nowhere else.

This looks like dead code to me. Hence removed.

+sub tapcheck
+{
+     InstallTemp();
+
+     my @args = ( "prove", "--verbose", "t/*.pl");
+
+     $ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+     $ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+     $ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+     # Find out all the existing TAP tests by simply looking for t/
+     # in the tree.

This target shall not run the SSL suite, for the same reason check-world shall
not run it. We could offer a distinct vcregress.pl target for TAP suites
excluded from check-world.

OK, for the sake of duplicating what GNU does, let's simply ignore it then.

Also I added an equivalent of --enable-tap-tests for this MSVC stuff,
removed afterwards by Heikki. Do we want it or not?

An updated patch is attached.
--
Michael

Attachments:

0001-Make-TAP-tests-work-on-Windows.patchtext/x-patch; charset=US-ASCII; name=0001-Make-TAP-tests-work-on-Windows.patchDownload
From 51d6d553742753a3389fcb67778662cb24274508 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sat, 25 Jul 2015 22:50:49 +0900
Subject: [PATCH] Make TAP tests work on Windows.

On Windows, use listen_address=127.0.0.1 to allow connections. We were
already using "pg_regress --config-auth" to set up HBA appropriately.
The standard_initdb helper function now sets up the server's
unix_socket_directories or listen_addresses in the config file, so that
they don't need to be specified in the pg_ctl command line anymore. That
way, the pg_ctl invocations in test programs don't need to differ between
Windows and Unix.

Add another helper function to configure the server's pg_hba.conf to
allow replication connections. The configuration is done similarly to
pg_regress --config-auth: trust on domain sockets on Unix, and SSPI
authentication on Windows.

Replace calls to "cat" and "touch" programs with built-in perl code.

Add "vcregress tapcheck" command for launching the tests on Windows.

Michael Paquier
---
 doc/src/sgml/install-windows.sgml            |   8 ++
 src/Makefile.global.in                       |   2 +-
 src/bin/pg_basebackup/t/010_pg_basebackup.pl | 138 ++++++++++++++-------------
 src/bin/pg_ctl/t/001_start_stop.pl           |  14 ++-
 src/bin/pg_ctl/t/002_status.pl               |   4 -
 src/bin/pg_rewind/RewindTest.pm              |  25 ++---
 src/test/perl/TestLib.pm                     |  79 ++++++++++++---
 src/tools/msvc/clean.bat                     |   7 ++
 src/tools/msvc/vcregress.pl                  |  42 +++++++-
 9 files changed, 217 insertions(+), 102 deletions(-)

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..306fb1f 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
@@ -451,6 +452,13 @@ $ENV{CONFIG}="Debug";
    For more information about the regression tests, see
    <xref linkend="regress">.
   </para>
+
+  <para>
+   The TAP test suite that can be run with <parameter>tapcheck</> has
+   a dependency with the <application>Perl</> module
+   <ulink url="http://search.cpan.org/~toddr/IPC-Run-0.94/">IPC::Run</>.
+   It can be downloaded from CPAN, and it needs to be placed in PERL5LIB.
+  </para>
  </sect2>
 
  <sect2>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index e2f7211..59c9eed 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -339,7 +339,7 @@ endef
 
 define prove_check
 rm -rf $(srcdir)/tmp_check/log
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
 endef
 
 else
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index e47c3a0..40b6b76 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,6 +1,7 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
 use Test::More tests => 35;
 
@@ -25,11 +26,7 @@ if (open BADCHARS, ">>$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
 	close BADCHARS;
 }
 
-open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
-close HBA;
+configure_hba_for_replication "$tempdir/pgdata";
 system_or_bail 'pg_ctl', '-D', "$tempdir/pgdata", 'reload';
 
 command_fails(
@@ -57,61 +54,7 @@ command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft' ],
 	'tar format');
 ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
 
-my $superlongname = "superlongname_" . ("x" x 100);
-
-system_or_bail 'touch', "$tempdir/pgdata/$superlongname";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
-	'pg_basebackup tar with long name fails');
-unlink "$tempdir/pgdata/$superlongname";
-
-# Create a temporary directory in the system location and symlink it
-# to our physical temp location.  That way we can use shorter names
-# for the tablespace directories, which hopefully won't run afoul of
-# the 99 character length limit.
-my $shorter_tempdir = tempdir_short . "/tempdir";
-symlink "$tempdir", $shorter_tempdir;
-
-mkdir "$tempdir/tblspc1";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
-psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
-	'tar format with tablespaces');
-ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
-my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
-is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
-	'plain format with tablespaces fails without tablespace mapping');
-
-command_ok(
-	[   'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
-		"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
-	'plain format with tablespaces succeeds with tablespace mapping');
-ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
-opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
-ok( (   grep {
-			-l "$tempdir/backup1/pg_tblspc/$_"
-			  and readlink "$tempdir/backup1/pg_tblspc/$_" eq
-			  "$tempdir/tbackup/tblspc1"
-		  } readdir($dh)),
-	"tablespace symlink was updated");
-closedir $dh;
-
-mkdir "$tempdir/tbl=spc2";
-psql 'postgres', "DROP TABLE test1;";
-psql 'postgres', "DROP TABLESPACE tblspc1;";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
-command_ok(
-	[   'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
-		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
-	'mapping tablespace with = sign in path');
-ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
-psql 'postgres', "DROP TABLESPACE tblspc2;";
-
+# Test incorrect arguments
 command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
 	'-T with empty old directory fails');
@@ -132,9 +75,72 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
 	'-T with invalid format fails');
 
-mkdir "$tempdir/$superlongname";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-	'pg_basebackup tar with long symlink target');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
+# Tar format doesn't support filenames longer than 100 bytes.
+my $superlongname = "superlongname_" . ("x" x 100);
+my $superlongpath = "$tempdir/pgdata/$superlongname";
+
+open FILE, ">$superlongpath" or die "unable to create file $superlongpath";
+close FILE;
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
+	'pg_basebackup tar with long name fails');
+unlink "$tempdir/pgdata/$superlongname";
+
+# The following tests test symlinks. Windows doesn't have symlinks, so
+# skip on Windows.
+SKIP: {
+    skip "symlinks not supported on Windows", 10 if ($Config{osname} eq "MSWin32");
+
+	# Create a temporary directory in the system location and symlink it
+	# to our physical temp location.  That way we can use shorter names
+	# for the tablespace directories, which hopefully won't run afoul of
+	# the 99 character length limit.
+	my $shorter_tempdir = tempdir_short . "/tempdir";
+	symlink "$tempdir", $shorter_tempdir;
+
+	mkdir "$tempdir/tblspc1";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
+	psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
+			   'tar format with tablespaces');
+	ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
+	my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
+	is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
+
+	command_fails(
+		[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
+		'plain format with tablespaces fails without tablespace mapping');
+
+	command_ok(
+		[   'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
+			"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
+		'plain format with tablespaces succeeds with tablespace mapping');
+	ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
+	opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
+	ok( (   grep {
+		-l "$tempdir/backup1/pg_tblspc/$_"
+			and readlink "$tempdir/backup1/pg_tblspc/$_" eq
+			"$tempdir/tbackup/tblspc1"
+			} readdir($dh)),
+		"tablespace symlink was updated");
+	closedir $dh;
+
+	mkdir "$tempdir/tbl=spc2";
+	psql 'postgres', "DROP TABLE test1;";
+	psql 'postgres', "DROP TABLESPACE tblspc1;";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
+	command_ok(
+		[   'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
+			"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
+		'mapping tablespace with = sign in path');
+	ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
+	psql 'postgres', "DROP TABLESPACE tblspc2;";
+
+	mkdir "$tempdir/$superlongname";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			   'pg_basebackup tar with long symlink target');
+	psql 'postgres', "DROP TABLESPACE tblspc3;";
+}
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index bcceb57..015e4d8 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{PG_REGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
+else
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index ec0a2a7..31f7c72 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -10,10 +10,6 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 	4, 'pg_ctl status with nonexistent directory');
 
 standard_initdb "$tempdir/data";
-open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
-close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
 	3, 'pg_ctl status with server not running');
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index db5e90b..098c342 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -195,19 +195,14 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file(
-		"$test_master_datadir/pg_hba.conf", qq(
-local replication all trust
-));
+	configure_hba_for_replication $test_master_datadir;
 
-	system_or_bail('pg_ctl' , '-w',
-				   '-D' , $test_master_datadir,
-				   "-o", "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+	system_or_bail('pg_ctl', '-w',
+				   '-D', $test_master_datadir,
+				   '-o', "-p $port_master", 'start');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST} = $tempdir_short;
 }
 
 sub create_standby
@@ -228,8 +223,7 @@ recovery_target_timeline='latest'
 
 	# Start standby
 	system_or_bail('pg_ctl', '-w', '-D', $test_standby_datadir,
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_standby",
-				   'start');
+				   '-o', "-p $port_standby", 'start');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -265,7 +259,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail('pg_ctl', '-D', $test_master_datadir, 'stop', '-m', 'fast');
+	system_or_bail('pg_ctl', '-D', $test_master_datadir, '-m', 'fast', 'stop');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -283,8 +277,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail('pg_ctl', '-D', $test_standby_datadir, 'stop',
-					   '-m', 'fast');
+		system_or_bail('pg_ctl', '-D', $test_standby_datadir,
+					   '-m', 'fast', 'stop');
 		command_ok(['pg_rewind',
 					"--debug",
 					"--source-pgdata=$test_standby_datadir",
@@ -323,8 +317,7 @@ recovery_target_timeline='latest'
 
 	# Restart the master to check that rewind went correctly
 	system_or_bail('pg_ctl', '-w', '-D', $test_master_datadir,
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+				   '-o', "-p $port_master", 'start');
 
 	#### Now run the test-specific parts to check the result
 }
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 0193d57..39bce44 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,11 +3,13 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
   tempdir_short
   standard_initdb
+  configure_hba_for_replication
   start_test_server
   restart_test_server
   psql
@@ -112,29 +114,78 @@ sub tempdir_short
 	return File::Temp::tempdir(CLEANUP => 1);
 }
 
+# Initialize a new cluster for testing.
+#
+# The PGHOST environment variable is set to connect to the new cluster.
+#
+# Authentication is set up so that only the current OS user can access the
+# cluster. On Unix, we use Unix domain socket connections, with the socket in
+# a directory that's only accessible to the current user to ensure that.
+# On Windows, we use SSPI authentication to ensure the same (by pg_regress
+# --config-auth).
 sub standard_initdb
 {
 	my $pgdata = shift;
 	system_or_bail('initdb', '-D', "$pgdata", '-A' , 'trust', '-N');
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata);
+
+	my $tempdir_short = tempdir_short;
+
+	open CONF, ">>$pgdata/postgresql.conf";
+	print CONF "\n# Added by TestLib.pm)\n";
+	if ($Config{osname} eq "MSWin32")
+	{
+		print CONF "listen_addresses = '127.0.0.1'\n";
+	}
+	else
+	{
+		print CONF "unix_socket_directories = '$tempdir_short'\n";
+		print CONF "listen_addresses = ''\n";
+	}
+	close CONF;
+
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
+}
+
+# Set up the cluster to allow replication connections, in the same way that
+# standard_initdb does for normal connections.
+sub configure_hba_for_replication
+{
+	my $pgdata = shift;
+
+	open HBA, ">>$pgdata/pg_hba.conf";
+	print HBA "\n# Allow replication (set up by TestLib.pm)\n";
+	if ($Config{osname} ne "MSWin32")
+	{
+		print HBA "local replication all trust\n";
+	}
+	else
+	{
+		print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	}
+	close HBA;
 }
 
 my ($test_server_datadir, $test_server_logfile);
 
+
+# Initialize a new cluster for testing, and start it.
+#
+# The first argument is a temporary directory to create the cluster in.
+# If the second argument is true, the cluster configured to accept
+# replication connections.
 sub start_test_server
 {
 	my ($tempdir) = @_;
 	my $ret;
 
-	my $tempdir_short = tempdir_short;
-
 	print("### Starting test server in $tempdir\n");
 	standard_initdb "$tempdir/pgdata";
-	$ret = system_log('pg_ctl', '-D', "$tempdir/pgdata", '-w', '-l',
-	  "$tempdir/logfile", '-o',
-"--fsync=off -k \"$tempdir_short\" --listen-addresses='' --log-statement=all",
-					'start');
+
+	$ret = system_log('pg_ctl', '-D', "$tempdir/pgdata", '-w',
+	  '-l', "$tempdir/logfile", '-o', "--fsync=off --log-statement=all",
+	  'start');
+
 	if ($ret != 0)
 	{
 		print "# pg_ctl failed; logfile:\n";
@@ -142,7 +193,6 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$tempdir/logfile";
 }
@@ -216,7 +266,9 @@ sub command_exit_is
 	print("# Running: " . join(" ", @{$cmd}) ."\n");
 	my $h = start $cmd;
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
@@ -269,7 +321,12 @@ sub issues_sql_like
 	truncate $test_server_logfile, 0;
 	my $result = run_log($cmd);
 	ok($result, "@$cmd exit code 0");
-	my $log = `cat '$test_server_logfile'`;
+
+	# read the server log file into variable
+	open SERVERLOG, '<', $test_server_logfile or die "Could not open server log file $test_server_logfile: $!";
+	my $log = do { local $/; <SERVERLOG> };
+	close SERVERLOG;
+
 	like($log, $expected_sql, "$test_name: SQL found in server log");
 }
 
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index fbe3cc6..e3da6aa 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -88,6 +88,13 @@ if exist src\test\regress\regress.dll del /q src\test\regress\regress.dll
 if exist src\test\regress\refint.dll del /q src\test\regress\refint.dll
 if exist src\test\regress\autoinc.dll del /q src\test\regress\autoinc.dll
 
+if exist src\bin\initdb\tmp_check rd /s /q src\bin\initdb\tmp_check
+if exist src\bin\pg_basebackup\tmp_check rd /s /q src\bin\pg_basebackup\tmp_check
+if exist src\bin\pg_config\tmp_check rd /s /q src\bin\pg_config\tmp_check
+if exist src\bin\pg_ctl\tmp_check rd /s /q src\bin\pg_ctl\tmp_check
+if exist src\bin\pg_rewind\tmp_check rd /s /q src\bin\pg_rewind\tmp_check
+if exist src\bin\scripts\tmp_check rd /s /q src\bin\scripts\tmp_check
+
 REM Clean up datafiles built with contrib
 REM cd contrib
 REM for /r %%f in (*.sql) do if exist %%f.in del %%f
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index 6196383..7daa564 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,43 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\//);
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.4.6

#17Michael Paquier
michael.paquier@gmail.com
In reply to: Michael Paquier (#16)
1 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Sat, Jul 25, 2015 at 10:54 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

An updated patch is attached.

Attached is v9, that fixes conflicts with 01f6bb4 and recent commits
that added TAP tests in pg_basebackup series.
--
Michael

Attachments:

0001-TAP-tests-for-MSVC.patchbinary/octet-stream; name=0001-TAP-tests-for-MSVC.patchDownload
From 8e918448313fc6e9902ddeb71b0189600b58187c Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Sat, 25 Jul 2015 06:41:42 -0700
Subject: [PATCH] TAP tests for MSVC

---
 doc/src/sgml/install-windows.sgml            |   8 ++
 src/Makefile.global.in                       |   2 +-
 src/bin/pg_basebackup/t/010_pg_basebackup.pl | 141 ++++++++++++++-------------
 src/bin/pg_ctl/t/001_start_stop.pl           |  14 ++-
 src/bin/pg_ctl/t/002_status.pl               |   4 -
 src/bin/pg_rewind/RewindTest.pm              |  21 ++--
 src/test/perl/TestLib.pm                     |  77 +++++++++++++--
 src/tools/msvc/clean.bat                     |   7 ++
 src/tools/msvc/vcregress.pl                  |  42 +++++++-
 9 files changed, 215 insertions(+), 101 deletions(-)

diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
index d154b44..068c719 100644
--- a/doc/src/sgml/install-windows.sgml
+++ b/doc/src/sgml/install-windows.sgml
@@ -439,6 +439,7 @@ $ENV{CONFIG}="Debug";
 <userinput>vcregress modulescheck</userinput>
 <userinput>vcregress ecpgcheck</userinput>
 <userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
 <userinput>vcregress upgradecheck</userinput>
 </screen>
 
@@ -451,6 +452,13 @@ $ENV{CONFIG}="Debug";
    For more information about the regression tests, see
    <xref linkend="regress">.
   </para>
+
+  <para>
+   The TAP test suite that can be run with <parameter>tapcheck</> has
+   a dependency with the <application>Perl</> module
+   <ulink url="http://search.cpan.org/~toddr/IPC-Run-0.94/">IPC::Run</>
+   that needs to be then placed in PERL5LIB.
+  </para>
  </sect2>
 
  <sect2>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index e87885b..1704ae0 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -339,7 +339,7 @@ endef
 
 define prove_check
 rm -rf $(CURDIR)/tmp_check/log
-cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) 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) t/*.pl
 endef
 
 else
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index b605fa9..5994285 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -1,6 +1,7 @@
 use strict;
 use warnings;
 use Cwd;
+use Config;
 use TestLib;
 use Test::More tests => 51;
 
@@ -25,11 +26,7 @@ if (open BADCHARS, ">>$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
 	close BADCHARS;
 }
 
-open HBA, ">>$tempdir/pgdata/pg_hba.conf";
-print HBA "local replication all trust\n";
-print HBA "host replication all 127.0.0.1/32 trust\n";
-print HBA "host replication all ::1/128 trust\n";
-close HBA;
+configure_hba_for_replication "$tempdir/pgdata";
 system_or_bail 'pg_ctl', '-D', "$tempdir/pgdata", 'reload';
 
 command_fails(
@@ -62,61 +59,6 @@ command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft' ],
 	'tar format');
 ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
 
-my $superlongname = "superlongname_" . ("x" x 100);
-
-system_or_bail 'touch', "$tempdir/pgdata/$superlongname";
-command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
-	'pg_basebackup tar with long name fails');
-unlink "$tempdir/pgdata/$superlongname";
-
-# Create a temporary directory in the system location and symlink it
-# to our physical temp location.  That way we can use shorter names
-# for the tablespace directories, which hopefully won't run afoul of
-# the 99 character length limit.
-my $shorter_tempdir = tempdir_short . "/tempdir";
-symlink "$tempdir", $shorter_tempdir;
-
-mkdir "$tempdir/tblspc1";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
-psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
-	'tar format with tablespaces');
-ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
-my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
-is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
-
-command_fails(
-	[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
-	'plain format with tablespaces fails without tablespace mapping');
-
-command_ok(
-	[   'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
-		"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
-	'plain format with tablespaces succeeds with tablespace mapping');
-ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
-opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
-ok( (   grep {
-			-l "$tempdir/backup1/pg_tblspc/$_"
-			  and readlink "$tempdir/backup1/pg_tblspc/$_" eq
-			  "$tempdir/tbackup/tblspc1"
-		  } readdir($dh)),
-	"tablespace symlink was updated");
-closedir $dh;
-
-mkdir "$tempdir/tbl=spc2";
-psql 'postgres', "DROP TABLE test1;";
-psql 'postgres', "DROP TABLESPACE tblspc1;";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
-command_ok(
-	[   'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
-		"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
-	'mapping tablespace with = sign in path');
-ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
-
-psql 'postgres', "DROP TABLESPACE tblspc2;";
-
 command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
 	'-T with empty old directory fails');
@@ -137,12 +79,75 @@ command_fails(
 	[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
 	'-T with invalid format fails');
 
-mkdir "$tempdir/$superlongname";
-psql 'postgres',
-  "CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
-command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
-	'pg_basebackup tar with long symlink target');
-psql 'postgres', "DROP TABLESPACE tblspc3;";
+# Tar format doesn't support filenames longer than 100 bytes.
+my $superlongname = "superlongname_" . ("x" x 100);
+my $superlongpath = "$tempdir/pgdata/$superlongname";
+
+open FILE, ">$superlongpath" or die "unable to create file $superlongpath";
+close FILE;
+command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
+	'pg_basebackup tar with long name fails');
+unlink "$tempdir/pgdata/$superlongname";
+
+# The following tests test symlinks. Windows doesn't have symlinks, so
+# skip on Windows.
+SKIP: {
+    skip "symlinks not supported on Windows", 10 if ($Config{osname} eq "MSWin32");
+
+	# Create a temporary directory in the system location and symlink it
+	# to our physical temp location.  That way we can use shorter names
+	# for the tablespace directories, which hopefully won't run afoul of
+	# the 99 character length limit.
+	my $shorter_tempdir = tempdir_short . "/tempdir";
+	symlink "$tempdir", $shorter_tempdir;
+
+	mkdir "$tempdir/tblspc1";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
+	psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
+			   'tar format with tablespaces');
+	ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
+	my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
+	is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
+
+	command_fails(
+		[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
+		'plain format with tablespaces fails without tablespace mapping');
+
+	command_ok(
+		[   'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
+			"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
+		'plain format with tablespaces succeeds with tablespace mapping');
+	ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
+	opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
+	ok( (   grep {
+		-l "$tempdir/backup1/pg_tblspc/$_"
+			and readlink "$tempdir/backup1/pg_tblspc/$_" eq
+			"$tempdir/tbackup/tblspc1"
+			} readdir($dh)),
+		"tablespace symlink was updated");
+	closedir $dh;
+
+	mkdir "$tempdir/tbl=spc2";
+	psql 'postgres', "DROP TABLE test1;";
+	psql 'postgres', "DROP TABLESPACE tblspc1;";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
+	command_ok(
+		[   'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
+			"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
+		'mapping tablespace with = sign in path');
+	ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
+	psql 'postgres', "DROP TABLESPACE tblspc2;";
+
+	mkdir "$tempdir/$superlongname";
+	psql 'postgres',
+	"CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
+	command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+			   'pg_basebackup tar with long symlink target');
+	psql 'postgres', "DROP TABLESPACE tblspc3;";
+}
 
 command_ok([ 'pg_basebackup', '-D', "$tempdir/backupR", '-R' ],
 	'pg_basebackup -R runs');
@@ -168,8 +173,8 @@ my $lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE
 is($lsn, '', 'restart LSN of new slot is null');
 command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', 'stream', '-S', 'slot1' ],
 	'pg_basebackup -X stream with replication slot runs');
-$lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
-like($lsn, qr!^0/[0-9A-Z]{8}$!, 'restart LSN of slot has advanced');
+$lsn = psql 'postgres', q{SELECT pg_xlogfile_name(restart_lsn) FROM pg_replication_slots WHERE slot_name = 'slot1'};
+like($lsn, qr!^[0-9A-Z]{24}$!, 'restart LSN of slot has advanced');
 
 command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', 'stream', '-S', 'slot1', '-R' ],
 	'pg_basebackup with replication slot and -R runs');
diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl
index bcceb57..015e4d8 100644
--- a/src/bin/pg_ctl/t/001_start_stop.pl
+++ b/src/bin/pg_ctl/t/001_start_stop.pl
@@ -1,5 +1,6 @@
 use strict;
 use warnings;
+use Config;
 use TestLib;
 use Test::More tests => 17;
 
@@ -15,12 +16,19 @@ command_exit_is([ 'pg_ctl', 'start', '-D', "$tempdir/nonexistent" ],
 
 command_ok([ 'pg_ctl', 'initdb', '-D', "$tempdir/data" ], 'pg_ctl initdb');
 command_ok(
-	[   "$ENV{top_builddir}/src/test/regress/pg_regress", '--config-auth',
+	[ $ENV{PG_REGRESS}, '--config-auth',
 		"$tempdir/data" ],
 	'configure authentication');
 open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
+if ($Config{osname} ne "MSWin32")
+{
+	print CONF "listen_addresses = ''\n";
+	print CONF "unix_socket_directories = '$tempdir_short'\n";
+}
+else
+{
+	print CONF "listen_addresses = '127.0.0.1'\n";
+}
 close CONF;
 command_ok([ 'pg_ctl', 'start', '-D', "$tempdir/data", '-w' ],
 	'pg_ctl start -w');
diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl
index ec0a2a7..31f7c72 100644
--- a/src/bin/pg_ctl/t/002_status.pl
+++ b/src/bin/pg_ctl/t/002_status.pl
@@ -10,10 +10,6 @@ command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/nonexistent" ],
 	4, 'pg_ctl status with nonexistent directory');
 
 standard_initdb "$tempdir/data";
-open CONF, ">>$tempdir/data/postgresql.conf";
-print CONF "listen_addresses = ''\n";
-print CONF "unix_socket_directories = '$tempdir_short'\n";
-close CONF;
 
 command_exit_is([ 'pg_ctl', 'status', '-D', "$tempdir/data" ],
 	3, 'pg_ctl status with server not running');
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm
index 755ecb7..85edf2b 100644
--- a/src/bin/pg_rewind/RewindTest.pm
+++ b/src/bin/pg_rewind/RewindTest.pm
@@ -192,20 +192,15 @@ max_connections = 10
 ));
 
 	# Accept replication connections on master
-	append_to_file(
-		"$test_master_datadir/pg_hba.conf", qq(
-local replication all trust
-));
+	configure_hba_for_replication $test_master_datadir;
 
 	system_or_bail('pg_ctl' , '-w',
 				   '-D' , $test_master_datadir,
 				   '-l',  "$log_path/master.log",
-				   "-o", "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+				   "-o", "-p $port_master", 'start');
 
 	#### Now run the test-specific parts to initialize the master before setting
 	# up standby
-	$ENV{PGHOST} = $tempdir_short;
 }
 
 sub create_standby
@@ -227,8 +222,7 @@ recovery_target_timeline='latest'
 	# Start standby
 	system_or_bail('pg_ctl', '-w', '-D', $test_standby_datadir,
 				   '-l', "$log_path/standby.log",
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_standby",
-				   'start');
+				   '-o', "-p $port_standby", 'start');
 
 	# Wait until the standby has caught up with the primary, by polling
 	# pg_stat_replication.
@@ -264,7 +258,7 @@ sub run_pg_rewind
 	my $test_mode = shift;
 
 	# Stop the master and be ready to perform the rewind
-	system_or_bail('pg_ctl', '-D', $test_master_datadir, 'stop', '-m', 'fast');
+	system_or_bail('pg_ctl', '-D', $test_master_datadir, '-m', 'fast', 'stop');
 
 	# At this point, the rewind processing is ready to run.
 	# We now have a very simple scenario with a few diverged WAL record.
@@ -282,8 +276,8 @@ sub run_pg_rewind
 	{
 		# Do rewind using a local pgdata as source
 		# Stop the master and be ready to perform the rewind
-		system_or_bail('pg_ctl', '-D', $test_standby_datadir, 'stop',
-					   '-m', 'fast');
+		system_or_bail('pg_ctl', '-D', $test_standby_datadir,
+					   '-m', 'fast', 'stop');
 		command_ok(['pg_rewind',
 					"--debug",
 					"--source-pgdata=$test_standby_datadir",
@@ -323,8 +317,7 @@ recovery_target_timeline='latest'
 	# Restart the master to check that rewind went correctly
 	system_or_bail('pg_ctl', '-w', '-D', $test_master_datadir,
 				   '-l', "$log_path/master.log",
-				   '-o', "-k $tempdir_short --listen-addresses='' -p $port_master",
-				   'start');
+				   '-o', "-p $port_master", 'start');
 
 	#### Now run the test-specific parts to check the result
 }
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index 1f69931..c6d1cdd 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -3,11 +3,13 @@ package TestLib;
 use strict;
 use warnings;
 
+use Config;
 use Exporter 'import';
 our @EXPORT = qw(
   tempdir
   tempdir_short
   standard_initdb
+  configure_hba_for_replication
   start_test_server
   restart_test_server
   psql
@@ -119,29 +121,78 @@ sub tempdir_short
 	return File::Temp::tempdir(CLEANUP => 1);
 }
 
+# Initialize a new cluster for testing.
+#
+# The PGHOST environment variable is set to connect to the new cluster.
+#
+# Authentication is set up so that only the current OS user can access the
+# cluster. On Unix, we use Unix domain socket connections, with the socket in
+# a directory that's only accessible to the current user to ensure that.
+# On Windows, we use SSPI authentication to ensure the same (by pg_regress
+# --config-auth).
 sub standard_initdb
 {
 	my $pgdata = shift;
 	system_or_bail('initdb', '-D', "$pgdata", '-A' , 'trust', '-N');
-	system_or_bail("$ENV{top_builddir}/src/test/regress/pg_regress",
-		'--config-auth', $pgdata);
+	system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata);
+
+	my $tempdir_short = tempdir_short;
+
+	open CONF, ">>$pgdata/postgresql.conf";
+	print CONF "\n# Added by TestLib.pm)\n";
+	if ($Config{osname} eq "MSWin32")
+	{
+		print CONF "listen_addresses = '127.0.0.1'\n";
+	}
+	else
+	{
+		print CONF "unix_socket_directories = '$tempdir_short'\n";
+		print CONF "listen_addresses = ''\n";
+	}
+	close CONF;
+
+	$ENV{PGHOST}         = ($Config{osname} eq "MSWin32") ? "127.0.0.1" : $tempdir_short;
+}
+
+# Set up the cluster to allow replication connections, in the same way that
+# standard_initdb does for normal connections.
+sub configure_hba_for_replication
+{
+	my $pgdata = shift;
+
+	open HBA, ">>$pgdata/pg_hba.conf";
+	print HBA "\n# Allow replication (set up by TestLib.pm)\n";
+	if ($Config{osname} ne "MSWin32")
+	{
+		print HBA "local replication all trust\n";
+	}
+	else
+	{
+		print HBA "host replication all 127.0.0.1/32 sspi include_realm=1 map=regress\n";
+	}
+	close HBA;
 }
 
 my ($test_server_datadir, $test_server_logfile);
 
+
+# Initialize a new cluster for testing, and start it.
+#
+# The first argument is a temporary directory to create the cluster in.
+# If the second argument is true, the cluster configured to accept
+# replication connections.
 sub start_test_server
 {
 	my ($tempdir) = @_;
 	my $ret;
 
-	my $tempdir_short = tempdir_short;
-
 	print("### Starting test server in $tempdir\n");
 	standard_initdb "$tempdir/pgdata";
+
 	$ret = system_log('pg_ctl', '-D', "$tempdir/pgdata", '-w', '-l',
-	  "$log_path/postmaster.log", '-o',
-"--fsync=off -k \"$tempdir_short\" --listen-addresses='' --log-statement=all",
-					'start');
+	  "$log_path/postmaster.log", '-o', "--fsync=off --log-statement=all",
+	  'start');
+
 	if ($ret != 0)
 	{
 		print "# pg_ctl failed; logfile:\n";
@@ -149,7 +200,6 @@ sub start_test_server
 		BAIL_OUT("pg_ctl failed");
 	}
 
-	$ENV{PGHOST}         = $tempdir_short;
 	$test_server_datadir = "$tempdir/pgdata";
 	$test_server_logfile = "$log_path/postmaster.log";
 }
@@ -242,7 +292,9 @@ sub command_exit_is
 	print("# Running: " . join(" ", @{$cmd}) ."\n");
 	my $h = start $cmd;
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }
 
 sub program_help_ok
@@ -295,7 +347,12 @@ sub issues_sql_like
 	truncate $test_server_logfile, 0;
 	my $result = run_log($cmd);
 	ok($result, "@$cmd exit code 0");
-	my $log = `cat '$test_server_logfile'`;
+
+	# read the server log file into variable
+	open SERVERLOG, '<', $test_server_logfile or die "Could not open server log file $test_server_logfile: $!";
+	my $log = do { local $/; <SERVERLOG> };
+	close SERVERLOG;
+
 	like($log, $expected_sql, "$test_name: SQL found in server log");
 }
 
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
index fbe3cc6..e3da6aa 100755
--- a/src/tools/msvc/clean.bat
+++ b/src/tools/msvc/clean.bat
@@ -88,6 +88,13 @@ if exist src\test\regress\regress.dll del /q src\test\regress\regress.dll
 if exist src\test\regress\refint.dll del /q src\test\regress\refint.dll
 if exist src\test\regress\autoinc.dll del /q src\test\regress\autoinc.dll
 
+if exist src\bin\initdb\tmp_check rd /s /q src\bin\initdb\tmp_check
+if exist src\bin\pg_basebackup\tmp_check rd /s /q src\bin\pg_basebackup\tmp_check
+if exist src\bin\pg_config\tmp_check rd /s /q src\bin\pg_config\tmp_check
+if exist src\bin\pg_ctl\tmp_check rd /s /q src\bin\pg_ctl\tmp_check
+if exist src\bin\pg_rewind\tmp_check rd /s /q src\bin\pg_rewind\tmp_check
+if exist src\bin\scripts\tmp_check rd /s /q src\bin\scripts\tmp_check
+
 REM Clean up datafiles built with contrib
 REM cd contrib
 REM for /r %%f in (*.sql) do if exist %%f.in del %%f
diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl
index 6196383..7daa564 100644
--- a/src/tools/msvc/vcregress.pl
+++ b/src/tools/msvc/vcregress.pl
@@ -7,7 +7,9 @@ use strict;
 our $config;
 
 use Cwd;
+use File::Basename;
 use File::Copy;
+use File::Find ();
 
 use Install qw(Install);
 
@@ -32,7 +34,7 @@ if (-e "src/tools/msvc/buildenv.pl")
 
 my $what = shift || "";
 if ($what =~
-/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck)$/i
+/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|tapcheck)$/i
   )
 {
 	$what = uc $what;
@@ -79,6 +81,7 @@ my %command = (
 	CONTRIBCHECK   => \&contribcheck,
 	MODULESCHECK   => \&modulescheck,
 	ISOLATIONCHECK => \&isolationcheck,
+	TAPCHECK       => \&tapcheck,
 	UPGRADECHECK   => \&upgradecheck,);
 
 my $proc = $command{$what};
@@ -172,6 +175,43 @@ sub isolationcheck
 	exit $status if $status;
 }
 
+sub tapcheck
+{
+	InstallTemp();
+
+	my @args = ( "prove", "--verbose", "t/*.pl");
+
+	$ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}";
+	$ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}";
+	$ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress";
+
+	# Find out all the existing TAP tests by simply looking for t/
+	# in the tree.
+	my $tap_dirs = [];
+	my @top_dir = ($topdir);
+	File::Find::find(
+		{   wanted => sub {
+				/^t\z/s
+				  && push(@$tap_dirs, $File::Find::name);
+			  }
+		},
+		@top_dir);
+
+	# Process each test
+	foreach my $test_path (@$tap_dirs)
+	{
+		next if ($test_path =~ /\/ssl\//);
+
+		my $dir = dirname($test_path);
+		chdir $dir;
+		# Reset those values, they may have been changed by another test.
+		$ENV{TESTDIR} = "$dir";
+		system(@args);
+		my $status = $? >> 8;
+		exit $status if $status;
+	}
+}
+
 sub plcheck
 {
 	chdir $startdir;
-- 
2.4.6

#18Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Michael Paquier (#17)
Re: Supporting TAP tests with MSVC and Windows

On 07/29/2015 10:13 AM, Michael Paquier wrote:

On Sat, Jul 25, 2015 at 10:54 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

An updated patch is attached.

Attached is v9, that fixes conflicts with 01f6bb4 and recent commits
that added TAP tests in pg_basebackup series.

Thanks, committed with some more tweaking. Peter just added a
slurp_file() function to TestLib.pm, so I used that to replace the call
to 'cat' instead of my previous snippet. I also fixed the issue in the
pg_basebackup test, that LSN is not necessarily 8 characters long,
slightly differently. Calling pg_xlogfile_name seemed a bit indirect.

I expanded the documentation on how to download and install IPC::Run. I
instructed to add PERL5LIB to buildenv.pl, pointing it to the extracted
IPC-Run-0.94/lib directory. Your phrasing of "putting it into PERL5LIB"
was pretty vague, and in fact the PERL5LIB environment variable was
overwritten in vcregress.pl, so just setting the PERL5LIB variable
wouldn't have worked. I changed vcregress.pl to not do that.

I considered moving the instructions on downloading and installing
IPC::Run in the Requirements section, instead of the Running the
Regression Tests section. But there are additional instructions on
downloading and installing more dependencies in the Building the
Documentation section too. The other dependencies in the Requirements
section affect the built binaries. Well, except for the Diff utility.
We're not totally consistent, but I think it's OK as it is.

Also I added an equivalent of --enable-tap-tests for this MSVC stuff,
removed afterwards by Heikki. Do we want it or not?

On Unix, that option controls whether "make check-world" runs the TAP
tests, but there is no equivalent of "check-world" on Windows. Maybe
there should be, but as long as there isn't, the only thing that the
option did was to stop "vcregress tapcheck" from working, if didn't
enable it in the config file first. That seems silly, so I removed it.
We'll need it if we add an equivalent of "make check-world" to
vcregress, but let's cross that bridge when we get there.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Michael Paquier
michael.paquier@gmail.com
In reply to: Heikki Linnakangas (#18)
Re: Supporting TAP tests with MSVC and Windows

On Thu, Jul 30, 2015 at 1:37 AM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

On 07/29/2015 10:13 AM, Michael Paquier wrote:

On Sat, Jul 25, 2015 at 10:54 PM, Michael Paquier
<michael.paquier@gmail.com> wrote:

An updated patch is attached.

Attached is v9, that fixes conflicts with 01f6bb4 and recent commits
that added TAP tests in pg_basebackup series.

Thanks, committed with some more tweaking. Peter just added a slurp_file()
function to TestLib.pm, so I used that to replace the call to 'cat' instead
of my previous snippet. I also fixed the issue in the pg_basebackup test,
that LSN is not necessarily 8 characters long, slightly differently. Calling
pg_xlogfile_name seemed a bit indirect.

Thanks!
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#20Noah Misch
noah@leadboat.com
In reply to: Michael Paquier (#19)
Re: Supporting TAP tests with MSVC and Windows

This (commit 13d856e of 2015-07-29) added the following:

--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -242,7 +288,17 @@ sub command_exit_is
 	print("# Running: " . join(" ", @{$cmd}) ."\n");
 	my $h = start $cmd;
 	$h->finish();
-	is($h->result(0), $expected, $test_name);
+
+	# On Windows, the exit status of the process is returned directly as the
+	# process's exit code, while on Unix, it's returned in the high bits
+	# of the exit code (see WEXITSTATUS macro in the standard <sys/wait.h>
+	# header file). IPC::Run's result function always returns exit code >> 8,
+	# assuming the Unix convention, which will always return 0 on Windows as
+	# long as the process was not terminated by an exception. To work around
+	# that, use $h->full_result on Windows instead.
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
 }

That behavior came up again in the context of a newer IPC::Run test case. I'm
considering changing the IPC::Run behavior such that the above would have been
unnecessary. However, if I do, the above code would want to adapt to handle
pre-change and post-change IPC::Run versions. If you have an opinion on
whether or how IPC::Run should change, I welcome comments on
https://github.com/toddr/IPC-Run/issues/161.

#21Andrew Dunstan
andrew@dunslane.net
In reply to: Noah Misch (#20)
Re: Supporting TAP tests with MSVC and Windows

On 2022-08-21 Su 20:40, Noah Misch wrote:

This (commit 13d856e of 2015-07-29) added the following:

--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -242,7 +288,17 @@ sub command_exit_is
print("# Running: " . join(" ", @{$cmd}) ."\n");
my $h = start $cmd;
$h->finish();
-	is($h->result(0), $expected, $test_name);
+
+	# On Windows, the exit status of the process is returned directly as the
+	# process's exit code, while on Unix, it's returned in the high bits
+	# of the exit code (see WEXITSTATUS macro in the standard <sys/wait.h>
+	# header file). IPC::Run's result function always returns exit code >> 8,
+	# assuming the Unix convention, which will always return 0 on Windows as
+	# long as the process was not terminated by an exception. To work around
+	# that, use $h->full_result on Windows instead.
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
}

That behavior came up again in the context of a newer IPC::Run test case. I'm
considering changing the IPC::Run behavior such that the above would have been
unnecessary. However, if I do, the above code would want to adapt to handle
pre-change and post-change IPC::Run versions. If you have an opinion on
whether or how IPC::Run should change, I welcome comments on
https://github.com/toddr/IPC-Run/issues/161.

Assuming it changes, we'll have to have a version test here. I don't
think we can have a flag day where we suddenly require IPC::Run's
bleeding edge on Windows. So changing it is a good thing, but it won't
help us much.

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

#22Noah Misch
noah@leadboat.com
In reply to: Andrew Dunstan (#21)
1 attachment(s)
Re: Supporting TAP tests with MSVC and Windows

On Mon, Aug 22, 2022 at 09:44:42AM -0400, Andrew Dunstan wrote:

On 2022-08-21 Su 20:40, Noah Misch wrote:

This (commit 13d856e of 2015-07-29) added the following:

--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -242,7 +288,17 @@ sub command_exit_is
print("# Running: " . join(" ", @{$cmd}) ."\n");
my $h = start $cmd;
$h->finish();
-	is($h->result(0), $expected, $test_name);
+
+	# On Windows, the exit status of the process is returned directly as the
+	# process's exit code, while on Unix, it's returned in the high bits
+	# of the exit code (see WEXITSTATUS macro in the standard <sys/wait.h>
+	# header file). IPC::Run's result function always returns exit code >> 8,
+	# assuming the Unix convention, which will always return 0 on Windows as
+	# long as the process was not terminated by an exception. To work around
+	# that, use $h->full_result on Windows instead.
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
}

That behavior came up again in the context of a newer IPC::Run test case. I'm
considering changing the IPC::Run behavior such that the above would have been
unnecessary. However, if I do, the above code would want to adapt to handle
pre-change and post-change IPC::Run versions. If you have an opinion on
whether or how IPC::Run should change, I welcome comments on
https://github.com/toddr/IPC-Run/issues/161.

Assuming it changes, we'll have to have a version test here. I don't
think we can have a flag day where we suddenly require IPC::Run's
bleeding edge on Windows. So changing it is a good thing, but it won't
help us much.

IPC::Run git now has the change, and we may release soon. Here's what I plan
to push to make PostgreSQL cope.

Attachments:

ipc-run-result-w32-v1.patchtext/plain; charset=us-asciiDownload
Author:     Noah Misch <noah@leadboat.com>
Commit:     Noah Misch <noah@leadboat.com>

    Account for IPC::Run::result() Windows behavior change.
    
    This restores compatibility with the not-yet-released successor of
    version 20220807.0.  Back-patch to 9.4, which introduced this code.
    
    Reviewed by FIXME.
    
    Discussion: https://postgr.es/m/FIXME

diff --git a/src/test/perl/PostgreSQL/Test/Utils.pm b/src/test/perl/PostgreSQL/Test/Utils.pm
index 99d3345..b139190 100644
--- a/src/test/perl/PostgreSQL/Test/Utils.pm
+++ b/src/test/perl/PostgreSQL/Test/Utils.pm
@@ -782,15 +782,11 @@ sub command_exit_is
 	my $h = IPC::Run::start $cmd;
 	$h->finish();
 
-	# On Windows, the exit status of the process is returned directly as the
-	# process's exit code, while on Unix, it's returned in the high bits
-	# of the exit code (see WEXITSTATUS macro in the standard <sys/wait.h>
-	# header file). IPC::Run's result function always returns exit code >> 8,
-	# assuming the Unix convention, which will always return 0 on Windows as
-	# long as the process was not terminated by an exception. To work around
-	# that, use $h->full_results on Windows instead.
+	# Normally, if the child called exit(N), IPC::Run::result() returns N.  On
+	# Windows, with IPC::Run v20220807.0 and earlier, full_results() is the
+	# method that returns N (https://github.com/toddr/IPC-Run/issues/161).
 	my $result =
-	    ($Config{osname} eq "MSWin32")
+	  ($Config{osname} eq "MSWin32" && $IPC::Run::VERSION <= 20220807.0)
 	  ? ($h->full_results)[0]
 	  : $h->result(0);
 	is($result, $expected, $test_name);
#23Andrew Dunstan
andrew@dunslane.net
In reply to: Noah Misch (#22)
Re: Supporting TAP tests with MSVC and Windows

On 2022-11-17 Th 01:18, Noah Misch wrote:

On Mon, Aug 22, 2022 at 09:44:42AM -0400, Andrew Dunstan wrote:

On 2022-08-21 Su 20:40, Noah Misch wrote:

This (commit 13d856e of 2015-07-29) added the following:

--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -242,7 +288,17 @@ sub command_exit_is
print("# Running: " . join(" ", @{$cmd}) ."\n");
my $h = start $cmd;
$h->finish();
-	is($h->result(0), $expected, $test_name);
+
+	# On Windows, the exit status of the process is returned directly as the
+	# process's exit code, while on Unix, it's returned in the high bits
+	# of the exit code (see WEXITSTATUS macro in the standard <sys/wait.h>
+	# header file). IPC::Run's result function always returns exit code >> 8,
+	# assuming the Unix convention, which will always return 0 on Windows as
+	# long as the process was not terminated by an exception. To work around
+	# that, use $h->full_result on Windows instead.
+	my $result = ($Config{osname} eq "MSWin32") ?
+		($h->full_results)[0] : $h->result(0);
+	is($result, $expected, $test_name);
}

That behavior came up again in the context of a newer IPC::Run test case. I'm
considering changing the IPC::Run behavior such that the above would have been
unnecessary. However, if I do, the above code would want to adapt to handle
pre-change and post-change IPC::Run versions. If you have an opinion on
whether or how IPC::Run should change, I welcome comments on
https://github.com/toddr/IPC-Run/issues/161.

Assuming it changes, we'll have to have a version test here. I don't
think we can have a flag day where we suddenly require IPC::Run's
bleeding edge on Windows. So changing it is a good thing, but it won't
help us much.

IPC::Run git now has the change, and we may release soon. Here's what I plan
to push to make PostgreSQL cope.

LGTM

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com