#!/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 # # 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