postgis/regress/run_test
Paul Ramsey 9ac7c6da23 Revert per #1246
git-svn-id: http://svn.osgeo.org/postgis/trunk@8243 b70326c6-7e19-0410-871a-916f4a2858ee
2011-11-26 05:04:27 +00:00

653 lines
16 KiB
Bash
Executable file

#!/bin/sh
DB=postgis_reg
# TODO: get this part generated by ./configure. For now
# we must make sure this matches REGRESS_INSTALLDIR in
# Makefile.in.
SHP2PGSQL=../loader/shp2pgsql
PGSQL2SHP=../loader/pgsql2shp
###################################################
#
# Usage ./run_test <testname> [<testname>]
#
# Create the spatial database 'postgis_reg'
# (or whatever $DB is set to) if it doesn't
# already exist.
#
# Run the <testname>.sql script
# Diff output against <testname>_expected
#
#
###################################################
# Set the locale to "C" so error messages match
# Save original locale to set back
ORIG_LC_ALL=$LC_ALL
ORIG_LANG=$LANG
export LC_ALL=C
export LANG=C
if [ -n "$USE_VERSION" ]; then
if [ "$USE_VERSION" -gt 74 ]; then
PGOPTIONS="${PGOPTIONS} -c lc_messages=C"
export PGOPTIONS
fi
fi
REGDIR=`dirname $0`
REGDIR=`cd "${REGDIR}" && pwd`
PSQL="psql"
if [ -z "$TMPDIR" ]; then
TMPDIR=/tmp/pgis_reg_$$
fi
mkdir -p ${TMPDIR}
VERBOSE=0
OPT_DROP=yes
OPT_CREATE=yes
OPT_WITH_TOPO=no
OPT_WITH_RASTER=no
if echo '\c' | grep c >/dev/null 2>&1; then
ECHO_N='echo -n'
ECHO_C=''
else
ECHO_N='echo'
ECHO_C='\c'
fi
###################################################
#
# Helper functions
#
###################################################
# Print a single dot
show_progress()
{
${ECHO_N} ".${ECHO_C}"
}
#
# fail <msg> <log>
#
fail ()
{
_msg="$1"
_log="$2"
if [ -z "$_log" ]; then
echo " failed ($_msg)"
elif test "$VERBOSE" -eq "1"; then
echo " failed ($_msg: $_log)"
echo "-----------------------------------------------------------------------------"
cat $_log
echo "-----------------------------------------------------------------------------"
else
echo " failed ($_msg: $_log)"
fi
FAIL=`expr $FAIL + 1`
}
#
# run_simple_sql
#
# Run an sql script and hide results unless it fails.
#
# SQL input file name is $1
#
run_simple_sql ()
{
_sql="$1"
if [ ! -r "$_sql" ]; then
fail "can't read $_sql"
return 1
fi
TMPFILE="${TMPDIR}/test_${RUN}_tmp"
# Dump output to a temp file.
${PSQL} -tXA < "${_sql}" ${DB} > ${TMPFILE} 2>&1
# Check if psql errored out.
if [ $? -gt 0 ]; then
fail "Unable to run sql script $_sql" "${TMPFILE}"
return 1
fi
# Check if psql produced any error output.
grep "^ERROR:" "${TMPFILE}"
if [ $? -eq 0 ]; then
fail "Errors while running sql script $_sql" "${TMPFILE}"
return 1
fi
rm ${TMPFILE}
}
#
# run_simple_test
#
# Run an sql script and compare results with the given expected output
#
# SQL input is ${TEST}.sql, expected output is {$TEST}_expected
#
run_simple_test ()
{
_sql="$1"
_expected="$2"
if [ -n "$3" ]; then
_msg="$3: "
else
_msg=
fi
if [ ! -r "$_sql" ]; then
fail "can't read $_sql"
return 1
fi
if [ ! -r "$_expected" ]; then
fail "can't read $_expected"
return 1
fi
show_progress
OUTFILE="${TMPDIR}/test_${RUN}_out"
TMPFILE="${TMPDIR}/test_${RUN}_tmp"
DIFFILE="${TMPDIR}/test_${RUN}_diff"
# Use intermediate file to prevent MingW buffering problems
${PSQL} -tXA < "${_sql}" ${DB} > ${TMPFILE} 2>&1
cat ${TMPFILE} \
| grep -v "^$" \
| grep -v "^INSERT" \
| grep -v "^DELETE" \
| grep -v "^CONTEXT" \
| grep -v "^UPDATE" \
| grep -v "^DROP" \
| grep -v "^CREATE" \
| grep -v "^SELECT" \
| grep -v "^SET" \
| grep -v "^LINE [0-9]" \
| grep -v "^ *^$" \
| sed 's/Infinity/inf/g;s/Inf/inf/g;s/1\.#INF/inf/g' \
| sed 's/[eE]\([+-]\)0\{1,\}\([0-9]\{1,\}\)/e\1\2/g' \
| sed 's/Self-intersection .*/Self-intersection/' \
| sed 's/^ROLLBACK/COMMIT/' \
> "${OUTFILE}"
rm ${TMPFILE}
if diff -u "${_expected}" "${OUTFILE}" > ${DIFFILE}; then
#SUCCESS=`expr $SUCCESS + 1`
rm "${OUTFILE}" "${DIFFILE}" # we don't need these anymore
return 0
else
fail "${_msg}diff expected obtained" "${DIFFILE}"
# rm "${OUTFILE}" # diff is enough
return 1
fi
}
#
# This runs the loader once and checks the output of it.
# It will NOT run if neither the expected SQL nor the expected
# select results file exists, unless you pass true for the final
# parameter.
#
# $1 - Description of this run of the loader, used for error messages.
# $2 - Table name to load into.
# $3 - The name of the file containing what the
# SQL generated by shp2pgsql should look like.
# $4 - The name of the file containing the expected results of
# SELECT geom FROM _tblname should look like.
# $5 - Command line options for shp2pgsql.
# $6 - If you pass true, this will run the loader even if neither
# of the expected results files exists (though of course
# the results won't be compared with anything).
#
run_loader_and_check_output()
{
_description=$1
_tblname=$2
_expected_sql_file=$3
_expected_select_results_file=$4
_loader_options=$5
_run_always=$6
# ON_ERROR_STOP is used by psql to return non-0 on an error
_psql_opts="--no-psqlrc --variable ON_ERROR_STOP=true"
if [ -n "$_run_always" -o -r "$_expected_sql_file" -o -r "$_expected_select_results_file" ]; then
show_progress
# Produce the output SQL file.
${SHP2PGSQL} $_loader_options -g the_geom ${TEST}.shp $_tblname \
> ${TMPDIR}/loader \
2> ${TMPDIR}/loader.err
if [ $? -gt 0 ]; then
fail " $_description: running shp2pgsql" "${TMPDIR}/loader.err"
return 1
fi
# Compare the output SQL file with the expected if there is one.
if [ -r $_expected_sql_file ]; then
show_progress
if diff "${TMPDIR}/loader" "$_expected_sql_file" > /dev/null; then
:
else
fail " $_description: actual SQL does not match expected.", \
"${TMPDIR}/loader"
fi
fi
# Blow away the test table if it already exists.
# MingW hack: use tr to strip off any trailing CR/LFs introduce by MingW which confuse expr
if [ `${PSQL} -t -A -c "SELECT count(*) FROM pg_tables WHERE tablename = '${_tblname}'" "${DB}" \
| tr -d '\r\n'` -gt 0 ]; then
show_progress
${PSQL} -c "DROP TABLE ${_tblname}" "${DB}" >> ${TMPDIR}/regress_log 2>&1
fi
# Run the loader SQL script.
show_progress
${PSQL} ${_psql_opts} -f ${TMPDIR}/loader "${DB}" > ${TMPDIR}/loader.err 2>&1
if [ $? -gt 0 ]; then
fail " $_description: running shp2pgsql output" "${TMPDIR}/loader.err"
return 1
fi
# Run the select script (if there is one)
if [ -r "${TEST}.select.sql" ]; then
if run_simple_test "${TEST}.select.sql" "$_expected_select_results_file" "$_description"; then
:
else
# That will have already called fail, so just return an error.
return 1
fi
fi
fi
return 0
}
#
# This runs the dumper once and checks the output of it.
# It will NOT run if the expected shp file does not exist, unless
# you pass true for the final parameter.
#
# $1 - Description of this run of the dumper, used for error messages.
# $2 - Table name to dump from.
# $3 - "Expected" .shp file to compare with.
# $3 - If you pass true, this will run the loader even if neither
# of the expected results files exists (though of course
# the results won't be compared with anything).
#
run_dumper_and_check_output()
{
_description=$1
_tblname=$2
_expected_shp_file=$3
_run_always=$4
if [ -n "$_run_always" -o -r "$_expected_shp_file" ]; then
show_progress
${PGSQL2SHP} -f ${TMPDIR}/dumper ${DB} "${_tblname}" > "${TMPDIR}/dumper.err" 2>&1
if [ $? -gt 0 ]; then
fail "$_description: dumping loaded table" "${TMPDIR}/dumper.err"
return 1
fi
# Compare with expected output if there is any.
if [ -r $_expected_shp_file ]; then
show_progress
if diff "${TMPDIR}"/dumper.shp "$_expected_shp_file" > /dev/null; then
:
else
ls -lL "${TMPDIR}"/dumper.shp "$_expected_shp_file" > "${TMPDIR}"/dumper.diff
fail "$_description: dumping loaded table" "${TMPDIR}/dumper.diff"
return 1
fi
fi
fi
return 0
}
#
# run_loader_test
#
# Load a shapefile with different methods, create a 'select *' SQL
# test and run simple test with provided expected output.
#
# SHP input is ${TEST}.shp, expected output is {$TEST}.expected
#
run_loader_test ()
{
# See if there is a custom command-line options file
_custom_opts=""
if [ -r ${TEST}.opts ]; then
_custom_opts=`grep -v ^\s*# ${TEST}.opts`
fi
# If we have some expected files to compare with, run in wkt mode.
if run_loader_and_check_output "wkt test" "loadedshp" "${TEST}-w.sql.expected" "${TEST}-w.select.expected" \
"-w $_custom_opts"; then
:
else
return 1
fi
# If we have some expected files to compare with, run in geography mode.
if run_loader_and_check_output "geog test" "loadedshp" "${TEST}-G.sql.expected" "${TEST}-G.select.expected" \
"-G $_custom_opts"; then
:
else
return 1
fi
# If we have some expected files to compare with, run the dumper and compare shape files.
if run_dumper_and_check_output "dumper geog test" "loadedshp" "${TEST}-G.shp.expected"; then
:
else
return 1
fi
# Always run in wkb ("normal") mode, even if there are no expected files to compare with.
if run_loader_and_check_output "wkb test" "loadedshp" "${TEST}.sql.expected" "${TEST}.select.expected" \
"$_custom_opts" "true"; then
:
else
return 1
fi
# If we have some expected files to compare with, run the dumper and compare shape files.
if run_dumper_and_check_output "dumper wkb test" "loadedshp" "${TEST}.shp.expected"; then
:
else
return 1
fi
# Some custom parameters can be incompatible with -D.
if [ -z "$_custom_opts" ]; then
# If we have some expected files to compare with, run in wkt dump mode.
if run_loader_and_check_output "wkt dump test" "loadedshp" "${TEST}-wD.sql.expected" \
"${TEST}-w.select.expected" "-w -D"; then
:
else
return 1
fi
# If we have some expected files to compare with, run in wkt dump mode.
if run_loader_and_check_output "geog dump test" "loadedshp" "${TEST}-GD.sql.expected" \
"${TEST}-G.select.expected" "-G -D"; then
:
else
return 1
fi
# If we have some expected files to compare with, run in wkb dump mode.
if run_loader_and_check_output "wkb dump test" "loadedshp" "${TEST}-D.sql.expected" \
"${TEST}.select.expected" "-D"; then
:
else
return 1
fi
fi
return 0
}
# Log an initialization error and optionally drop the db
init_db_error ()
{
echo
echo " Something went wrong ($1)."
echo " For details, check ${TMPDIR}/regress_log"
echo
if test x"$OPT_DROP" = "xyes" -a x"$OPT_CREATE" = "xyes"; then
dropdb "${DB}" > /dev/null
else
: echo "Drop database ${DB} manually"
fi
exit 1
}
###################################################
#
# Parse command line opts
#
###################################################
while [ -n "$1" ]; do
if test "$1" = "-v"; then
VERBOSE=1
shift
continue
elif test "$1" = "--nodrop"; then
OPT_DROP=no
shift
continue
elif test "$1" = "--nocreate"; then
OPT_CREATE=no
shift
continue
elif test "$1" = "--topology"; then
OPT_WITH_TOPO=yes
shift
continue
elif test "$1" = "--raster"; then
OPT_WITH_RASTER=yes
shift
continue
else
break
fi
done
if [ -z "$1" ]; then
echo "Usage: $0 [-v] [--topology] [--nocreate] [--nodrop] <test> [<test>]" >&2
exit 1
fi
###################################################
#
# Prepare the database
#
###################################################
db_exists=`${PSQL} -l | grep -w ${DB}`
if test -z "$db_exists"; then
if test x"$OPT_CREATE" = "xyes"; then
echo "Creating spatial db ${DB} "
# ON_ERROR_STOP is used by psql to return non-0 on an error
_psql_opts="--no-psqlrc --variable ON_ERROR_STOP=true"
createdb --template=template0 --lc-collate="C" "${DB}" > ${TMPDIR}/regress_log
createlang plpgsql "${DB}" >> ${TMPDIR}/regress_log
${PSQL} ${_psql_opts} -Xf ${REGDIR}/postgis.sql "${DB}" >> ${TMPDIR}/regress_log 2>&1 || init_db_error "core module initialization"
if test x"$OPT_WITH_TOPO" = "xyes"; then
if test -e ${REGDIR}/../topology/topology.sql; then
echo "Adding topology support"
${PSQL} ${_psql_opts} -Xf ${REGDIR}/../topology/topology.sql "${DB}" >> ${TMPDIR}/regress_log 2>&1 || init_db_error "topology initialization"
else
echo "Topology support skipped (topology.sql not found)"
fi
fi
if test x"$OPT_WITH_RASTER" = "xyes"; then
SCRIPT=${REGDIR}/../raster/test/regress/rtpostgis.sql
if test -e ${SCRIPT}; then
echo "Adding raster support"
${PSQL} ${_psql_opts} -Xf ${SCRIPT} "${DB}" >> ${TMPDIR}/regress_log 2>&1 || init_db_error "raster module initialization"
else
echo "Raster support skipped (rtpostgis.sql not found)"
fi
fi
else
echo "Database ${DB} does not exist" >&2
echo "Run w/out the --nocreate flag to create it" >&2
exit 1
fi
else
if test x"$OPT_CREATE" = "xyes"; then
echo "Database ${DB} already exist." >&2
echo "Run with the --nocreate flag to use it " \
"or drop it and try again." >&2
exit 1
else
echo "Using existing database ${DB}"
fi
fi
libver=`${PSQL} -tAc "select postgis_lib_version()" "${DB}"`
if [ -z "$libver" ]; then
dropdb "${DB}"
echo
echo " Something went wrong (no postgis installed in ${DB})."
if [ -z "$db_exists" ]; then
echo " For details, check ${TMPDIR}/regress_log"
fi
echo
exit 1
fi
###################################################
#
# Report runtime environment
#
###################################################
geosver=`${PSQL} -tAc "select postgis_geos_version()" "${DB}"`
projver=`${PSQL} -tAc "select postgis_proj_version()" "${DB}"`
if test x"$OPT_WITH_RASTER" = "xyes"; then
gdalver=`${PSQL} -tAc "select postgis_gdal_version()" "${DB}"`
fi
libbuilddate=`${PSQL} -tAc "select postgis_lib_build_date()" "${DB}"`
pgsqlver=`${PSQL} -tAc "select version()" "${DB}"`
echo "TMPDIR is ${TMPDIR}"
echo "PATH is ${PATH}"
echo
echo " $pgsqlver"
echo " Postgis $libver - $libbuilddate"
if [ -n "$geosver" ]; then
echo " GEOS: $geosver"
fi
if [ -n "$projver" ]; then
echo " PROJ: $projver"
fi
if [ -n "$gdalver" ]; then
echo " GDAL: $gdalver"
fi
###################################################
#
# Run the tests
#
###################################################
echo
echo "Running tests"
echo
RUN=0
SKIP=0
FAIL=0
#SUCCESS=0
while [ -n "$1" ]; do
TEST="$1"; shift;
# catch a common mistake (strip trailing .sql)
TEST=`echo "$TEST" | sed 's/\.sql$//'`
#printf %20s " ${TEST}"
#echo -ne " ${TEST}"
${ECHO_N} " ${TEST}${ECHO_C}"
RUN=`expr $RUN + 1`
# Check for a "-pre.sh" file in case there are non-SQL setup tasks needed before
# the test can be run.
if [ -r "${TEST}-pre.sh" ]; then
"${TEST}-pre.sh"
if [ $? -gt 0 ]; then
fail " setup script failed"
continue
else
show_progress
fi
fi
# Check for a "-pre.sql" file in case there is setup SQL needed before
# the test can be run.
if [ -r "${TEST}-pre.sql" ]; then
if run_simple_sql "${TEST}-pre.sql"; then
show_progress
else
continue
fi
fi
# Check .dbf *before* .sql as loader test could
# create the .sql
# Check for .dbf not just .shp since the loader can load
# .dbf files without a .shp.
if [ -r "${TEST}.dbf" ]; then
if run_loader_test; then
echo " ok"
fi
elif [ -r "${TEST}.sql" ]; then
if run_simple_test ${TEST}.sql ${TEST}_expected; then
echo " ok"
fi
else
echo "Skipped (can't read ${TEST}.sql)"
SKIP=`expr $SKIP + 1`
continue
fi
# Check for a "-post.sql" file in case there is teardown SQL needed after
# the test has been run.
if [ -r "${TEST}-post.sql" ]; then
if ! run_simple_sql "${TEST}-post.sql"; then
echo " ... but cleanup sql failed!"
fi
fi
# Check for a "-post.sh" file in case there are non-SQL teardown tasks needed after
# the test has been run.
if [ -r "${TEST}-post.sh" ]; then
"${TEST}-post.sh"
if [ $? -gt 0 ]; then
echo " ... but cleanup script failed!"
fi
fi
done
echo
echo "Run tests: $RUN"
#echo "Skipped: $SKIP"
#echo "Successful: $SUCCESS"
echo "Failed: $FAIL"
if test x"$OPT_DROP" = "xyes" -a x"$OPT_CREATE" = "xyes"; then
sleep 1
dropdb "${DB}" > /dev/null
else
: echo "Drop database ${DB} manually"
fi
# Set the locale back to the original
export LC_ALL=$ORIG_LC_ALL
export LANG=$ORIG_LANG
exit $FAIL