#! /bin/sh
-# $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.8 2000/10/22 22:15:09 petere Exp $
+# $PostgreSQL: pgsql/src/test/regress/pg_regress.sh,v 1.65 2006/07/18 00:32:41 tgl Exp $
me=`basename $0`
: ${TMPDIR=/tmp}
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 \`.')
--schedule=FILE use test ordering schedule from FILE
(may be used multiple times to concatenate)
--temp-install[=DIR] create a temporary installation (in DIR)
+ --no-locale use C locale
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
Options for using an existing installation:
--host=HOST use postmaster running on HOST
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
+
# ----------
# Check for echo -n vs echo \c
bindir='@bindir@'
datadir='@datadir@'
host_platform='@host_tuple@'
+enable_shared='@enable_shared@'
+GCC=@GCC@
+
+if [ "$GCC" = yes ]; then
+ compiler=gcc
+else
+ compiler=cc
+fi
unset mode
unset schedule
unset debug
+unset nolocale
unset top_builddir
unset temp_install
unset multibyte
-export PGHOST
-export PGPORT
-
dbname=regression
hostname=localhost
+maxconnections=0
+temp_port=65432
+load_langs=""
: ${GMAKE='@GMAKE@'}
--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;;
+ --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=\(.*\)"`
esac
done
-
# ----------
-# When on Windows, QNX or BeOS, don't use Unix sockets.
+# warn of Cygwin likely failure if maxconnections = 0
+# and we are running parallel tests
# ----------
case $host_platform in
- *-*-cygwin* | *-*-qnx* | *beos*)
+ *-*-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
+
+
+# ----------
+# On some platforms we can't use Unix sockets.
+# ----------
+case $host_platform in
+ *-*-cygwin* | *-*-mingw32*)
unix_sockets=no;;
*)
unix_sockets=yes;;
# ----------
case $host_platform in
- *-*-qnx*)
+ *-*-sco3.2v5*)
DIFFFLAGS=-b;;
*)
DIFFFLAGS=-w;;
# ----------
PGTZ='PST8PDT'; export PGTZ
-PGDATESTYLE='ISO,US'; export PGDATESTYLE
+PGDATESTYLE='ISO, MDY'; export PGDATESTYLE
# ----------
# with the result of the last shell command before the `exit'. Hence
# we have to write `(exit x); exit' below this point.
-trap '
- savestatus=$?
+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
-' 0
+}
+
+trap 'exit_trap $?' 0
-trap '
- savestatus=$?
+sig_trap() {
+ savestatus=$1
echo; echo "caught signal"
if [ -n "$postmaster_pid" ]; then
echo "signalling fast shutdown to postmaster with pid $postmaster_pid"
unset postmaster_pid
fi
(exit $savestatus); exit
-' 1 2 13 15
+}
+
+trap 'sig_trap $?' 1 2 13 15
# ----------
# Scan resultmap file to find which platform-specific expected files to use.
# The format of each line of the file is
-# testname/hostplatformpattern=substitutefile
+# testname/hostplatformpattern=substitutefile
# where the hostplatformpattern is evaluated per the rules of expr(1),
# namely, it is a standard regular expression with an implicit ^ at the start.
+# What hostplatformpattern will be matched against is the config.guess output
+# followed by either ':gcc' or ':cc' (independent of the actual name of the
+# compiler executable).
#
# The tempfile hackery is needed because some shells will run the loop
# inside a subshell, whereupon shell variables set therein aren't seen
# ----------
cat /dev/null >$TMPFILE
-while read LINE
-do
- HOSTPAT=`expr "$LINE" : '.*/\(.*\)='`
- if [ `expr "$host_platform" : "$HOSTPAT"` -ne 0 ]
- then
- # remove hostnamepattern from line so that there are no shell
- # wildcards in SUBSTLIST; else later 'for' could expand them!
- TESTNAME=`expr "$LINE" : '\(.*\)/'`
- SUBST=`echo "$LINE" | sed 's/^.*=//'`
- echo "$TESTNAME=$SUBST" >> $TMPFILE
- fi
-done <"$inputdir/resultmap"
+if [ -f "$inputdir/resultmap" ]
+then
+ while read LINE
+ do
+ HOSTPAT=`expr "$LINE" : '.*/\(.*\)='`
+ if [ `expr "$host_platform:$compiler" : "$HOSTPAT"` -ne 0 ]
+ then
+ # remove hostnamepattern from line so that there are no shell
+ # wildcards in SUBSTLIST; else later 'for' could expand them!
+ TESTNAME=`expr "$LINE" : '\(.*\)/'`
+ SUBST=`echo "$LINE" | sed 's/^.*=//'`
+ echo "$TESTNAME=$SUBST" >> $TMPFILE
+ fi
+ done <"$inputdir/resultmap"
+fi
SUBSTLIST=`cat $TMPFILE`
rm -f $TMPFILE
temp_install="`pwd`/$temp_install"
fi
- bindir=$temp_install/$bindir
- libdir=$temp_install/$libdir
- datadir=$temp_install/$datadir
+ 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
- PGPORT=65432
+
+ # 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,
- # feel free to account for others as well.
+ # (if you run multibyte). LD_LIBRARY_PATH covers many platforms.
+ # DYLD_LIBRARY_PATH works on Darwin, and maybe other Mach-based systems.
+ # Feel free to account for others as well.
# ----------
if [ -n "$LD_LIBRARY_PATH" ]; then
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
+
+ # ----------
+ # 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"
if [ ! -d "$LOGDIR" ]; then
mkdir -p "$LOGDIR" || { (exit 2); exit; }
fi
- $GMAKE -C "$top_builddir" DESTDIR="$temp_install" install >"$LOGDIR/install.log" 2>&1
+ $GMAKE -C "$top_builddir" DESTDIR="$temp_install/install" install with_perl=no with_python=no >"$LOGDIR/install.log" 2>&1
if [ $? -ne 0 ]
then
(exit 2); exit
fi
-
message "initializing database system"
- [ "$debug" = yes ] && initdb_options='--debug'
+ [ "$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 ]
message "starting postmaster"
[ "$debug" = yes ] && postmaster_options="$postmaster_options -d 5"
- [ "$unix_sockets" = no ] && postmaster_options="$postmaster_options -i"
+ if [ "$unix_sockets" = no ]; 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"
(exit 2); exit
fi
- # give postmaster some time to pass WAL recovery
- sleep 3
-
else # not temp-install
- # If Unix sockets are not available, use the local host by default.
- [ "$unix_sockets" = no ] && ${PGHOST=$hostname}
+ # ----------
+ # 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"
if [ -n "$PGHOST" ]; then
echo "(using postmaster on $PGHOST, $port_info)"
else
- echo "(using postmaster on Unix socket, $port_info)"
+ if [ "$unix_sockets" = no ]; then
+ echo "(using postmaster on localhost, $port_info)"
+ else
+ echo "(using postmaster on Unix socket, $port_info)"
+ fi
fi
+
message "dropping database \"$dbname\""
- "$bindir/dropdb" $psql_options "$dbname" >/dev/null 2>&1
+ "$bindir/dropdb" $psql_options "$dbname"
# errors can be ignored
fi
# Set up SQL shell for the test.
# ----------
-PSQL="$bindir/psql -a -q -X $psql_options"
+psql_test_options="-a -q -X $psql_options"
# ----------
# ----------
PGTZ='PST8PDT'; export PGTZ
-PGDATESTYLE='Postgres,US'; export PGDATESTYLE
+PGDATESTYLE='Postgres, MDY'; export PGDATESTYLE
# ----------
# ----------
# Create the regression database
+# We use template0 so that any installation-local cruft in template1
+# will not mess up the tests.
# ----------
message "creating database \"$dbname\""
-"$bindir/createdb" $encoding_opt $psql_options "$dbname"
+"$bindir/createdb" $encoding_opt $psql_options --template template0 "$dbname"
if [ $? -ne 0 ]; then
echo "$me: createdb failed"
(exit 2); exit
fi
+"$bindir/psql" -q -X $psql_options -c "\
+alter database \"$dbname\" set lc_messages to 'C';
+alter database \"$dbname\" set lc_monetary to 'C';
+alter database \"$dbname\" set lc_numeric to 'C';
+alter database \"$dbname\" set lc_time to 'C';" "$dbname"
+if [ $? -ne 0 ]; then
+ echo "$me: could not set database default locales"
+ (exit 2); exit
+fi
+
# ----------
-# Install the PL/pgSQL language in it
+# Install any requested PL languages
# ----------
-case $host_platform in
- *-*-qnx*) : ;;
- *)
- message "installing PL/pgSQL"
- "$bindir/createlang" -L "$libdir" $psql_options plpgsql $dbname
- if [ $? -ne 0 ] && [ $? -ne 2 ]; then
- echo "$me: createlang failed"
- (exit 2); exit
+if [ "$enable_shared" = yes ]; then
+ for lang in xyzzy $load_langs ; do
+ if [ "$lang" != "xyzzy" ]; then
+ message "installing $lang"
+ "$bindir/createlang" $psql_options $lang $dbname
+ if [ $? -ne 0 ] && [ $? -ne 2 ]; then
+ echo "$me: createlang $lang failed"
+ (exit 2); exit
+ fi
fi
- ;;
-esac
+ done
+fi
# ----------
lno=0
(
- cat $schedule
+ [ "$enable_shared" != yes ] && echo "ignore: plpgsql"
+ cat $schedule </dev/null
for x in $extra_tests; do
echo "test: $x"
done
# Run a single test
formatted=`echo $1 | awk '{printf "%-20.20s", $1;}'`
$ECHO_N "test $formatted ... $ECHO_C"
-
- $PSQL -d "$dbname" <"$inputdir/sql/$1.sql" >"$outputdir/results/$1.out" 2>&1
+ ( "$bindir/psql" $psql_test_options -d "$dbname" <"$inputdir/sql/$1.sql" >"$outputdir/results/$1.out" 2>&1 )&
+ wait
else
# Start a parallel group
- $ECHO_N "parallel group ($# tests): " $ECHO_C
+ $ECHO_N "parallel group ($# tests): $ECHO_C"
+ if [ $maxconnections -gt 0 ] ; then
+ connnum=0
+ test $# -gt $maxconnections && $ECHO_N "(in groups of $maxconnections) $ECHO_C"
+ fi
for name do
- ( $PSQL -d $dbname <"$inputdir/sql/$name.sql" >"$outputdir/results/$name.out" 2>&1
+ (
+ "$bindir/psql" $psql_test_options -d "$dbname" <"$inputdir/sql/$name.sql" >"$outputdir/results/$name.out" 2>&1
$ECHO_N " $name$ECHO_C"
) &
+ if [ $maxconnections -gt 0 ] ; then
+ connnum=`expr \( $connnum + 1 \) % $maxconnections`
+ test $connnum -eq 0 && wait
+ fi
done
wait
echo
# to a system-specific expected file.
# There shouldn't be multiple matches, but take the last if there are.
- EXPECTED="$inputdir/expected/${name}.out"
+ EXPECTED="$inputdir/expected/${name}"
for LINE in $SUBSTLIST
do
if [ `expr "$LINE" : "$name="` -ne 0 ]
then
SUBST=`echo "$LINE" | sed 's/^.*=//'`
- EXPECTED="$inputdir/expected/${SUBST}.out"
+ EXPECTED="$inputdir/expected/${SUBST}"
fi
done
- diff $DIFFFLAGS $EXPECTED $outputdir/results/${name}.out >/dev/null 2>&1
- case $? in
+ # If there are multiple equally valid result files, loop to get the right one.
+ # If none match, diff against the closest one.
+
+ bestfile=
+ bestdiff=
+ result=2
+ for thisfile in $EXPECTED.out ${EXPECTED}_[0-9].out; do
+ [ ! -r "$thisfile" ] && continue
+ diff $DIFFFLAGS $thisfile $outputdir/results/${name}.out >/dev/null 2>&1
+ result=$?
+ case $result in
+ 0) break;;
+ 1) thisdiff=`diff $DIFFFLAGS $thisfile $outputdir/results/${name}.out | wc -l`
+ if [ -z "$bestdiff" ] || [ "$thisdiff" -lt "$bestdiff" ]; then
+ bestdiff=$thisdiff; bestfile=$thisfile
+ fi
+ continue;;
+ 2) break;;
+ esac
+ done
+
+ # Now print the result.
+
+ case $result in
0)
echo "ok";;
1)
- ( diff $DIFFFLAGS -C3 $EXPECTED $outputdir/results/${name}.out
+ ( diff $DIFFFLAGS -C3 $bestfile $outputdir/results/${name}.out
echo
echo "======================================================================"
echo ) >> "$diff_file"
fi
;;
2)
- # desaster struck
+ # disaster struck
echo "trouble" 1>&2
(exit 2); exit;;
esac
if [ -n "$postmaster_pid" ]; then
message "shutting down postmaster"
- kill -15 "$postmaster_pid"
+ "$bindir/pg_ctl" -s -D "$PGDATA" stop
+ wait "$postmaster_pid"
unset postmaster_pid
fi
msg="$count_failed of $count_total tests failed."
result=1
else
- msg="$count_failed of $count_total tests failed, $count_ignored failed test(s) ignored."
+ msg="`expr $count_failed + $count_ignored` of $count_total tests failed, $count_ignored of these failures ignored."
result=1
fi