Add TAP tests for client programs

Reviewed-by: Pavel Stěhule <pavel.stehule@gmail.com>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
This commit is contained in:
Peter Eisentraut 2014-04-14 21:33:46 -04:00
parent 7b5a9d61a8
commit 7d0f493f19
39 changed files with 745 additions and 3 deletions

View File

@ -66,9 +66,9 @@ check check-tests: all
check check-tests installcheck installcheck-parallel installcheck-tests:
$(MAKE) -C src/test/regress $@
$(call recurse,check-world,src/test src/pl src/interfaces/ecpg contrib,check)
$(call recurse,check-world,src/test src/pl src/interfaces/ecpg contrib src/bin,check)
$(call recurse,installcheck-world,src/test src/pl src/interfaces/ecpg contrib,installcheck)
$(call recurse,installcheck-world,src/test src/pl src/interfaces/ecpg contrib src/bin,installcheck)
GNUmakefile: GNUmakefile.in $(top_builddir)/config.status
./config.status $@

47
configure vendored
View File

@ -627,6 +627,7 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
vpath_build
PROVE
OSX
XSLTPROC
COLLATEINDEX
@ -14350,6 +14351,52 @@ fi
done
#
# Check for test tools
#
for ac_prog in prove
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_PROVE+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PROVE"; then
ac_cv_prog_PROVE="$PROVE" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PROVE="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
PROVE=$ac_cv_prog_PROVE
if test -n "$PROVE"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROVE" >&5
$as_echo "$PROVE" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$PROVE" && break
done
# Thread testing
# We have to run the thread test near the end so we have all our symbols

View File

@ -1817,6 +1817,11 @@ PGAC_PATH_COLLATEINDEX
AC_CHECK_PROGS(XSLTPROC, xsltproc)
AC_CHECK_PROGS(OSX, [osx sgml2xml sx])
#
# Check for test tools
#
AC_CHECK_PROGS(PROVE, prove)
# Thread testing
# We have to run the thread test near the end so we have all our symbols

View File

@ -333,7 +333,8 @@ su - postgres
<application>Perl</> 5.8 or later is needed to build from a Git checkout,
or if you changed the input files for any of the build steps that
use Perl scripts. If building on Windows you will need
<application>Perl</> in any case.
<application>Perl</> in any case. <application>Perl</application> is
also required to run some test suites.
</para>
</listitem>
</itemizedlist>

View File

@ -204,6 +204,12 @@ make installcheck-world
located in <filename>src/test/isolation</>.
</para>
</listitem>
<listitem>
<para>
Tests of client programs under <filename>src/bin</filename>. See
also <xref linkend="regress-tap">.
</para>
</listitem>
</itemizedlist>
<para>
@ -660,6 +666,28 @@ float8:out:i.86-.*-openbsd=float8-small-is-zero.out
</sect1>
<sect1 id="regress-tap">
<title>TAP Tests</title>
<para>
The client program tests under <filename>src/bin</filename> use the Perl
TAP tools and are run by <command>prove</command>. You can pass
command-line options to <command>prove</command> by setting
the <command>make</command> variable <varname>PROVE_FLAGS</>, for example:
<programlisting>
make -C src/bin check PROVE_FLAGS='--reverse'
</programlisting>
The default is <literal>--verbose</literal>. See the manual page
of <command>prove</command> for more information.
</para>
<para>
The tests written in Perl require the Perl
module <literal>IPC::Run</literal>, otherwise most tests will be skipped.
This module is available from CPAN or an operating system package.
</para>
</sect1>
<sect1 id="regress-coverage">
<title>Test Coverage Examination</title>

View File

@ -292,6 +292,22 @@ XGETTEXT = @XGETTEXT@
GZIP = gzip
BZIP2 = bzip2
# Testing
PROVE = @PROVE@
PG_PROVE_FLAGS = --ext='.pl' -I $(top_srcdir)/src/test/perl/
PROVE_FLAGS = --verbose
define prove_installcheck
PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS)
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
PATH="$(CURDIR)/tmp_check/install$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS)
endef
# Installation.
install_bin = @install_bin@

