mirror of
https://github.com/postgres/postgres.git
synced 2025-07-26 01:22:12 +03:00
Rewrite ECPG regression test driver in C, by splitting the standard
regression driver into two parts and reusing half of it. Required to run ECPG tests without a shell on MSVC builds. Fix ECPG thread tests for MSVC build (incl output files). Joachim Wieland and Magnus Hagander
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
# $PostgreSQL: pgsql/src/interfaces/ecpg/test/Makefile,v 1.67 2007/03/29 12:02:24 meskes Exp $
|
# $PostgreSQL: pgsql/src/interfaces/ecpg/test/Makefile,v 1.68 2007/06/12 11:07:30 mha Exp $
|
||||||
|
|
||||||
subdir = src/interfaces/ecpg/test
|
subdir = src/interfaces/ecpg/test
|
||||||
top_builddir = ../../../..
|
top_builddir = ../../../..
|
||||||
@ -8,12 +8,12 @@ include $(top_builddir)/src/Makefile.global
|
|||||||
# this is also defined in test/connect/Makefile
|
# this is also defined in test/connect/Makefile
|
||||||
TEMP_PORT = 5$(DEF_PGPORT)
|
TEMP_PORT = 5$(DEF_PGPORT)
|
||||||
|
|
||||||
|
# where to find psql for testing an existing installation
|
||||||
|
PSQLDIR = $(bindir)
|
||||||
|
|
||||||
# default encoding
|
# default encoding
|
||||||
MULTIBYTE = SQL_ASCII
|
MULTIBYTE = SQL_ASCII
|
||||||
|
|
||||||
# threading
|
|
||||||
THREAD := $(shell grep -q "define ENABLE_THREAD_SAFETY" ../include/ecpg_config.h && echo "--enable-threading")
|
|
||||||
|
|
||||||
# locale
|
# locale
|
||||||
NOLOCALE =
|
NOLOCALE =
|
||||||
ifdef NO_LOCALE
|
ifdef NO_LOCALE
|
||||||
@ -26,6 +26,15 @@ else
|
|||||||
abs_builddir := $(shell pwd -W)
|
abs_builddir := $(shell pwd -W)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# stuff to pass into build of pg_regress
|
||||||
|
EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \
|
||||||
|
'-DMAKEPROG="$(MAKE)"' \
|
||||||
|
'-DSHELLPROG="$(SHELL)"' \
|
||||||
|
'-DDLSUFFIX="$(DLSUFFIX)"'
|
||||||
|
|
||||||
|
REGRESSINCLUDES = "-I$(top_builddir)/src/test/regress"
|
||||||
|
REGRESSDRIVER = "$(top_builddir)/src/test/regress/pg_regress.o"
|
||||||
|
|
||||||
all install installdirs uninstall distprep:
|
all install installdirs uninstall distprep:
|
||||||
$(MAKE) -C connect $@
|
$(MAKE) -C connect $@
|
||||||
$(MAKE) -C expected $@
|
$(MAKE) -C expected $@
|
||||||
@ -45,20 +54,21 @@ clean distclean maintainer-clean:
|
|||||||
$(MAKE) -C compat_informix $@
|
$(MAKE) -C compat_informix $@
|
||||||
$(MAKE) -C thread $@
|
$(MAKE) -C thread $@
|
||||||
rm -rf tmp_check results log
|
rm -rf tmp_check results log
|
||||||
rm -f pg_regress regression.diffs
|
rm -f pg_regress regression.diffs pg_regress_ecpg.o
|
||||||
|
|
||||||
all: pg_regress
|
# Build regression test driver
|
||||||
|
|
||||||
pg_regress: pg_regress.sh $(top_builddir)/src/Makefile.global
|
all: pg_regress$(X)
|
||||||
sed -e 's,@bindir@,$(bindir),g' \
|
|
||||||
-e 's,@libdir@,$(libdir),g' \
|
pg_regress$(X): pg_regress_ecpg.o
|
||||||
-e 's,@pkglibdir@,$(pkglibdir),g' \
|
$(CC) $(CFLAGS) $^ $(REGRESSDRIVER) $(LDFLAGS) $(LIBS) -o $@
|
||||||
-e 's,@datadir@,$(datadir),g' \
|
|
||||||
-e 's/@VERSION@/$(VERSION)/g' \
|
# dependencies ensure that path changes propagate
|
||||||
-e 's/@host_tuple@/$(host_tuple)/g' \
|
pg_regress_ecpg.o: pg_regress_ecpg.c $(top_builddir)/src/port/pg_config_paths.h
|
||||||
-e 's,@GMAKE@,$(MAKE),g' \
|
$(CC) $(CFLAGS) $(CPPFLAGS) -I$(top_builddir)/src/port $(REGRESSINCLUDES) $(EXTRADEFS) -c -o $@ $<
|
||||||
-e 's/@enable_shared@/$(enable_shared)/g' \
|
|
||||||
$< >$@
|
$(top_builddir)/src/port/pg_config_paths.h: $(top_builddir)/src/Makefile.global
|
||||||
|
$(MAKE) -C $(top_builddir)/src/port pg_config_paths.h
|
||||||
|
|
||||||
# When doing a VPATH build, copy over the .pgc, .stdout and .stderr
|
# When doing a VPATH build, copy over the .pgc, .stdout and .stderr
|
||||||
# files so that the driver script can find them. We have to use an
|
# files so that the driver script can find them. We have to use an
|
||||||
@ -78,11 +88,11 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
check: all
|
check: all
|
||||||
sh ./pg_regress --dbname=regress1 --temp-install --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) $(THREAD)
|
./pg_regress --dbname=regress1,connectdb --top-builddir=$(top_builddir) --temp-install=./tmp_check --temp-port=$(TEMP_PORT) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) $(THREAD) --schedule=$(srcdir)/ecpg_schedule --create-role=connectuser,connectdb
|
||||||
|
|
||||||
# the same options, but with --listen-on-tcp
|
# the same options, but with --listen-on-tcp
|
||||||
checktcp: all
|
checktcp: all
|
||||||
sh ./pg_regress --dbname=regress1 --temp-install --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) --listen-on-tcp $(THREAD)
|
./pg_regress --dbname=regress1,connectdb --top-builddir=$(top_builddir) --temp-install=./tmp_check --temp-port=$(TEMP_PORT) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) $(THREAD) --schedule=$(srcdir)/ecpg_schedule_tcp --create-role=connectuser,connectdb --host=localhost
|
||||||
|
|
||||||
installcheck: all
|
installcheck: all
|
||||||
sh ./pg_regress --dbname=regress1 --top-builddir=$(top_builddir) --load-language=plpgsql $(NOLOCALE)
|
./pg_regress --psqldir=$(PSQLDIR) --dbname=regress1,connectdb --top-builddir=$(top_builddir) --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE) $(THREAD) --schedule=$(srcdir)/ecpg_schedule --create-role=connectuser,connectdb
|
||||||
|
40
src/interfaces/ecpg/test/ecpg_schedule
Normal file
40
src/interfaces/ecpg/test/ecpg_schedule
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
test: compat_informix/dec_test
|
||||||
|
test: compat_informix/charfuncs
|
||||||
|
test: compat_informix/rfmtdate
|
||||||
|
test: compat_informix/rfmtlong
|
||||||
|
test: compat_informix/rnull
|
||||||
|
test: compat_informix/test_informix
|
||||||
|
test: compat_informix/test_informix2
|
||||||
|
test: connect/test2
|
||||||
|
test: connect/test3
|
||||||
|
test: connect/test4
|
||||||
|
test: connect/test5
|
||||||
|
test: pgtypeslib/dt_test
|
||||||
|
test: pgtypeslib/dt_test2
|
||||||
|
test: pgtypeslib/num_test
|
||||||
|
test: pgtypeslib/num_test2
|
||||||
|
test: preproc/comment
|
||||||
|
test: preproc/define
|
||||||
|
test: preproc/init
|
||||||
|
test: preproc/type
|
||||||
|
test: preproc/variable
|
||||||
|
test: preproc/whenever
|
||||||
|
test: sql/array
|
||||||
|
test: sql/binary
|
||||||
|
test: sql/code100
|
||||||
|
test: sql/copystdout
|
||||||
|
test: sql/define
|
||||||
|
test: sql/desc
|
||||||
|
test: sql/dynalloc
|
||||||
|
test: sql/dynalloc2
|
||||||
|
test: sql/dyntest
|
||||||
|
test: sql/execute
|
||||||
|
test: sql/fetch
|
||||||
|
test: sql/func
|
||||||
|
test: sql/indicators
|
||||||
|
test: sql/quote
|
||||||
|
test: sql/show
|
||||||
|
test: sql/insupd
|
||||||
|
test: sql/parser
|
||||||
|
test: thread/thread
|
||||||
|
test: thread/thread_implicit
|
@ -153,15 +153,19 @@ void *test_thread(void *arg)
|
|||||||
|
|
||||||
|
|
||||||
/* build up connection name, and connect to database */
|
/* build up connection name, and connect to database */
|
||||||
|
#ifndef WIN32_ONLY_COMPILER
|
||||||
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#else
|
||||||
|
_snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#endif
|
||||||
/* exec sql whenever sqlerror sqlprint ; */
|
/* exec sql whenever sqlerror sqlprint ; */
|
||||||
#line 107 "thread.pgc"
|
#line 111 "thread.pgc"
|
||||||
|
|
||||||
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , l_connection, 0);
|
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , l_connection, 0);
|
||||||
#line 108 "thread.pgc"
|
#line 112 "thread.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 108 "thread.pgc"
|
#line 112 "thread.pgc"
|
||||||
|
|
||||||
if( sqlca.sqlcode != 0 )
|
if( sqlca.sqlcode != 0 )
|
||||||
{
|
{
|
||||||
@ -169,10 +173,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
|
|||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
{ ECPGtrans(__LINE__, l_connection, "begin transaction ");
|
{ ECPGtrans(__LINE__, l_connection, "begin transaction ");
|
||||||
#line 114 "thread.pgc"
|
#line 118 "thread.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 114 "thread.pgc"
|
#line 118 "thread.pgc"
|
||||||
|
|
||||||
|
|
||||||
/* insert into test_thread table */
|
/* insert into test_thread table */
|
||||||
@ -183,10 +187,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
|
|||||||
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int),
|
ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int),
|
||||||
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
||||||
#line 119 "thread.pgc"
|
#line 123 "thread.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 119 "thread.pgc"
|
#line 123 "thread.pgc"
|
||||||
|
|
||||||
if( sqlca.sqlcode != 0 )
|
if( sqlca.sqlcode != 0 )
|
||||||
printf("%s: ERROR: insert failed!\n", l_connection);
|
printf("%s: ERROR: insert failed!\n", l_connection);
|
||||||
@ -194,16 +198,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
|
|||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
{ ECPGtrans(__LINE__, l_connection, "commit");
|
{ ECPGtrans(__LINE__, l_connection, "commit");
|
||||||
#line 125 "thread.pgc"
|
#line 129 "thread.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 125 "thread.pgc"
|
#line 129 "thread.pgc"
|
||||||
|
|
||||||
{ ECPGdisconnect(__LINE__, l_connection);
|
{ ECPGdisconnect(__LINE__, l_connection);
|
||||||
#line 126 "thread.pgc"
|
#line 130 "thread.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 126 "thread.pgc"
|
#line 130 "thread.pgc"
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -154,15 +154,19 @@ void *test_thread(void *arg)
|
|||||||
|
|
||||||
|
|
||||||
/* build up connection name, and connect to database */
|
/* build up connection name, and connect to database */
|
||||||
|
#ifndef WIN32_ONLY_COMPILER
|
||||||
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#else
|
||||||
|
_snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#endif
|
||||||
/* exec sql whenever sqlerror sqlprint ; */
|
/* exec sql whenever sqlerror sqlprint ; */
|
||||||
#line 108 "thread_implicit.pgc"
|
#line 112 "thread_implicit.pgc"
|
||||||
|
|
||||||
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , l_connection, 0);
|
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , l_connection, 0);
|
||||||
#line 109 "thread_implicit.pgc"
|
#line 113 "thread_implicit.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 109 "thread_implicit.pgc"
|
#line 113 "thread_implicit.pgc"
|
||||||
|
|
||||||
if( sqlca.sqlcode != 0 )
|
if( sqlca.sqlcode != 0 )
|
||||||
{
|
{
|
||||||
@ -170,10 +174,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
|
|||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
{ ECPGtrans(__LINE__, NULL, "begin transaction ");
|
{ ECPGtrans(__LINE__, NULL, "begin transaction ");
|
||||||
#line 115 "thread_implicit.pgc"
|
#line 119 "thread_implicit.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 115 "thread_implicit.pgc"
|
#line 119 "thread_implicit.pgc"
|
||||||
|
|
||||||
|
|
||||||
/* insert into test_thread table */
|
/* insert into test_thread table */
|
||||||
@ -184,10 +188,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
|
|||||||
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
|
||||||
ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int),
|
ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int),
|
||||||
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
|
||||||
#line 120 "thread_implicit.pgc"
|
#line 124 "thread_implicit.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 120 "thread_implicit.pgc"
|
#line 124 "thread_implicit.pgc"
|
||||||
|
|
||||||
if( sqlca.sqlcode != 0 )
|
if( sqlca.sqlcode != 0 )
|
||||||
printf("%s: ERROR: insert failed!\n", l_connection);
|
printf("%s: ERROR: insert failed!\n", l_connection);
|
||||||
@ -195,16 +199,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
|
|||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
{ ECPGtrans(__LINE__, NULL, "commit");
|
{ ECPGtrans(__LINE__, NULL, "commit");
|
||||||
#line 126 "thread_implicit.pgc"
|
#line 130 "thread_implicit.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 126 "thread_implicit.pgc"
|
#line 130 "thread_implicit.pgc"
|
||||||
|
|
||||||
{ ECPGdisconnect(__LINE__, l_connection);
|
{ ECPGdisconnect(__LINE__, l_connection);
|
||||||
#line 127 "thread_implicit.pgc"
|
#line 131 "thread_implicit.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint();}
|
if (sqlca.sqlcode < 0) sqlprint();}
|
||||||
#line 127 "thread_implicit.pgc"
|
#line 131 "thread_implicit.pgc"
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -1,811 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# $PostgreSQL: pgsql/src/interfaces/ecpg/test/pg_regress.sh,v 1.19 2007/03/29 12:02:24 meskes Exp $
|
|
||||||
|
|
||||||
me=`basename $0`
|
|
||||||
|
|
||||||
message(){
|
|
||||||
_dashes='==============' # 14
|
|
||||||
_spaces=' ' # 38
|
|
||||||
_msg=`echo "$1$_spaces" | cut -c 1-38`
|
|
||||||
echo "$_dashes $_msg $_dashes"
|
|
||||||
}
|
|
||||||
|
|
||||||
build_help(){
|
|
||||||
help="\
|
|
||||||
PostgreSQL regression test driver
|
|
||||||
|
|
||||||
Usage: $me [options...] [extra tests...]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--dbname=DB use database DB (default \`regression')
|
|
||||||
--debug turn on debug mode in programs that are run
|
|
||||||
--inputdir=DIR take input files from DIR (default \`.')
|
|
||||||
--load-language=lang load the named language before running the
|
|
||||||
tests; can appear multiple times
|
|
||||||
--max-connections=N maximum number of concurrent connections
|
|
||||||
(default is 0 meaning unlimited)
|
|
||||||
--multibyte=ENCODING use ENCODING as the multibyte encoding, and
|
|
||||||
also run a test by the same name
|
|
||||||
--outputdir=DIR place output files in DIR (default \`.')
|
|
||||||
--temp-install[=DIR] create a temporary installation (in DIR)
|
|
||||||
--no-locale use C locale
|
|
||||||
$1
|
|
||||||
Options for \`temp-install' mode:
|
|
||||||
--top-builddir=DIR (relative) path to top level build directory
|
|
||||||
--temp-port=PORT port number to start temp postmaster on
|
|
||||||
--listen-on-tcp listen on the tcp port as well
|
|
||||||
--enable-threading expect threading to be enabled
|
|
||||||
|
|
||||||
Options for using an existing installation:
|
|
||||||
--host=HOST use postmaster running on HOST
|
|
||||||
--port=PORT use postmaster running at PORT
|
|
||||||
--user=USER connect as USER
|
|
||||||
|
|
||||||
The exit status is 0 if all tests passed, 1 if some tests failed, and 2
|
|
||||||
if the tests could not be run for some reason.
|
|
||||||
|
|
||||||
Report bugs to <pgsql-bugs@postgresql.org>."
|
|
||||||
}
|
|
||||||
|
|
||||||
init_vars(){
|
|
||||||
: ${TMPDIR=/tmp}
|
|
||||||
TMPFILE=$TMPDIR/pg_regress.$$
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Initialize default settings
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
: ${inputdir=.}
|
|
||||||
: ${outputdir=.}
|
|
||||||
|
|
||||||
libdir='@libdir@'
|
|
||||||
bindir='@bindir@'
|
|
||||||
datadir='@datadir@'
|
|
||||||
host_platform='@host_tuple@'
|
|
||||||
enable_shared='@enable_shared@'
|
|
||||||
VERSION=@VERSION@
|
|
||||||
|
|
||||||
unset mode
|
|
||||||
unset schedule
|
|
||||||
unset debug
|
|
||||||
unset nolocale
|
|
||||||
unset top_builddir
|
|
||||||
unset temp_install
|
|
||||||
unset multibyte
|
|
||||||
|
|
||||||
dbname=regression
|
|
||||||
hostname=localhost
|
|
||||||
maxconnections=0
|
|
||||||
temp_port=65432
|
|
||||||
load_langs=""
|
|
||||||
listen_on_tcp=no
|
|
||||||
enable_threading=no
|
|
||||||
|
|
||||||
: ${GMAKE='@GMAKE@'}
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_general_options(){
|
|
||||||
# ----------
|
|
||||||
# Parse command line options
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
while [ "$#" -gt 0 ]
|
|
||||||
do
|
|
||||||
case $1 in
|
|
||||||
--help|-\?)
|
|
||||||
echo "$help"
|
|
||||||
exit 0;;
|
|
||||||
--version)
|
|
||||||
echo "pg_regress (PostgreSQL $VERSION)"
|
|
||||||
exit 0;;
|
|
||||||
--dbname=*)
|
|
||||||
dbname=`expr "x$1" : "x--dbname=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--debug)
|
|
||||||
debug=yes
|
|
||||||
shift;;
|
|
||||||
--inputdir=*)
|
|
||||||
inputdir=`expr "x$1" : "x--inputdir=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--listen-on-tcp)
|
|
||||||
listen_on_tcp=yes
|
|
||||||
shift;;
|
|
||||||
--enable-threading)
|
|
||||||
enable_threading=yes
|
|
||||||
shift;;
|
|
||||||
--load-language=*)
|
|
||||||
lang=`expr "x$1" : "x--load-language=\(.*\)"`
|
|
||||||
load_langs="$load_langs $lang"
|
|
||||||
unset lang
|
|
||||||
shift;;
|
|
||||||
--multibyte=*)
|
|
||||||
multibyte=`expr "x$1" : "x--multibyte=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--no-locale)
|
|
||||||
nolocale=yes
|
|
||||||
shift;;
|
|
||||||
--temp-install)
|
|
||||||
temp_install=./tmp_check
|
|
||||||
shift;;
|
|
||||||
--temp-install=*)
|
|
||||||
temp_install=`expr "x$1" : "x--temp-install=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--max-connections=*)
|
|
||||||
maxconnections=`expr "x$1" : "x--max-connections=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--outputdir=*)
|
|
||||||
outputdir=`expr "x$1" : "x--outputdir=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--top-builddir=*)
|
|
||||||
top_builddir=`expr "x$1" : "x--top-builddir=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--temp-port=*)
|
|
||||||
temp_port=`expr "x$1" : "x--temp-port=\(.*\)"`
|
|
||||||
shift;;
|
|
||||||
--host=*)
|
|
||||||
PGHOST=`expr "x$1" : "x--host=\(.*\)"`
|
|
||||||
export PGHOST
|
|
||||||
unset PGHOSTADDR
|
|
||||||
shift;;
|
|
||||||
--port=*)
|
|
||||||
PGPORT=`expr "x$1" : "x--port=\(.*\)"`
|
|
||||||
export PGPORT
|
|
||||||
shift;;
|
|
||||||
--user=*)
|
|
||||||
PGUSER=`expr "x$1" : "x--user=\(.*\)"`
|
|
||||||
export PGUSER
|
|
||||||
shift;;
|
|
||||||
-*)
|
|
||||||
# on error, this will not return but exit
|
|
||||||
parse_special_options "$1"
|
|
||||||
shift;;
|
|
||||||
*)
|
|
||||||
extra_tests="$extra_tests $1"
|
|
||||||
shift;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setup_environment_variables(){
|
|
||||||
|
|
||||||
# This function has two parts. Part 1 sets/unsets environment variables
|
|
||||||
# independently of what options the script receives.
|
|
||||||
# Part 2 later sets environment variables with respect to the
|
|
||||||
# options given.
|
|
||||||
|
|
||||||
# =======
|
|
||||||
# PART 1: Options independent stuff goes here
|
|
||||||
# =======
|
|
||||||
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Unset locale settings
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
unset LC_COLLATE LC_CTYPE LC_MONETARY LC_MESSAGES LC_NUMERIC LC_TIME LC_ALL LANG LANGUAGE
|
|
||||||
|
|
||||||
# On Windows the default locale may not be English, so force it
|
|
||||||
case $host_platform in
|
|
||||||
*-*-cygwin*|*-*-mingw32*)
|
|
||||||
LANG=en
|
|
||||||
export LANG
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# On some platforms we can't use Unix sockets.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
case $host_platform in
|
|
||||||
*-*-cygwin* | *-*-mingw32*)
|
|
||||||
listen_on_tcp=yes
|
|
||||||
esac
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Set up diff to ignore horizontal white space differences.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
case $host_platform in
|
|
||||||
*-*-sco3.2v5*)
|
|
||||||
DIFFFLAGS=-b;;
|
|
||||||
*)
|
|
||||||
DIFFFLAGS=-w;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Check for echo -n vs echo \c
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
if echo '\c' | grep c >/dev/null 2>&1; then
|
|
||||||
ECHO_N='echo -n'
|
|
||||||
ECHO_C=''
|
|
||||||
else
|
|
||||||
ECHO_N='echo'
|
|
||||||
ECHO_C='\c'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Set backend timezone and datestyle explicitly
|
|
||||||
#
|
|
||||||
# To pass the horology test in its current form, the postmaster must be
|
|
||||||
# started with PGDATESTYLE=ISO, while the frontend must be started with
|
|
||||||
# PGDATESTYLE=Postgres. We set the postmaster values here and change
|
|
||||||
# to the frontend settings after the postmaster has been started.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
PGTZ='PST8PDT'; export PGTZ
|
|
||||||
PGDATESTYLE='ISO, MDY'; export PGDATESTYLE
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Set up SQL shell for the test.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
psql_test_options="-a -q -X $psql_options"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# =======
|
|
||||||
# PART 2: Options dependent stuff goes here
|
|
||||||
# =======
|
|
||||||
|
|
||||||
LOGDIR=$outputdir/log
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# warn of Cygwin likely failure if maxconnections = 0
|
|
||||||
# and we are running parallel tests
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
case $host_platform in
|
|
||||||
*-*-cygwin*)
|
|
||||||
case "$schedule" in
|
|
||||||
*parallel_schedule*)
|
|
||||||
if [ $maxconnections -eq 0 ] ; then
|
|
||||||
echo Using unlimited parallel connections is likely to fail or hang on Cygwin.
|
|
||||||
echo Try \"$me --max-connections=n\" or \"gmake MAX_CONNECTIONS=n check\"
|
|
||||||
echo with n = 5 or 10 if this happens.
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Set up multibyte environment
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
if [ -n "$multibyte" ]; then
|
|
||||||
PGCLIENTENCODING=$multibyte
|
|
||||||
export PGCLIENTENCODING
|
|
||||||
encoding_opt="-E $multibyte"
|
|
||||||
else
|
|
||||||
unset PGCLIENTENCODING
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
do_temp_install(){
|
|
||||||
if echo x"$temp_install" | grep -v '^x/' >/dev/null 2>&1; then
|
|
||||||
temp_install="`pwd`/$temp_install"
|
|
||||||
fi
|
|
||||||
|
|
||||||
bindir=$temp_install/install/$bindir
|
|
||||||
libdir=$temp_install/install/$libdir
|
|
||||||
datadir=$temp_install/install/$datadir
|
|
||||||
PGDATA=$temp_install/data
|
|
||||||
|
|
||||||
if [ "$unix_sockets" = no ]; then
|
|
||||||
PGHOST=$hostname
|
|
||||||
export PGHOST
|
|
||||||
unset PGHOSTADDR
|
|
||||||
else
|
|
||||||
unset PGHOST
|
|
||||||
unset PGHOSTADDR
|
|
||||||
fi
|
|
||||||
|
|
||||||
# since Makefile isn't very bright, check for out-of-range temp_port
|
|
||||||
if [ "$temp_port" -ge 1024 -a "$temp_port" -le 65535 ] ; then
|
|
||||||
PGPORT=$temp_port
|
|
||||||
else
|
|
||||||
PGPORT=65432
|
|
||||||
fi
|
|
||||||
export PGPORT
|
|
||||||
|
|
||||||
# Get rid of environment stuff that might cause psql to misbehave
|
|
||||||
# while contacting our temp installation
|
|
||||||
unset PGDATABASE PGUSER PGSERVICE PGSSLMODE PGREQUIRESSL PGCONNECT_TIMEOUT
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Set up shared library paths, needed by psql and pg_encoding
|
|
||||||
# (if you run multibyte). LD_LIBRARY_PATH covers many platforms.
|
|
||||||
# DYLD_LIBRARY_PATH works on Darwin, and maybe other Mach-based systems.
|
|
||||||
# LIBPATH is for AIX.
|
|
||||||
# Feel free to account for others as well.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
if [ -n "$LD_LIBRARY_PATH" ]; then
|
|
||||||
LD_LIBRARY_PATH="$libdir:$LD_LIBRARY_PATH"
|
|
||||||
else
|
|
||||||
LD_LIBRARY_PATH=$libdir
|
|
||||||
fi
|
|
||||||
export LD_LIBRARY_PATH
|
|
||||||
|
|
||||||
if [ -n "$DYLD_LIBRARY_PATH" ]; then
|
|
||||||
DYLD_LIBRARY_PATH="$libdir:$DYLD_LIBRARY_PATH"
|
|
||||||
else
|
|
||||||
DYLD_LIBRARY_PATH=$libdir
|
|
||||||
fi
|
|
||||||
export DYLD_LIBRARY_PATH
|
|
||||||
|
|
||||||
if [ -n "$LIBPATH" ]; then
|
|
||||||
LIBPATH="$libdir:$LIBPATH"
|
|
||||||
else
|
|
||||||
LIBPATH=$libdir
|
|
||||||
fi
|
|
||||||
export LIBPATH
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Windows needs shared libraries in PATH. (Only those linked into
|
|
||||||
# executables, not dlopen'ed ones)
|
|
||||||
# ----------
|
|
||||||
case $host_platform in
|
|
||||||
*-*-cygwin*|*-*-mingw32*)
|
|
||||||
PATH=$libdir:$PATH
|
|
||||||
export PATH
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -d "$temp_install" ]; then
|
|
||||||
message "removing existing temp installation"
|
|
||||||
rm -rf "$temp_install"
|
|
||||||
fi
|
|
||||||
|
|
||||||
message "creating temporary installation"
|
|
||||||
if [ ! -d "$LOGDIR" ]; then
|
|
||||||
mkdir -p "$LOGDIR" || { (exit 2); exit; }
|
|
||||||
fi
|
|
||||||
$GMAKE -C "$top_builddir" DESTDIR="$temp_install/install" install with_perl=no with_python=no >"$LOGDIR/install.log" 2>&1
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
echo
|
|
||||||
echo "$me: installation failed"
|
|
||||||
echo "Examine $LOGDIR/install.log for the reason."
|
|
||||||
echo
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
message "initializing database system"
|
|
||||||
[ "$debug" = yes ] && initdb_options="--debug"
|
|
||||||
[ "$nolocale" = yes ] && initdb_options="$initdb_options --no-locale"
|
|
||||||
"$bindir/initdb" -D "$PGDATA" -L "$datadir" --noclean $initdb_options >"$LOGDIR/initdb.log" 2>&1
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
echo
|
|
||||||
echo "$me: initdb failed"
|
|
||||||
echo "Examine $LOGDIR/initdb.log for the reason."
|
|
||||||
echo
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Start postmaster
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
message "starting postmaster"
|
|
||||||
[ "$debug" = yes ] && postmaster_options="$postmaster_options -d 5"
|
|
||||||
if [ "$listen_on_tcp" = yes ]; then
|
|
||||||
postmaster_options="$postmaster_options -c listen_addresses=$hostname"
|
|
||||||
else
|
|
||||||
postmaster_options="$postmaster_options -c listen_addresses="
|
|
||||||
fi
|
|
||||||
"$bindir/postmaster" -D "$PGDATA" -F $postmaster_options >"$LOGDIR/postmaster.log" 2>&1 &
|
|
||||||
postmaster_pid=$!
|
|
||||||
|
|
||||||
# Wait till postmaster is able to accept connections (normally only
|
|
||||||
# a second or so, but Cygwin is reportedly *much* slower). Don't
|
|
||||||
# wait forever, however.
|
|
||||||
i=0
|
|
||||||
max=60
|
|
||||||
until "$bindir/psql" -X $psql_options postgres </dev/null 2>/dev/null
|
|
||||||
do
|
|
||||||
i=`expr $i + 1`
|
|
||||||
if [ $i -ge $max ]
|
|
||||||
then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if kill -0 $postmaster_pid >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
: still starting up
|
|
||||||
else
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
if kill -0 $postmaster_pid >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
echo "running on port $PGPORT with pid $postmaster_pid"
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
echo "$me: postmaster did not start"
|
|
||||||
echo "Examine $LOGDIR/postmaster.log for the reason."
|
|
||||||
echo
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
dont_temp_install(){
|
|
||||||
# ----------
|
|
||||||
# Windows needs shared libraries in PATH. (Only those linked into
|
|
||||||
# executables, not dlopen'ed ones)
|
|
||||||
# ----------
|
|
||||||
case $host_platform in
|
|
||||||
*-*-cygwin*|*-*-mingw32*)
|
|
||||||
PATH=$libdir:$PATH
|
|
||||||
export PATH
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -n "$PGPORT" ]; then
|
|
||||||
port_info="port $PGPORT"
|
|
||||||
else
|
|
||||||
port_info="default port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$PGHOST" ]; then
|
|
||||||
echo "(using postmaster on $PGHOST, $port_info)"
|
|
||||||
else
|
|
||||||
if [ "$unix_sockets" = no ]; then
|
|
||||||
echo "(using postmaster on localhost, $port_info)"
|
|
||||||
else
|
|
||||||
echo "(using postmaster on Unix socket, $port_info)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_client_environment_variables(){
|
|
||||||
PGDATESTYLE='Postgres'
|
|
||||||
export PGDATESTYLE
|
|
||||||
}
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Exit trap to remove temp file and shut down postmaster
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
# Note: There are some stupid shells (even among recent ones) that
|
|
||||||
# ignore the argument to exit (as in `exit 1') if there is an exit
|
|
||||||
# trap. The trap (and thus the shell script) will then always exit
|
|
||||||
# with the result of the last shell command before the `exit'. Hence
|
|
||||||
# we have to write `(exit x); exit' below this point.
|
|
||||||
|
|
||||||
exit_trap(){
|
|
||||||
savestatus=$1
|
|
||||||
if [ -n "$postmaster_pid" ]; then
|
|
||||||
kill -2 "$postmaster_pid"
|
|
||||||
wait "$postmaster_pid"
|
|
||||||
unset postmaster_pid
|
|
||||||
fi
|
|
||||||
rm -f "$TMPFILE" && exit $savestatus
|
|
||||||
}
|
|
||||||
|
|
||||||
sig_trap() {
|
|
||||||
savestatus=$1
|
|
||||||
echo; echo "caught signal"
|
|
||||||
if [ -n "$postmaster_pid" ]; then
|
|
||||||
echo "signalling fast shutdown to postmaster with pid $postmaster_pid"
|
|
||||||
kill -2 "$postmaster_pid"
|
|
||||||
wait "$postmaster_pid"
|
|
||||||
unset postmaster_pid
|
|
||||||
fi
|
|
||||||
(exit $savestatus); exit
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_database(){
|
|
||||||
# this receives the name of the database to set up as its argument
|
|
||||||
"$bindir/psql" -q -X $psql_options -c "\
|
|
||||||
alter database \"$1\" set lc_messages to 'C';
|
|
||||||
alter database \"$1\" set lc_monetary to 'C';
|
|
||||||
alter database \"$1\" set lc_numeric to 'C';
|
|
||||||
alter database \"$1\" set lc_time to 'C';" "$1"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "$me: could not set database default locales"
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Install any requested PL languages
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
if [ "$enable_shared" = yes ]; then
|
|
||||||
for lang in xyzzy $load_langs ; do
|
|
||||||
if [ "$lang" != "xyzzy" ]; then
|
|
||||||
message "installing $lang"
|
|
||||||
"$bindir/createlang" $psql_options $lang "$1"
|
|
||||||
if [ $? -ne 0 ] && [ $? -ne 2 ]; then
|
|
||||||
echo "$me: createlang $lang failed"
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
drop_database(){
|
|
||||||
message "dropping database \"$1\""
|
|
||||||
"$bindir/dropdb" $psql_options "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
create_database(){
|
|
||||||
# ----------
|
|
||||||
# We use template0 so that any installation-local cruft in template1
|
|
||||||
# will not mess up the tests.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
message "creating database \"$1\""
|
|
||||||
"$bindir/createdb" $encoding_opt $psql_options --template template0 "$1"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "$me: createdb failed"
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
setup_database "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
database_cleanup(){
|
|
||||||
# ----------
|
|
||||||
# Remove regressuser* and regressgroup* user accounts.
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
message "dropping regression test user accounts"
|
|
||||||
"$bindir/psql" -q -X $psql_options -c 'DROP GROUP regressgroup1; DROP GROUP regressgroup2; DROP USER regressuser1, regressuser2, regressuser3, regressuser4;' $dbname 2>/dev/null
|
|
||||||
if [ $? -eq 2 ]; then
|
|
||||||
echo "$me: could not drop user accounts"
|
|
||||||
(exit 2); exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
postmaster_shutdown(){
|
|
||||||
# ----------
|
|
||||||
# Server shutdown
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
if [ -n "$postmaster_pid" ]; then
|
|
||||||
message "shutting down postmaster"
|
|
||||||
"$bindir/pg_ctl" -s -D "$PGDATA" stop
|
|
||||||
wait "$postmaster_pid"
|
|
||||||
unset postmaster_pid
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluate(){
|
|
||||||
# ----------
|
|
||||||
# Evaluation
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
count_total=`cat "$result_summary_file" | grep '\.\.\.' | wc -l | sed 's/ //g'`
|
|
||||||
count_ok=`cat "$result_summary_file" | grep '\.\.\. ok' | wc -l | sed 's/ //g'`
|
|
||||||
count_failed=`cat "$result_summary_file" | grep '\.\.\. FAILED' | wc -l | sed 's/ //g'`
|
|
||||||
count_ignored=`cat "$result_summary_file" | grep '\.\.\. failed (ignored)' | wc -l | sed 's/ //g'`
|
|
||||||
|
|
||||||
echo
|
|
||||||
if [ $count_total -eq $count_ok ]; then
|
|
||||||
msg="All $count_total tests passed."
|
|
||||||
result=0
|
|
||||||
elif [ $count_failed -eq 0 ]; then
|
|
||||||
msg="$count_ok of $count_total tests passed, $count_ignored failed test(s) ignored."
|
|
||||||
result=0
|
|
||||||
elif [ $count_ignored -eq 0 ]; then
|
|
||||||
msg="$count_failed of $count_total tests failed."
|
|
||||||
result=1
|
|
||||||
else
|
|
||||||
msg="`expr $count_failed + $count_ignored` of $count_total tests failed, $count_ignored of these failures ignored."
|
|
||||||
result=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
dashes=`echo " $msg " | sed 's/./=/g'`
|
|
||||||
echo "$dashes"
|
|
||||||
echo " $msg "
|
|
||||||
echo "$dashes"
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [ -s "$diff_file" ]; then
|
|
||||||
echo "The differences that caused some tests to fail can be viewed in the"
|
|
||||||
echo "file \`$diff_file'. A copy of the test summary that you see"
|
|
||||||
echo "above is saved in the file \`$result_summary_file'."
|
|
||||||
echo
|
|
||||||
else
|
|
||||||
rm -f "$diff_file" "$result_summary_file"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
additional_regress_options=""
|
|
||||||
|
|
||||||
build_help "$additional_regress_options"
|
|
||||||
init_vars
|
|
||||||
|
|
||||||
parse_special_options(){
|
|
||||||
# no special options so far
|
|
||||||
case $1 in
|
|
||||||
-*)
|
|
||||||
echo "$me: invalid argument $1" 1>&2
|
|
||||||
exit 2;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# this will call parse_special_options from above
|
|
||||||
parse_general_options $*
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Set up the environment variables (some of them depend on the parameters)
|
|
||||||
# ----------
|
|
||||||
setup_environment_variables
|
|
||||||
|
|
||||||
trap 'exit_trap $?' 0
|
|
||||||
trap 'sig_trap $?' 1 2 13 15
|
|
||||||
|
|
||||||
if [ x"$temp_install" != x"" ]
|
|
||||||
then
|
|
||||||
do_temp_install
|
|
||||||
#PGPORT=$temp_port; export PGPORT
|
|
||||||
else # not temp-install
|
|
||||||
dont_temp_install
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Postmaster is started, now we can change some environment variables for the
|
|
||||||
# client
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
setup_client_environment_variables
|
|
||||||
|
|
||||||
# set up the dbs we use for ecpg regression tests
|
|
||||||
drop_database "$dbname"
|
|
||||||
create_database "$dbname"
|
|
||||||
drop_database connectdb
|
|
||||||
create_database connectdb
|
|
||||||
|
|
||||||
# ----------
|
|
||||||
# Let's go
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
message "running regression test queries"
|
|
||||||
|
|
||||||
outputdir="results"
|
|
||||||
|
|
||||||
if [ ! -d "$outputdir" ]; then
|
|
||||||
mkdir -p "$outputdir" || { (exit 2); exit; }
|
|
||||||
fi
|
|
||||||
#result_summary_file=$outputdir/regression.out
|
|
||||||
#diff_file=$outputdir/regression.diffs
|
|
||||||
|
|
||||||
#cat /dev/null >"$result_summary_file"
|
|
||||||
#cat /dev/null >"$diff_file"
|
|
||||||
|
|
||||||
# we also have different users for ecpg regression diffs (need them for testing
|
|
||||||
# connects)
|
|
||||||
echo "$bindir/createuser" $psql_options -R -S -D -q regressuser1
|
|
||||||
"$bindir/createuser" $psql_options -R -S -D -q regressuser1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo Could not create user regressuser1
|
|
||||||
fi
|
|
||||||
echo "$bindir/createuser" $psql_options -R -S -D -q connectuser
|
|
||||||
"$bindir/createuser" $psql_options -R -S -D -q connectuser
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo Could not create user connectuser
|
|
||||||
fi
|
|
||||||
# to test username = dbname
|
|
||||||
echo "$bindir/createuser" $psql_options -R -S -D -q connectdb
|
|
||||||
"$bindir/createuser" $psql_options -R -S -D -q connectdb
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo Could not create user connectdb
|
|
||||||
fi
|
|
||||||
|
|
||||||
# this variable prevents that the PID gets included in the logfiles
|
|
||||||
#ECPG_REGRESSION=1; export ECPG_REGRESSION
|
|
||||||
LD_LIBRARY_PATH=$libdir:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
|
|
||||||
|
|
||||||
DIFFPRETTYFLAGS="$DIFFFLAGS -C3"
|
|
||||||
FAILNUM=""
|
|
||||||
|
|
||||||
rm -f regression.diffs
|
|
||||||
|
|
||||||
for i in \
|
|
||||||
connect/*.pgc \
|
|
||||||
compat_informix/*.pgc \
|
|
||||||
preproc/*.pgc \
|
|
||||||
pgtypeslib/*.pgc \
|
|
||||||
sql/*.pgc \
|
|
||||||
thread/*.pgc; do
|
|
||||||
|
|
||||||
formatted=`echo $i | awk '{printf "%-38.38s", $1;}'`
|
|
||||||
$ECHO_N "testing $formatted ... $ECHO_C"
|
|
||||||
|
|
||||||
# connect/test1.pgc uses tcp to connect to the server. We run this test
|
|
||||||
# only if called with --listen-on-tcp
|
|
||||||
if [ $listen_on_tcp = no ] && [ "$i" = "connect/test1.pgc" ]; then
|
|
||||||
echo skipped
|
|
||||||
continue;
|
|
||||||
fi
|
|
||||||
|
|
||||||
runprg=`echo $i | sed -e 's,\.pgc$,,'`
|
|
||||||
outprg=`echo $runprg | sed -e's/\//-/'`
|
|
||||||
|
|
||||||
case $host_platform in
|
|
||||||
*-*-mingw32*)
|
|
||||||
PLATFORM_TAG="-MinGW32"
|
|
||||||
;;
|
|
||||||
*-*-openbsd3.8)
|
|
||||||
# OpenBSD 3.8 is buggy:
|
|
||||||
# http://archives.postgresql.org/pgsql-hackers/2006-09/msg00593.php
|
|
||||||
PLATFORM_TAG="-OpenBSD3.8.broken"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
outfile_stderr="$outputdir/$outprg.stderr"
|
|
||||||
outfile_stdout="$outputdir/$outprg.stdout"
|
|
||||||
outfile_source="$outputdir/$outprg.c"
|
|
||||||
cp $runprg.c "$outfile_source"
|
|
||||||
# echo "$runprg > $outfile_stdout 2> $outfile_stderr"
|
|
||||||
$runprg > "$outfile_stdout" 2> "$outfile_stderr"
|
|
||||||
|
|
||||||
mv "$outfile_source" "$outfile_source.tmp"
|
|
||||||
cat "$outfile_source.tmp" | sed -e 's,^\(#line [0-9]*\) ".*/\([^/]*\)",\1 "\2",' > "$outfile_source"
|
|
||||||
rm "$outfile_source.tmp"
|
|
||||||
|
|
||||||
if [ "$enable_threading" = yes ] && [ "${i%%/*}" = "thread" ]; then
|
|
||||||
expectedoutprg="expected/$outprg-thread"
|
|
||||||
else
|
|
||||||
expectedoutprg="expected/$outprg"
|
|
||||||
fi
|
|
||||||
|
|
||||||
expected_stdout="$expectedoutprg$PLATFORM_TAG.stdout"
|
|
||||||
if [ ! -f "$expected_stdout" ]; then
|
|
||||||
expected_stdout="$expectedoutprg.stdout"
|
|
||||||
fi
|
|
||||||
# threading has log output disabled
|
|
||||||
expected_stderr="expected/$outprg$PLATFORM_TAG.stderr"
|
|
||||||
if [ ! -f "$expected_stderr" ]; then
|
|
||||||
expected_stderr="expected/$outprg.stderr"
|
|
||||||
fi
|
|
||||||
# the source should be identical on all platforms
|
|
||||||
expected_source="expected/$outprg.c"
|
|
||||||
|
|
||||||
DIFFER=""
|
|
||||||
diff $DIFFFLAGS "$expected_stderr" "$outfile_stderr" > /dev/null 2>&1
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
DIFFER="$DIFFER, log"
|
|
||||||
diff $DIFFPRETTYFLAGS "$expected_stderr" "$outfile_stderr" >> regression.diffs 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
diff $DIFFFLAGS "$expected_stdout" "$outfile_stdout" > /dev/null 2>&1
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
DIFFER="$DIFFER, output"
|
|
||||||
diff $DIFFPRETTYFLAGS "$expected_stdout" "$outfile_stdout" >> regression.diffs 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
diff $DIFFFLAGS "$expected_source" "$outputdir"/$outprg.c > /dev/null 2>&1
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
DIFFER="$DIFFER, source"
|
|
||||||
diff $DIFFPRETTYFLAGS "$expected_source" "$outputdir"/$outprg.c >> regression.diffs 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
DIFFER=`echo $DIFFER | sed -e 's/^, //'`
|
|
||||||
if [ "x$DIFFER" = "x" ]; then
|
|
||||||
echo ok
|
|
||||||
else
|
|
||||||
echo "FAILED ($DIFFER)"
|
|
||||||
# some sh's don't know about $((x+1))
|
|
||||||
FAILNUM=x$FAILNUM
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
postmaster_shutdown
|
|
||||||
|
|
||||||
# FAILNUM is empty if no test has failed
|
|
||||||
[ x"$FAILNUM" = x"" ] && exit 0
|
|
||||||
(exit 1); exit
|
|
||||||
|
|
177
src/interfaces/ecpg/test/pg_regress_ecpg.c
Normal file
177
src/interfaces/ecpg/test/pg_regress_ecpg.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* pg_regress_ecpg --- regression test driver for ecpg
|
||||||
|
*
|
||||||
|
* This is a C implementation of the previous shell script for running
|
||||||
|
* the regression tests, and should be mostly compatible with it.
|
||||||
|
* Initial author of C translation: Magnus Hagander
|
||||||
|
*
|
||||||
|
* This code is released under the terms of the PostgreSQL License.
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/interfaces/ecpg/test/pg_regress_ecpg.c,v 1.1 2007/06/12 11:07:30 mha Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pg_regress.h"
|
||||||
|
|
||||||
|
#define LINEBUFSIZE 300
|
||||||
|
static void
|
||||||
|
ecpg_filter(const char *sourcefile, const char *outfile)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Create a filtered copy of sourcefile, replacing
|
||||||
|
* #line x "./../bla/foo.h"
|
||||||
|
* with
|
||||||
|
* #line x "foo.h"
|
||||||
|
*/
|
||||||
|
FILE *s, *t;
|
||||||
|
char linebuf[LINEBUFSIZE];
|
||||||
|
|
||||||
|
s = fopen(sourcefile, "r");
|
||||||
|
if (!s)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not open file %s for reading\n", sourcefile);
|
||||||
|
exit_nicely(2);
|
||||||
|
}
|
||||||
|
t = fopen(outfile, "w");
|
||||||
|
if (!t)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not open file %s for writing\n", outfile);
|
||||||
|
exit_nicely(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(linebuf, LINEBUFSIZE, s))
|
||||||
|
{
|
||||||
|
/* check for "#line " in the beginning */
|
||||||
|
if (strstr(linebuf, "#line ") == linebuf)
|
||||||
|
{
|
||||||
|
char *p = strchr(linebuf, '"');
|
||||||
|
char *n;
|
||||||
|
int plen = 1;
|
||||||
|
while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL))
|
||||||
|
{
|
||||||
|
plen++;
|
||||||
|
}
|
||||||
|
/* plen is one more than the number of . and / characters */
|
||||||
|
if (plen > 1)
|
||||||
|
{
|
||||||
|
n = (char *) malloc(plen);
|
||||||
|
strncpy(n, p+1, plen - 1);
|
||||||
|
n[plen-1] = '\0';
|
||||||
|
replace_string(linebuf, n, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fputs(linebuf, t);
|
||||||
|
}
|
||||||
|
fclose(s);
|
||||||
|
fclose(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start an ecpg test process for specified file (including redirection),
|
||||||
|
* and return process ID
|
||||||
|
*/
|
||||||
|
|
||||||
|
static PID_TYPE
|
||||||
|
ecpg_start_test(const char *testname,
|
||||||
|
_stringlist **resultfiles,
|
||||||
|
_stringlist **expectfiles,
|
||||||
|
_stringlist **tags)
|
||||||
|
{
|
||||||
|
PID_TYPE pid;
|
||||||
|
char inprg[MAXPGPATH];
|
||||||
|
char insource[MAXPGPATH];
|
||||||
|
char *outfile_stdout, expectfile_stdout[MAXPGPATH];
|
||||||
|
char *outfile_stderr, expectfile_stderr[MAXPGPATH];
|
||||||
|
char *outfile_source, expectfile_source[MAXPGPATH];
|
||||||
|
char cmd[MAXPGPATH * 3];
|
||||||
|
char *testname_dash;
|
||||||
|
|
||||||
|
snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
|
||||||
|
|
||||||
|
testname_dash = strdup(testname);
|
||||||
|
replace_string(testname_dash, "/", "-");
|
||||||
|
snprintf(expectfile_stdout, sizeof(expectfile_stdout),
|
||||||
|
"%s/expected/%s.stdout",
|
||||||
|
outputdir, testname_dash);
|
||||||
|
snprintf(expectfile_stderr, sizeof(expectfile_stderr),
|
||||||
|
"%s/expected/%s.stderr",
|
||||||
|
outputdir, testname_dash);
|
||||||
|
snprintf(expectfile_source, sizeof(expectfile_source),
|
||||||
|
"%s/expected/%s.c",
|
||||||
|
outputdir, testname_dash);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can use replace_string() here because the replacement string does
|
||||||
|
* not occupy more space than the replaced one.
|
||||||
|
*/
|
||||||
|
outfile_stdout = strdup(expectfile_stdout);
|
||||||
|
replace_string(outfile_stdout, "/expected/", "/results/");
|
||||||
|
outfile_stderr = strdup(expectfile_stderr);
|
||||||
|
replace_string(outfile_stderr, "/expected/", "/results/");
|
||||||
|
outfile_source = strdup(expectfile_source);
|
||||||
|
replace_string(outfile_source, "/expected/", "/results/");
|
||||||
|
|
||||||
|
add_stringlist_item(resultfiles, outfile_stdout);
|
||||||
|
add_stringlist_item(expectfiles, expectfile_stdout);
|
||||||
|
add_stringlist_item(tags, "stdout");
|
||||||
|
|
||||||
|
add_stringlist_item(resultfiles, outfile_stderr);
|
||||||
|
add_stringlist_item(expectfiles, expectfile_stderr);
|
||||||
|
add_stringlist_item(tags, "stderr");
|
||||||
|
|
||||||
|
add_stringlist_item(resultfiles, outfile_source);
|
||||||
|
add_stringlist_item(expectfiles, expectfile_source);
|
||||||
|
add_stringlist_item(tags, "source");
|
||||||
|
|
||||||
|
snprintf(insource, sizeof(insource), "%s.c", testname);
|
||||||
|
ecpg_filter(insource, outfile_source);
|
||||||
|
|
||||||
|
snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd),
|
||||||
|
SYSTEMQUOTE "\"%s\" >\"%s\" 2>\"%s\"" SYSTEMQUOTE,
|
||||||
|
inprg,
|
||||||
|
outfile_stdout,
|
||||||
|
outfile_stderr);
|
||||||
|
|
||||||
|
pid = spawn_process(cmd);
|
||||||
|
|
||||||
|
if (pid == INVALID_PID)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("could not start process for test %s\n"),
|
||||||
|
testname);
|
||||||
|
exit_nicely(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(outfile_stdout);
|
||||||
|
free(outfile_stderr);
|
||||||
|
free(outfile_source);
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ecpg_init(void)
|
||||||
|
{
|
||||||
|
/* no reason to set -w for ecpg checks, except for when on windows */
|
||||||
|
if (strstr(host_platform, "-win32"))
|
||||||
|
basic_diff_opts = "-w";
|
||||||
|
else
|
||||||
|
basic_diff_opts = "";
|
||||||
|
if (strstr(host_platform, "-win32"))
|
||||||
|
pretty_diff_opts = "-C3 -w";
|
||||||
|
else
|
||||||
|
pretty_diff_opts = "-C3";
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return regression_main(argc, argv, ecpg_init, ecpg_start_test);
|
||||||
|
}
|
||||||
|
|
3
src/interfaces/ecpg/test/resultmap
Normal file
3
src/interfaces/ecpg/test/resultmap
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
compat_informix/dec_test:stdout:i.86-pc-win32vc=compat_informix-dec_test-MinGW32.stdout
|
||||||
|
pgtypeslib/num_test:stdout:i.86-pc-win32vc=pgtypeslib-num_test-MinGW32.stdout
|
||||||
|
pgtypeslib/num_test2:stdout:i.86-pc-win32vc=pgtypeslib-num_test2-MinGW32.stdout
|
@ -103,7 +103,11 @@ void *test_thread(void *arg)
|
|||||||
EXEC SQL END DECLARE SECTION;
|
EXEC SQL END DECLARE SECTION;
|
||||||
|
|
||||||
/* build up connection name, and connect to database */
|
/* build up connection name, and connect to database */
|
||||||
|
#ifndef WIN32_ONLY_COMPILER
|
||||||
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#else
|
||||||
|
_snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#endif
|
||||||
EXEC SQL WHENEVER sqlerror sqlprint;
|
EXEC SQL WHENEVER sqlerror sqlprint;
|
||||||
EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection;
|
EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection;
|
||||||
if( sqlca.sqlcode != 0 )
|
if( sqlca.sqlcode != 0 )
|
||||||
|
@ -104,7 +104,11 @@ void *test_thread(void *arg)
|
|||||||
EXEC SQL END DECLARE SECTION;
|
EXEC SQL END DECLARE SECTION;
|
||||||
|
|
||||||
/* build up connection name, and connect to database */
|
/* build up connection name, and connect to database */
|
||||||
|
#ifndef WIN32_ONLY_COMPILER
|
||||||
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#else
|
||||||
|
_snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
|
||||||
|
#endif
|
||||||
EXEC SQL WHENEVER sqlerror sqlprint;
|
EXEC SQL WHENEVER sqlerror sqlprint;
|
||||||
EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection;
|
EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection;
|
||||||
if( sqlca.sqlcode != 0 )
|
if( sqlca.sqlcode != 0 )
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
# Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
# Portions Copyright (c) 1994, Regents of the University of California
|
# Portions Copyright (c) 1994, Regents of the University of California
|
||||||
#
|
#
|
||||||
# $PostgreSQL: pgsql/src/test/regress/GNUmakefile,v 1.67 2007/03/13 22:56:48 tgl Exp $
|
# $PostgreSQL: pgsql/src/test/regress/GNUmakefile,v 1.68 2007/06/12 11:07:32 mha Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \
|
|||||||
|
|
||||||
all: submake-libpgport pg_regress$(X)
|
all: submake-libpgport pg_regress$(X)
|
||||||
|
|
||||||
pg_regress$(X): pg_regress.o
|
pg_regress$(X): pg_regress.o pg_regress_main.o
|
||||||
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LIBS) -o $@
|
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LIBS) -o $@
|
||||||
|
|
||||||
# dependencies ensure that path changes propagate
|
# dependencies ensure that path changes propagate
|
||||||
@ -165,7 +165,7 @@ clean distclean maintainer-clean: clean-lib
|
|||||||
# things built by `all' target
|
# things built by `all' target
|
||||||
rm -f $(NAME)$(DLSUFFIX) $(OBJS)
|
rm -f $(NAME)$(DLSUFFIX) $(OBJS)
|
||||||
$(MAKE) -C $(contribdir)/spi clean
|
$(MAKE) -C $(contribdir)/spi clean
|
||||||
rm -f $(output_files) $(input_files) pg_regress.o pg_regress$(X)
|
rm -f $(output_files) $(input_files) pg_regress_main.o pg_regress.o pg_regress$(X)
|
||||||
# things created by various check targets
|
# things created by various check targets
|
||||||
rm -rf testtablespace
|
rm -rf testtablespace
|
||||||
rm -rf results tmp_check log
|
rm -rf results tmp_check log
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.32 2007/05/31 15:13:06 petere Exp $
|
* $PostgreSQL: pgsql/src/test/regress/pg_regress.c,v 1.33 2007/06/12 11:07:34 mha Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres_fe.h"
|
#include "pg_regress.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -32,26 +32,11 @@
|
|||||||
#include "getopt_long.h"
|
#include "getopt_long.h"
|
||||||
#include "pg_config_paths.h"
|
#include "pg_config_paths.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
#define PID_TYPE pid_t
|
|
||||||
#define INVALID_PID (-1)
|
|
||||||
#else
|
|
||||||
#define PID_TYPE HANDLE
|
|
||||||
#define INVALID_PID INVALID_HANDLE_VALUE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* simple list of strings */
|
|
||||||
typedef struct _stringlist
|
|
||||||
{
|
|
||||||
char *str;
|
|
||||||
struct _stringlist *next;
|
|
||||||
} _stringlist;
|
|
||||||
|
|
||||||
/* for resultmap we need a list of pairs of strings */
|
/* for resultmap we need a list of pairs of strings */
|
||||||
typedef struct _resultmap
|
typedef struct _resultmap
|
||||||
{
|
{
|
||||||
char *test;
|
char *test;
|
||||||
|
char *type;
|
||||||
char *resultfile;
|
char *resultfile;
|
||||||
struct _resultmap *next;
|
struct _resultmap *next;
|
||||||
} _resultmap;
|
} _resultmap;
|
||||||
@ -63,10 +48,10 @@ typedef struct _resultmap
|
|||||||
* In non-temp_install mode, the only thing we need is the location of psql,
|
* In non-temp_install mode, the only thing we need is the location of psql,
|
||||||
* which we expect to find in psqldir, or in the PATH if psqldir isn't given.
|
* which we expect to find in psqldir, or in the PATH if psqldir isn't given.
|
||||||
*/
|
*/
|
||||||
static char *bindir = PGBINDIR;
|
char *bindir = PGBINDIR;
|
||||||
static char *libdir = LIBDIR;
|
char *libdir = LIBDIR;
|
||||||
static char *datadir = PGSHAREDIR;
|
char *datadir = PGSHAREDIR;
|
||||||
static char *host_platform = HOST_TUPLE;
|
char *host_platform = HOST_TUPLE;
|
||||||
#ifndef WIN32_ONLY_COMPILER
|
#ifndef WIN32_ONLY_COMPILER
|
||||||
static char *makeprog = MAKEPROG;
|
static char *makeprog = MAKEPROG;
|
||||||
#endif
|
#endif
|
||||||
@ -76,14 +61,15 @@ static char *shellprog = SHELLPROG;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* currently we can use the same diff switches on all platforms */
|
/* currently we can use the same diff switches on all platforms */
|
||||||
static const char *basic_diff_opts = "-w";
|
const char *basic_diff_opts = "-w";
|
||||||
static const char *pretty_diff_opts = "-w -C3";
|
const char *pretty_diff_opts = "-w -C3";
|
||||||
|
|
||||||
/* options settable from command line */
|
/* options settable from command line */
|
||||||
static char *dbname = "regression";
|
_stringlist *dblist = NULL;
|
||||||
static bool debug = false;
|
bool debug = false;
|
||||||
static char *inputdir = ".";
|
char *inputdir = ".";
|
||||||
static char *outputdir = ".";
|
char *outputdir = ".";
|
||||||
|
char *psqldir = NULL;
|
||||||
static _stringlist *loadlanguage = NULL;
|
static _stringlist *loadlanguage = NULL;
|
||||||
static int max_connections = 0;
|
static int max_connections = 0;
|
||||||
static char *encoding = NULL;
|
static char *encoding = NULL;
|
||||||
@ -93,11 +79,11 @@ static char *temp_install = NULL;
|
|||||||
static char *top_builddir = NULL;
|
static char *top_builddir = NULL;
|
||||||
static int temp_port = 65432;
|
static int temp_port = 65432;
|
||||||
static bool nolocale = false;
|
static bool nolocale = false;
|
||||||
static char *psqldir = NULL;
|
|
||||||
static char *hostname = NULL;
|
static char *hostname = NULL;
|
||||||
static int port = -1;
|
static int port = -1;
|
||||||
static char *user = NULL;
|
static char *user = NULL;
|
||||||
static char *srcdir = NULL;
|
static char *srcdir = NULL;
|
||||||
|
static _stringlist *extraroles = NULL;
|
||||||
|
|
||||||
/* internal variables */
|
/* internal variables */
|
||||||
static const char *progname;
|
static const char *progname;
|
||||||
@ -170,7 +156,7 @@ unlimit_core_size(void)
|
|||||||
/*
|
/*
|
||||||
* Add an item at the end of a stringlist.
|
* Add an item at the end of a stringlist.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
add_stringlist_item(_stringlist ** listhead, const char *str)
|
add_stringlist_item(_stringlist ** listhead, const char *str)
|
||||||
{
|
{
|
||||||
_stringlist *newentry = malloc(sizeof(_stringlist));
|
_stringlist *newentry = malloc(sizeof(_stringlist));
|
||||||
@ -188,6 +174,37 @@ add_stringlist_item(_stringlist ** listhead, const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free a stringlist.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
free_stringlist(_stringlist **listhead)
|
||||||
|
{
|
||||||
|
if (listhead == NULL || *listhead == NULL)
|
||||||
|
return;
|
||||||
|
if ((*listhead)->next != NULL)
|
||||||
|
free_stringlist(&((*listhead)->next));
|
||||||
|
free((*listhead)->str);
|
||||||
|
free(*listhead);
|
||||||
|
*listhead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Split a delimited string into a stringlist
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
split_to_stringlist(const char *s, const char *delim, _stringlist **listhead)
|
||||||
|
{
|
||||||
|
char *sc = strdup(s);
|
||||||
|
char *token = strtok(sc, delim);
|
||||||
|
while (token)
|
||||||
|
{
|
||||||
|
add_stringlist_item(listhead, token);
|
||||||
|
token = strtok(NULL, delim);
|
||||||
|
}
|
||||||
|
free(sc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print a progress banner on stdout.
|
* Print a progress banner on stdout.
|
||||||
*/
|
*/
|
||||||
@ -265,7 +282,7 @@ stop_postmaster(void)
|
|||||||
* Always exit through here, not through plain exit(), to ensure we make
|
* Always exit through here, not through plain exit(), to ensure we make
|
||||||
* an effort to shut down a temp postmaster
|
* an effort to shut down a temp postmaster
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
exit_nicely(int code)
|
exit_nicely(int code)
|
||||||
{
|
{
|
||||||
stop_postmaster();
|
stop_postmaster();
|
||||||
@ -349,7 +366,7 @@ string_matches_pattern(const char *str, const char *pattern)
|
|||||||
* Replace all occurances of a string in a string with a different string.
|
* Replace all occurances of a string in a string with a different string.
|
||||||
* NOTE: Assumes there is enough room in the target buffer!
|
* NOTE: Assumes there is enough room in the target buffer!
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
replace_string(char *string, char *replace, char *replacement)
|
replace_string(char *string, char *replace, char *replacement)
|
||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@ -537,6 +554,7 @@ load_resultmap(void)
|
|||||||
while (fgets(buf, sizeof(buf), f))
|
while (fgets(buf, sizeof(buf), f))
|
||||||
{
|
{
|
||||||
char *platform;
|
char *platform;
|
||||||
|
char *file_type;
|
||||||
char *expected;
|
char *expected;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -546,7 +564,16 @@ load_resultmap(void)
|
|||||||
buf[--i] = '\0';
|
buf[--i] = '\0';
|
||||||
|
|
||||||
/* parse out the line fields */
|
/* parse out the line fields */
|
||||||
platform = strchr(buf, '/');
|
file_type = strchr(buf, ':');
|
||||||
|
if (!file_type)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("incorrectly formatted resultmap entry: %s\n"),
|
||||||
|
buf);
|
||||||
|
exit_nicely(2);
|
||||||
|
}
|
||||||
|
*file_type++ = '\0';
|
||||||
|
|
||||||
|
platform = strchr(file_type, ':');
|
||||||
if (!platform)
|
if (!platform)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("incorrectly formatted resultmap entry: %s\n"),
|
fprintf(stderr, _("incorrectly formatted resultmap entry: %s\n"),
|
||||||
@ -574,6 +601,7 @@ load_resultmap(void)
|
|||||||
_resultmap *entry = malloc(sizeof(_resultmap));
|
_resultmap *entry = malloc(sizeof(_resultmap));
|
||||||
|
|
||||||
entry->test = strdup(buf);
|
entry->test = strdup(buf);
|
||||||
|
entry->type = strdup(file_type);
|
||||||
entry->resultfile = strdup(expected);
|
entry->resultfile = strdup(expected);
|
||||||
entry->next = resultmap;
|
entry->next = resultmap;
|
||||||
resultmap = entry;
|
resultmap = entry;
|
||||||
@ -582,6 +610,35 @@ load_resultmap(void)
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check in resultmap if we should be looking at a different file
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
const char *get_expectfile(const char *testname, const char *file)
|
||||||
|
{
|
||||||
|
char *file_type;
|
||||||
|
_resultmap *rm;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the file type from the file name. This is just what is
|
||||||
|
* following the last dot in the file name.
|
||||||
|
*/
|
||||||
|
if (!file || !(file_type = strrchr(file, '.')))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
file_type++;
|
||||||
|
|
||||||
|
for (rm = resultmap; rm != NULL; rm = rm->next)
|
||||||
|
{
|
||||||
|
if (strcmp(testname, rm->test) == 0 && strcmp(file_type, rm->type) == 0)
|
||||||
|
{
|
||||||
|
return rm->resultfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handy subroutine for setting an environment variable "var" to "val"
|
* Handy subroutine for setting an environment variable "var" to "val"
|
||||||
*/
|
*/
|
||||||
@ -704,7 +761,7 @@ initialize_environment(void)
|
|||||||
|
|
||||||
/* psql will be installed into temp-install bindir */
|
/* psql will be installed into temp-install bindir */
|
||||||
psqldir = bindir;
|
psqldir = bindir;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up shared library paths to include the temp install.
|
* Set up shared library paths to include the temp install.
|
||||||
*
|
*
|
||||||
@ -820,7 +877,7 @@ psql_command(const char *database, const char *query,...)
|
|||||||
*
|
*
|
||||||
* Returns the process ID (or HANDLE) so we can wait for it later
|
* Returns the process ID (or HANDLE) so we can wait for it later
|
||||||
*/
|
*/
|
||||||
static PID_TYPE
|
PID_TYPE
|
||||||
spawn_process(const char *cmdline)
|
spawn_process(const char *cmdline)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -943,43 +1000,6 @@ spawn_process(const char *cmdline)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* start a psql test process for specified file (including redirection),
|
|
||||||
* and return process ID
|
|
||||||
*/
|
|
||||||
static PID_TYPE
|
|
||||||
psql_start_test(const char *testname)
|
|
||||||
{
|
|
||||||
PID_TYPE pid;
|
|
||||||
char infile[MAXPGPATH];
|
|
||||||
char outfile[MAXPGPATH];
|
|
||||||
char psql_cmd[MAXPGPATH * 3];
|
|
||||||
|
|
||||||
snprintf(infile, sizeof(infile), "%s/sql/%s.sql",
|
|
||||||
inputdir, testname);
|
|
||||||
snprintf(outfile, sizeof(outfile), "%s/results/%s.out",
|
|
||||||
outputdir, testname);
|
|
||||||
|
|
||||||
snprintf(psql_cmd, sizeof(psql_cmd),
|
|
||||||
SYSTEMQUOTE "\"%s%spsql\" -X -a -q -d \"%s\" < \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
|
|
||||||
psqldir ? psqldir : "",
|
|
||||||
psqldir ? "/" : "",
|
|
||||||
dbname,
|
|
||||||
infile,
|
|
||||||
outfile);
|
|
||||||
|
|
||||||
pid = spawn_process(psql_cmd);
|
|
||||||
|
|
||||||
if (pid == INVALID_PID)
|
|
||||||
{
|
|
||||||
fprintf(stderr, _("could not start process for test %s\n"),
|
|
||||||
testname);
|
|
||||||
exit_nicely(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count bytes in file
|
* Count bytes in file
|
||||||
*/
|
*/
|
||||||
@ -1061,6 +1081,26 @@ make_directory(const char *dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In: filename.ext, Return: filename_i.ext, where 0 < i <= 9
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
get_alternative_expectfile(const char *expectfile, int i)
|
||||||
|
{
|
||||||
|
char *last_dot;
|
||||||
|
int ssize = strlen(expectfile) + 2 + 1;
|
||||||
|
char *tmp = (char *)malloc(ssize);
|
||||||
|
char *s = (char *)malloc(ssize);
|
||||||
|
strcpy(tmp, expectfile);
|
||||||
|
last_dot = strrchr(tmp,'.');
|
||||||
|
if (!last_dot)
|
||||||
|
return NULL;
|
||||||
|
*last_dot = '\0';
|
||||||
|
snprintf(s, ssize, "%s_%d.%s", tmp, i, last_dot+1);
|
||||||
|
free(tmp);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run a "diff" command and also check that it didn't crash
|
* Run a "diff" command and also check that it didn't crash
|
||||||
*/
|
*/
|
||||||
@ -1098,42 +1138,38 @@ run_diff(const char *cmd, const char *filename)
|
|||||||
* In the true case, the diff is appended to the diffs file.
|
* In the true case, the diff is appended to the diffs file.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
results_differ(const char *testname)
|
results_differ(const char *testname, const char *resultsfile, const char *default_expectfile)
|
||||||
{
|
{
|
||||||
const char *expectname;
|
|
||||||
char resultsfile[MAXPGPATH];
|
|
||||||
char expectfile[MAXPGPATH];
|
char expectfile[MAXPGPATH];
|
||||||
char diff[MAXPGPATH];
|
char diff[MAXPGPATH];
|
||||||
char cmd[MAXPGPATH * 3];
|
char cmd[MAXPGPATH * 3];
|
||||||
char best_expect_file[MAXPGPATH];
|
char best_expect_file[MAXPGPATH];
|
||||||
_resultmap *rm;
|
|
||||||
FILE *difffile;
|
FILE *difffile;
|
||||||
int best_line_count;
|
int best_line_count;
|
||||||
int i;
|
int i;
|
||||||
int l;
|
int l;
|
||||||
|
const char *platform_expectfile;
|
||||||
|
|
||||||
/* Check in resultmap if we should be looking at a different file */
|
/*
|
||||||
expectname = testname;
|
* We can pass either the resultsfile or the expectfile, they should
|
||||||
for (rm = resultmap; rm != NULL; rm = rm->next)
|
* have the same type (filename.type) anyway.
|
||||||
|
*/
|
||||||
|
platform_expectfile = get_expectfile(testname, resultsfile);
|
||||||
|
|
||||||
|
strcpy(expectfile, default_expectfile);
|
||||||
|
if (platform_expectfile)
|
||||||
{
|
{
|
||||||
if (strcmp(testname, rm->test) == 0)
|
/*
|
||||||
{
|
* Replace everything afer the last slash in expectfile with what the
|
||||||
expectname = rm->resultfile;
|
* platform_expectfile contains.
|
||||||
break;
|
*/
|
||||||
}
|
char *p = strrchr(expectfile, '/');
|
||||||
|
if (p)
|
||||||
|
strcpy(++p, platform_expectfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name of test results file */
|
|
||||||
snprintf(resultsfile, sizeof(resultsfile), "%s/results/%s.out",
|
|
||||||
outputdir, testname);
|
|
||||||
|
|
||||||
/* Name of expected-results file */
|
|
||||||
snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
|
|
||||||
inputdir, expectname);
|
|
||||||
|
|
||||||
/* Name to use for temporary diff file */
|
/* Name to use for temporary diff file */
|
||||||
snprintf(diff, sizeof(diff), "%s/results/%s.diff",
|
snprintf(diff, sizeof(diff), "%s.diff", resultsfile);
|
||||||
outputdir, testname);
|
|
||||||
|
|
||||||
/* OK, run the diff */
|
/* OK, run the diff */
|
||||||
snprintf(cmd, sizeof(cmd),
|
snprintf(cmd, sizeof(cmd),
|
||||||
@ -1153,14 +1189,15 @@ results_differ(const char *testname)
|
|||||||
|
|
||||||
for (i = 0; i <= 9; i++)
|
for (i = 0; i <= 9; i++)
|
||||||
{
|
{
|
||||||
snprintf(expectfile, sizeof(expectfile), "%s/expected/%s_%d.out",
|
char *alt_expectfile;
|
||||||
inputdir, expectname, i);
|
|
||||||
if (!file_exists(expectfile))
|
alt_expectfile = get_alternative_expectfile(expectfile, i);
|
||||||
|
if (!file_exists(alt_expectfile))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd),
|
snprintf(cmd, sizeof(cmd),
|
||||||
SYSTEMQUOTE "diff %s \"%s\" \"%s\" > \"%s\"" SYSTEMQUOTE,
|
SYSTEMQUOTE "diff %s \"%s\" \"%s\" > \"%s\"" SYSTEMQUOTE,
|
||||||
basic_diff_opts, expectfile, resultsfile, diff);
|
basic_diff_opts, alt_expectfile, resultsfile, diff);
|
||||||
|
|
||||||
if (run_diff(cmd, diff) == 0)
|
if (run_diff(cmd, diff) == 0)
|
||||||
{
|
{
|
||||||
@ -1173,8 +1210,9 @@ results_differ(const char *testname)
|
|||||||
{
|
{
|
||||||
/* This diff was a better match than the last one */
|
/* This diff was a better match than the last one */
|
||||||
best_line_count = l;
|
best_line_count = l;
|
||||||
strcpy(best_expect_file, expectfile);
|
strcpy(best_expect_file, alt_expectfile);
|
||||||
}
|
}
|
||||||
|
free(alt_expectfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1182,14 +1220,11 @@ results_differ(const char *testname)
|
|||||||
* haven't found a complete match yet.
|
* haven't found a complete match yet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (strcmp(expectname, testname) != 0)
|
if (platform_expectfile)
|
||||||
{
|
{
|
||||||
snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
|
|
||||||
inputdir, testname);
|
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd),
|
snprintf(cmd, sizeof(cmd),
|
||||||
SYSTEMQUOTE "diff %s \"%s\" \"%s\" > \"%s\"" SYSTEMQUOTE,
|
SYSTEMQUOTE "diff %s \"%s\" \"%s\" > \"%s\"" SYSTEMQUOTE,
|
||||||
basic_diff_opts, expectfile, resultsfile, diff);
|
basic_diff_opts, default_expectfile, resultsfile, diff);
|
||||||
|
|
||||||
if (run_diff(cmd, diff) == 0)
|
if (run_diff(cmd, diff) == 0)
|
||||||
{
|
{
|
||||||
@ -1203,7 +1238,7 @@ results_differ(const char *testname)
|
|||||||
{
|
{
|
||||||
/* This diff was a better match than the last one */
|
/* This diff was a better match than the last one */
|
||||||
best_line_count = l;
|
best_line_count = l;
|
||||||
strcpy(best_expect_file, expectfile);
|
strcpy(best_expect_file, default_expectfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,16 +1337,23 @@ wait_for_tests(PID_TYPE * pids, char **names, int num_tests)
|
|||||||
* Run all the tests specified in one schedule file
|
* Run all the tests specified in one schedule file
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
run_schedule(const char *schedule)
|
run_schedule(const char *schedule, test_function tfunc)
|
||||||
{
|
{
|
||||||
#define MAX_PARALLEL_TESTS 100
|
#define MAX_PARALLEL_TESTS 100
|
||||||
char *tests[MAX_PARALLEL_TESTS];
|
char *tests[MAX_PARALLEL_TESTS];
|
||||||
|
_stringlist *resultfiles[MAX_PARALLEL_TESTS];
|
||||||
|
_stringlist *expectfiles[MAX_PARALLEL_TESTS];
|
||||||
|
_stringlist *tags[MAX_PARALLEL_TESTS];
|
||||||
PID_TYPE pids[MAX_PARALLEL_TESTS];
|
PID_TYPE pids[MAX_PARALLEL_TESTS];
|
||||||
_stringlist *ignorelist = NULL;
|
_stringlist *ignorelist = NULL;
|
||||||
char scbuf[1024];
|
char scbuf[1024];
|
||||||
FILE *scf;
|
FILE *scf;
|
||||||
int line_num = 0;
|
int line_num = 0;
|
||||||
|
|
||||||
|
memset(resultfiles,0,sizeof(_stringlist *) * MAX_PARALLEL_TESTS);
|
||||||
|
memset(expectfiles,0,sizeof(_stringlist *) * MAX_PARALLEL_TESTS);
|
||||||
|
memset(tags,0,sizeof(_stringlist *) * MAX_PARALLEL_TESTS);
|
||||||
|
|
||||||
scf = fopen(schedule, "r");
|
scf = fopen(schedule, "r");
|
||||||
if (!scf)
|
if (!scf)
|
||||||
{
|
{
|
||||||
@ -1330,6 +1372,15 @@ run_schedule(const char *schedule)
|
|||||||
|
|
||||||
line_num++;
|
line_num++;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_PARALLEL_TESTS; i++)
|
||||||
|
{
|
||||||
|
if (resultfiles[i] == NULL)
|
||||||
|
break;
|
||||||
|
free_stringlist(&resultfiles[i]);
|
||||||
|
free_stringlist(&expectfiles[i]);
|
||||||
|
free_stringlist(&tags[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* strip trailing whitespace, especially the newline */
|
/* strip trailing whitespace, especially the newline */
|
||||||
i = strlen(scbuf);
|
i = strlen(scbuf);
|
||||||
while (i > 0 && isspace((unsigned char) scbuf[i - 1]))
|
while (i > 0 && isspace((unsigned char) scbuf[i - 1]))
|
||||||
@ -1394,7 +1445,7 @@ run_schedule(const char *schedule)
|
|||||||
if (num_tests == 1)
|
if (num_tests == 1)
|
||||||
{
|
{
|
||||||
status(_("test %-20s ... "), tests[0]);
|
status(_("test %-20s ... "), tests[0]);
|
||||||
pids[0] = psql_start_test(tests[0]);
|
pids[0] = (tfunc)(tests[0], &resultfiles[0], &expectfiles[0], &tags[0]);
|
||||||
wait_for_tests(pids, NULL, 1);
|
wait_for_tests(pids, NULL, 1);
|
||||||
/* status line is finished below */
|
/* status line is finished below */
|
||||||
}
|
}
|
||||||
@ -1411,7 +1462,7 @@ run_schedule(const char *schedule)
|
|||||||
wait_for_tests(pids + oldest, tests + oldest, i - oldest);
|
wait_for_tests(pids + oldest, tests + oldest, i - oldest);
|
||||||
oldest = i;
|
oldest = i;
|
||||||
}
|
}
|
||||||
pids[i] = psql_start_test(tests[i]);
|
pids[i] = (tfunc)(tests[i], &resultfiles[i], &expectfiles[i], &tags[i]);
|
||||||
}
|
}
|
||||||
wait_for_tests(pids + oldest, tests + oldest, i - oldest);
|
wait_for_tests(pids + oldest, tests + oldest, i - oldest);
|
||||||
status_end();
|
status_end();
|
||||||
@ -1421,7 +1472,7 @@ run_schedule(const char *schedule)
|
|||||||
status(_("parallel group (%d tests): "), num_tests);
|
status(_("parallel group (%d tests): "), num_tests);
|
||||||
for (i = 0; i < num_tests; i++)
|
for (i = 0; i < num_tests; i++)
|
||||||
{
|
{
|
||||||
pids[i] = psql_start_test(tests[i]);
|
pids[i] = (tfunc)(tests[i], &resultfiles[i], &expectfiles[i], &tags[i]);
|
||||||
}
|
}
|
||||||
wait_for_tests(pids, tests, num_tests);
|
wait_for_tests(pids, tests, num_tests);
|
||||||
status_end();
|
status_end();
|
||||||
@ -1430,10 +1481,36 @@ run_schedule(const char *schedule)
|
|||||||
/* Check results for all tests */
|
/* Check results for all tests */
|
||||||
for (i = 0; i < num_tests; i++)
|
for (i = 0; i < num_tests; i++)
|
||||||
{
|
{
|
||||||
|
_stringlist *rl, *el, *tl;
|
||||||
|
bool differ = false;
|
||||||
|
|
||||||
if (num_tests > 1)
|
if (num_tests > 1)
|
||||||
status(_(" %-20s ... "), tests[i]);
|
status(_(" %-20s ... "), tests[i]);
|
||||||
|
|
||||||
if (results_differ(tests[i]))
|
/*
|
||||||
|
* Advance over all three lists simultaneously.
|
||||||
|
*
|
||||||
|
* Compare resultfiles[j] with expectfiles[j] always.
|
||||||
|
* Tags are optional but if there are tags, the tag list has the
|
||||||
|
* same length as the other two lists.
|
||||||
|
*/
|
||||||
|
for (rl = resultfiles[i], el = expectfiles[i], tl = tags[i];
|
||||||
|
rl != NULL; /* rl and el have the same length */
|
||||||
|
rl = rl->next, el = el->next)
|
||||||
|
{
|
||||||
|
bool newdiff;
|
||||||
|
if (tl)
|
||||||
|
tl = tl->next; /* tl has the same lengt has rl and el if it exists */
|
||||||
|
|
||||||
|
newdiff = results_differ(tests[i], rl->str, el->str);
|
||||||
|
if (newdiff && tl)
|
||||||
|
{
|
||||||
|
printf("%s ", tl->str);
|
||||||
|
}
|
||||||
|
differ |= newdiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (differ)
|
||||||
{
|
{
|
||||||
bool ignore = false;
|
bool ignore = false;
|
||||||
_stringlist *sl;
|
_stringlist *sl;
|
||||||
@ -1474,15 +1551,43 @@ run_schedule(const char *schedule)
|
|||||||
* Run a single test
|
* Run a single test
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
run_single_test(const char *test)
|
run_single_test(const char *test, test_function tfunc)
|
||||||
{
|
{
|
||||||
PID_TYPE pid;
|
PID_TYPE pid;
|
||||||
|
_stringlist *resultfiles;
|
||||||
|
_stringlist *expectfiles;
|
||||||
|
_stringlist *tags;
|
||||||
|
_stringlist *rl, *el, *tl;
|
||||||
|
bool differ = false;
|
||||||
|
|
||||||
status(_("test %-20s ... "), test);
|
status(_("test %-20s ... "), test);
|
||||||
pid = psql_start_test(test);
|
pid = (tfunc)(test, &resultfiles, &expectfiles, &tags);
|
||||||
wait_for_tests(&pid, NULL, 1);
|
wait_for_tests(&pid, NULL, 1);
|
||||||
|
|
||||||
if (results_differ(test))
|
/*
|
||||||
|
* Advance over all three lists simultaneously.
|
||||||
|
*
|
||||||
|
* Compare resultfiles[j] with expectfiles[j] always.
|
||||||
|
* Tags are optional but if there are tags, the tag list has the
|
||||||
|
* same length as the other two lists.
|
||||||
|
*/
|
||||||
|
for (rl = resultfiles, el = expectfiles, tl = tags;
|
||||||
|
rl != NULL; /* rl and el have the same length */
|
||||||
|
rl = rl->next, el = el->next)
|
||||||
|
{
|
||||||
|
bool newdiff;
|
||||||
|
if (tl)
|
||||||
|
tl = tl->next; /* tl has the same lengt has rl and el if it exists */
|
||||||
|
|
||||||
|
newdiff = results_differ(test, rl->str, el->str);
|
||||||
|
if (newdiff && tl)
|
||||||
|
{
|
||||||
|
printf("%s ", tl->str);
|
||||||
|
}
|
||||||
|
differ |= newdiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (differ)
|
||||||
{
|
{
|
||||||
status(_("FAILED"));
|
status(_("FAILED"));
|
||||||
fail_count++;
|
fail_count++;
|
||||||
@ -1534,6 +1639,63 @@ open_result_files(void)
|
|||||||
make_directory(file);
|
make_directory(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drop_database_if_exists(const char *dbname)
|
||||||
|
{
|
||||||
|
header(_("dropping database \"%s\""), dbname);
|
||||||
|
psql_command("postgres", "DROP DATABASE IF EXISTS \"%s\"", dbname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_database(const char *dbname)
|
||||||
|
{
|
||||||
|
_stringlist *sl;
|
||||||
|
/*
|
||||||
|
* We use template0 so that any installation-local cruft in template1 will
|
||||||
|
* not mess up the tests.
|
||||||
|
*/
|
||||||
|
header(_("creating database \"%s\""), dbname);
|
||||||
|
if (encoding)
|
||||||
|
psql_command("postgres", "CREATE DATABASE \"%s\" TEMPLATE=template0 ENCODING='%s'", dbname, encoding);
|
||||||
|
else
|
||||||
|
psql_command("postgres", "CREATE DATABASE \"%s\" TEMPLATE=template0", dbname);
|
||||||
|
psql_command(dbname,
|
||||||
|
"ALTER DATABASE \"%s\" SET lc_messages TO 'C';"
|
||||||
|
"ALTER DATABASE \"%s\" SET lc_monetary TO 'C';"
|
||||||
|
"ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
|
||||||
|
"ALTER DATABASE \"%s\" SET lc_time TO 'C';"
|
||||||
|
"ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
|
||||||
|
dbname, dbname, dbname, dbname, dbname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install any requested procedural languages
|
||||||
|
*/
|
||||||
|
for (sl = loadlanguage; sl != NULL; sl = sl->next)
|
||||||
|
{
|
||||||
|
header(_("installing %s"), sl->str);
|
||||||
|
psql_command(dbname, "CREATE LANGUAGE \"%s\"", sl->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drop_role_if_exists(const char *rolename)
|
||||||
|
{
|
||||||
|
header(_("dropping role \"%s\""), rolename);
|
||||||
|
psql_command("postgres", "DROP ROLE IF EXISTS \"%s\"", rolename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_role(const char *rolename, const _stringlist *granted_dbs)
|
||||||
|
{
|
||||||
|
header(_("creating role \"%s\""), rolename);
|
||||||
|
psql_command("postgres", "CREATE ROLE \"%s\" WITH LOGIN", rolename);
|
||||||
|
for (; granted_dbs != NULL; granted_dbs = granted_dbs->next)
|
||||||
|
{
|
||||||
|
psql_command("postgres", "GRANT ALL ON DATABASE \"%s\" TO \"%s\"",
|
||||||
|
granted_dbs->str, rolename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
help(void)
|
help(void)
|
||||||
{
|
{
|
||||||
@ -1547,6 +1709,7 @@ help(void)
|
|||||||
printf(_(" --inputdir=DIR take input files from DIR (default \".\")\n"));
|
printf(_(" --inputdir=DIR take input files from DIR (default \".\")\n"));
|
||||||
printf(_(" --load-language=lang load the named language before running the\n"));
|
printf(_(" --load-language=lang load the named language before running the\n"));
|
||||||
printf(_(" tests; can appear multiple times\n"));
|
printf(_(" tests; can appear multiple times\n"));
|
||||||
|
printf(_(" --create-role=ROLE create the specified role before testing\n"));
|
||||||
printf(_(" --max-connections=N maximum number of concurrent connections\n"));
|
printf(_(" --max-connections=N maximum number of concurrent connections\n"));
|
||||||
printf(_(" (default is 0 meaning unlimited)\n"));
|
printf(_(" (default is 0 meaning unlimited)\n"));
|
||||||
printf(_(" --multibyte=ENCODING use ENCODING as the multibyte encoding\n"));
|
printf(_(" --multibyte=ENCODING use ENCODING as the multibyte encoding\n"));
|
||||||
@ -1574,7 +1737,7 @@ help(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc)
|
||||||
{
|
{
|
||||||
_stringlist *sl;
|
_stringlist *sl;
|
||||||
int c;
|
int c;
|
||||||
@ -1602,6 +1765,7 @@ main(int argc, char *argv[])
|
|||||||
{"user", required_argument, NULL, 15},
|
{"user", required_argument, NULL, 15},
|
||||||
{"psqldir", required_argument, NULL, 16},
|
{"psqldir", required_argument, NULL, 16},
|
||||||
{"srcdir", required_argument, NULL, 17},
|
{"srcdir", required_argument, NULL, 17},
|
||||||
|
{"create-role", required_argument, NULL, 18},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1613,6 +1777,12 @@ main(int argc, char *argv[])
|
|||||||
hostname = "localhost";
|
hostname = "localhost";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We call the initialization function here because that way we can set
|
||||||
|
* default parameters and let them be overwritten by the commandline.
|
||||||
|
*/
|
||||||
|
ifunc();
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "hV", long_options, &option_index)) != -1)
|
while ((c = getopt_long(argc, argv, "hV", long_options, &option_index)) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
@ -1624,7 +1794,7 @@ main(int argc, char *argv[])
|
|||||||
printf("pg_regress (PostgreSQL %s)\n", PG_VERSION);
|
printf("pg_regress (PostgreSQL %s)\n", PG_VERSION);
|
||||||
exit_nicely(0);
|
exit_nicely(0);
|
||||||
case 1:
|
case 1:
|
||||||
dbname = strdup(optarg);
|
split_to_stringlist(strdup(optarg), ", ", &dblist);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
debug = true;
|
debug = true;
|
||||||
@ -1697,6 +1867,9 @@ main(int argc, char *argv[])
|
|||||||
case 17:
|
case 17:
|
||||||
srcdir = strdup(optarg);
|
srcdir = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 18:
|
||||||
|
split_to_stringlist(strdup(optarg), ", ", &extraroles);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* getopt_long already emitted a complaint */
|
/* getopt_long already emitted a complaint */
|
||||||
fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"),
|
fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"),
|
||||||
@ -1865,45 +2038,21 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Using an existing installation, so may need to get rid of
|
* Using an existing installation, so may need to get rid of
|
||||||
* pre-existing database.
|
* pre-existing database(s) and role(s)
|
||||||
*/
|
*/
|
||||||
header(_("dropping database \"%s\""), dbname);
|
for (sl = dblist; sl; sl = sl->next)
|
||||||
psql_command("postgres", "DROP DATABASE IF EXISTS \"%s\"", dbname);
|
drop_database_if_exists(sl->str);
|
||||||
|
for (sl = extraroles; sl; sl = sl->next)
|
||||||
|
drop_role_if_exists(sl->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the test database
|
* Create the test database(s) and role(s)
|
||||||
*
|
|
||||||
* We use template0 so that any installation-local cruft in template1 will
|
|
||||||
* not mess up the tests.
|
|
||||||
*/
|
*/
|
||||||
header(_("creating database \"%s\""), dbname);
|
for (sl = dblist; sl; sl = sl->next)
|
||||||
if (encoding)
|
create_database(sl->str);
|
||||||
psql_command("postgres",
|
for (sl = extraroles; sl; sl = sl->next)
|
||||||
"CREATE DATABASE \"%s\" TEMPLATE=template0 ENCODING='%s'",
|
create_role(sl->str, dblist);
|
||||||
dbname, encoding);
|
|
||||||
else
|
|
||||||
/* use installation default */
|
|
||||||
psql_command("postgres",
|
|
||||||
"CREATE DATABASE \"%s\" TEMPLATE=template0",
|
|
||||||
dbname);
|
|
||||||
|
|
||||||
psql_command(dbname,
|
|
||||||
"ALTER DATABASE \"%s\" SET lc_messages TO 'C';"
|
|
||||||
"ALTER DATABASE \"%s\" SET lc_monetary TO 'C';"
|
|
||||||
"ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
|
|
||||||
"ALTER DATABASE \"%s\" SET lc_time TO 'C';"
|
|
||||||
"ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
|
|
||||||
dbname, dbname, dbname, dbname, dbname);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install any requested PL languages
|
|
||||||
*/
|
|
||||||
for (sl = loadlanguage; sl != NULL; sl = sl->next)
|
|
||||||
{
|
|
||||||
header(_("installing %s"), sl->str);
|
|
||||||
psql_command(dbname, "CREATE LANGUAGE \"%s\"", sl->str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ready to run the tests
|
* Ready to run the tests
|
||||||
@ -1912,12 +2061,12 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
for (sl = schedulelist; sl != NULL; sl = sl->next)
|
for (sl = schedulelist; sl != NULL; sl = sl->next)
|
||||||
{
|
{
|
||||||
run_schedule(sl->str);
|
run_schedule(sl->str, tfunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sl = extra_tests; sl != NULL; sl = sl->next)
|
for (sl = extra_tests; sl != NULL; sl = sl->next)
|
||||||
{
|
{
|
||||||
run_single_test(sl->str);
|
run_single_test(sl->str, tfunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
59
src/test/regress/pg_regress.h
Normal file
59
src/test/regress/pg_regress.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* pg_regress.h --- regression test driver
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/test/regress/pg_regress.h,v 1.1 2007/06/12 11:07:34 mha Exp $
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres_fe.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#define PID_TYPE pid_t
|
||||||
|
#define INVALID_PID (-1)
|
||||||
|
#else
|
||||||
|
#define PID_TYPE HANDLE
|
||||||
|
#define INVALID_PID INVALID_HANDLE_VALUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* simple list of strings */
|
||||||
|
typedef struct _stringlist
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
struct _stringlist *next;
|
||||||
|
} _stringlist;
|
||||||
|
|
||||||
|
typedef PID_TYPE (*test_function)(const char *,
|
||||||
|
_stringlist **,
|
||||||
|
_stringlist **,
|
||||||
|
_stringlist **);
|
||||||
|
typedef void (*init_function)(void);
|
||||||
|
|
||||||
|
extern char *bindir;
|
||||||
|
extern char *libdir;
|
||||||
|
extern char *datadir;
|
||||||
|
extern char *host_platform;
|
||||||
|
|
||||||
|
extern _stringlist *dblist;
|
||||||
|
extern bool debug;
|
||||||
|
extern char *inputdir;
|
||||||
|
extern char *outputdir;
|
||||||
|
/*
|
||||||
|
* This should not be global but every module should be able to read command
|
||||||
|
* line parameters.
|
||||||
|
*/
|
||||||
|
extern char *psqldir;
|
||||||
|
|
||||||
|
extern const char *basic_diff_opts;
|
||||||
|
extern const char *pretty_diff_opts;
|
||||||
|
|
||||||
|
int regression_main(int argc, char *argv[],
|
||||||
|
init_function ifunc, test_function tfunc);
|
||||||
|
void add_stringlist_item(_stringlist ** listhead, const char *str);
|
||||||
|
PID_TYPE spawn_process(const char *cmdline);
|
||||||
|
void exit_nicely(int code);
|
||||||
|
void replace_string(char *string, char *replace, char *replacement);
|
||||||
|
|
78
src/test/regress/pg_regress_main.c
Normal file
78
src/test/regress/pg_regress_main.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* pg_regress_main --- regression test for the main backend
|
||||||
|
*
|
||||||
|
* This is a C implementation of the previous shell script for running
|
||||||
|
* the regression tests, and should be mostly compatible with it.
|
||||||
|
* Initial author of C translation: Magnus Hagander
|
||||||
|
*
|
||||||
|
* This code is released under the terms of the PostgreSQL License.
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/test/regress/pg_regress_main.c,v 1.1 2007/06/12 11:07:34 mha Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pg_regress.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start a psql test process for specified file (including redirection),
|
||||||
|
* and return process ID
|
||||||
|
*/
|
||||||
|
static PID_TYPE
|
||||||
|
psql_start_test(const char *testname,
|
||||||
|
_stringlist **resultfiles,
|
||||||
|
_stringlist **expectfiles,
|
||||||
|
_stringlist **tags)
|
||||||
|
{
|
||||||
|
PID_TYPE pid;
|
||||||
|
char infile[MAXPGPATH];
|
||||||
|
char outfile[MAXPGPATH];
|
||||||
|
char expectfile[MAXPGPATH];
|
||||||
|
char psql_cmd[MAXPGPATH * 3];
|
||||||
|
|
||||||
|
snprintf(infile, sizeof(infile), "%s/sql/%s.sql",
|
||||||
|
inputdir, testname);
|
||||||
|
snprintf(outfile, sizeof(outfile), "%s/results/%s.out",
|
||||||
|
outputdir, testname);
|
||||||
|
snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out",
|
||||||
|
inputdir, testname);
|
||||||
|
|
||||||
|
add_stringlist_item(resultfiles, outfile);
|
||||||
|
add_stringlist_item(expectfiles, expectfile);
|
||||||
|
|
||||||
|
snprintf(psql_cmd, sizeof(psql_cmd),
|
||||||
|
SYSTEMQUOTE "\"%s%spsql\" -X -a -q -d \"%s\" < \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
|
||||||
|
psqldir ? psqldir : "",
|
||||||
|
psqldir ? "/" : "",
|
||||||
|
dblist->str,
|
||||||
|
infile,
|
||||||
|
outfile);
|
||||||
|
|
||||||
|
pid = spawn_process(psql_cmd);
|
||||||
|
|
||||||
|
if (pid == INVALID_PID)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("could not start process for test %s\n"),
|
||||||
|
testname);
|
||||||
|
exit_nicely(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
psql_init(void)
|
||||||
|
{
|
||||||
|
/* set default regression database name */
|
||||||
|
add_stringlist_item(&dblist, "regression");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return regression_main(argc, argv, psql_init, psql_start_test);
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
float4/i.86-pc-mingw32=float4-exp-three-digits
|
float4:out:i.86-pc-mingw32=float4-exp-three-digits.out
|
||||||
float4/i.86-pc-win32vc=float4-exp-three-digits
|
float4:out:i.86-pc-win32vc=float4-exp-three-digits.out
|
||||||
float8/i.86-.*-freebsd=float8-small-is-zero
|
float8:out:i.86-.*-freebsd=float8-small-is-zero.out
|
||||||
float8/i.86-.*-openbsd=float8-small-is-zero
|
float8:out:i.86-.*-openbsd=float8-small-is-zero.out
|
||||||
float8/i.86-.*-netbsd=float8-small-is-zero
|
float8:out:i.86-.*-netbsd=float8-small-is-zero.out
|
||||||
float8/m68k-.*-netbsd=float8-small-is-zero
|
float8:out:m68k-.*-netbsd=float8-small-is-zero.out
|
||||||
float8/i.86-pc-mingw32=float8-exp-three-digits-win32
|
float8:out:i.86-pc-mingw32=float8-exp-three-digits-win32.out
|
||||||
float8/i.86-pc-win32vc=float8-exp-three-digits-win32
|
float8:out:i.86-pc-win32vc=float8-exp-three-digits-win32.out
|
||||||
float8/i.86-pc-cygwin=float8-small-is-zero
|
float8:out:i.86-pc-cygwin=float8-small-is-zero.out
|
||||||
int8/i.86-pc-mingw32=int8-exp-three-digits
|
int8:out:i.86-pc-mingw32=int8-exp-three-digits.out
|
||||||
int8/i.86-pc-win32vc=int8-exp-three-digits
|
int8:out:i.86-pc-win32vc=int8-exp-three-digits.out
|
||||||
|
@ -3,7 +3,7 @@ package Install;
|
|||||||
#
|
#
|
||||||
# Package that provides 'make install' functionality for msvc builds
|
# Package that provides 'make install' functionality for msvc builds
|
||||||
#
|
#
|
||||||
# $PostgreSQL: pgsql/src/tools/msvc/Install.pm,v 1.15 2007/05/13 15:33:07 mha Exp $
|
# $PostgreSQL: pgsql/src/tools/msvc/Install.pm,v 1.16 2007/06/12 11:07:34 mha Exp $
|
||||||
#
|
#
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
@ -25,6 +25,7 @@ sub Install
|
|||||||
require 'config.pl';
|
require 'config.pl';
|
||||||
|
|
||||||
chdir("../../..") if (-f "../../../configure");
|
chdir("../../..") if (-f "../../../configure");
|
||||||
|
chdir("../../../..") if (-f "../../../../configure");
|
||||||
my $conf = "";
|
my $conf = "";
|
||||||
if (-d "debug")
|
if (-d "debug")
|
||||||
{
|
{
|
||||||
@ -115,6 +116,7 @@ sub CopySetOfFiles
|
|||||||
{
|
{
|
||||||
chomp;
|
chomp;
|
||||||
next if /regress/; # Skip temporary install in regression subdir
|
next if /regress/; # Skip temporary install in regression subdir
|
||||||
|
next if /ecpg.test/; # Skip temporary install in regression subdir
|
||||||
my $tgt = $target . basename($_);
|
my $tgt = $target . basename($_);
|
||||||
print ".";
|
print ".";
|
||||||
my $src = $norecurse?(dirname($spec) . '/' . $_):$_;
|
my $src = $norecurse?(dirname($spec) . '/' . $_):$_;
|
||||||
|
@ -3,7 +3,7 @@ package Mkvcbuild;
|
|||||||
#
|
#
|
||||||
# Package that generates build files for msvc build
|
# Package that generates build files for msvc build
|
||||||
#
|
#
|
||||||
# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.11 2007/04/27 16:45:54 mha Exp $
|
# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.12 2007/06/12 11:07:34 mha Exp $
|
||||||
#
|
#
|
||||||
use Carp;
|
use Carp;
|
||||||
use Win32;
|
use Win32;
|
||||||
@ -154,6 +154,15 @@ sub mkvcbuild
|
|||||||
$ecpg->AddDefine('PATCHLEVEL=1');
|
$ecpg->AddDefine('PATCHLEVEL=1');
|
||||||
$ecpg->AddReference($libpgport);
|
$ecpg->AddReference($libpgport);
|
||||||
|
|
||||||
|
my $pgregress_ecpg = $solution->AddProject('pg_regress_ecpg','exe','misc');
|
||||||
|
$pgregress_ecpg->AddFile('src\interfaces\ecpg\test\pg_regress_ecpg.c');
|
||||||
|
$pgregress_ecpg->AddFile('src\test\regress\pg_regress.c');
|
||||||
|
$pgregress_ecpg->AddIncludeDir('src\port');
|
||||||
|
$pgregress_ecpg->AddIncludeDir('src\test\regress');
|
||||||
|
$pgregress_ecpg->AddDefine('HOST_TUPLE="i686-pc-win32vc"');
|
||||||
|
$pgregress_ecpg->AddDefine('FRONTEND');
|
||||||
|
$pgregress_ecpg->AddReference($libpgport);
|
||||||
|
|
||||||
# src/bin
|
# src/bin
|
||||||
my $initdb = AddSimpleFrontend('initdb', 1);
|
my $initdb = AddSimpleFrontend('initdb', 1);
|
||||||
$initdb->AddLibrary('wsock32.lib ws2_32.lib');
|
$initdb->AddLibrary('wsock32.lib ws2_32.lib');
|
||||||
@ -315,6 +324,7 @@ sub mkvcbuild
|
|||||||
|
|
||||||
my $pgregress = $solution->AddProject('pg_regress','exe','misc');
|
my $pgregress = $solution->AddProject('pg_regress','exe','misc');
|
||||||
$pgregress->AddFile('src\test\regress\pg_regress.c');
|
$pgregress->AddFile('src\test\regress\pg_regress.c');
|
||||||
|
$pgregress->AddFile('src\test\regress\pg_regress_main.c');
|
||||||
$pgregress->AddIncludeDir('src\port');
|
$pgregress->AddIncludeDir('src\port');
|
||||||
$pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"');
|
$pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"');
|
||||||
$pgregress->AddDefine('FRONTEND');
|
$pgregress->AddDefine('FRONTEND');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
REM $PostgreSQL: pgsql/src/tools/msvc/clean.bat,v 1.4 2007/03/23 09:53:33 mha Exp $
|
REM $PostgreSQL: pgsql/src/tools/msvc/clean.bat,v 1.5 2007/06/12 11:07:34 mha Exp $
|
||||||
|
|
||||||
set D=%CD%
|
set D=%CD%
|
||||||
if exist ..\msvc if exist ..\..\..\src cd ..\..\..
|
if exist ..\msvc if exist ..\..\..\src cd ..\..\..
|
||||||
@ -59,6 +59,10 @@ call :del tsearch2\tsearch2.sql
|
|||||||
call :del tsearch2\uninstall_tsearch2.sql
|
call :del tsearch2\uninstall_tsearch2.sql
|
||||||
|
|
||||||
cd %D%
|
cd %D%
|
||||||
|
|
||||||
|
REM Clean up ecpg regression test files
|
||||||
|
msbuild ecpg_regression.proj /t:clean /v:q
|
||||||
|
|
||||||
goto :eof
|
goto :eof
|
||||||
|
|
||||||
|
|
||||||
|
46
src/tools/msvc/ecpg_regression.proj
Normal file
46
src/tools/msvc/ecpg_regression.proj
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="all">
|
||||||
|
<!--
|
||||||
|
MSBuild project file to build ecpg regression tests
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TESTDIR>..\..\interfaces\ecpg\test</TESTDIR>
|
||||||
|
<CONFIG>Debug</CONFIG>
|
||||||
|
<OUTDIR>..\..\..\..\..\$(CONFIG)\</OUTDIR>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(CONFIG)'=='DEBUG'">
|
||||||
|
<!-- set debug runtime library if necessary to be compatible with the LIB files generated -->
|
||||||
|
<DEBUGLIB>d</DEBUGLIB>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Pgc Include="$(TESTDIR)\**\*.pgc" Exclude="$(TESTDIR)\performance\perftest.pgc"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<OutputToDelete Include="$(TESTDIR)\**\*.exe" />
|
||||||
|
<OutputToDelete Include="$(TESTDIR)\**\*.exe.manifest" />
|
||||||
|
<OutputToDelete Include="$(TESTDIR)\**\*.obj" />
|
||||||
|
<OutputToDelete Include="$(TESTDIR)\**\*.c" Exclude="$(TESTDIR)\pg_regress_ecpg.c;$(TESTDIR)\expected\*.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="all" Inputs="@(Pgc)" Outputs="%(RelativeDir)%(Filename).exe">
|
||||||
|
<!-- Set special parameters for some tests -->
|
||||||
|
<CreateProperty Value="-C INFORMIX" Condition="'%(Pgc.RelativeDir)'=='$(TESTDIR)\compat_informix\'">
|
||||||
|
<Output TaskParameter="Value" PropertyName="ECPGPARAM" />
|
||||||
|
</CreateProperty>
|
||||||
|
<CreateProperty Value="-C INFORMIX -r no_indicator" Condition="'%(Pgc.FileName)'=='rnull'">
|
||||||
|
<Output TaskParameter="Value" PropertyName="ECPGPARAM" />
|
||||||
|
</CreateProperty>
|
||||||
|
|
||||||
|
<!-- Run ECPG and the Visual C++ compiler on the files. Don't bother with dependency check between the steps -->
|
||||||
|
<Exec WorkingDirectory="%(Pgc.RelativeDir)" Command="$(OUTDIR)ecpg\ecpg -I ../../include --regression $(ECPGPARAM) -o %(Pgc.Filename).c %(Pgc.Filename).pgc" />
|
||||||
|
<Exec WorkingDirectorY="%(Pgc.RelativeDir)" Command="cl /nologo %(Pgc.FileName).c /TC /MD$(DEBUGLIB) /DENABLE_THREAD_SAFETY /DWIN32 /DWIN32_ONLY_COMPILER /I. /I..\..\include /I..\..\..\libpq /I..\..\..\..\include /link /defaultlib:$(OUTDIR)libecpg\libecpg.lib /defaultlib:$(OUTDIR)libecpg_compat\libecpg_compat.lib /defaultlib:$(OUTDIR)libpgtypes\libpgtypes.lib" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- Clean up all output files -->
|
||||||
|
<Target Name="clean">
|
||||||
|
<Delete Files="@(OutputToDelete)" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
@ -1,5 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
REM $PostgreSQL: pgsql/src/tools/msvc/vcregress.bat,v 1.11 2007/04/21 20:58:05 mha Exp $
|
REM $PostgreSQL: pgsql/src/tools/msvc/vcregress.bat,v 1.12 2007/06/12 11:07:34 mha Exp $
|
||||||
|
|
||||||
SETLOCAL
|
SETLOCAL
|
||||||
SET STARTDIR=%CD%
|
SET STARTDIR=%CD%
|
||||||
@ -11,6 +11,7 @@ if /I "%1"=="check" SET what=CHECK
|
|||||||
if /I "%1"=="installcheck" SET what=INSTALLCHECK
|
if /I "%1"=="installcheck" SET what=INSTALLCHECK
|
||||||
if /I "%1"=="plcheck" SET what=PLCHECK
|
if /I "%1"=="plcheck" SET what=PLCHECK
|
||||||
if /I "%1"=="contribcheck" SET what=CONTRIBCHECK
|
if /I "%1"=="contribcheck" SET what=CONTRIBCHECK
|
||||||
|
if /I "%1"=="ecpgcheck" SET what=ECPGCHECK
|
||||||
if "%what%"=="" goto usage
|
if "%what%"=="" goto usage
|
||||||
|
|
||||||
SET CONFIG=Debug
|
SET CONFIG=Debug
|
||||||
@ -28,10 +29,20 @@ SET SCHEDULE=parallel
|
|||||||
SET TEMPPORT=54321
|
SET TEMPPORT=54321
|
||||||
IF NOT "%2"=="" SET SCHEDULE=%2
|
IF NOT "%2"=="" SET SCHEDULE=%2
|
||||||
|
|
||||||
SET PERL5LIB=..\..\tools\msvc
|
IF "%what%"=="ECPGCHECK" (
|
||||||
|
cd "%STARTDIR%"
|
||||||
|
msbuild ecpg_regression.proj /p:config=%CONFIG%
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
cd "%TOPDIR%"
|
||||||
|
cd src\interfaces\ecpg\test
|
||||||
|
SET SCHEDULE=ecpg
|
||||||
|
)
|
||||||
|
|
||||||
|
SET PERL5LIB=%TOPDIR%\src\tools\msvc
|
||||||
|
|
||||||
if "%what%"=="INSTALLCHECK" ..\..\..\%CONFIG%\pg_regress\pg_regress --psqldir="..\..\..\%CONFIG%\psql" --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale
|
if "%what%"=="INSTALLCHECK" ..\..\..\%CONFIG%\pg_regress\pg_regress --psqldir="..\..\..\%CONFIG%\psql" --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale
|
||||||
if "%what%"=="CHECK" ..\..\..\%CONFIG%\pg_regress\pg_regress --psqldir="..\..\..\%CONFIG%\psql" --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale --temp-install=./tmp_check --top-builddir="%TOPDIR%" --temp-port=%TEMPPORT%
|
if "%what%"=="CHECK" ..\..\..\%CONFIG%\pg_regress\pg_regress --psqldir="..\..\..\%CONFIG%\psql" --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale --temp-install=./tmp_check --top-builddir="%TOPDIR%" --temp-port=%TEMPPORT%
|
||||||
|
if "%what%"=="ECPGCHECK" ..\..\..\..\%CONFIG%\pg_regress_ecpg\pg_regress_ecpg --psqldir="..\..\..\%CONFIG%\psql" --dbname=regress1,connectdb --create-role=connectuser,connectdb --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale --temp-install=./tmp_check --top-builddir="%TOPDIR%" --temp-port=%TEMPPORT%
|
||||||
if "%what%"=="PLCHECK" call :plcheck
|
if "%what%"=="PLCHECK" call :plcheck
|
||||||
if "%what%"=="CONTRIBCHECK" call :contribcheck
|
if "%what%"=="CONTRIBCHECK" call :contribcheck
|
||||||
SET E=%ERRORLEVEL%
|
SET E=%ERRORLEVEL%
|
||||||
@ -40,7 +51,7 @@ cd "%STARTDIR%"
|
|||||||
exit /b %E%
|
exit /b %E%
|
||||||
|
|
||||||
:usage
|
:usage
|
||||||
echo "Usage: vcregress <check|installcheck> [schedule]"
|
echo "Usage: vcregress <check|installcheck|plcheck|contribcheck|ecpgcheck> [schedule]"
|
||||||
goto :eof
|
goto :eof
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user