#
#--------------------------------------------------
# This Perl script executes  tests handed down to it
# via the environment variable PLANG_TESTS.  The
# script was develored for the plang distribution.
#
# Terry Clark July 1998
#--------------------------------------------------

#--------------------------------------------------
#
#--------------------------------------------------
#use strict
##########

$debug      = 0;

!$debug || print STDERR "entered runtest.pl\n";

#--------------------------------------------------
# options
#      verbose: sends basic message to stderr
#        debug: sends more info to stderr
#   upperprocs: range check on the max number of processes
#      mulstep: the additive factor for loop over
#               0 < nproc < maxproc. E.g, mulstep=2 for ^2.
#--------------------------------------------------
$verbose    = 1;
$upperprocs = 1024;
$mulstep    = 1;

$maxproc    = 0;

$maxproc  = $ENV{"PLANG_MPROCS"};
$plangtop = $ENV{"PLANG_TOP"};
$netint   = $ENV{"PLANG_NETINT"};
$plangbin = $ENV{"PLANG_BIN"};
$logf     = $ENV{"PLANG_LOG"};
$llogf    = $ENV{"PLANG_LLOG"};
$tmpf     = $ENV{"PLANG_TMP"};
$ptests   = $ENV{"PLANG_TESTS"};
$platform = $ENV{"PLANG_PLATFORM"};
$mpirun   = $ENV{"PLANG_MPIRUN"};

!$debug || print STDERR "testing with ".$ptests."\n";
!$debug || print STDERR "   plangtop=",$plangtop,"\n";
!$debug || print STDERR "   netint=",$netint,"\n";
!$debug || print STDERR "   plangbin=",$plangbin,"\n";
!$debug || print STDERR "   platform=",$platform,"\n";
!$debug || print STDERR "   mpirun=",$mpirun,"\n";

if ($maxproc >$upperprocs || $maxproc<=0) {
   die "upper bound on n-processes invalid ".$maxproc."\n";
}



#-----------------------------------------
# look for network interface specifics 
#-----------------------------------------

if ($netint eq "isim") {
    $isim   = $plangtop."/BIN/ISIM/".$platform."/isim";
    checkfile("rx",$isim,0);
} elsif ($platform eq "linux" && $netint eq "pvm") {
    $pvmrun = $plangbin."/pvmrun";
    checkfile("rx",$pvmrun,0);
} elsif ($platform eq "sp2" && $netint eq "mpi") {
    $poerun  = "poe";
} elsif ($platform eq "linux" && $netint eq "mpi") {
   checkfile("rx",$mpirun,0);
} elsif ($platform eq "t3e" && $netint eq "mpi") {
   checkfile("rx",$mpirun,0);
} elsif ($platform eq "sgi64" && $netint eq "mpi") {
   checkfile("rx",$mpirun,0);
}

#-----------------------------------------
# initialize tmp file, logfiles, and test 
#-----------------------------------------
checkclear($tmpf);


!$debug || print STDERR "LOGFILE: ".$logf."\n";
!$debug || print STDERR "LOGFILE: ".$llogf."\n";

checkclear($logf);
open(LOG,">>".$logf)  || die "could not open log file\n";
checkclear($llogf);
open(LLOG,">>".$llogf) || die "could not open long log file\n";

$catstring = "cat ".$tmpf." >> ".$llogf;

#-----------------------------------------
# loop over tests
#-----------------------------------------
@plangtests = split(' ', $ptests);
foreach $testname ( @plangtests ) {
     !$debug || print STDERR "   testname=",$testname,"\n";
     $test   = $plangbin."/".$testname;
     checkfile("rx",$test,0);

     for ($nproc=2; $nproc<$maxproc+1; $nproc+=$mulstep) {
        if ($netint eq "isim") {
             isimRun($test,$tmpf,$nproc,$isim);
        } elsif ($platform eq "sp2") {
             poeRun($test,$tmpf,$nproc,$poerun);
        } elsif ($platform eq "linux" && $netint eq "mpi") {
             mpiRun($test,$tmpf,$nproc,$mpirun,$platform);
        } elsif ($platform eq "t3e" && $netint eq "mpi") {
             mpiRun($test,$tmpf,$nproc,$mpirun,$platform);
        } elsif ($platform eq "linux" && $netint eq "pvm") {
             pvmRun($test,$tmpf,$nproc,$pvmrun,$platform);
        } elsif ($platform eq "sgi64" && $netint eq "mpi") {
             mpiRun($test,$tmpf,$nproc,$mpirun,$platform);
        }
   	system $catstring;
        checkOK($testname,$tmpf,$nproc);
     }#for nproc 

} #foreach test



close  LOG;
close LLOG;


