#! /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.
if [ -z "$MPICH_USE_LIB_MPIRUN" ] ; then
    IFS="${IFS= 	}"; saveifs="$IFS"; IFS="${IFS}:"
    for dir in $PATH ; do 
        if [ -x $dir/mpirun ] ; then
	    if [ -n "MPICH 1.1.1 (O) of : 1998/07/13 13:29:16" ] ; then
		# Test that we've found the correct mpirun
		if strings $dir/mpirun | grep "MPIRUN for MPICH" > /dev/null ; then
		    :
		else
		    # echo "$dir/mpirun isn't for MPICH"
		    continue
		fi
	    fi
            mpirun="mpirun"
            break
        fi
    done
    IFS="$saveifs"
fi
if [ -z "$mpirun" -a -x "./mpirun" ] ; then
    mpirun=./mpirun
fi
#
# Here is the location of the MPICH version of mpirun
if [ -z "$mpirun" -a -x /usr/src/redhat/BUILD/mpich/lib/LINUX/ch_p4/mpirun ] ; then 
    mpirun="/usr/src/redhat/BUILD/mpich/lib/LINUX/ch_p4/mpirun"
fi
if [ -z "$mpirun" ] ; then
    echo "No mpirun in path.  Testing can not proceed."
    exit 1
fi
#
quiet=0
runtests=1
makeeach=0
MAKE="make --no-print-directory"
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
    fi
}
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
}
# If the programs are not available, run make.
if [ ! -x sigchk -a $makeeach = 0 ] ; then
    $MAKE default
fi
#
testfiles=""
if [ $runtests = 1 ] ; then

OutTime
testfiles="$testfiles timers.out"
/bin/rm -f timers.out
MakeExe timers
echo "*** Timer tests ***"
echo "*** Timer tests ***" >> timers.out
$mpirun $args -np 1 timers $* >> timers.out 2>&1
echo "*** Timer tests ***" >> timers.out
CleanExe timers

OutTime
testfiles="$testfiles init.out"
/bin/rm -f init.out
MakeExe init
echo "*** MPI_Initialized tests ***"
echo "*** MPI_Initialized tests ***" >> init.out
$mpirun $args -np 2 ./init $* >> init.out 2>&1
echo "*** MPI_Initialized tests ***" >> init.out
CleanExe init

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

OutTime
testfiles="$testfiles gtime.out"
/bin/rm -f gtime.out
MakeExe gtime
echo "*** WTIME_IS_GLOBAL ***"
echo "*** WTIME_IS_GLOBAL ***" >> gtime.out
$mpirun $args -np 1 gtime $* >> gtime.out 2>&1
echo "*** WTIME_IS_GLOBAL ***" >> gtime.out
CleanExe gtime

OutTime
testfiles="$testfiles errhand.out"
/bin/rm -f errhand.out
MakeExe errhand
echo "*** Tests of error handling ***" 
echo "*** Tests of error handling ***" >>errhand.out
$mpirun $args -np 1 errhand $* >> errhand.out 2>&1
echo "*** Tests of error handling ***" >>errhand.out
CleanExe errhand

OutTime
testfiles="$testfiles sigchk.out"
/bin/rm -f sigchk.out
MakeExe sigchk
echo "*** Tests of signals used ***"
echo "*** Tests of signals used ***" >> sigchk.out
$mpirun $args -np 1 sigchk $* >> sigchk.out 2>&1
echo "*** Tests of signals used ***" >> sigchk.out
CleanExe sigchk

#
# If there was a Unix standard interface to ps, we could check for orphaned
# processes...
if ps -ef > /dev/null 2>&1 ; then
   PSPGM="ps -ef"
else
   PSPGM="ps -auxww"
fi
OutTime
testfiles="$testfiles aborttest.out"
/bin/rm -f aborttest.out aborttest.p1 aborttest.p2
MakeExe aborttest
echo "*** Tests of MPI_Abort ***"
echo "*** Tests of MPI_Abort ***" >> aborttest.out
$PSPGM | grep $LOGNAME > aborttest.p1
$mpirun $args -np 2 aborttest $* > /dev/null 2>&1
$PSPGM | grep $LOGNAME > aborttest.p2
# If there was a consistant format, we could process it ...
ndiff="`cat aborttest.p1 | wc -l` - `cat aborttest.p2 | wc -l`"
ndiff=`expr $ndiff`
if test "$ndiff" = 0 ; then
    echo "All processes aborted" >> aborttest.out    
else
    echo "Suspicious processes remain" >> aborttest.out
    echo "Processes before" >> aborttest.out
    cat aborttest.p1 >> aborttest.out
    echo "Processes after" >> aborttest.out
    cat aborttest.p2 >> aborttest.out
fi
echo "*** Tests of MPI_Abort ***" >> aborttest.out
CleanExe aborttest

OutTime
/bin/rm -f aborttest.p1 aborttest.p2
echo "*** Tests of MPI_Abort (alt) ***"
echo "*** Tests of MPI_Abort (alt) ***" >> aborttest.out
$PSPGM | grep $LOGNAME > aborttest.p1
$mpirun $args -np 2 aborttest -altmaster $* > /dev/null 2>&1
$PSPGM | grep $LOGNAME > aborttest.p2
ndiff="`cat aborttest.p1 | wc -l` - `cat aborttest.p2 | wc -l`"
ndiff=`expr $ndiff`
if test "$ndiff" = 0 ; then
    echo "All processes aborted" >> aborttest.out    
else
    echo "Suspicious processes remain" >> aborttest.out
    echo "Processes before" >> aborttest.out
    cat aborttest.p1 >> aborttest.out
    echo "Processes after" >> aborttest.out
    cat aborttest.p2 >> aborttest.out
fi
echo "*** Tests of MPI_Abort (alt) ***" >> aborttest.out
/bin/rm -f aborttest.p1 aborttest.p2
CleanExe aborttest

#
# Run Fortran tests ONLY if Fortran available
if [ 1 = 1 ] ; then 

    OutTime
    testfiles="$testfiles errstringsf.out"
    /bin/rm -f errstringsf.out
    MakeExe errstringsf
    echo "*** Tests of Fortran error strings ***"
    echo "*** Tests of  Fortran error strings ***" >> errstringsf.out
    $mpirun $args -np 1 errstringsf $* >> errstringsf.out 2>&1
    echo "*** Tests of  Fortran error strings ***" >> errstringsf.out
    CleanExe errstringsf

fi

else
    # Just run checks
    testfiles=*.out
    if test "$testfiles" eq "*.out" ; then
	echo "No output files remain from previous test!"
	exit 1
    fi
fi

#
echo '*** Checking for differences from expected output ***'
/bin/rm -f env.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`" >> env.diff
	    diff -b $file `basename $file .out`.std >> env.diff
	    nodiff=0
	fi
    else
        echo "Can not find file $stdfile to compare against for test `basename $file .out`"
    fi
done
if [ -s env.diff ] ; then
   cat env.diff
elif [ $nodiff = 1 ] ; then
   echo "-- No differences found; test successful"
fi
exit 0
