#! /bin/sh
mpirun="@MPIRUN@"
STOPFILE=${MPITEST_STOPTEST:-"$HOME/.stopmpichtests"}
#
# If the programs are not available, run make.
runtests=1
makeeach=0
check_at_once=1
quiet=0
MAKE="@MAKE@"
srcdir=@srcdir@
check_canrun=0
subset_only=0
FILENAME=test
# Using shifts should remove args from the list.
for arg in "$@" ; do
    case $arg in 
	-checkonly)
	shift
	runtests=0
	;;
        -margs=*)
	shift
	margs=`echo $arg | sed 's/-margs=//'`
	args="$args $margs"
	;;
	-echo)
	shift
	set -x
	;;
	-check)
	check_canrun=1
	;;
	-quiet)
	shift
	quiet=1
	;;
	-small)
	shift
	makeeach=1
	;;
	-subset)
	shift
	subset_only=1
	;;
	-fname=*)
	FILENAME=`echo $arg|sed 's/-*fname=//'`
	;;
	-atend)
	shift
	check_at_once=0
	;;
	-help|-u)
	shift
	echo "runtests [-fname=FILENAME] [-checkonly] [-atend] [-check]"
	echo "run tests in this directory.  If -checkonly set, just run"
	echo "the differences check (do NOT rerun the test programs)."
	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."
	echo "If -check is used, only a single simple test is run; this"
	echo "is used to check that mpirun can run an MPI program."
	echo "If -subset is used, we skip tests for atomicity and shared"
	echo "file pointers which can fail on some distributed file systems" 
	exit 1
	;;
	*)
	if test -n "$arg" ; then
	    echo "Passing remaining arguments to programs ($*)"
	    break
        fi
	;;
    esac
done

