]> granicus.if.org Git - postgresql/blob - src/test/regress/pg_regress.sh
Don't hide error message from dropdb.
[postgresql] / src / test / regress / pg_regress.sh
1 #! /bin/sh
2 # $Header: /cvsroot/pgsql/src/test/regress/Attic/pg_regress.sh,v 1.11 2000/11/21 17:34:21 petere Exp $
3
4 me=`basename $0`
5 : ${TMPDIR=/tmp}
6 TMPFILE=$TMPDIR/pg_regress.$$
7
8 help="\
9 PostgreSQL regression test driver
10
11 Usage: $me [options...] [extra tests...]
12
13 Options:
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)
22
23 Options for \`temp-install' mode:
24   --top-builddir=DIR        (relative) path to top level build directory
25
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
30
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.
33
34 Report bugs to <pgsql-bugs@postgresql.org>."
35
36
37 message(){
38     _dashes='==============' # 14
39     _spaces='                                      ' # 38
40     _msg=`echo "$1$_spaces" | cut -c 1-38`
41     echo "$_dashes $_msg $_dashes"
42 }
43
44
45 # ----------
46 # Unset locale settings
47 # ----------
48
49 unset LC_COLLATE LC_CTYPE LC_MONETARY LC_MESSAGES LC_NUMERIC LC_TIME LC_ALL LANG LANGUAGE
50
51
52 # ----------
53 # Check for echo -n vs echo \c
54 # ----------
55
56 if echo '\c' | grep c >/dev/null 2>&1; then
57     ECHO_N='echo -n'
58     ECHO_C=''
59 else
60     ECHO_N='echo'
61     ECHO_C='\c'
62 fi
63
64
65 # ----------
66 # Initialize default settings
67 # ----------
68
69 : ${inputdir=.}
70 : ${outputdir=.}
71
72 libdir='@libdir@'
73 bindir='@bindir@'
74 datadir='@datadir@'
75 host_platform='@host_tuple@'
76 enable_shared='@enable_shared@'
77
78 unset mode
79 unset schedule
80 unset debug
81 unset top_builddir
82 unset temp_install
83 unset multibyte
84
85 export PGHOST
86 export PGPORT
87
88 dbname=regression
89 hostname=localhost
90
91 : ${GMAKE='@GMAKE@'}
92
93
94 # ----------
95 # Parse command line options
96 # ----------
97
98 while [ "$#" -gt 0 ]
99 do
100     case $1 in
101         --help|-\?)
102                 echo "$help"
103                 exit 0;;
104         --version)
105                 echo "pg_regress (PostgreSQL @VERSION@)"
106                 exit 0;;
107         --debug)
108                 debug=yes
109                 shift;;
110         --inputdir=*)
111                 inputdir=`expr "x$1" : "x--inputdir=\(.*\)"`
112                 shift;;
113         --multibyte=*)
114                 multibyte=`expr "x$1" : "x--multibyte=\(.*\)"`
115                 shift;;
116         --temp-install)
117                 temp_install=./tmp_check
118                 shift;;
119         --temp-install=*)
120                 temp_install=`expr "x$1" : "x--temp-install=\(.*\)"`
121                 shift;;
122         --outputdir=*)
123                 outputdir=`expr "x$1" : "x--outputdir=\(.*\)"`
124                 shift;;
125         --schedule=*)
126                 foo=`expr "x$1" : "x--schedule=\(.*\)"`
127                 schedule="$schedule $foo"
128                 shift;;
129         --top-builddir=*)
130                 top_builddir=`expr "x$1" : "x--top-builddir=\(.*\)"`
131                 shift;;
132         --host=*)
133                 PGHOST=`expr "x$1" : "x--host=\(.*\)"`
134                 shift;;
135         --port=*)
136                 PGPORT=`expr "x$1" : "x--port=\(.*\)"`
137                 shift;;
138         --user=*)
139                 PGUSER=`expr "x$1" : "x--user=\(.*\)"`
140                 export PGUSER
141                 shift;;
142         -*)
143                 echo "$me: invalid argument $1" 1>&2
144                 exit 2;;
145         *)
146                 extra_tests="$extra_tests $1"
147                 shift;;
148     esac
149 done
150
151
152 # ----------
153 # When on Windows, QNX or BeOS, don't use Unix sockets.
154 # ----------
155
156 case $host_platform in
157     *-*-cygwin* | *-*-qnx* | *beos*)
158         unix_sockets=no;;
159     *)
160         unix_sockets=yes;;
161 esac
162
163
164 # ----------
165 # Set up diff to ignore horizontal white space differences.
166 # ----------
167
168 case $host_platform in
169     *-*-qnx*)
170         DIFFFLAGS=-b;;
171     *)
172         DIFFFLAGS=-w;;
173 esac
174
175
176 # ----------
177 # Set backend timezone and datestyle explicitly
178 #
179 # To pass the horology test in its current form, the postmaster must be
180 # started with PGDATESTYLE=ISO, while the frontend must be started with
181 # PGDATESTYLE=Postgres.  We set the postmaster values here and change
182 # to the frontend settings after the postmaster has been started.
183 # ----------
184
185 PGTZ='PST8PDT'; export PGTZ
186 PGDATESTYLE='ISO,US'; export PGDATESTYLE
187
188
189 # ----------
190 # Exit trap to remove temp file and shut down postmaster
191 # ----------
192
193 # Note:  There are some stupid shells (even among recent ones) that
194 # ignore the argument to exit (as in `exit 1') if there is an exit
195 # trap.  The trap (and thus the shell script) will then always exit
196 # with the result of the last shell command before the `exit'.  Hence
197 # we have to write `(exit x); exit' below this point.
198
199 trap '
200     savestatus=$?
201     if [ -n "$postmaster_pid" ]; then
202         kill -2 "$postmaster_pid"
203         wait "$postmaster_pid"
204         unset postmaster_pid
205     fi
206     rm -f "$TMPFILE" && exit $savestatus
207 ' 0
208
209 trap '
210     savestatus=$?
211     echo; echo "caught signal"
212     if [ -n "$postmaster_pid" ]; then
213         echo "signalling fast shutdown to postmaster with pid $postmaster_pid"
214         kill -2 "$postmaster_pid"
215         wait "$postmaster_pid"
216         unset postmaster_pid
217     fi
218     (exit $savestatus); exit
219 ' 1 2 13 15
220
221
222
223 # ----------
224 # Scan resultmap file to find which platform-specific expected files to use.
225 # The format of each line of the file is
226 #               testname/hostplatformpattern=substitutefile
227 # where the hostplatformpattern is evaluated per the rules of expr(1),
228 # namely, it is a standard regular expression with an implicit ^ at the start.
229 #
230 # The tempfile hackery is needed because some shells will run the loop
231 # inside a subshell, whereupon shell variables set therein aren't seen
232 # outside the loop :-(
233 # ----------
234
235 cat /dev/null >$TMPFILE
236 while read LINE
237 do
238     HOSTPAT=`expr "$LINE" : '.*/\(.*\)='`
239     if [ `expr "$host_platform" : "$HOSTPAT"` -ne 0 ]
240     then
241         # remove hostnamepattern from line so that there are no shell
242         # wildcards in SUBSTLIST; else later 'for' could expand them!
243         TESTNAME=`expr "$LINE" : '\(.*\)/'`
244         SUBST=`echo "$LINE" | sed 's/^.*=//'`
245         echo "$TESTNAME=$SUBST" >> $TMPFILE
246     fi
247 done <"$inputdir/resultmap"
248 SUBSTLIST=`cat $TMPFILE`
249 rm -f $TMPFILE
250
251
252 LOGDIR=$outputdir/log
253
254 if [ x"$temp_install" != x"" ]
255 then
256     if echo x"$temp_install" | grep -v '^x/' >/dev/null 2>&1; then
257         temp_install="`pwd`/$temp_install"
258     fi
259
260     bindir=$temp_install/$bindir
261     libdir=$temp_install/$libdir
262     datadir=$temp_install/$datadir
263     PGDATA=$temp_install/data
264     if [ "$unix_sockets" = no ]; then
265         PGHOST=$hostname
266     else
267         unset PGHOST
268     fi
269     PGPORT=65432
270
271     # ----------
272     # Set up shared library paths, needed by psql and pg_encoding
273     # (if you run multibyte).  LD_LIBRARY_PATH covers many platforms,
274     # feel free to account for others as well.
275     # ----------
276
277     if [ -n "$LD_LIBRARY_PATH" ]; then
278         LD_LIBRARY_PATH="$libdir:$LD_LIBRARY_PATH"
279     else
280         LD_LIBRARY_PATH=$libdir
281     fi
282     export LD_LIBRARY_PATH
283
284
285     if [ -d "$temp_install" ]; then
286         message "removing existing temp installation"
287         rm -rf "$temp_install"
288     fi
289
290     message "creating temporary installation"
291     if [ ! -d "$LOGDIR" ]; then
292         mkdir -p "$LOGDIR" || { (exit 2); exit; }
293     fi
294     $GMAKE -C "$top_builddir" DESTDIR="$temp_install" install with_perl=no with_python=no >"$LOGDIR/install.log" 2>&1
295
296     if [ $? -ne 0 ]
297     then
298         echo
299         echo "$me: installation failed"
300         echo "Examine $LOGDIR/install.log for the reason."
301         echo
302         (exit 2); exit
303     fi
304
305
306     message "initializing database system"
307     [ "$debug" = yes ] && initdb_options='--debug'
308     "$bindir/initdb" -D "$PGDATA" -L "$datadir" --noclean $initdb_options >"$LOGDIR/initdb.log" 2>&1
309
310     if [ $? -ne 0 ]
311     then
312         echo
313         echo "$me: initdb failed"
314         echo "Examine $LOGDIR/initdb.log for the reason."
315         echo
316         (exit 2); exit
317     fi
318
319
320     # ----------
321     # Start postmaster
322     # ----------
323
324     message "starting postmaster"
325     [ "$debug" = yes ] && postmaster_options="$postmaster_options -d 5"
326     [ "$unix_sockets" = no ] && postmaster_options="$postmaster_options -i"
327     "$bindir/postmaster" -D "$PGDATA" -F $postmaster_options >"$LOGDIR/postmaster.log" 2>&1 &
328     postmaster_pid=$!
329
330     if kill -0 $postmaster_pid >/dev/null 2>&1
331     then
332         echo "running on port $PGPORT with pid $postmaster_pid"
333     else
334         echo
335         echo "$me: postmaster did not start"
336         echo "Examine $LOGDIR/postmaster.log for the reason."
337         echo
338         (exit 2); exit
339     fi
340
341     # give postmaster some time to pass WAL recovery
342     sleep 3
343
344 else # not temp-install
345
346     # If Unix sockets are not available, use the local host by default.
347     [ "$unix_sockets" = no ] && ${PGHOST=$hostname}
348
349     if [ -n "$PGPORT" ]; then
350         port_info="port $PGPORT"
351     else
352         port_info="default port"
353     fi
354
355     if [ -n "$PGHOST" ]; then
356         echo "(using postmaster on $PGHOST, $port_info)"
357     else
358         echo "(using postmaster on Unix socket, $port_info)"
359     fi
360     message "dropping database \"$dbname\""
361     "$bindir/dropdb" $psql_options "$dbname"
362     # errors can be ignored
363 fi
364
365
366 # ----------
367 # Set up SQL shell for the test.
368 # ----------
369
370 PSQL="$bindir/psql -a -q -X $psql_options"
371
372
373 # ----------
374 # Set frontend timezone and datestyle explicitly
375 # ----------
376
377 PGTZ='PST8PDT'; export PGTZ
378 PGDATESTYLE='Postgres,US'; export PGDATESTYLE
379
380
381 # ----------
382 # Set up multibyte environment
383 # ----------
384
385 if [ -n "$multibyte" ]; then
386     PGCLIENTENCODING=$multibyte
387     export PGCLIENTENCODING
388     encoding_opt="-E $multibyte"
389 else
390     unset PGCLIENTENCODING
391 fi
392
393
394 # ----------
395 # Create the regression database
396 # ----------
397
398 message "creating database \"$dbname\""
399 "$bindir/createdb" $encoding_opt $psql_options "$dbname"
400 if [ $? -ne 0 ]; then
401     echo "$me: createdb failed"
402     (exit 2); exit
403 fi
404
405
406 # ----------
407 # Install the PL/pgSQL language in it
408 # ----------
409
410 if [ "$enable_shared" = yes ]; then
411         message "installing PL/pgSQL"
412         "$bindir/createlang" -L "$libdir" $psql_options plpgsql $dbname
413         if [ $? -ne 0 ] && [ $? -ne 2 ]; then
414             echo "$me: createlang failed"
415             (exit 2); exit
416         fi
417 fi
418
419
420 # ----------
421 # Let's go
422 # ----------
423
424 message "running regression test queries"
425
426 if [ ! -d "$outputdir/results" ]; then
427     mkdir -p "$outputdir/results" || { (exit 2); exit; }
428 fi
429 result_summary_file=$outputdir/regression.out
430 diff_file=$outputdir/regression.diffs
431
432 cat /dev/null >"$result_summary_file"
433 cat /dev/null >"$diff_file"
434
435 lno=0
436 (
437     [ "$enable_shared" != yes ] && echo "ignore: plpgsql"
438     cat $schedule
439     for x in $extra_tests; do
440         echo "test: $x"
441     done
442 ) | sed 's/[    ]*#.*//g' | \
443 while read line
444 do
445     # Count line numbers
446     lno=`expr $lno + 1`
447     [ -z "$line" ] && continue
448
449     set X $line; shift
450
451     if [ x"$1" = x"ignore:" ]; then
452         shift
453         ignore_list="$ignore_list $@"
454         continue
455     elif [ x"$1" != x"test:" ]; then
456         echo "$me:$schedule:$lno: syntax error"
457         (exit 2); exit
458     fi
459
460     shift
461
462     # ----------
463     # Start tests
464     # ----------
465
466     if [ $# -eq 1 ]; then
467         # Run a single test
468         formatted=`echo $1 | awk '{printf "%-20.20s", $1;}'`
469         $ECHO_N "test $formatted ... $ECHO_C"
470
471         $PSQL -d "$dbname" <"$inputdir/sql/$1.sql" >"$outputdir/results/$1.out" 2>&1
472     else
473         # Start a parallel group
474         $ECHO_N "parallel group ($# tests): $ECHO_C"
475         for name do
476             ( $PSQL -d $dbname <"$inputdir/sql/$name.sql" >"$outputdir/results/$name.out" 2>&1
477               $ECHO_N " $name$ECHO_C"
478             ) &
479         done
480         wait
481         echo
482     fi
483
484     # ----------
485     # Run diff
486     # (We do not want to run the diffs immediately after each test,
487     # because they would certainly get corrupted if run in parallel
488     # subshells.)
489     # ----------
490
491     for name do
492         if [ $# -ne 1 ]; then
493             formatted=`echo "$name" | awk '{printf "%-20.20s", $1;}'`
494             $ECHO_N "     $formatted ... $ECHO_C"
495         fi
496
497         # Check list extracted from resultmap to see if we should compare
498         # to a system-specific expected file.
499         # There shouldn't be multiple matches, but take the last if there are.
500
501         EXPECTED="$inputdir/expected/${name}.out"
502         for LINE in $SUBSTLIST
503         do
504             if [ `expr "$LINE" : "$name="` -ne 0 ]
505             then
506                 SUBST=`echo "$LINE" | sed 's/^.*=//'`
507                 EXPECTED="$inputdir/expected/${SUBST}.out"
508             fi
509         done
510
511         diff $DIFFFLAGS $EXPECTED $outputdir/results/${name}.out >/dev/null 2>&1
512         case $? in
513             0)
514                 echo "ok";;
515             1)
516                 ( diff $DIFFFLAGS -C3 $EXPECTED $outputdir/results/${name}.out
517                   echo
518                   echo "======================================================================"
519                   echo ) >> "$diff_file"
520                 if echo " $ignore_list " | grep " $name " >/dev/null 2>&1 ; then
521                     echo "failed (ignored)"
522                 else
523                     echo "FAILED"
524                 fi
525                 ;;
526             2)
527                 # desaster struck
528                 echo "trouble" 1>&2
529                 (exit 2); exit;;
530         esac
531     done
532 done | tee "$result_summary_file" 2>&1
533
534 [ $? -ne 0 ] && exit
535
536 # ----------
537 # Server shutdown
538 # ----------
539
540 if [ -n "$postmaster_pid" ]; then
541     message "shutting down postmaster"
542     kill -15 "$postmaster_pid"
543     unset postmaster_pid
544 fi
545
546 rm -f "$TMPFILE"
547
548
549 # ----------
550 # Evaluation
551 # ----------
552
553 count_total=`cat "$result_summary_file" | grep '\.\.\.' | wc -l | sed 's/ //g'`
554 count_ok=`cat "$result_summary_file" | grep '\.\.\. ok' | wc -l | sed 's/ //g'`
555 count_failed=`cat "$result_summary_file" | grep '\.\.\. FAILED' | wc -l | sed 's/ //g'`
556 count_ignored=`cat "$result_summary_file" | grep '\.\.\. failed (ignored)' | wc -l | sed 's/ //g'`
557
558 echo
559 if [ $count_total -eq $count_ok ]; then
560     msg="All $count_total tests passed."
561     result=0
562 elif [ $count_failed -eq 0 ]; then
563     msg="$count_ok of $count_total tests passed, $count_ignored failed test(s) ignored."
564     result=0
565 elif [ $count_ignored -eq 0 ]; then
566     msg="$count_failed of $count_total tests failed."
567     result=1
568 else
569     msg="$count_failed of $count_total tests failed, $count_ignored failed test(s) ignored."
570     result=1
571 fi
572
573 dashes=`echo " $msg " | sed 's/./=/g'`
574 echo "$dashes"
575 echo " $msg "
576 echo "$dashes"
577 echo
578
579 if [ -s "$diff_file" ]; then
580     echo "The differences that caused some tests to fail can be viewed in the"
581     echo "file \`$diff_file'.  A copy of the test summary that you see"
582     echo "above is saved in the file \`$result_summary_file'."
583     echo
584 else
585     rm -f "$diff_file" "$result_summary_file"
586 fi
587
588
589 (exit $result); exit