View File

@ -2,3 +2,5 @@
/localtime.c
/initdb
/tmp_check/

View File

@ -57,3 +57,10 @@ clean distclean maintainer-clean:
# ensure that changes in datadir propagate into object file
initdb.o: initdb.c $(top_builddir)/src/Makefile.global
check: all
$(prove_check)
installcheck:
$(prove_installcheck)

View File

@ -0,0 +1,37 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 14;
my $tempdir = TestLib::tempdir;
program_help_ok('initdb');
program_version_ok('initdb');
program_options_handling_ok('initdb');
command_ok(['initdb', "$tempdir/data"], 'basic initdb');
command_fails(['initdb', "$tempdir/data"], 'existing data directory');
command_ok(['initdb', '-N', "$tempdir/data2"], 'nosync');
command_ok(['initdb', '-S', "$tempdir/data2"], 'sync only');
command_fails(['initdb', '-S', "$tempdir/data3"], 'sync missing data directory');
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');
system_or_bail "rm -rf $tempdir/*";
command_fails(['initdb', "$tempdir/data", '-X', 'pgxlog'], 'relative xlog directory not allowed');
system_or_bail "rm -rf $tempdir/*";
mkdir "$tempdir/pgxlog";
command_ok(['initdb', "$tempdir/data", '-X', "$tempdir/pgxlog"], 'existing empty xlog directory');
system_or_bail "rm -rf $tempdir/*";
mkdir "$tempdir/pgxlog";
mkdir "$tempdir/pgxlog/lost+found";
command_fails(['initdb', "$tempdir/data", '-X', "$tempdir/pgxlog"], 'existing nonempty xlog directory');
system_or_bail "rm -rf $tempdir/*";
command_ok(['initdb', "$tempdir/data", '-T', 'german'], 'select default dictionary');

View File

@ -1,3 +1,5 @@
/pg_basebackup
/pg_receivexlog
/pg_recvlogical
/tmp_check/

View File

@ -48,3 +48,9 @@ clean distclean maintainer-clean:
rm -f pg_basebackup$(X) pg_receivexlog$(X) pg_recvlogical$(X) \
pg_basebackup.o pg_receivexlog.o pg_recvlogical.o \
$(OBJS)
check: all
$(prove_check)
installcheck:
$(prove_installcheck)

View File

