#!/bin/bash
# This is the script to run the sdet benchmark
#
# reqparam value The number of scripts to run (you may specify things like "1 4 16")
# optparam prefix "-i" value The number of iterations to run (default 10)
# optparam prefix "-l" value The directory to run the test in (default $TMPDIR)
# optparam prefix "-v" Be verbose with the output
#

. /etc/autobench.conf || . functions

# Process the arguments ######################################################
USAGE="Usage: $0 number-of-scripts [-i iterations] [-l location-to-run-in] [-v]"
if [ $# -lt 1 ]; then
	echo $USAGE
	exit 1
fi

RUNDIR="autobench"
SCRIPTS=
#SCRIPTS=$1
#shift
# defaults
ITERATIONS=10
RUNLOCATION=$TMPDIR/sdet

if [ -n "$RUN_NUMBER" ]; then
	RUN_SUFFIX=".$RUN_NUMBER"
fi

while [ $# -gt 0 ]; do
	case $1 in
	-i)
		if [ $# -gt 1 ]; then
			ITERATIONS=$2
			shift 2
		else
			echo $USAGE
			exit 1
		fi
		;;
	-l)
		if [ $# -gt 1 ]; then
			RUNLOCATION=$2
			shift 2
		else
			echo $USAGE
			exit 1
		fi
		;;
	-v)
		VERBOSE=yes
		shift
		;;
	*)
		SCRIPTS="$SCRIPTS $1"
		shift
		#echo $USAGE
		#exit 1
		;;
	esac
done

# Install support files ######################################################
if [ ! \( -e $AUTODIR/sources/sdet \) ]; then
	$AUTODIR/scripts/benchmarks/install/sdet || exit 2
fi

getcommand doprofilers
doprofilers install


# Prepare the benchmark ######################################################
pushd $AUTODIR/sources/sdet > /dev/null

# Check the dependancies

# some distros have the english dicionary in english.dat, others in en.dat
if echo "hi" | aspell -l -p ./benchspec/057.sdet/bin/custom-dict.english > /dev/null 2> /dev/null; then
	rm ./benchspec/057.sdet/bin/custom-dict
	ln -sf custom-dict.english ./benchspec/057.sdet/bin/custom-dict
elif echo "hi" | aspell -l -p ./benchspec/057.sdet/bin/custom-dict.en > /dev/null 2> /dev/null; then
	rm ./benchspec/057.sdet/bin/custom-dict
	ln -sf custom-dict.en ./benchspec/057.sdet/bin/custom-dict
else
	echo "hi" | aspell -l -p ./benchspec/057.sdet/bin/custom-dict.english 2>&1
	echo Please fix the above aspell error
	exit 1
fi

if ! vmstat 2 2 2>&1 > /dev/null; then
	echo Please update your procps tools before using 2.6 kernels
	exit 1
fi


if [ ! -e ./shrc ]; then
	echo Please run from the sdet directory
	exit 1
fi

# Some math functions
SCALE=4	# How many places after the decimal place to use
if [ -n "`which dc`" ]; then
	MATH_INT="d"
elif [ -n "`which bc`" ]; then
	MATH_INT="b"
else
	MATH_INT="i"
fi

function mymath() {
	case $MATH_INT in
		d) a=`echo $2 | tr - _`	# dc uses _ to represent negative numbers
			 b=`echo $3 | tr - _`
			 echo "$SCALE k $a $b $1 p" | dc 
			 ;;
		b) echo -e "scale=$SCALE\n$2 $1 $3" | bc ;;
		i) a=`echo $2 | cut -f1 -d.`
			 b=`echo $3 | cut -f1 -d.`
			 echo $((a${1}b))
			 ;;
	esac
}

function mysqrt()	{ 
	case $MATH_INT in
		d) echo "$SCALE k $1 v p" | dc ;;
		b) echo -e "scale=$SCALE\nsqrt($1)" | bc ;;
	esac
}

function myadd()	{ mymath "+" $1 $2 ; }
function mysub()	{ mymath "-" $1 $2 ; }
function mymult() 	{ mymath "*" $1 $2 ; }
function mydiv()	{ mymath "/" $1 $2 ; }
# end math functions

# Prepare sdet
for LOC in $RUNLOCATION; do
	mkdir -p $RUNLOCATION
done
rm -rf /tmp/sdet-tmp 2> /dev/null
mkdir -p /tmp/sdet-tmp

. ./shrc

# If they asked for more then one iteration, we will do a warmup first
if [ $ITERATIONS -gt 1 ]; then
	echo "Warming up the system..........."
	export ITERATION="warmup"
	spec_auto 1 linux warmup-dir 1 1 "$RUNLOCATION" validate 057.sdet > /dev/null
fi

if [ -z "$VERBOSE" ]; then
	REDIR_TO="/tmp/sdet-tmp/stdout.$$"
else
	REDIR_TO="/dev/stdout"
fi

