blob: a1042510eafd44f8f559df55b58c2199ba5d31d3 [file] [log] [blame]
#!/bin/sh
# from ckmame:runtest,v 1.22 2005/12/27 09:41:51 dillo Exp
#
# runtest -- run regression tests
# Copyright (C) 2002-2007 Dieter Baron and Thomas Klausner
#
# This file is part of libzip, a library to manipulate ZIP archives.
# The authors can be contacted at <libzip@nih.at>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# runtest TESTNAME
#
# files:
# TESTNAME.test: test scenario
#
# test scenario:
# Lines beginning with # are comments.
#
# The following commands are recognized; return and args must
# appear exactly once, the others are optional.
#
# args ARGS
# run program with command line arguments ARGS
#
# description TEXT
# description of what test is for
#
# file TEST IN OUT
# copy file IN as TEST, compare against OUT after program run.
#
# file-del TEST IN
# copy file IN as TEST, check that it is removed by program.
#
# file-new TEST OUT
# check that file TEST is created by program and compare
# against OUT.
#
# mkdir MODE NAME
# create directory NAME with permissions MODE.
#
# program PRG
# run PRG.
#
# return RET
# RET is the expected exit code
#
# stderr TEXT
# program is expected to produce the error message TEXT. If
# multiple stderr commands are used, the messages are
# expected in the order given.
#
# stdout TEXT
# program is expected to print TEXT to stdout. If multiple
# stdout commands are used, the messages are expected in
# the order given.
#
# exit status
# runtest uses the following exit codes:
# 0: test passed
# 1: test failed
# 2: other error
# 77: test was skipped
#
# environment variables:
# VERBOSE: if set, be more verbose (e. g., output diffs)
# NOCLEANUP: if set, don't delete directory test is run in
die() {
echo "$0: $*" >&2;
cleanup;
exit 2;
}
fail() {
if [ ! -z "${VERBOSE}" ]
then
echo "${TEST} -- FAILED: $*";
fi;
cleanup;
exit 1;
}
skip() {
if [ ! -z "${VERBOSE}" ]
then
echo "${TEST} -- skipped: $*";
fi;
cleanup;
exit 77;
}
succeed() {
if [ ! -z "${VERBOSE}" ]
then
echo "${TEST} -- passed";
fi
cleanup;
exit 0;
}
cleanup() {
cd ..;
if [ -z "${NOCLEANUP}" ]
then
chmod -R u+rw ${DIR};
rm -r ${DIR};
fi
}
check_in_out_exists() {
if [ ! -f "$2" ]
then
fail "missing output file: '$2'"
elif [ ! -f "$1" ]
then
die "cannot find input file '$1'"
fi
}
checkdb() {
check_in_out_exists "$1" "$2"
out=`../dbdump "$2" | sort | diff ${DIFF_FLAGS} "$1" -`
if [ $? -ne 0 ]
then
if [ $VERBOSE ]
then
echo "$out"
fi
fail "$3"
fi
}
checkfile() {
check_in_out_exists "$1" "$2"
out=`diff ${DIFF_FLAGS} "$1" "$2"`
if [ $? -ne 0 ]
then
if [ $VERBOSE ]
then
echo "$out"
fi
fail "$3"
fi
}
checkzip() {
check_in_out_exists "$1" "$2"
# quiet CRC errors
${ZIPCMP} -t ${ZIPCMP_FLAGS} "$1" "$2" 2>/dev/null
if [ $? -ne 0 ]
then
fail "$3"
fi
}
test_empty() {
if [ ! -z "$1" ]
then
die "directive $2 appeared twice in test file"
fi
}
test_set() {
if [ -z "$1" ]
then
die "required directive $2 missing in test file"
fi
}
copy_file() {
src="${srcdir}/$1"
if [ ! -f "$src" ]
then
die "source file '$src' does not exist"
fi
dir=`dirname "$2"`
if [ ! -d "$dir" ]
then
mkdir -p "$dir"
fi
cp "$src" "$2"
}
# GNU sort behaves differently on locales other than C, breaking tests
LC_ALL=C
export LC_ALL
#testdir=`dirname $1`
TEST=`echo $1 | sed -e s',.*/,,' -e 's/\.test$//'`
shift
DIR=${TEST}.d$$
if [ -z "${srcdir}" ]
then
srcdir=..
else
# XXX: fix for absolute srcdir?
srcdir=../${srcdir}
fi
if [ -z "${ZIPCMP}" ]
then
ZIPCMP=zipcmp
else
if expr "${ZIPCMP}" : '[^/].*/' > /dev/null
then
ZIPCMP="../${ZIPCMP}"
fi
fi
if [ -z "${VERBOSE}" ]
then
DIFF_FLAGS=''
ZIPCMP_FLAGS='-q'
else
DIFF_FLAGS='-u'
ZIPCMP_FLAGS='-v'
fi
# XXX: set up trap to cleanup
mkdir ${DIR} || ( die "cannot create test directory ${DIR}" )
cd ${DIR} || ( die "cannot cd to test directory ${DIR}" )
{
RET=''
ARGS=''
FILES=''
FILES_SHOULD=''
DESCR=''
touch stderr stdout
while read cmd arg
do
case $cmd in
\#*) ;;
args)
test_empty "${ARGS}" args
ARGS="$arg";;
description)
test_empty "${DESCR}" description
DESCR="$arg";;
file)
set $arg
copy_file "$2" "$1"
FILES="${FILES} ${srcdir}/$3!$1";;
file-del)
set $arg
copy_file "$2" "$1";;
file-new)
set $arg
FILES="${FILES} ${srcdir}/$2!$1";;
mkdir)
set $arg
mkdir "$2" && chmod "$1" "$2";;
program)
PROGRAM=../"$arg";;
return)
test_empty "${RET}" return
RET="$arg";;
stderr)
echo "${PROGRAM}: $arg" >> stderr;;
stdout)
echo "$arg" >> stdout;;
*)
die "unknown directive '$cmd'"
esac
done
test_set "${RET}" return
test_set "${ARGS}" args
if [ -z "${PROGRAM}" ]
then
die no program to run given
fi
if [ ! -z "${SETUP_ONLY}" ]
then
echo ${DIR}
exit 0
fi
if [ ! -z "${VERBOSE}" ]
then
echo "${TEST}: ${DESCR}"
echo "running: ${PROGRAM} ${ARGS}"
fi
${PROGRAM} ${ARGS} > gotout 2> goterr
ret=$?
if [ $ret -ne ${RET} ]
then
if [ ! -z "${VERBOSE}" ]
then
cat gotout
cat goterr
fi
fail "unexpected exit status: got $ret, expected ${RET}"
fi
FILES_SHOULD="${FILES_SHOULD} stderr stdout gotout goterr"
checkfile stderr goterr "unexpected error output"
checkfile stdout gotout "unexpected output"
if [ ! -z "${FILES}" ]
then
for fs in ${FILES}
do
set -- `echo ${fs} | tr '!' ' '`
FILES_SHOULD="${FILES_SHOULD} $2"
case "$2" in
*.db)
checkdb "$1" "$2" "database $2 wrong";;
*.zip)
checkzip "$1" "$2" "zip file $2 wrong";;
*)
checkfile "$1" "$2" "file $2 wrong";;
esac
done
fi
# check that no additional files exist
echo gotfiles shouldfiles ${FILES_SHOULD} | tr ' ' '\012' | sort > shouldfiles
touch gotfiles
find . -type f -print | sed 's!^./!!' | sort > gotfiles
checkfile shouldfiles gotfiles "unexpected/missing files"
succeed
} < ${srcdir}/${TEST}.test