@ -0,0 +1,90 @@
use strict;
use warnings;
use Cwd;
use TestLib;
use Test::More tests => 28;
program_help_ok('pg_basebackup');
program_version_ok('pg_basebackup');
program_options_handling_ok('pg_basebackup');
my $tempdir = tempdir;
start_test_server $tempdir;
command_fails(['pg_basebackup'], 'pg_basebackup needs target directory specified');
command_fails(['pg_basebackup', '-D', "$tempdir/backup"], 'pg_basebackup fails because of hba');
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;
system_or_bail 'pg_ctl', '-s', '-D', "$tempdir/pgdata", 'reload';
command_fails(['pg_basebackup', '-D', "$tempdir/backup"], 'pg_basebackup fails because of WAL configuration');
open CONF, ">>$tempdir/pgdata/postgresql.conf";
print CONF "max_wal_senders = 10\n";
print CONF "wal_level = archive\n";
close CONF;
restart_test_server;
command_ok(['pg_basebackup', '-D', "$tempdir/backup"], 'pg_basebackup runs');
ok(-f "$tempdir/backup/PG_VERSION", 'backup was created');
command_ok(['pg_basebackup', '-D', "$tempdir/backup2", '--xlogdir', "$tempdir/xlog2"], 'separate xlog directory');
ok(-f "$tempdir/backup2/PG_VERSION", 'backup was created');
ok(-d "$tempdir/xlog2/", 'xlog directory was created');
command_ok(['pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft'], 'tar format');
ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
mkdir "$tempdir/tblspc1";
psql 'postgres', "CREATE TABLESPACE tblspc1 LOCATION '$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$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 '$tempdir/tbl=spc2';";
command_ok(['pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
"-T$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');

View File

@ -0,0 +1,8 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 3;
program_help_ok('pg_receivexlog');
program_version_ok('pg_receivexlog');
program_options_handling_ok('pg_receivexlog');

View File

@ -1 +1,2 @@
/pg_config
/tmp_check/

View File

@ -47,3 +47,9 @@ uninstall:
clean distclean maintainer-clean:
rm -f pg_config$(X) $(OBJS)
check: all
$(prove_check)
installcheck:
$(prove_installcheck)

View File

@ -0,0 +1,12 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 7;
program_help_ok('pg_config');
program_version_ok('pg_config');
program_options_handling_ok('pg_config');
command_like(['pg_config', '--bindir'], qr/bin/, 'pg_config single option'); # XXX might be wrong
command_like(['pg_config', '--bindir', '--libdir'], qr/bin.*\n.*lib/, 'pg_config two options');
command_like(['pg_config', '--libdir', '--bindir'], qr/lib.*\n.*bin/, 'pg_config two options different order');
command_like(['pg_config'], qr/.*\n.*\n.*/, 'pg_config without options prints many lines');

View File

@ -1 +1,2 @@
/pg_controldata
/tmp_check/

View File

@ -33,3 +33,9 @@ uninstall:
clean distclean maintainer-clean:
rm -f pg_controldata$(X) $(OBJS)
check: all
$(prove_check)
installcheck:
$(prove_installcheck)

View File

@ -0,0 +1,14 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 6;
my $tempdir = TestLib::tempdir;
program_help_ok('pg_controldata');
program_version_ok('pg_controldata');
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";
command_like(['pg_controldata', "$tempdir/data"], qr/checkpoint/, 'pg_controldata produces output');

View File

@ -1 +1,2 @@
/pg_ctl
/tmp_check/

View File

@ -36,3 +36,9 @@ uninstall:
clean distclean maintainer-clean:
rm -f pg_ctl$(X) $(OBJS)
check: all
$(prove_check)
installcheck:
$(prove_installcheck)

View File

@ -0,0 +1,25 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 10;
my $tempdir = TestLib::tempdir;
program_help_ok('pg_ctl');
program_version_ok('pg_ctl');
program_options_handling_ok('pg_ctl');
command_ok(['pg_ctl', 'initdb', '-D', "$tempdir/data"], 'pg_ctl initdb');
open CONF, ">>$tempdir/data/postgresql.conf";
print CONF "listen_addresses = ''\n";
print CONF "unix_socket_directories = '$tempdir'\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'], 'second pg_ctl start succeeds');
command_ok(['pg_ctl', 'stop', '-D', "$tempdir/data", '-w', '-m', 'fast'], 'pg_ctl stop -w');
command_fails(['pg_ctl', 'stop', '-D', "$tempdir/data", '-w', '-m', 'fast'], 'second pg_ctl stop fails');
command_ok(['pg_ctl', 'restart', '-D', "$tempdir/data", '-w', '-m', 'fast'], 'pg_ctl restart with server not running');
command_ok(['pg_ctl', 'restart', '-D', "$tempdir/data", '-w', '-m', 'fast'], 'pg_ctl restart with server running');
system_or_bail 'pg_ctl', '-s', 'stop', '-D', "$tempdir/data", '-m', 'fast';

View File

@ -0,0 +1,19 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 2;
my $tempdir = TestLib::tempdir;
system_or_bail "initdb -D $tempdir/data -A trust >/dev/null";
open CONF, ">>$tempdir/data/postgresql.conf";
print CONF "listen_addresses = ''\n";
print CONF "unix_socket_directories = '$tempdir'\n";
close CONF;
command_exit_is(['pg_ctl', 'status', '-D', "$tempdir/data"], 3, 'pg_ctl status with server not running');
system_or_bail 'pg_ctl', '-s', '-l', "$tempdir/logfile", '-D', "$tempdir/data", '-w', 'start';
command_exit_is(['pg_ctl', 'status', '-D', "$tempdir/data"], 0, 'pg_ctl status with server running');
system_or_bail 'pg_ctl', '-s', 'stop', '-D', "$tempdir/data", '-m', 'fast';

View File

@ -14,3 +14,5 @@
/kwlookup.c
/mbprint.c
/print.c
/tmp_check/

View File

@ -68,3 +68,10 @@ clean distclean maintainer-clean:
rm -f $(addsuffix $(X), $(PROGRAMS)) $(addsuffix .o, $(PROGRAMS))
rm -f common.o dumputils.o kwlookup.o keywords.o print.o mbprint.o $(WIN32RES)
rm -f dumputils.c print.c mbprint.c kwlookup.c keywords.c
check: all
$(prove_check)
installcheck:
$(prove_installcheck)

View File

@ -0,0 +1,18 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 6;
program_help_ok('clusterdb');
program_version_ok('clusterdb');
program_options_handling_ok('clusterdb');
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['clusterdb', 'postgres'], qr/statement: CLUSTER;/, 'SQL CLUSTER run');
command_fails(['clusterdb', '-t', 'nonexistent', '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'], qr/statement: CLUSTER test1;/, 'cluster specific table');

View File

@ -0,0 +1,9 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 1;
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['clusterdb', '-a'], qr/statement: CLUSTER.*statement: CLUSTER/s, 'cluster all databases');

