
Creating the Unix-domain socket in the build directory can run into name-length limitations. Therefore, create the socket file in the default temporary directory of the operating system. Keep the temporary data directory etc. in the build tree.
226 lines
4.4 KiB
Perl
226 lines
4.4 KiB
Perl
package TestLib;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Exporter 'import';
|
|
our @EXPORT = qw(
|
|
tempdir
|
|
tempdir_short
|
|
start_test_server
|
|
restart_test_server
|
|
psql
|
|
system_or_bail
|
|
|
|
command_ok
|
|
command_fails
|
|
command_exit_is
|
|
program_help_ok
|
|
program_version_ok
|
|
program_options_handling_ok
|
|
command_like
|
|
issues_sql_like
|
|
);
|
|
|
|
use Cwd;
|
|
use File::Spec;
|
|
use File::Temp ();
|
|
use Test::More;
|
|
|
|
BEGIN
|
|
{
|
|
eval {
|
|
require IPC::Run;
|
|
import IPC::Run qw(run start);
|
|
1;
|
|
} or do
|
|
{
|
|
plan skip_all => "IPC::Run not available";
|
|
}
|
|
}
|
|
|
|
delete $ENV{PGCONNECT_TIMEOUT};
|
|
delete $ENV{PGDATA};
|
|
delete $ENV{PGDATABASE};
|
|
delete $ENV{PGHOSTADDR};
|
|
delete $ENV{PGREQUIRESSL};
|
|
delete $ENV{PGSERVICE};
|
|
delete $ENV{PGSSLMODE};
|
|
delete $ENV{PGUSER};
|
|
|
|
if (!$ENV{PGPORT})
|
|
{
|
|
$ENV{PGPORT} = 65432;
|
|
}
|
|
|
|
$ENV{PGPORT} = int($ENV{PGPORT}) % 65536;
|
|
|
|
|
|
#
|
|
# Helper functions
|
|
#
|
|
|
|
|
|
sub tempdir
|
|
{
|
|
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);
|
|
}
|
|
|
|
my ($test_server_datadir, $test_server_logfile);
|
|
|
|
sub start_test_server
|
|
{
|
|
my ($tempdir) = @_;
|
|
my $ret;
|
|
|
|
my $tempdir_short = tempdir_short;
|
|
|
|
system "initdb -D $tempdir/pgdata -A trust -N >/dev/null";
|
|
$ret = system 'pg_ctl', '-D', "$tempdir/pgdata", '-s', '-w', '-l',
|
|
"$tempdir/logfile", '-o',
|
|
"--fsync=off -k $tempdir_short --listen-addresses='' --log-statement=all",
|
|
'start';
|
|
|
|
if ($ret != 0)
|
|
{
|
|
system('cat', "$tempdir/logfile");
|
|
BAIL_OUT("pg_ctl failed");
|
|
}
|
|
|
|
$ENV{PGHOST} = $tempdir_short;
|
|
$test_server_datadir = "$tempdir/pgdata";
|
|
$test_server_logfile = "$tempdir/logfile";
|
|
}
|
|
|
|
sub restart_test_server
|
|
{
|
|
system 'pg_ctl', '-s', '-D', $test_server_datadir, '-w', '-l',
|
|
$test_server_logfile, 'restart';
|
|
}
|
|
|
|
END
|
|
{
|
|
if ($test_server_datadir)
|
|
{
|
|
system 'pg_ctl', '-D', $test_server_datadir, '-s', '-w', '-m',
|
|
'immediate', 'stop';
|
|
}
|
|
}
|
|
|
|
sub psql
|
|
{
|
|
my ($dbname, $sql) = @_;
|
|
run [ 'psql', '-X', '-q', '-d', $dbname, '-f', '-' ], '<', \$sql or die;
|
|
}
|
|
|
|
sub system_or_bail
|
|
{
|
|
system(@_) == 0 or BAIL_OUT("system @_ failed: $?");
|
|
}
|
|
|
|
|
|
#
|
|
# Test functions
|
|
#
|
|
|
|
|
|
sub command_ok
|
|
{
|
|
my ($cmd, $test_name) = @_;
|
|
my $result = run $cmd, '>', File::Spec->devnull(), '2>',
|
|
File::Spec->devnull();
|
|
ok($result, $test_name);
|
|
}
|
|
|
|
sub command_fails
|
|
{
|
|
my ($cmd, $test_name) = @_;
|
|
my $result = run $cmd, '>', File::Spec->devnull(), '2>',
|
|
File::Spec->devnull();
|
|
ok(!$result, $test_name);
|
|
}
|
|
|
|
sub command_exit_is
|
|
{
|
|
my ($cmd, $expected, $test_name) = @_;
|
|
my $h = start $cmd, '>', File::Spec->devnull(), '2>',
|
|
File::Spec->devnull();
|
|
$h->finish();
|
|
is($h->result(0), $expected, $test_name);
|
|
}
|
|
|
|
sub program_help_ok
|
|
{
|
|
my ($cmd) = @_;
|
|
subtest "$cmd --help" => sub {
|
|
plan tests => 3;
|
|
my ($stdout, $stderr);
|
|
my $result = run [ $cmd, '--help' ], '>', \$stdout, '2>', \$stderr;
|
|
ok($result, "$cmd --help exit code 0");
|
|
isnt($stdout, '', "$cmd --help goes to stdout");
|
|
is($stderr, '', "$cmd --help nothing to stderr");
|
|
};
|
|
}
|
|
|
|
sub program_version_ok
|
|
{
|
|
my ($cmd) = @_;
|
|
subtest "$cmd --version" => sub {
|
|
plan tests => 3;
|
|
my ($stdout, $stderr);
|
|
my $result = run [ $cmd, '--version' ], '>', \$stdout, '2>', \$stderr;
|
|
ok($result, "$cmd --version exit code 0");
|
|
isnt($stdout, '', "$cmd --version goes to stdout");
|
|
is($stderr, '', "$cmd --version nothing to stderr");
|
|
};
|
|
}
|
|
|
|
sub program_options_handling_ok
|
|
{
|
|
my ($cmd) = @_;
|
|
subtest "$cmd options handling" => sub {
|
|
plan tests => 2;
|
|
my ($stdout, $stderr);
|
|
my $result = run [ $cmd, '--not-a-valid-option' ], '>', \$stdout,
|
|
'2>', \$stderr;
|
|
ok(!$result, "$cmd with invalid option nonzero exit code");
|
|
isnt($stderr, '', "$cmd with invalid option prints error message");
|
|
};
|
|
}
|
|
|
|
sub command_like
|
|
{
|
|
my ($cmd, $expected_stdout, $test_name) = @_;
|
|
subtest $test_name => sub {
|
|
plan tests => 3;
|
|
my ($stdout, $stderr);
|
|
my $result = run $cmd, '>', \$stdout, '2>', \$stderr;
|
|
ok($result, "@$cmd exit code 0");
|
|
is($stderr, '', "@$cmd no stderr");
|
|
like($stdout, $expected_stdout, "$test_name: matches");
|
|
};
|
|
}
|
|
|
|
sub issues_sql_like
|
|
{
|
|
my ($cmd, $expected_sql, $test_name) = @_;
|
|
subtest $test_name => sub {
|
|
plan tests => 2;
|
|
my ($stdout, $stderr);
|
|
truncate $test_server_logfile, 0;
|
|
my $result = run $cmd, '>', \$stdout, '2>', \$stderr;
|
|
ok($result, "@$cmd exit code 0");
|
|
my $log = `cat $test_server_logfile`;
|
|
like($log, $expected_sql, "$test_name: SQL found in server log");
|
|
};
|
|
}
|
|
|
|
1;
|