#-------------
sub poeRun {

  !$debug || print STDERR "entered poeRun\n";

  $progname = $_[0];
  $tmpfile  = $_[1];
  $nproc    = $_[2];
  $poerun   = $_[3];
  $runpoe = $poerun." ".$progname." -procs ".$nproc." -rmpool 1"." > ".$tmpfile."|";

  !$debug || print STDERR " runpoe=",$runpoe,"\n";

  open(POE,$runpoe) || die "could not execute poe\n";
  close POE;

}

#-------------
sub isimRun {

  $progname = $_[0];
  $tmpfile  = $_[1];
  $nproc    = $_[2];
  $isim     = $_[3];
  $runisim = "|".$isim." > ".$tmpfile;
  $getcube = "gc -t".$nproc."\n";
  $loadprog = "load ".$progname."\n";

  $start = "start\n";
  $quit  = "quit\n";


  !$debug || print STDERR "   isim runisim=",$runisim,"\n";
  !$debug || print STDERR "   isim getcube=",$getcube;
  !$debug || print STDERR "   isim loadprog=",$loadprog;
  !$debug || print STDERR "   isim start=",$start;
  !$debug || print STDERR "   isim quit=",$quit;



  open(ISIM,$runisim) || die "could not execute isim\n";
  print ISIM $getcube;
  print ISIM $loadprog;
  print ISIM $start;
  print ISIM $quit;
  close ISIM;

#print ISIM "gc -t8\n";
#print ISIM "load overview-isim\n";
#print ISIM "start\n";
#print ISIM "exit\n";
#die "done early\n";

}

#-------------
sub mpiRun {

  !$debug || print STDERR "entered mpiRun\n";

  local $progname = $_[0];
  local $tmpfile  = $_[1];
  local $nproc    = $_[2];
  local $mpirun   = $_[3];
  local $platform = $_[4];

  if ($platform eq "linux") {
     $runmpi = $mpirun." -np ".$nproc." ".$progname." > ".$tmpfile."|";
  } elsif ($platform eq "t3e") {
     $runmpi = $mpirun." -np ".$nproc." ".$progname." > ".$tmpfile."|";
  } elsif ($platform eq "sgi64") {
     $runmpi = $mpirun." -np ".$nproc." ".$progname." > ".$tmpfile."|";
  }

  !$debug || print STDERR " runmpi=",$runmpi,"\n";

  open(MPI,$runmpi) || die "could not execute mpi\n";
  close MPI;

}

#-------------
sub pvmRun {

  !$debug || print STDERR "entered pvmRun\n";

  local $progname = $_[0];
  local $tmpfile  = $_[1];
  local $nproc    = $_[2];
  local $pvmrun   = $_[3];
  local $platform = $_[4];

  if ($platform eq "linux") {
     $runpvm = $pvmrun." -n ".$nproc." ".$progname." > ".$tmpfile."|";
  } elsif ($platform eq "t3e") {
     $runpvm = $pvmrun." -n ".$nproc." ".$progname." > ".$tmpfile."|";
  }

  !$debug || print STDERR " runpvm=",$runpvm,"\n";

  open(PVM,$runpvm) || die "could not execute pvm3.4 \n";
  close PVM;

}


#-------------
sub checkOK {
  my ($progname) = $_[0];
  my ($tmp)      = $_[1];
  my ($nproc)    = $_[2];
  my ($npass)    = 0;

  open(TMP,$tmp) || die "could not open output file\n";

  while (<TMP>) {
    !$debug || print STDERR $_;
    if (/passed/) { 
      $npass++;
    } 
  }  #while

  if ($npass == $nproc) {
     $outcome = $progname." passed,  nproc= ".$nproc."\n";
  }
  else {
     $outcome = $progname." failed,  nproc= ".$nproc."\n";
  }

  print  LOG  $outcome;
  print  LLOG $outcome;
  !$debug || !$verbose  || print STDERR $outcome;
  print STDERR $outcome;


  close(TMP);
}


#-------------
sub checkfile {

 $_    = $_[0];
 $name = $_[1];
 $okay = $_[2];

 !$debug || print STDERR "checkfile name:",$name,"\n";

 if (! -e $name) {
    $okay || die "could not find ".$name."\n";
    system "touch",$name; 
 } 

 if ( /r/ && ! -r $name) {
    $okay || die "could not read ".$name."\n";
 }

 if ( /x/ && ! -x $name) {
    $okay || die "cannot execute ".$name."\n";
 }

 if ( /w/ && ! -w $name) {
    $okay || die "cannot write ".$name."\n";
 }



}

#---------------
sub checkclear {
  my ($progname) = $_[0];
  checkfile("e",$progname,1);
  system "cat /dev/null > ".$progname; 
}





