<userinput>vcregress contribcheck</userinput>
<userinput>vcregress ecpgcheck</userinput>
<userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress tapcheck</userinput>
<userinput>vcregress upgradecheck</userinput>
</screen>
For more information about the regression tests, see
<xref linkend="regress">.
</para>
+
+ <para>
+ Running the TAP regression tests, with "vcregress tapcheck", requires an
+ additional Perl module to be installed:
+ <variablelist>
+ <varlistentry>
+ <term><productname>IPC::Run</productname></term>
+ <listitem><para>
+ As of this writing, <literal>IPC::Run</> is not included in the
+ ActiveState Perl installation, nor in the ActiveState Perl Package
+ Manager (PPM) library. To install, download the
+ <filename>IPC-Run-<version>.tar.gz</> source archive from CPAN,
+ at <ulink url="http://search.cpan.org/dist/IPC-Run/"></>, and
+ uncompress. Edit the <filename>buildenv.pl</> file, and add a PERL5LIB
+ variable to point to the <filename>lib</> subdirectory from the
+ extracted archive. For example:
+<programlisting>
+$ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
+</programlisting>
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
</sect2>
<sect2>
define prove_installcheck
rm -rf $(CURDIR)/tmp_check/log
-cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
+cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
endef
define prove_check
rm -rf $(CURDIR)/tmp_check/log
$(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)' 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)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) t/*.pl
endef
else
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(
'tar format');
ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
-# 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;";
+# The following tests test symlinks. Windows doesn't have symlinks, so
+# skip on Windows.
+SKIP: {
+ # 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.
+ skip "symlinks not supported on Windows", 9 if ($windows_os);
+
+ 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" ],
use strict;
use warnings;
+use Config;
use TestLib;
use Test::More tests => 16;
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";
+print CONF "fsync = off\n";
+if (! $windows_os)
+{
+ 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');
my $tempdir_short = TestLib::tempdir_short;
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');
my $ok = 1;
for my $fh (@$self) {
print $fh @_ or $ok = 0;
+ $fh->flush or $ok = 0;
}
return $ok;
}
tempdir
tempdir_short
standard_initdb
+ configure_hba_for_replication
start_test_server
restart_test_server
psql
+ slurp_dir
+ slurp_file
system_or_bail
system_log
run_log
sub tempdir
{
- return File::Temp::tempdir('tmp_testXXXX', DIR => $ENV{TESTDIR} || cwd(), CLEANUP => 1);
+ return File::Temp::tempdir(
+ 'tmp_testXXXX',
+ DIR => $ENV{TESTDIR} || cwd(),
+ CLEANUP => 1);
}
sub tempdir_short
{
+
# Use a separate temp dir outside the build tree for the
# Unix-domain socket, to avoid file name length issues.
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";
+ print CONF "fsync = off\n";
+ if ($windows_os)
+ {
+ 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} = $windows_os ? "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 (! $windows_os)
+ {
+ 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 in given directory, and start it.
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', "--log-statement=all",
+ 'start');
+
if ($ret != 0)
{
print "# pg_ctl failed; logfile:\n";
BAIL_OUT("pg_ctl failed");
}
- $ENV{PGHOST} = $tempdir_short;
$test_server_datadir = "$tempdir/pgdata";
$test_server_logfile = "$log_path/postmaster.log";
}
sub psql
{
my ($dbname, $sql) = @_;
+ my ($stdout, $stderr);
print("# Running SQL command: $sql\n");
- run [ 'psql', '-X', '-q', '-d', $dbname, '-f', '-' ], '<', \$sql or die;
+ run [ 'psql', '-X', '-A', '-t', '-q', '-d', $dbname, '-f', '-' ], '<', \$sql, '>', \$stdout, '2>', \$stderr or die;
+ chomp $stdout;
+ $stdout =~ s/\r//g if $Config{osname} eq 'msys';
+ return $stdout;
+}
+
+sub slurp_dir
+{
+ my ($dir) = @_;
+ opendir(my $dh, $dir) or die;
+ my @direntries = readdir $dh;
+ closedir $dh;
+ return @direntries;
+}
+
+sub slurp_file
+{
+ local $/;
+ local @ARGV = @_;
+ my $contents = <>;
+ $contents =~ s/\r//g if $Config{osname} eq 'msys';
+ return $contents;
}
sub system_or_bail
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);
}
sub program_help_ok
truncate $test_server_logfile, 0;
my $result = run_log($cmd);
ok($result, "@$cmd exit code 0");
- my $log = `cat '$test_server_logfile'`;
+ my $log = slurp_file($test_server_logfile);
like($log, $expected_sql, "$test_name: SQL found in server log");
}
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\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
our $config;
use Cwd;
+use File::Basename;
use File::Copy;
+use File::Find ();
use Install qw(Install);
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;
$schedule = "parallel" if ($what eq 'CHECK' || $what =~ /PARALLEL/);
}
-$ENV{PERL5LIB} = "$topdir/src/tools/msvc";
+$ENV{PERL5LIB} = "$topdir/src/tools/msvc;$ENV{PERL5LIB}";
my $maxconn = "";
$maxconn = "--max_connections=$ENV{MAX_CONNECTIONS}"
ECPGCHECK => \&ecpgcheck,
CONTRIBCHECK => \&contribcheck,
ISOLATIONCHECK => \&isolationcheck,
+ TAPCHECK => \&tapcheck,
UPGRADECHECK => \&upgradecheck,);
my $proc = $command{$what};
exit $status if $status;
}
+sub tapcheck
+{
+ my @args = ( "prove", "--verbose", "t/*.pl");
+ my $mstat = 0;
+
+ $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 looking for t/ directories
+ # 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)
+ {
+ my $dir = dirname($test_path);
+ my $tmp_root = "$dir/tmp_check";
+ (mkdir $tmp_root || die $!) unless -d $tmp_root;
+ my $tmp_install = "$tmp_root/install";
+ Install($tmp_install, "all", $config);
+ chdir $dir;
+ # Reset those values, they may have been changed by another test.
+ $ENV{TESTDIR} = "$dir";
+ system(@args);
+ my $status = $? >> 8;
+ $mstat ||= $status;
+ }
+ exit $mstat if $mstat;
+}
+
sub plcheck
{
chdir "../../pl";