2 # $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.19 2001/02/18 17:53:55 tgl Exp $
6 TMPFILE=$TMPDIR/pg_regress.$$
9 PostgreSQL regression test driver
11 Usage: $me [options...] [extra tests...]
14 --debug turn on debug mode in programs that are run
15 --inputdir=DIR take input files from DIR (default \`.')
16 --multibyte=ENCODING use ENCODING as the multibyte encoding, and
17 also run a test by the same name
18 --outputdir=DIR place output files in DIR (default \`.')
19 --schedule=FILE use test ordering schedule from FILE
20 (may be used multiple times to concatenate)
21 --temp-install[=DIR] create a temporary installation (in DIR)
23 Options for \`temp-install' mode:
24 --top-builddir=DIR (relative) path to top level build directory
26 Options for using an existing installation:
27 --host=HOST use postmaster running on HOST
28 --port=PORT use postmaster running at PORT
29 --user=USER connect as USER
31 The exit status is 0 if all tests passed, 1 if some tests failed, and 2
32 if the tests could not be run for some reason.
34 Report bugs to <pgsql-bugs@postgresql.org>."
38 _dashes='==============' # 14
40 _msg=`echo "$1$_spaces" | cut -c 1-38`
41 echo "$_dashes $_msg $_dashes"
46 # Unset locale settings
49 unset LC_COLLATE LC_CTYPE LC_MONETARY LC_MESSAGES LC_NUMERIC LC_TIME LC_ALL LANG LANGUAGE
53 # Check for echo -n vs echo \c
56 if echo '\c' | grep c >/dev/null 2>&1; then
66 # Initialize default settings
75 host_platform='@host_tuple@'
76 enable_shared='@enable_shared@'
79 if [ "$GCC" = yes ]; then
99 # Parse command line options
109 echo "pg_regress (PostgreSQL @VERSION@)"
115 inputdir=`expr "x$1" : "x--inputdir=\(.*\)"`
118 multibyte=`expr "x$1" : "x--multibyte=\(.*\)"`
121 temp_install=./tmp_check
124 temp_install=`expr "x$1" : "x--temp-install=\(.*\)"`
127 outputdir=`expr "x$1" : "x--outputdir=\(.*\)"`
130 foo=`expr "x$1" : "x--schedule=\(.*\)"`
131 schedule="$schedule $foo"
134 top_builddir=`expr "x$1" : "x--top-builddir=\(.*\)"`
137 PGHOST=`expr "x$1" : "x--host=\(.*\)"`
141 PGPORT=`expr "x$1" : "x--port=\(.*\)"`
145 PGUSER=`expr "x$1" : "x--user=\(.*\)"`
149 echo "$me: invalid argument $1" 1>&2
152 extra_tests="$extra_tests $1"
159 # When on QNX or BeOS, don't use Unix sockets.
162 case $host_platform in
171 # Set up diff to ignore horizontal white space differences.
174 case $host_platform in
183 # Set backend timezone and datestyle explicitly
185 # To pass the horology test in its current form, the postmaster must be
186 # started with PGDATESTYLE=ISO, while the frontend must be started with
187 # PGDATESTYLE=Postgres. We set the postmaster values here and change
188 # to the frontend settings after the postmaster has been started.
191 PGTZ='PST8PDT'; export PGTZ
192 PGDATESTYLE='ISO,US'; export PGDATESTYLE
196 # Exit trap to remove temp file and shut down postmaster
199 # Note: There are some stupid shells (even among recent ones) that
200 # ignore the argument to exit (as in `exit 1') if there is an exit
201 # trap. The trap (and thus the shell script) will then always exit
202 # with the result of the last shell command before the `exit'. Hence
203 # we have to write `(exit x); exit' below this point.
207 if [ -n "$postmaster_pid" ]; then
208 kill -2 "$postmaster_pid"
209 wait "$postmaster_pid"
212 rm -f "$TMPFILE" && exit $savestatus
217 echo; echo "caught signal"
218 if [ -n "$postmaster_pid" ]; then
219 echo "signalling fast shutdown to postmaster with pid $postmaster_pid"
220 kill -2 "$postmaster_pid"
221 wait "$postmaster_pid"
224 (exit $savestatus); exit
230 # Scan resultmap file to find which platform-specific expected files to use.
231 # The format of each line of the file is
232 # testname/hostplatformpattern=substitutefile
233 # where the hostplatformpattern is evaluated per the rules of expr(1),
234 # namely, it is a standard regular expression with an implicit ^ at the start.
235 # What hostplatformpattern will be matched against is the config.guess output
236 # followed by either ':gcc' or ':cc' (independent of the actual name of the
237 # compiler executable).
239 # The tempfile hackery is needed because some shells will run the loop
240 # inside a subshell, whereupon shell variables set therein aren't seen
241 # outside the loop :-(
244 cat /dev/null >$TMPFILE
245 if [ -f "$inputdir/resultmap" ]
249 HOSTPAT=`expr "$LINE" : '.*/\(.*\)='`
250 if [ `expr "$host_platform:$compiler" : "$HOSTPAT"` -ne 0 ]
252 # remove hostnamepattern from line so that there are no shell
253 # wildcards in SUBSTLIST; else later 'for' could expand them!
254 TESTNAME=`expr "$LINE" : '\(.*\)/'`
255 SUBST=`echo "$LINE" | sed 's/^.*=//'`
256 echo "$TESTNAME=$SUBST" >> $TMPFILE
258 done <"$inputdir/resultmap"
260 SUBSTLIST=`cat $TMPFILE`
264 LOGDIR=$outputdir/log
266 if [ x"$temp_install" != x"" ]
268 if echo x"$temp_install" | grep -v '^x/' >/dev/null 2>&1; then
269 temp_install="`pwd`/$temp_install"
272 bindir=$temp_install/install/$bindir
273 libdir=$temp_install/install/$libdir
274 datadir=$temp_install/install/$datadir
275 PGDATA=$temp_install/data
277 if [ "$unix_sockets" = no ]; then
287 # Set up shared library paths, needed by psql and pg_encoding
288 # (if you run multibyte). LD_LIBRARY_PATH covers many platforms,
289 # feel free to account for others as well.
292 if [ -n "$LD_LIBRARY_PATH" ]; then
293 LD_LIBRARY_PATH="$libdir:$LD_LIBRARY_PATH"
295 LD_LIBRARY_PATH=$libdir
297 export LD_LIBRARY_PATH
300 # Windows needs shared libraries in PATH. (Only those linked into
301 # executables, not dlopen'ed ones)
303 case $host_platform in *-*-cygwin*)
309 if [ -d "$temp_install" ]; then
310 message "removing existing temp installation"
311 rm -rf "$temp_install"
314 message "creating temporary installation"
315 if [ ! -d "$LOGDIR" ]; then
316 mkdir -p "$LOGDIR" || { (exit 2); exit; }
318 $GMAKE -C "$top_builddir" DESTDIR="$temp_install/install" install with_perl=no with_python=no >"$LOGDIR/install.log" 2>&1
323 echo "$me: installation failed"
324 echo "Examine $LOGDIR/install.log for the reason."
330 message "initializing database system"
331 [ "$debug" = yes ] && initdb_options='--debug'
332 "$bindir/initdb" -D "$PGDATA" -L "$datadir" --noclean $initdb_options >"$LOGDIR/initdb.log" 2>&1
337 echo "$me: initdb failed"
338 echo "Examine $LOGDIR/initdb.log for the reason."
348 message "starting postmaster"
349 [ "$debug" = yes ] && postmaster_options="$postmaster_options -d 5"
350 [ "$unix_sockets" = no ] && postmaster_options="$postmaster_options -i"
351 "$bindir/postmaster" -D "$PGDATA" -F $postmaster_options >"$LOGDIR/postmaster.log" 2>&1 &
354 if kill -0 $postmaster_pid >/dev/null 2>&1
356 echo "running on port $PGPORT with pid $postmaster_pid"
359 echo "$me: postmaster did not start"
360 echo "Examine $LOGDIR/postmaster.log for the reason."
365 # give postmaster some time to pass WAL recovery
368 else # not temp-install
370 # If Unix sockets are not available, use the local host by default.
371 if [ "$unix_sockets" = no ]; then
376 if [ -n "$PGPORT" ]; then
377 port_info="port $PGPORT"
379 port_info="default port"
382 if [ -n "$PGHOST" ]; then
383 echo "(using postmaster on $PGHOST, $port_info)"
385 echo "(using postmaster on Unix socket, $port_info)"
387 message "dropping database \"$dbname\""
388 "$bindir/dropdb" $psql_options "$dbname"
389 # errors can be ignored
394 # Set up SQL shell for the test.
397 PSQL="$bindir/psql -a -q -X $psql_options"
401 # Set frontend timezone and datestyle explicitly
404 PGTZ='PST8PDT'; export PGTZ
405 PGDATESTYLE='Postgres,US'; export PGDATESTYLE
409 # Set up multibyte environment
412 if [ -n "$multibyte" ]; then
413 PGCLIENTENCODING=$multibyte
414 export PGCLIENTENCODING
415 encoding_opt="-E $multibyte"
417 unset PGCLIENTENCODING
422 # Create the regression database
423 # We use template0 so that any installation-local cruft in template1
424 # will not mess up the tests.
427 message "creating database \"$dbname\""
428 "$bindir/createdb" $encoding_opt $psql_options --template template0 "$dbname"
429 if [ $? -ne 0 ]; then
430 echo "$me: createdb failed"
436 # Install the PL/pgSQL language in it
439 if [ "$enable_shared" = yes ]; then
440 message "installing PL/pgSQL"
441 "$bindir/createlang" -L "$libdir" $psql_options plpgsql $dbname
442 if [ $? -ne 0 ] && [ $? -ne 2 ]; then
443 echo "$me: createlang failed"
453 message "running regression test queries"
455 if [ ! -d "$outputdir/results" ]; then
456 mkdir -p "$outputdir/results" || { (exit 2); exit; }
458 result_summary_file=$outputdir/regression.out
459 diff_file=$outputdir/regression.diffs
461 cat /dev/null >"$result_summary_file"
462 cat /dev/null >"$diff_file"
466 [ "$enable_shared" != yes ] && echo "ignore: plpgsql"
467 cat $schedule </dev/null
468 for x in $extra_tests; do
471 ) | sed 's/[ ]*#.*//g' | \
476 [ -z "$line" ] && continue
480 if [ x"$1" = x"ignore:" ]; then
482 ignore_list="$ignore_list $@"
484 elif [ x"$1" != x"test:" ]; then
485 echo "$me:$schedule:$lno: syntax error"
495 if [ $# -eq 1 ]; then
497 formatted=`echo $1 | awk '{printf "%-20.20s", $1;}'`
498 $ECHO_N "test $formatted ... $ECHO_C"
500 $PSQL -d "$dbname" <"$inputdir/sql/$1.sql" >"$outputdir/results/$1.out" 2>&1
502 # Start a parallel group
503 $ECHO_N "parallel group ($# tests): $ECHO_C"
505 ( $PSQL -d $dbname <"$inputdir/sql/$name.sql" >"$outputdir/results/$name.out" 2>&1
506 $ECHO_N " $name$ECHO_C"
515 # (We do not want to run the diffs immediately after each test,
516 # because they would certainly get corrupted if run in parallel
521 if [ $# -ne 1 ]; then
522 formatted=`echo "$name" | awk '{printf "%-20.20s", $1;}'`
523 $ECHO_N " $formatted ... $ECHO_C"
526 # Check list extracted from resultmap to see if we should compare
527 # to a system-specific expected file.
528 # There shouldn't be multiple matches, but take the last if there are.
530 EXPECTED="$inputdir/expected/${name}.out"
531 for LINE in $SUBSTLIST
533 if [ `expr "$LINE" : "$name="` -ne 0 ]
535 SUBST=`echo "$LINE" | sed 's/^.*=//'`
536 EXPECTED="$inputdir/expected/${SUBST}.out"
540 diff $DIFFFLAGS $EXPECTED $outputdir/results/${name}.out >/dev/null 2>&1
545 ( diff $DIFFFLAGS -C3 $EXPECTED $outputdir/results/${name}.out
547 echo "======================================================================"
548 echo ) >> "$diff_file"
549 if echo " $ignore_list " | grep " $name " >/dev/null 2>&1 ; then
550 echo "failed (ignored)"
561 done | tee "$result_summary_file" 2>&1
569 if [ -n "$postmaster_pid" ]; then
570 message "shutting down postmaster"
571 kill -15 "$postmaster_pid"
582 count_total=`cat "$result_summary_file" | grep '\.\.\.' | wc -l | sed 's/ //g'`
583 count_ok=`cat "$result_summary_file" | grep '\.\.\. ok' | wc -l | sed 's/ //g'`
584 count_failed=`cat "$result_summary_file" | grep '\.\.\. FAILED' | wc -l | sed 's/ //g'`
585 count_ignored=`cat "$result_summary_file" | grep '\.\.\. failed (ignored)' | wc -l | sed 's/ //g'`
588 if [ $count_total -eq $count_ok ]; then
589 msg="All $count_total tests passed."
591 elif [ $count_failed -eq 0 ]; then
592 msg="$count_ok of $count_total tests passed, $count_ignored failed test(s) ignored."
594 elif [ $count_ignored -eq 0 ]; then
595 msg="$count_failed of $count_total tests failed."
598 msg="$count_failed of $count_total tests failed, $count_ignored failed test(s) ignored."
602 dashes=`echo " $msg " | sed 's/./=/g'`
608 if [ -s "$diff_file" ]; then
609 echo "The differences that caused some tests to fail can be viewed in the"
610 echo "file \`$diff_file'. A copy of the test summary that you see"
611 echo "above is saved in the file \`$result_summary_file'."
614 rm -f "$diff_file" "$result_summary_file"