# Run the benchmark ##########################################################
# They may have said "1 4 16" scripts
for SCRIPT_COUNT in $SCRIPTS; do
	if [ `echo $SCRIPTS | wc -w` -gt 1 ]; then
		SCRIPT_PART=".$SCRIPT_COUNT"
	else
		SCRIPT_PART=""
	fi
	rm tests.results/057.sdet/$RUNDIR/* 2> /dev/null

	echo "Running $ITERATIONS iterations with $SCRIPT_COUNT scripts......."

	for ((CUR_IT=1; CUR_IT<=$ITERATIONS; CUR_IT++)); do
		if [ $ITERATIONS -gt 1 ]; then
			ITERATION_PART=".$CUR_IT"
		else
			ITERATION_PART=""
		fi
		SUFFIX="$SCRIPT_PART$ITERATION_PART"
		export ITERATION=`echo $SUFFIX | sed -e "s/^\.//"`
		SUFFIX="$RUN_SUFFIX$SUFFIX"

		# Run the test
		echo "Running SDET client_count = $SCRIPT_COUNT ITERATION $CUR_IT OF $ITERATION"
		spec_auto 1 linux $RUNDIR 1 $SCRIPT_COUNT \
			"$RUNLOCATION" validate 057.sdet > $REDIR_TO

		if [ $? != 0 ]; then
			echo error during iteration $i;
			exit 1;
		fi
		if [ -z "$VERBOSE" ]; then
			cat $REDIR_TO | grep SDET_THROUGH
			rm $REDIR_TO
		fi

		# Store the result
		for RESULT_FILE in tests.results/057.sdet/$RUNDIR/*; do 
			# should be files g. & l.
			RESULT_FILE=`basename $RESULT_FILE`
			mv tests.results/057.sdet/$RUNDIR/$RESULT_FILE $LOGDIR/benchmark/$RESULT_FILE$SUFFIX
		done
	done
	# Do a run for profiling
	startprofilers $SCRIPT_COUNT
	spec_auto 1 linux $RUNDIR 1 $SCRIPT_COUNT \
		"$RUNLOCATION" validate 057.sdet > $REDIR_TO
	stopprofilers $SCRIPT_COUNT
	doprofilers report $SCRIPT_COUNT
done

# Post process the results...
echo "Postprocessing results"
for SCRIPT_COUNT in $SCRIPTS; do
	if [ `echo $SCRIPTS | wc -w` -gt 1 ]; then
		SCRIPT_PART=".$SCRIPT_COUNT"
	else
		SCRIPT_PART=""
	fi

	SUM=0
	RESULTS=""
	for ((CUR_IT=1; CUR_IT<=$ITERATIONS; CUR_IT++)); do
		if [ $ITERATIONS -gt 1 ]; then
			ITERATION_PART=".$CUR_IT"
		else
			ITERATION_PART=""
		fi
		SUFFIX="$RUN_SUFFIX$SCRIPT_PART$ITERATION_PART"
		ITERATION=`echo $SUFFIX | sed -e "s/^\.//"`
		doprofilers postprocess $ITERATION
		NEW_RESULT=`ls $LOGDIR/benchmark/g.*$SUFFIX`
		THIS_RESULT=`cat "$NEW_RESULT" | tail -n1 | cut -f2`
		SUM=`myadd $SUM $THIS_RESULT`
		RESULTS="$RESULTS $THIS_RESULT"
	done

	# We have all the results, calculate some stats
	AVG=`mydiv $SUM $ITERATIONS`
	STD_DEV=0
	for ((CUR_IT=1; CUR_IT<=$ITERATIONS; CUR_IT++)); do
		RESULT=`echo $RESULTS | cut -f$CUR_IT -d" "`
		DIFF=`mysub $RESULT $AVG`
		PROD=`mymult $DIFF $DIFF`
		STD_DEV=`myadd $STD_DEV $PROD`
	done

	if [ $ITERATIONS -gt 1 ]; then
		STD_DEV=`mydiv $STD_DEV $ITERATIONS`
		STD_DEV=`mysqrt $STD_DEV`
		echo "Results: $RESULTS"
		echo "Results: $RESULTS" > $LOGDIR/benchmark/sdetout.$RUN_NUMBER$SCRIPT_PART
		echo -e "Scripts: $SCRIPT_COUNT\tAverage Throughput: $AVG\t Standard Deviation: $STD_DEV"
		echo -e "Scripts: $SCRIPT_COUNT\tAverage Throughput: $AVG\t Standard Deviation: $STD_DEV" >> $LOGDIR/benchmark/sdetout.$RUN_NUMBER$SCRIPT_PART
	else
		echo -e "Scripts: $SCRIPT_COUNT\tThroughput: $RESULTS"
		echo -e "Scripts: $SCRIPT_COUNT\tThroughput: $RESULTS" > $LOGDIR/benchmark/sdetout.$RUN_NUMBER$SCRIPT_PART
	fi

done

# Clean up the run location(s) to save space
for i in $RUNLOCATION; do
	rm -rf $i/*
done

popd > /dev/null
