#! /bin/sh
:
#
# this shell script tests the spool file locking code for correctness
#

TESTDIR=/tmp/smailspool.$$
CMDNAME=$0

echo "$CMDNAME: testing spool file locking routines"
echo

# XXX should get these values from /usr/include/exitcodes.h????
#
EX_NOINPUT=66		# from exitcodes.h; cannot open input
EX_TEMPFAIL=75		# from exitcodes.h; temp failure; user can retry

#
# create the test directory 
#
[ -d $TESTDIR ] || mkdir $TESTDIR
if [ ! -d $TESTDIR ]; then
	echo "$CMDNAME - fail" 1>&2
	echo "$CMDNAME: Failed to create test directory '$TESTDIR'" 1>&2
	exit 1
fi

#
# choose our spool directory; smail will create it for us
#
SPOOLDIR0=$TESTDIR/spool0

#
# set a trap to cleanup when we exit
#
trap "rm -fr $TESTDIR" 0

#
# cd to the source directory and make the test program
#
(
	echo "make testspool"
	make testspool
	if [ $? -ne 0 -o ! -x ./testspool ]; then
		echo "$CMDNAME: make of 'testspool' failed" 1>&2
		exit 1
	fi
)

#
# verify that we can create spool files
#
# create 5 spool files to play with in $SPOOLDIR0.
# each spool file is more than 5 Kbyte in size so that we can
# we can put it to sleep writing to a pipeline.  standard input
# cannot contain `@' because that causes testspool to simulate
# a write error (for testing of alternate spooling directories).
#
echo "testing create of spool files"
i=0;
while [ $i -lt 5 ]; do
	sed -e 's/@//g' spool.c | ./testspool -s$SPOOLDIR0 c 
	if [ $? -ne 0 ]; then
		echo "$CMDNAME: failed to create a spool file" 1>&2
		exit 1
	fi
	i=`expr $i + 1`
done

#
# verify that we can open and lock the spool files
#
# open the spool files 10 times each
#
echo "testing opening spool files"
i=0
while [ $i -lt 10 ]; do
	for fl in $SPOOLDIR0/input/*; do
		./testspool ow $fl > /dev/null
		if [ $? -ne 0 ]; then
			echo "$CMDNAME: couldn't open spool file '$fl'" 1>&2
			exit 1
		fi
	done
	i=`expr $i + 1`
done
wait

#
# verify that the lock actually works
#
# open each spool file and hold it locked for 2 seconds while we
# verify that another process can't open it.  we hold the spool
# file locked by sleeping on the consumer of the output, which
# is more than 5 Kbyte (one pipe buffer) in size
#
echo "testing spool file locking"
for fl in $SPOOLDIR0/input/*; do
	./testspool ow $fl | sleep 2 > /dev/null &

	./testspool o $fl 2> /dev/null
	if [ $? -ne $EX_TEMPFAIL ]; then
		echo "$CMDNAME: spool file '$fl' was not locked" 1>&2
		exit 1
	fi

	wait
done

#
# verify that the lock actually works using lock_by_name
#
# open each spool file and hold it locked for 2 seconds while we
# verify that another process can't open it.  we hold the spool
# file locked by sleeping on the consumer of the output, which
# is more than 5 Kbyte (one pipe buffer) in size
#
echo "testing spool file locking using lock_by_name"
for fl in $SPOOLDIR0/input/*; do
	./testspool -n ow $fl | sleep 2 > /dev/null &

	./testspool -n o $fl 2> /dev/null
	if [ $? -ne $EX_TEMPFAIL ]; then
		echo "$CMDNAME: spool file '$fl' was not locked" 1>&2
		exit 1
	fi

	wait
done

#
# test unlinking and missing file code
#
# open, lock, and unlink each file. then attempt to do
# it again.  the first attempt should succeed, but the
# second should fail ...
#
echo "testing spool file lock, unlink, and unlink detection"
for fl in $SPOOLDIR0/input/*; do
	./testspool ou $fl 
	if [ $? -ne 0 ]; then
		echo "$CMDNAME: spool file '$fl' could not be removed" 1>&2
		exit 1
	fi

	./testspool ou $fl 2> /dev/null
	if [ $? -ne $EX_NOINPUT ]; then
		echo "$CMDNAME: spool file '$fl' was openable" 1>&2
		exit 1
	fi

	./testspool ou $fl 2>&1 | grep "open failed" > /dev/null
	if [ $? -ne 0 ]; then
		echo "$CMDNAME: spool file '$fl' didn't fail open" 1>&2
		exit 1
	fi
done

echo
echo "$CMDNAME: all tests passed"
exit 0
