#!/usr/bin/bash
# This script runs trinity with default parameters

DURATION=300
GROUP=
SYSCALL=

###SHELLPACK preamble trinity-bench 0

###SHELLPACK parseargBegin
###SHELLPACK parseargInstall
###SHELLPACK parseargParam   --duration	DURATION
###SHELLPACK parseargParam   --group    GROUP
###SHELLPACK parseargParam   --syscall	SYSCALL
###SHELLPACK parseargEnd

###SHELLPACK check_install_required trinity-${VERSION}
###SHELLPACK init_complete

install-depends system-user-nobody

# Default limit duration to 15 minutes of testing
if [ "$DURATION" = "" ]; then
	DURATION=900
fi

GROUP_PARAM=
if [ "$GROUP" != "" ]; then
	GROUP_PARAM="-g $GROUP"
fi

SYSCALL_PARAM=
if [ "$SYSCALL" != "" ]; then
	SYSCALL_PARAM="-N $SYSCALL"
fi

# Run trinity in the background
echo Launching trinity
cd $SHELLPACK_DATA || die "Failed to cd to $SHELLPACK_DATA"
mkdir tmp
chmod 777 tmp
TAINT=`cat /proc/sys/kernel/tainted`
STARTTIME=`date +%s`
ENDTIME=$((STARTTIME+$DURATION))
su -s /bin/bash nobody -c "$SHELLPACK_SOURCES/trinity-$VERSION-installed/trinity -q $SYSCALL_PARAM $GROUP_PARAM" 2>&1 | tee $LOGDIR_RESULTS/trinity.log &
TRINITY_PID=$!

echo -n Waiting for trinity to exit, max $DURATION seconds or a kernel taint
CURRENTTIME=`date +%s`
PID_RUNNING=running
TRINITY_STATUS=0
while [ "$PID_RUNNING" != "" ]; do
	PID_RUNNING=`ps h --pid $TRINITY_PID`
	echo MARK: Trinity PID $TRINITY_PID Maximum $((($ENDTIME - $CURRENTTIME))) seconds to go
	sleep 5

	# Check expired duration
	if [ $CURRENTTIME -ge $ENDTIME ]; then
		echo Duration expired
		if [ "$SYSCALL" = "" ]; then
			echo WARNING: Unexpected expiration
			TRINITY_STATUS=1
		else
			echo Duration expired
		fi
		shutdown_pid trinity $TRINITY_PID
		PID_RUNNING=
		continue
	fi

	# Check for abnormal exit before duration expired
	if [ "$PID_RUNNING" = "" ]; then
		if [ "$SYSCALL" != "" ]; then
			wait $TRINITY_PID
			if [ $? -eq 0 ]; then
				TRINITY_STATUS=0
			else
				TRINITY_STATUS=2
			fi
		else
			echo ERROR: Trinity died before duration expired
			TRINITY_STATUS=3
		fi
		continue
	fi

	# Check for change in taint
	if [ "`cat /proc/sys/kernel/tainted`" != $TAINT ]; then
		cat $LOGDIR_RESULTS/trinity.log
		echo ERROR: Taint flag changed `cat /proc/sys/kernel/tainted`
		shutdown_pid trinity $TRINITY_PID
		PID_RUNNING=
		TRINITY_STATUS=4
	fi

	# Check for trinity bugs
	grep -q ^BUG $LOGDIR_RESULTS/trinity.log
	if [ $? -eq 0 ]; then
		echo WARNING: Trinity reported an internal bug
		shutdown_pid trinity $TRINITY_PID
		PID_RUNNING=
		TRINITY_STATUS=5
	fi

	CURRENTTIME=`date +%s`
done
echo

echo $TRINITY_STATUS > $LOGDIR_RESULTS/trinity.error
echo Final trinity status: $TRINITY_STATUS

exit $SHELLPACK_SUCCESS
