fatal()
{
echo "fatal: $*" >/dev/stderr
exit 1
}
make_is_fmake() {
${MAKE_PROG} -f Makefile.non-existent -v 2>&1 | \
grep -q "cannot open.*non-existent"
}
ensure_workdir()
{
if [ ! -d ${WORK_DIR} ] ; then
fatal "working directory ${WORK_DIR} does not exist."
fi
}
ensure_run()
{
if [ -z "${TEST_N}" ] ; then
TEST_N=1
fi
FAIL=
N=1
while [ ${N} -le ${TEST_N} ] ; do
if ! skip_test ${N} ; then
if [ ! -f ${OUTPUT_DIR}/status.${N} -o \
! -f ${OUTPUT_DIR}/stdout.${N} -o \
! -f ${OUTPUT_DIR}/stderr.${N} ] ; then
echo "Test ${SUBDIR}/${N} no yet run"
FAIL=yes
fi
fi
N=$((N + 1))
done
if [ ! -z "${FAIL}" ] ; then
exit 1
fi
}
print_usage()
{
echo "Usage: sh -v -m <path> -w <dir> $0 command(s)"
echo " setup - setup working directory"
echo " run - run the tests"
echo " show - show test results"
echo " compare - compare actual and expected results"
echo " diff - diff actual and expected results"
echo " reset - reset the test to its initial state"
echo " clean - delete working and output directory"
echo " test - setup + run + compare"
echo " prove - setup + run + compare + clean"
echo " desc - print short description"
echo " update - update the expected results with the current results"
echo " help - show this information"
}
skip_test()
{
eval skip=\${TEST_${1}_SKIP}
if [ -z "${skip}" ] ; then
return 1
else
return 0
fi
}
common_setup()
{
if [ -e ${SRC_DIR}/Makefile.test -a ! -e ${WORK_DIR}/Makefile ] ; then
cp ${SRC_DIR}/Makefile.test ${WORK_DIR}/Makefile
fi
set -- ${TEST_MAKE_DIRS}
while [ $# -ne 0 ] ; do
if [ ! -d ${WORK_DIR}/${1} ] ; then
mkdir -p -m ${2} ${WORK_DIR}/${1}
else
chmod ${2} ${WORK_DIR}/${1}
fi
shift ; shift
done
set -- ${TEST_COPY_FILES}
while [ $# -ne 0 ] ; do
local dstname="$(echo ${1} | sed -e 's,Makefile.test,Makefile,')"
if [ ! -e ${WORK_DIR}/${dstname} ] ; then
cp ${SRC_DIR}/${1} ${WORK_DIR}/${dstname}
fi
chmod ${2} ${WORK_DIR}/${dstname}
shift ; shift
done
eval set -- ${TEST_TOUCH}
while [ $# -ne 0 ] ; do
eval touch ${2} ${WORK_DIR}/${1}
shift ; shift
done
eval set -- ${TEST_LINKS}
while [ $# -ne 0 ] ; do
eval ln ${WORK_DIR}/${1} ${WORK_DIR}/${2}
shift ; shift
done
}
eval_setup()
{
if [ -d ${WORK_DIR} ] ; then
fatal "working directory ${WORK_DIR} already exists."
fi
mkdir -p ${WORK_DIR}
rm -rf ${OUTPUT_DIR}
mkdir -p ${OUTPUT_DIR}
common_setup
setup_test
}
setup_test()
{
}
eval_reset()
{
ensure_workdir
rm -rf ${OUTPUT_DIR}/*
common_setup
for f in ${TEST_CLEAN_FILES} ; do
rm -rf ${WORK_DIR}/${f}
done
reset_test
}
reset_test()
{
}
eval_clean()
{
if [ -n "${TEST_CLEANUP}" ] ; then
. ${SRC_DIR}/cleanup
fi
if [ -z "${NO_TEST_CLEANUP}" ] ; then
rm -rf ${WORK_DIR}
rm -rf ${OUTPUT_DIR}
fi
}
eval_run()
{
ensure_workdir
if [ -z "${TEST_N}" ] ; then
TEST_N=1
fi
N=1
while [ ${N} -le ${TEST_N} ] ; do
if ! skip_test ${N} ; then
( cd ${WORK_DIR} ;
exec 1>${OUTPUT_DIR}/stdout.${N} 2>${OUTPUT_DIR}/stderr.${N}
run_test ${N}
echo $? >${OUTPUT_DIR}/status.${N}
)
fi
N=$((N + 1))
done
}
run_test()
{
eval args=\${TEST_${1}-test${1}}
${MAKE_PROG} $args
}
eval_show()
{
ensure_workdir
if [ -z "${TEST_N}" ] ; then
TEST_N=1
fi
N=1
while [ ${N} -le ${TEST_N} ] ; do
if ! skip_test ${N} ; then
echo "=== Test ${N} Status =================="
cat ${OUTPUT_DIR}/status.${N}
echo ".......... Stdout .................."
cat ${OUTPUT_DIR}/stdout.${N}
echo ".......... Stderr .................."
cat ${OUTPUT_DIR}/stderr.${N}
fi
N=$((N + 1))
done
}
eval_compare()
{
ensure_workdir
ensure_run
if [ -z "${TEST_N}" ] ; then
TEST_N=1
fi
echo "1..${TEST_N}"
N=1
while [ ${N} -le ${TEST_N} ] ; do
fail=
todo=
skip=
if ! skip_test ${N} ; then
do_compare stdout ${N} || fail="${fail}stdout "
do_compare stderr ${N} || fail="${fail}stderr "
do_compare status ${N} || fail="${fail}status "
eval todo=\${TEST_${N}_TODO}
else
eval skip=\${TEST_${N}_SKIP}
fi
msg=
if [ ! -z "$fail" ]; then
msg="${msg}not "
fi
msg="${msg}ok ${N} ${SUBDIR}/${N}"
if [ ! -z "$fail" -o ! -z "$todo" -o ! -z "$skip" ]; then
msg="${msg} # "
fi
if [ ! -z "$skip" ] ; then
msg="${msg}skip ${skip}; "
fi
if [ ! -z "$todo" ] ; then
msg="${msg}TODO ${todo}; "
fi
if [ ! -z "$fail" ] ; then
msg="${msg}reason: ${fail}"
fi
echo ${msg}
N=$((N + 1))
done
}
do_compare()
{
local EXPECTED RESULT
EXPECTED="${SRC_DIR}/expected.$1.$2"
RESULT="${OUTPUT_DIR}/$1.$2"
if [ -f $EXPECTED ]; then
cat $RESULT | sed -e "s,^$(basename $MAKE_PROG):,make:," | \
diff -u $EXPECTED -
return $?
else
return 1
fi
}
eval_diff()
{
ensure_workdir
ensure_run
if [ -z "${TEST_N}" ] ; then
TEST_N=1
fi
N=1
while [ ${N} -le ${TEST_N} ] ; do
if ! skip_test ${N} ; then
FAIL=
do_diff stdout ${N}
do_diff stderr ${N}
do_diff status ${N}
fi
N=$((N + 1))
done
}
do_diff()
{
local EXPECTED RESULT
EXPECTED="${SRC_DIR}/expected.$1.$2"
RESULT="${OUTPUT_DIR}/$1.$2"
echo diff -u $EXPECTED $RESULT
if [ -f $EXPECTED ]; then
diff -u $EXPECTED $RESULT
else
echo "${EXPECTED} does not exist"
fi
}
eval_update()
{
ensure_workdir
ensure_run
if [ -z "${TEST_N}" ] ; then
TEST_N=1
fi
FAIL=
N=1
while [ ${N} -le ${TEST_N} ] ; do
if ! skip_test ${N} ; then
cp ${OUTPUT_DIR}/stdout.${N} expected.stdout.${N}
cp ${OUTPUT_DIR}/stderr.${N} expected.stderr.${N}
cp ${OUTPUT_DIR}/status.${N} expected.status.${N}
fi
N=$((N + 1))
done
}
eval_desc()
{
echo "${SUBDIR}: ${DESC}"
}
eval_test()
{
eval_setup
eval_run
eval_compare
}
eval_prove()
{
eval_setup
eval_run
eval_compare
eval_clean
}
eval_cmd()
{
if [ $# -eq 0 ] ; then
set -- prove
fi
if ! make_is_fmake ; then
for i in $(jot ${TEST_N:-1}) ; do
eval TEST_${i}_SKIP=\"make is not fmake\"
done
fi
for i
do
case $i in
setup | run | compare | diff | clean | reset | show | \
test | prove | desc | update)
eval eval_$i
;;
* | help)
print_usage
;;
esac
done
}
SRC_DIR=$(dirname $0)
SRC_BASE=`cd ${SRC_DIR} ; while [ ! -f common.sh ] ; do cd .. ; done ; pwd`
SUBDIR=`echo ${SRC_DIR} | sed "s@${SRC_BASE}/@@"`
WORK_DIR=$(pwd)/work/${SUBDIR}
OUTPUT_DIR=${WORK_DIR}.OUTPUT
MAKE_PROG=${MAKE_PROG:-/usr/bin/make}