#! /bin/sh
#
# Run some of the tests.  If any arguments are provided, pass them to the
# test programs.
#
# -mvhome is needed for the ANL SP, and is ignored by others
args="-pg -mvhome"
#
# Some people don't include "." in their path (! in case an ls trojan horse,
# I guess - if someone does that to you, you have bigger problems).  This
# code tests to see if you have a path to mpirun; if not, it tries ./mpirun.
IFS="${IFS= 	}"; saveifs="$IFS"; IFS="${IFS}:"
for dir in $PATH ; do 
    if [ -x $dir/mpirun ] ; then
        mpirun="mpirun"
        break
    fi
done
IFS="$saveifs"
if [ -z "$mpirun" -a -x "./mpirun" ] ; then
    mpirun=./mpirun
fi
if [ -z "$mpirun" ] ; then
    echo "No mpirun in path.  Testing can not proceed."
    exit 1
fi
#
# If the programs are not available, run make.
runtests=1
makeeach=0
quiet=0
check_at_once=1
MAKE="make"
for arg in "$@" ; do
    case $arg in 
	-checkonly)
	runtests=0
	;;
        -margs=*)
	margs=`echo $arg | sed 's/-margs=//'`
	args="$args $margs"
	;;
	-echo)
	set -x
	;;
	-small)
	makeeach=1
	;;
	-quiet)
	shift
	quiet=1
	;;
	-atend)
	check_at_once=0
	;;
	-help|-u)
	echo "runtests [-checkonly] [-margs='...'] [-atend]"
	echo "run tests in this directory.  If -checkonly set, just run"
	echo "the differences check (do NO rerun the test programs)."
	echo "If -margs is used, these options are passed to mpirun."
	echo "If -small is used, the examples are built, run, and deleted."
	echo "If -atend is used, the success of the tests is checked only"
	echo "at the end of the test rather than also after each test."
	exit 1
	;;
	*)
	if test -n "$arg" ; then
	    echo "Passing remaining arguments to programs ($*)"
	    break
        fi
	;;
    esac
done

# MakeExe program-name
MakeExe() {
    if [ ! -x $1 ] ; then
	$MAKE $1
    fi
}
# CleanExe program-name
CleanExe() {
    if [ $makeeach = 1 ] ; then
	/bin/rm -f $1 $1.o
    fi
}
# Output marker
OutTime() {
    if [ $quiet = 0 ] ; then
	if [ -z "$hostname" ] ; then
	    hostname=`hostname`
	fi
	d=`date`
	echo "$hostname : $d"
    fi
}
# Do an "on the fly" check for problems.
CheckOutput() {
  if [ $check_at_once = 1 ] ; then
    stdfile=$1.std
    if [ ! -s $1.out ] ; then
        echo "No output file $1.out!"
    elif [ -s $stdfile ] ; then
        stdfile2=${stdfile}2
        if diff -b $1.out $stdfile > /dev/null ; then
	    true
	elif [ -s $stdfile2 ] ; then 
	    # check for alternate in case configuration has fewer datatypes
	    if diff -b $1.out $stdfile2 > /dev/null ; then
	        true
            else
	        echo "Differences in $1.out"
	        diff -b $1.out $stdfile
	        nodiff=0
	    fi
        else
	    echo "Differences in $1.out"
	    diff -b $1.out $stdfile
	fi
    else
        echo "Can not find file $stdfile to compare against for test $1"
    fi
  fi
}
## RunTest program-name marker-text outputfile programargs
#RunTest() {
#    testfiles="$testfiles $3"
#    /bin/rm -f $3
#    MakeExe $1
#    echo "$2"
#    echo "$2" >> $3
#    $mpirun $args -np 2 $1 "$4" >> $3 2>&1
#    echo "$2" >> $3
#    CleanExe $1
#}   

# If the programs are not available, run make.
if [ ! -x sendrecv -a $makeeach = 0 ] ; then
    $MAKE default
fi

testfiles=""
if [ $runtests = 1 ] ; then
echo '**** Testing MPI Profiling routines ****'

OutTime
testfiles="$testfiles ptest.out"
/bin/rm -f ptest.out
MakeExe ptest
echo '**** Testing MPI_Pcontrol ****' >> ptest.out
echo '**** Testing MPI_Pcontrol ****' 
$mpirun $args -np 1 ptest "$@" >> ptest.out 2>&1
echo '**** Testing MPI_Pcontrol ****' >> ptest.out
#CheckOutput ptest
CleanExe ptest
#
# Run Fortran tests ONLY if Fortran available
#if [ 1 = 1 ] ; then 
#    echo "FORTRAN TESTS"
    #
    #echo "*** secondf ***" >> pt2pt.out
    #$mpirun $args -np 2 secondf "$@" >> pt2pt.out 2>&1
    #
    #testfiles="$testfiles allpair.out"
    #/bin/rm -f allpair.out
    #MakeExe allpair
    #echo '*** Testing pt-2-pt from Fortran ***'
    #echo '*** Testing pt-2-pt from Fortran ***' >> allpair.out
    #$mpirun $args -np 2 allpair "$@" >> allpair.out 2>&1
    #echo '*** Testing pt-2-pt from Fortran ***' >> allpair.out
    #CheckOutput allpair
    #CleanExe allpair
    #
#    echo "END OF FORTRAN TESTS"
#fi
#
else
    # Just run checks
    testfiles=`echo *.out`
    if test "$testfiles" = "*.out" ; then
	echo "No output files remain from previous test!"
	exit 1
    fi
fi
#
echo '*** Checking for differences from expected output ***'
/bin/rm -f profile.diff
nodiff=1
for file in $testfiles ; do
    stdfile=`basename $file .out`.std
    # if basename is sendrecv or isndrcv, then we may want to test 
    # with .std2 as well.  We should really separate out the long double
    # tests ...
    if [ -s $stdfile ] ; then
	stdfile2=${stdfile}2
        if diff -b $file $stdfile > /dev/null ; then
	    true
	elif [ -s $stdfile2 ] ; then 
	    # check for alternate in case configuration has fewer datatypes
	    if diff -b $file $stdfile2 > /dev/null ; then
	        true
            else
	        echo "Differences in `basename $file .out`" >> profile.diff
	        diff -b $file $stdfile >> profile.diff
	        nodiff=0
	    fi
        else
	    echo "Differences in `basename $file .out`" >> profile.diff
	    diff -b $file $stdfile >> profile.diff
	    nodiff=0
	fi
    else
        echo "Can not find file $stdfile to compare against for test `basename $file .out`"
	nodiff=0
    fi
done
if [ -s profile.diff ] ; then
   cat profile.diff
elif [ $nodiff = 1 ] ; then
   echo "-- No differences found; test successful"
fi
exit 0

