#! /bin/sh
mpirun="mpirun"
STOPFILE=$HOME/.stopmpichtests
#
# If the programs are not available, run make.
runtests=1
makeeach=0
check_at_once=1
quiet=0
MAKE="make"
srcdir=/build/lam-vXW2Mm/lam-7.1.4/romio/test
check_canrun=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
	;;
	-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."
	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
	/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() {
  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 "$@" >> simple.out 2>&1
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 "$@" >> async.out 2>&1
CheckOutput async
CleanExe async
#
OutTime
testfiles="$testfiles atomicity.out"
\rm -f atomicity.out
MakeExe atomicity
\rm -f $FILENAME*
echo '**** Testing atomicity.c ****'
$mpirun -np 4 ./atomicity -fname $FILENAME "$@" >> atomicity.out 2>&1
CheckOutput atomicity
CleanExe atomicity
#
OutTime
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 "$@" >> coll_test.out 2>&1
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 "$@" >> excl.out 2>&1
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 "$@" >> file_info.out 2>&1
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 "$@" >> i_noncontig.out 2>&1
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 "$@" >> noncontig.out 2>&1
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 "$@" >> noncontig_coll.out 2>&1
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 "$@" >> noncontig_coll2.out 2>&1
CheckOutput noncontig_coll2
CleanExe noncontig_coll2
#
OutTime
testfiles="$testfiles misc.out"
\rm -f misc.out
MakeExe misc
\rm -f $FILENAME*
echo '**** Testing misc.c ****'
$mpirun -np 4 ./misc -fname $FILENAME "$@" >> misc.out 2>&1
CheckOutput misc
CleanExe misc
#
OutTime
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 "$@" >> shared_fp.out 2>&1
CheckOutput shared_fp
CleanExe shared_fp
#
OutTime
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 "$@" >> split_coll.out 2>&1
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 "$@" >> psimple.out 2>&1
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 "$@" >> error.out 2>&1
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 "$@" >> status.out 2>&1
CheckOutput status
CleanExe status
#
if [ 0 = 0 ] ; then 
    echo ""
    echo "FORTRAN TESTS"
    OutTime
    testfiles="$testfiles fmisc.out"
    \rm -f fmisc.out
    MakeExe fmisc
    \rm -f $FILENAME*
    echo '**** Testing fmisc.f ****'
    $mpirun -np 4 ./fmisc -fname $FILENAME "$@" >> fmisc.out 2>&1
    CheckOutput fmisc
    CleanExe fmisc
#
    OutTime
    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 "$@" >> fcoll_test.out 2>&1
    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 "$@" >> pfcoll_test.out 2>&1
    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 ***'
/bin/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

