#! /bin/sh
#
#  SCCS		%W%	%G%
#
#  This script locates and runs various regression tests for bru.
#  Tests are numbered sequentially, starting at 000.  Each test has
#  the following components:
#
#	1.	There is a mandatory test driver program called "run"
#		which performs all the grunt work of setting up for the
#		test and then then running the test.
#
#	2.	There is an optional file of input which is passed to
#		the test driver on it's standard input stream.  This
#		file is named "test.input".
#
#	3.	There is an optional file of sed commands which are
#		used to postprocess the output generated by the test,
#		to eliminate things that change from run to run, such
#		as the date of archive creation for example.  This file
#		is named "test.sed".
#
#	4.	There is an mandatory file which contains the expected
#		output for each test.  This file may be empty if no
#		output is expected.  The actual output is compared with
#		this file, after any postprocessing using the test.sed
#		file.  If the file does not exist, it is automatically
#		created the first time the test is run.  This makes adding
#		new tests easier.  This file is named "test.output".
#
#  Invoke as "testbru <flags> <bru executable> <flags> <testnumber>".
#  I.E. "testbru /usr/bin/bru"  or "testbru /usr/bin/bru -p t001 t004"

if test -x /bin/sh
then
	SHELL=/bin/sh ; export SHELL
fi

#  Ensure that '.' is in PATH, and that we pick up our own things
#  first, in case of a naming conflict.

PATH=.:$PATH ; export PATH

#  First save our invocation name for printing in messages.

me=`basename $0`

#  Parse all args that are intended for the test driver (us).

while true
do
	case $1 in
		-v)	verbose=on
			shift
			;;
		*)	break
			;;
	esac
done

#  Now locate the bru executable.  If one was given on the command line
#  then silently use it, after testing that it exists and is executable.
#  If one is not given then look in a list of standard places and print
#  a warning about which one we are using.  Also, we need to get its
#  absolute pathname.

case $1 in
	t[0-9][0-9][0-9])	tfound=yes
				;;
	*)			tfound=no
				;;
esac

if [ "$#" -eq "0" -o "$tfound" = "yes" ]
then
	if test -x bru
	then
		bru=bru
	elif test -x /bin/bru
	then
		bru=/bin/bru
	elif test -x /usr/bin/bru
	then
		bru=/usr/bin/bru
	elif test -x /usr/local/bin/bru
	then
		bru=/usr/local/bin/bru
	fi
	if [ "$bru" = "" ]
	then
		echo 1>&2 "$me: no bru executable specified"
		exit 1
	else
		echo 1>&2 "$me: warning - defaulting to use $bru"
	fi
else
	bru=$1
	shift
fi
if test ! -x $bru
then
	echo 1>&2 "$me: $bru does not appear to be executable bru program"
	exit 1
fi
dir=`dirname $bru`
file=`basename $bru`
dir=`(cd $dir; pwd)`
bru=$dir/$file

#  Parse the remaining args as flags to pass to the test driver.

while true
do
	case $1 in
		-*)	testflags="$testflags $1"
			shift
			;;
		*)	break
			;;
	esac
done

#  If we ate all the command line args without seeing any explicit test
#  numbers, then run all the available tests.

if [ "$#" -eq "0" ]
then
	set -- t[0-9][0-9][0-9]
	if test ! -f $1/run
	then
		echo 1>&2 "$me: no test drivers found, nothing to do"
		exit 1
	fi
fi

#  Set up name of temporary files and directory where they go.
#  Set up traps to catch signals 1, 2, 13, and 15.

TMPDIR=${TMPDIR:-/tmp}
tmpout1=$TMPDIR/tbru1.$$
tmpout2=$TMPDIR/tbru2.$$
trap "rm -f $tmpout1 $tmpout2 ; exit 1" 1 2 13 15

#  Loop through each of the desired test basenames and run the test for
#  each one.  Complain if the driver program is not found.


echo "\nRESULT\tNUMBER\tGOAL"
echo "------\t------\t---------------------------------------------------"

testroot=`pwd`
for tnum in $*
do
	if test ! -d $tnum
	then
		echo 1>&2 "$me: missing test $tnum"
	elif test ! -f $tnum/run
	then
		echo 1>&2 "$me: missing test driver $tnum/run"
	else
		if test ! -x $tnum/run
		then
			chmod +x $tnum/run
		fi
		cd $tnum
		goal=`$SHELL run -g`
		if test -f test.input
		then
			input=test.input
		else
			input=/dev/null
		fi
		$SHELL run $testflags $bru <$input >$tmpout1 2>&1
		if test -f test.sed
		then
			sed -f test.sed <$tmpout1 >$tmpout2
			mv $tmpout2 $tmpout1
		fi
		if test -f test.output.Z
		then
			compress -d <test.output.Z >test.output
			if cmp test.output $tmpout1 >/dev/null 2>&1
			then
				echo "OK\t${tnum}\t${goal}"
				rm -f $tmpout1
			else
				echo "FAIL\t${tnum}\t${goal}"
				diff test.output $tmpout1 >test.diff
				mv $tmpout1 test.bad
			fi
			rm -f test.output
		else
			echo "FAIL\t${tnum}\t(output missing, created it)"
			compress <$tmpout1 >test.output.Z
			rm -f $tmpout1
		fi
		cd $testroot
	fi
done

rm -f $tmpout1 $tmpout2

exit 0
