#! /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
#
#
test_mpi2=1
runtests=1
quiet=0
makeeach=0
MAKE="make"
for arg in "$@" ; do
    case $arg in 
	-checkonly )
	runtests=0
	;;
        -margs=*)
	margs=`echo $arg | sed 's/-margs=//'`
	args="$args $margs"
	;;
	-small)
	makeeach=1
	;;
	-quiet)
	shift
	quiet=1
	;;
	-help|-u)
	echo "runtests [-checkonly] [-margs='...']"
	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."
	exit 1
	;;
	*)
	if test -n "$arg" ; then
   	    echo "runtests: Unknown argument ($arg)"
	    exit 1
        fi
	;;
    esac
done

MakeExe() {
    if [ ! -x $1 ] ; then
	$MAKE $1
        if [ ! -x $1 ] ; then 
	    echo "Could not build executable $1; aborting tests"
	    exit 1
        fi
    fi
}
CleanExe() {
    if [ $makeeach = 1 ] ; then
	/bin/rm $1 $1.o
    fi
}
# Output marker
OutTime() {
    if [ $quiet = 0 ] ; then
	if [ -z "$hostname" ] ; then
	    hostname=`hostname`
	fi
	d=`date`
	echo "$hostname : $d"
    fi
}

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

testfiles=""
if [ $runtests = 1 ] ; then

#
# Run Fortran tests ONLY if Fortran available
if [ 1 = 1 ] ; then 
    OutTime
    testfiles="$testfiles attrf.out"
    /bin/rm -f attrf.out
    MakeExe attrtest
    echo '*** Testing attributes from Fortran ***'
    echo '*** Testing attributes from Fortran ***' >> attrf.out
    $mpirun $args -np 2 attrtest $* >> attr.out 2>&1
    echo '*** Testing attributes from Fortran ***' >> attrf.out
    CleanExe attrtest

    if [ $test_mpi2 = 1 ] ; then

    OutTime
    testfiles="$testfiles commnamesf.out"
    /bin/rm -f commnamesf.out
    MakeExe commnamesf
    echo '*** Testing Communicator Names from Fortran ***'
    echo '*** Testing Communicator Names from Fortran ***' >> commnamesf.out
    $mpirun $args -np 1 commnamesf $* >> commnamesf.out 2>&1
    echo '*** Testing Communicator Names from Fortran ***' >> commnamesf.out
    CleanExe commnamesf

    fi
fi

OutTime
testfiles="$testfiles attr.out"
/bin/rm -f attr.out
MakeExe attrt
echo '*** Testing attributes ***'
echo '*** Testing attributes ***' >> attr.out
$mpirun $args -np 2 attrt $* >> attr.out 2>&1
echo '*** Testing attributes ***' >> attr.out
CleanExe attrt

OutTime
testfiles="$testfiles attrerr.out"
/bin/rm -f attrerr.out
MakeExe attrerr
echo '*** Testing attributes (2) ***'
echo '*** Testing attributes (2) ***' >> attrerr.out
$mpirun $args -np 1 attrerr $* >> attrerr.out 2>&1
echo '*** Testing attributes (2) ***' >> attrerr.out
CleanExe attrerr

OutTime
testfiles="$testfiles grouptest.out"
/bin/rm -f grouptest.out
MakeExe grouptest
echo '*** Testing Groups ***'
echo '*** Testing Groups ***' >> grouptest.out
$mpirun $args -np 4 grouptest $* >> grouptest.out 2>&1
echo '*** Testing Groups ***' >> grouptest.out
CleanExe grouptest

OutTime
testfiles="$testfiles groupcreate.out"
/bin/rm -f groupcreate.out
MakeExe groupcreate
echo '*** Testing Group creation ***'
echo '*** Testing Group creation ***' >> groupcreate.out
$mpirun $args -np 4 groupcreate $* >> groupcreate.out 2>&1
echo '*** Testing Group creation ***' >> groupcreate.out
CleanExe groupcreate

OutTime
testfiles="$testfiles ictest.out"
/bin/rm -f ictest.out
MakeExe ictest
echo '*** Testing Intercommunicators ***'
echo '*** Testing Intercommunicators ***' >> ictest.out
$mpirun $args -np 4 ictest $* >> ictest.out 2>&1
echo '*** Testing Intercommunicators ***' >> ictest.out
CleanExe ictest

#
# ictest2 relies on a inconsistency in the standard, to wit, that the
# leader in both groups can be the same process.  This seems to be
# essential in a dynamic setting, since the only process both groups can
# access may be the single parent process (other than using client/server
# intercommunicator creating routines, with the parent providing the common
# information).
#
#testfiles="$testfiles ictest2.out"
#/bin/rm -f ictest2.out
#MakeExe ictest2
#echo '*** Testing Intercommunicators (2) ***'
#echo '*** Testing Intercommunicators (2) ***' >> ictest2.out
#$mpirun $args -np 4 ictest2 $* >> ictest2.out 2>&1
#echo '*** Testing Intercommunicators (2) ***' >> ictest2.out
#CleanExe ictest2

OutTime
testfiles="$testfiles ictest3.out"
/bin/rm -f ictest3.out
MakeExe ictest3
echo '*** Testing Intercommunicators (3) ***'
echo '*** Testing Intercommunicators (3) ***' >> ictest3.out
$mpirun $args -np 4 ictest3 $* >> ictest3.out 2>&1
echo '*** Testing Intercommunicators (3) ***' >> ictest3.out
CleanExe ictest3

if [ $test_mpi2 = 1 ] ; then

    OutTime
    testfiles="$testfiles commnames.out"
    /bin/rm -f commnames.out
    MakeExe commnames
    echo '*** Testing Communicator Names ***'
    echo '*** Testing Communicator Names ***' >> commnames.out
    $mpirun $args -np 2 commnames $* >> commnames.out 2>&1
    echo '*** Testing Communicator Names ***' >> commnames.out
    CleanExe commnames

fi
else
    # Just run checks
    testfiles=`echo *.out`
fi

echo '*** Checking for differences from expected output ***'
/bin/rm -f context.diff
nodiff=1
for file in $testfiles ; do
    stdfile=`basename $file .out`.std
    if [ -s $stdfile ] ; then
        if diff -b $file `basename $file .out`.std > /dev/null ; then
	    true
        else
	    echo "Differences in `basename $file .out`" >> context.diff
	    diff -b $file `basename $file .out`.std >> context.diff
	    nodiff=0
	fi
    else
        echo "Can not find file $stdfile to compare against for test `basename $file .out`"
    fi
done
if [ -s context.diff ] ; then
   cat context.diff
elif [ $nodiff = 1 ] ; then
   echo "-- No differences found; test successful"
fi
exit 0