View File

@ -0,0 +1,16 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 6;
program_help_ok('createdb');
program_version_ok('createdb');
program_options_handling_ok('createdb');
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['createdb', 'foobar1'], qr/statement: CREATE DATABASE foobar1/, 'SQL CREATE DATABASE run');
issues_sql_like(['createdb', 'foobar2', '-l', 'C', '-E', 'LATIN1', '-T', 'template0'], qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/, 'create database with encoding');
command_fails(['createdb', 'foobar1'], 'fails if database already exists');

View File

@ -0,0 +1,18 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 6;
program_help_ok('createlang');
program_version_ok('createlang');
program_options_handling_ok('createlang');
my $tempdir = tempdir;
start_test_server $tempdir;
command_fails(['createlang', 'plpgsql', 'postgres'], 'fails if language already exists');
psql 'postgres', 'DROP EXTENSION plpgsql';
issues_sql_like(['createlang', 'plpgsql', 'postgres'], qr/statement: CREATE EXTENSION "plpgsql"/, 'SQL CREATE EXTENSION run');
command_like(['createlang', '--list', 'postgres'], qr/plpgsql/, 'list output');

View File

@ -0,0 +1,26 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 8;
program_help_ok('createuser');
program_version_ok('createuser');
program_options_handling_ok('createuser');
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['createuser', 'user1'],
qr/statement: CREATE ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;/,
'SQL CREATE USER run');
issues_sql_like(['createuser', '-L', 'role1'],
qr/statement: CREATE ROLE role1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN;/,
'create a non-login role');
issues_sql_like(['createuser', '-r', 'user2'],
qr/statement: CREATE ROLE user2 NOSUPERUSER NOCREATEDB CREATEROLE INHERIT LOGIN;/,
'create a CREATEROLE user');
issues_sql_like(['createuser', '-s', 'user3'],
qr/statement: CREATE ROLE user3 SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;/,
'create a superuser');
command_fails(['createuser', 'user1'], 'fails if role already exists');

View File

@ -0,0 +1,16 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 5;
program_help_ok('dropdb');
program_version_ok('dropdb');
program_options_handling_ok('dropdb');
my $tempdir = tempdir;
start_test_server $tempdir;
psql 'postgres', 'CREATE DATABASE foobar1';
issues_sql_like(['dropdb', 'foobar1'], qr/statement: DROP DATABASE foobar1/, 'SQL DROP DATABASE run');
command_fails(['dropdb', 'nonexistent'], 'fails with nonexistent database');

View File

@ -0,0 +1,15 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 5;
program_help_ok('droplang');
program_version_ok('droplang');
program_options_handling_ok('droplang');
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['droplang', 'plpgsql', 'postgres'], qr/statement: DROP EXTENSION "plpgsql"/, 'SQL DROP EXTENSION run');
command_fails(['droplang', 'nonexistent', 'postgres'], 'fails with nonexistent language');