# MakeExe program-name
MakeExe() {
    if [ -s $STOPFILE ] ; then 
        echo "Found stopfile; exiting"
        exit 0
    fi
    if [ ! -x $1 ] ; then
	$MAKE $1
        if [ ! -x $1 ] ; then 
	    echo "Could not build executable $1; aborting tests"
	    exit 1
        fi
    fi
}
# CleanExe program-name
CleanExe() {
    if [ $makeeach = 1 ] ; then
	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() {
  bfile=$1
  if [ $check_at_once = 1 ] ; then
    stdfile=${srcdir}/std/$bfile.std
    if [ ! -s $bfile.out ] ; then
        echo "No output file $bfile.out!"
    elif [ -s $stdfile ] ; then
        stdfile2=${stdfile}2
        # Handle Fortran systems that generate stop statements
        rm -f ${bfile}.tout
	grep -v 'FORTRAN STOP' ${bfile}.out > ${bfile}.tout
        if diff -b $bfile.tout $stdfile > /dev/null ; then
	    true
	elif [ -s $stdfile2 ] ; then 
	    # check for alternate in case configuration has fewer datatypes
	    if diff -b $bfile.tout $stdfile2 > /dev/null ; then
	        true
            else
	        echo "Differences in $bfile.out"
	        diff -b $bfile.tout $stdfile
	        nodiff=0
	    fi
        else
	    echo "Differences in $bfile.out"
	    diff -b $bfile.tout $stdfile
	fi
        rm -f ${bfile}.tout
    else
        echo "Can not find file $stdfile to compare against for test $bfile"
    fi
  fi
}

# nothing uses this function yet... just toying with the concept
RunTest() {
      OutTime
      testfiles="$testfiles ${1}.out"
      rm -rf ${1}.out
      MakeExe simple
      rm -rf $FILENAME*
      echo "**** Testing ${1}.c ****"
      mpirun -np 4 ./${1} -fname $FILENAME "$@" >>${1}.out 2>1
      CheckOutput ${1} 
      CleanExe ${1}
}

# If the programs are not available, run make.
if [ ! -x simple -a $makeeach = 0 ] ; then
    $MAKE default
fi
#
testfiles=""
if [ $runtests = 1 ] ; then
echo '**** Testing I/O functions ****'
#
OutTime
testfiles="$testfiles simple.out"
\rm -f simple.out
MakeExe simple
\rm -f $FILENAME*
echo '**** Testing simple.c ****'
$mpirun -np 4 ./simple -fname $FILENAME
# CheckOutput simple
CleanExe simple
#
OutTime
testfiles="$testfiles async.out"
\rm -f async.out
MakeExe async
\rm -f $FILENAME*
echo '**** Testing async.c ****'
$mpirun -np 4 ./async -fname $FILENAME
# CheckOutput async
CleanExe async
#
OutTime
if [ $subset_only -eq 0 ] ; then 
	testfiles="$testfiles atomicity.out"
	\rm -f atomicity.out
	MakeExe atomicity
	\rm -f $FILENAME*
	echo '**** Testing atomicity.c ****'
	# Atomicity test recommends at least 8 processes (separate processors 
	# even better)
	$mpirun -np 4 ./atomicity -fname $FILENAME
	# CheckOutput atomicity
	CleanExe atomicity
	#
	OutTime
fi
testfiles="$testfiles coll_test.out"
\rm -f coll_test.out
MakeExe coll_test
\rm -f $FILENAME*
echo '**** Testing coll_test.c ****'
$mpirun -np 4 ./coll_test -fname $FILENAME
# CheckOutput coll_test
CleanExe coll_test
#
OutTime
testfiles="$testfiles excl.out"
\rm -f excl.out
MakeExe excl
\rm -f $FILENAME*
echo '**** Testing excl.c ****'
$mpirun -np 4 ./excl -fname $FILENAME
# CheckOutput excl
CleanExe excl
#
OutTime
testfiles="$testfiles file_info.out"
\rm -f file_info.out
MakeExe file_info
\rm -f $FILENAME*
echo '**** Testing file_info.c ****'
$mpirun -np 4 ./file_info -fname $FILENAME
# CheckOutput file_info
CleanExe file_info
#
OutTime
testfiles="$testfiles i_noncontig.out"
\rm -f i_noncontig.out
MakeExe i_noncontig
\rm -f $FILENAME*
echo '**** Testing i_noncontig.c ****'
$mpirun -np 2 ./i_noncontig -fname $FILENAME
# CheckOutput i_noncontig
CleanExe i_noncontig
#
OutTime
testfiles="$testfiles noncontig.out"
\rm -f noncontig.out
MakeExe noncontig
\rm -f $FILENAME*
echo '**** Testing noncontig.c ****'
$mpirun -np 2 ./noncontig -fname $FILENAME
# CheckOutput noncontig
CleanExe noncontig
#
OutTime
testfiles="$testfiles noncontig_coll.out"
\rm -f noncontig_coll.out
MakeExe noncontig_coll
\rm -f $FILENAME*
echo '**** Testing noncontig_coll.c ****'
$mpirun -np 2 ./noncontig_coll -fname $FILENAME
# CheckOutput noncontig_coll
CleanExe noncontig_coll
#
OutTime
testfiles="$testfiles noncontig_coll2.out"
\rm -f noncontig_coll2.out
MakeExe noncontig_coll2
\rm -f $FILENAME*
echo '**** Testing noncontig_coll2.c ****'
$mpirun -np 4 ./noncontig_coll2 -fname $FILENAME
# CheckOutput noncontig_coll2
CleanExe noncontig_coll2
#
OutTime
if [ $subset_only -eq 0 ] ; then 
	testfiles="$testfiles misc.out"
	\rm -f misc.out
	MakeExe misc
	\rm -f $FILENAME*
	echo '**** Testing misc.c ****'
	$mpirun -np 4 ./misc -fname $FILENAME
	# CheckOutput misc
	CleanExe misc
	#
	OutTime
fi
if [ $subset_only -eq 0 ] ; then
	testfiles="$testfiles shared_fp.out"
	\rm -f shared_fp.out
	MakeExe shared_fp
	\rm -f $FILENAME*
	echo '**** Testing shared_fp.c ****'
	$mpirun -np 4 ./shared_fp -fname $FILENAME
	# CheckOutput shared_fp
	CleanExe shared_fp
	#
	OutTime
fi
testfiles="$testfiles split_coll.out"
\rm -f split_coll.out
MakeExe split_coll
\rm -f $FILENAME*
echo '**** Testing split_coll.c ****'
$mpirun -np 4 ./split_coll -fname $FILENAME
# CheckOutput split_coll
CleanExe split_coll
#
OutTime
testfiles="$testfiles psimple.out"
\rm -f psimple.out
MakeExe psimple
\rm -f $FILENAME*
echo '**** Testing psimple.c ****'
$mpirun -np 4 ./psimple -fname $FILENAME
# CheckOutput psimple
CleanExe psimple
#
OutTime
testfiles="$testfiles error.out"
\rm -f error.out
MakeExe error
\rm -f $FILENAME*
echo '**** Testing error.c ****'
$mpirun -np 1 ./error -fname $FILENAME
# CheckOutput error
CleanExe error
#
OutTime
testfiles="$testfiles status.out"
\rm -f status.out
MakeExe status
\rm -f $FILENAME*
echo '**** Testing status.c ****'
# Some systems have a status program.
$mpirun -np 1 ./status -fname $FILENAME
# CheckOutput status
CleanExe status
#
if [ @NOF77@ = 0 ] ; then 
    echo ""
    echo "FORTRAN TESTS"
    OutTime
    if [ $subset_only -eq 0 ] ; then
	    testfiles="$testfiles fmisc.out"
	    \rm -f fmisc.out
	    MakeExe fmisc
	    \rm -f $FILENAME*
	    echo '**** Testing fmisc.f ****'
	    $mpirun -np 4 ./fmisc -fname $FILENAME
	    # CheckOutput fmisc
	    CleanExe fmisc
	    #
	    OutTime
    fi
    testfiles="$testfiles fcoll_test.out"
    \rm -f fcoll_test.out
    MakeExe fcoll_test
    \rm -f $FILENAME*
    echo '**** Testing fcoll_test.f ****'
    $mpirun -np 4 ./fcoll_test -fname $FILENAME
    # CheckOutput fcoll_test
    CleanExe fcoll_test
#
    OutTime
    testfiles="$testfiles pfcoll_test.out"
    \rm -f pfcoll_test.out
    MakeExe pfcoll_test
    \rm -f $FILENAME*
    echo '**** Testing pfcoll_test.f ****'
    $mpirun -np 4 ./pfcoll_test -fname $FILENAME
    # CheckOutput pfcoll_test
    CleanExe pfcoll_test
#
echo ""
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 ***'
# rm -f iotests.diff
# nodiff=1
# for file in $testfiles ; do
#     stdfile="${srcdir}/std/`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
#         # Handle Fortran systems that generate stop statements
# 	bfile="`basename $file .out`.tout"
#         rm -f ${bfile}
# 	grep -v 'FORTRAN STOP' ${file} > ${bfile}
#         if diff -b $bfile $stdfile > /dev/null ; then
# 	    true
# 	elif [ -s $stdfile2 ] ; then 
# 	    # check for alternate in case configuration has fewer datatypes
# 	    if diff -b $bfile $stdfile2 > /dev/null ; then
# 	        true
#             else
# 	        echo "Differences in `basename $file .out`" >> iotests.diff
# 	        diff -b $bfile $stdfile >> iotests.diff
# 	        nodiff=0
# 	    fi
#         else
# 	    echo "Differences in `basename $file .out`" >> iotests.diff
# 	    diff -b $bfile $stdfile >> iotests.diff
# 	    nodiff=0
# 	fi
#         rm -f ${bfile}
#     else
#         echo "Can not find file $stdfile to compare against for test `basename $file .out`"
# 	nodiff=0
#     fi
# done
# if [ -s iotests.diff ] ; then
#    cat iotests.diff
# elif [ $nodiff = 1 ] ; then
#    echo "-- No differences found; test successful"
# fi
 exit 0
 
