diff --git a/src/interfaces/ecpg/test/Makefile.regress b/src/interfaces/ecpg/test/Makefile.regress new file mode 100644 index 0000000000000000000000000000000000000000..bee1048a2811b0a96e417cb47947f8a76f2a8ea1 --- /dev/null +++ b/src/interfaces/ecpg/test/Makefile.regress @@ -0,0 +1,16 @@ +override CPPFLAGS := -I$(srcdir)/../../include -I$(libpq_srcdir) $(CPPFLAGS) +override CFLAGS += $(PTHREAD_CFLAGS) -I$(srcdir)/../../include -I$(libpq_srcdir) -I../../include -I$(top_builddir)/src/include +override LDFLAGS += -L../../ecpglib -L ../../pgtypeslib -L../../../libpq +override LIBS += -lpgtypes -lecpg -lpq + +ECPG = ../../preproc/ecpg -I$(srcdir)/../../include + +%: %.c + $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(PTHREAD_LIBS) -o $@ + +%.c: %.pgc ../regression.h + $(ECPG) -o $@ -I$(srcdir) $< + +clean: + rm -f $(TESTS) $(TESTS:%=%.o) $(TESTS:%=%.c) + diff --git a/src/interfaces/ecpg/test/pg_regress.inc.sh.in b/src/interfaces/ecpg/test/pg_regress.inc.sh.in new file mode 100644 index 0000000000000000000000000000000000000000..ed9726b207057c6d6cb6a99f755dcf0d2b8b94c0 --- /dev/null +++ b/src/interfaces/ecpg/test/pg_regress.inc.sh.in @@ -0,0 +1,611 @@ +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 + +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@' + GCC=@GCC@ + VERSION=@VERSION@ + + 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 + + dbname=regression + hostname=localhost + maxconnections=0 + temp_port=65432 + load_langs="" + listen_on_tcp=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;; + --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. + # 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 + + # ---------- + # 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 + + message "dropping database \"$dbname\"" + "$bindir/dropdb" $psql_options "$dbname" + # errors can be ignored +} + +setup_client_environment_variables(){ + export PGDATESTYLE=Postgres +} + +# ---------- +# 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 +} + +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 +} + diff --git a/src/interfaces/ecpg/test/pg_regress.sh b/src/interfaces/ecpg/test/pg_regress.sh new file mode 100644 index 0000000000000000000000000000000000000000..45f1458855f8524f82b2a5f215bd32e6f8d9a8f1 --- /dev/null +++ b/src/interfaces/ecpg/test/pg_regress.sh @@ -0,0 +1,127 @@ +#! /bin/sh +# $PostgreSQL: pgsql/src/interfaces/ecpg/test/pg_regress.sh,v 1.1 2006/08/02 13:53:45 meskes Exp $ + +me=`basename $0` + +. pg_regress.inc.sh + +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 +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 +#"$bindir/createdb" $encoding_opt $psql_options --template template0 regress1 +#"$bindir/createdb" $encoding_opt $psql_options --template template0 connectdb +#database_cleanup +create_database $dbname +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 + +# this variable prevents that the PID gets included in the logfiles +export ECPG_DONT_LOG_PID=1 +export PGPORT=$temp_port +export LD_LIBRARY_PATH=$libdir + +for i in \ + connect/*.pgc \ + compat_informix/*.pgc \ + complex/*.pgc \ + errors/*.pgc \ + pgtypeslib/*.pgc \ + sql/*.pgc \ + thread/*.pgc; do + + formatted=`echo $i | awk '{printf "%-38.38s", $1;}'` + $ECHO_N "testing $formatted ... $ECHO_C" + + runprg=${i/.pgc/} + outfile_stderr=$outputdir/${runprg//\//-}.stderr + outfile_stdout=$outputdir/${runprg//\//-}.stdout + cp $runprg.c "$outputdir/${runprg//\//-}.c" +# echo "$runprg > $outfile_stdout 2> $outfile_stderr" + $runprg > "$outfile_stdout" 2> "$outfile_stderr" + DIFFER="" + diff -u expected/${runprg//\//-}.stderr "$outputdir"/${runprg//\//-}.stderr >/dev/null 2>&1 || DIFFER="$DIFFER, log" + diff -u expected/${runprg//\//-}.stdout "$outputdir"/${runprg//\//-}.stdout >/dev/null 2>&1 || DIFFER="$DIFFER, output" + diff -u expected/${runprg//\//-}.c "$outputdir"/${runprg//\//-}.c >/dev/null 2>&1 || DIFFER="$DIFFER, source" + DIFFER=${DIFFER#, } + if [ "x$DIFFER" = "x" ]; then + echo ok + else + echo "FAILED ($DIFFER)" + fi +done + +diff -ur expected/ $outputdir > regression.diff && rm regression.diff + +[ $? -ne 0 ] && exit + +postmaster_shutdown +evaluate + +(exit $result); exit + diff --git a/src/interfaces/ecpg/test/regression.h b/src/interfaces/ecpg/test/regression.h new file mode 100644 index 0000000000000000000000000000000000000000..f614938cef753f60d38ccc960723f2e514a70ecf --- /dev/null +++ b/src/interfaces/ecpg/test/regression.h @@ -0,0 +1,5 @@ +exec sql define REGRESSDB1 regress1; +exec sql define REGRESSDB2 connectdb; + +exec sql define REGRESSUSER1 regressuser1; +exec sql define REGRESSUSER2 regressuser2;