View File

@ -0,0 +1,16 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 5;
program_help_ok('dropuser');
program_version_ok('dropuser');
program_options_handling_ok('dropuser');
my $tempdir = tempdir;
start_test_server $tempdir;
psql 'postgres', 'CREATE ROLE foobar1';
issues_sql_like(['dropuser', 'foobar1'], qr/statement: DROP ROLE foobar1/, 'SQL DROP ROLE run');
command_fails(['dropuser', 'nonexistent'], 'fails with nonexistent user');

View File

@ -0,0 +1,15 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 5;
program_help_ok('pg_isready');
program_version_ok('pg_isready');
program_options_handling_ok('pg_isready');
command_fails(['pg_isready'], 'fails with no server running');
my $tempdir = tempdir;
start_test_server $tempdir;
command_ok(['pg_isready'], 'succeeds with server running');

View File

@ -0,0 +1,21 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 7;
program_help_ok('reindexdb');
program_version_ok('reindexdb');
program_options_handling_ok('reindexdb');
my $tempdir = tempdir;
start_test_server $tempdir;
$ENV{PGOPTIONS} = '--client-min-messages=WARNING';
issues_sql_like(['reindexdb', 'postgres'], qr/statement: REINDEX DATABASE postgres;/, 'SQL REINDEX run');
psql 'postgres', 'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a);';
issues_sql_like(['reindexdb', 'postgres', '-t', 'test1'], qr/statement: REINDEX TABLE test1;/, 'reindex specific table');
issues_sql_like(['reindexdb', 'postgres', '-i', 'test1x'], qr/statement: REINDEX INDEX test1x;/, 'reindex specific index');
issues_sql_like(['reindexdb', 'postgres', '-s'], qr/statement: REINDEX SYSTEM postgres;/, 'reindex system tables');

View File

@ -0,0 +1,11 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 1;
my $tempdir = tempdir;
start_test_server $tempdir;
$ENV{PGOPTIONS} = '--client-min-messages=WARNING';
issues_sql_like(['reindexdb', '-a'], qr/statement: REINDEX.*statement: REINDEX/s, 'reindex all databases');

View File

@ -0,0 +1,17 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 8;
program_help_ok('vacuumdb');
program_version_ok('vacuumdb');
program_options_handling_ok('vacuumdb');
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['vacuumdb', 'postgres'], qr/statement: VACUUM;/, 'SQL VACUUM run');
issues_sql_like(['vacuumdb', '-f', 'postgres'], qr/statement: VACUUM \(FULL\);/, 'vacuumdb -f');
issues_sql_like(['vacuumdb', '-F', 'postgres'], qr/statement: VACUUM \(FREEZE\);/, 'vacuumdb -F');
issues_sql_like(['vacuumdb', '-z', 'postgres'], qr/statement: VACUUM \(ANALYZE\);/, 'vacuumdb -z');
issues_sql_like(['vacuumdb', '-Z', 'postgres'], qr/statement: ANALYZE;/, 'vacuumdb -z');

View File

@ -0,0 +1,9 @@
use strict;
use warnings;
use TestLib;
use Test::More tests => 1;
my $tempdir = tempdir;
start_test_server $tempdir;
issues_sql_like(['vacuumdb', '-a'], qr/statement: VACUUM.*statement: VACUUM/s, 'vacuum all databases');

186
src/test/perl/TestLib.pm Normal file
View File

@ -0,0 +1,186 @@
package TestLib;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(
tempdir
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('testXXXX', DIR => cwd(), CLEANUP => 1);
}
my ($test_server_datadir, $test_server_logfile);
sub start_test_server {
my ($tempdir) = @_;
my $ret;
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 --listen-addresses='' --log-statement=all", 'start';
if ($ret != 0) {
system('cat', "$tempdir/logfile");
BAIL_OUT("pg_ctl failed");
}
$ENV{PGHOST} = $tempdir;
$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;