Blame test/commands/cmdtests.in

Packit 0848f5
#! @PERL@ -w
Packit 0848f5
# -*- Mode: perl; -*-
Packit 0848f5
#
Packit 0848f5
# Test the commands provided as part of MPICH
Packit 0848f5
#
Packit 0848f5
# mpicc, mpicxx - handle -Dname="foo bar" and -Dname='"foo bar"'
Packit 0848f5
# (not done yet - see mpich1 test/command/runtests)
Packit 0848f5
# mpiexec - environment handling; stdout, stderr redirection
Packit 0848f5
#
Packit 0848f5
# Configuration values
Packit 0848f5
my $prefix      = "@prefix@";
Packit 0848f5
my $exec_prefix = "@exec_prefix@";
Packit 0848f5
my $bindir      = "@bindir@";
Packit 0848f5
my $srcdir      = "@srcdir@";
Packit 0848f5
Packit 0848f5
# Global variables
Packit 0848f5
my $errors = 0;
Packit 0848f5
Packit 0848f5
$gVerbose = 0;
Packit 0848f5
Packit 0848f5
$xmlOutput = 0;
Packit 0848f5
$xmlFile = "";
Packit 0848f5
$xmlOutputContinue = 0;
Packit 0848f5
# testoutput is used to keep a copy of all output in case there is an
Packit 0848f5
# error and XML output containing the messages is desired.
Packit 0848f5
$testoutput = "";
Packit 0848f5
Packit 0848f5
# The MPD process manager has trouble with stdin.  While this should be
Packit 0848f5
# fixed, for the moment, we provide a way to turn off those tests
Packit 0848f5
$testStdin = 0;
Packit 0848f5
if (defined($ENV{"MPIEXEC_HAS_STDIN"})) { $testStdin = 1; }
Packit 0848f5
Packit 0848f5
# Set a default for the timeout 
Packit 0848f5
# (The stdintest has hung sometimes; a correctly functioning mpiexec
Packit 0848f5
# will abort when this timelimit is exceeded)
Packit 0848f5
if (!defined($ENV{"MPIEXEC_TIMEOUT"})) {
Packit 0848f5
    $ENV{"MPIEXEC_TIMEOUT"} = 20;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
#
Packit 0848f5
# Get a way to kill processes
Packit 0848f5
my $killall = '@KILLALL@';
Packit 0848f5
my $myusername = "";
Packit 0848f5
if (defined($ENV{'LOGNAME'})) {
Packit 0848f5
    $myusername = $ENV{'LOGNAME'};
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# -------------------------------------------------------------------------
Packit 0848f5
if (defined($ENV{'XMLFILE'})) {
Packit 0848f5
    $xmlOutput = 1;
Packit 0848f5
    $xmlFile   = $ENV{'XMLFILE'};
Packit 0848f5
}
Packit 0848f5
if (defined($ENV{'XMLCONTINUE'}) && $ENV{'XMLCONTINUE'} eq "YES") {
Packit 0848f5
    $xmlOutputContinue = 1;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
foreach $_ (@ARGV) {
Packit 0848f5
    if (/-debug/ || /-verbose/) { 
Packit 0848f5
	$gVerbose = 1;
Packit 0848f5
    }
Packit 0848f5
    if (/-xmlfile=(.*)/) {
Packit 0848f5
	$xmlFile = $1;
Packit 0848f5
	$xmlOutput = 1;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	print STDERR "Unrecognized argument $_\n";
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
# -------------------------------------------------------------------------
Packit 0848f5
if ($xmlOutput) {
Packit 0848f5
    if ($xmlOutputContinue) {
Packit 0848f5
	open XMLFD, ">>$xmlFile" || die "Cannot append to $xmlFile";
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	open XMLFD, ">$xmlFile" || die "Cannot open $xmlFile for writing";
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
# -------------------------------------------------------------------------
Packit 0848f5
# mpiexec env handling
Packit 0848f5
# We assume that we can run non-MPI programs
Packit 0848f5
%SaveENV = %ENV;
Packit 0848f5
Packit 0848f5
$ENV{TestEnvVar} = "test var name";
Packit 0848f5
%EnvBase = ('PMI_FD' => 1, 'PMI_RANK' => 0, 'PMI_SIZE' => 1, 
Packit 0848f5
	    'PMI_DEBUG' => 0, 
Packit 0848f5
	    'MPI_APPNUM' => 0, 'MPI_UNIVERSE_SIZE' => 1, 
Packit 0848f5
	    'PMI_PORT' => 1, 
Packit 0848f5
	    'MPICH_INTERFACE_HOSTNAME' => 1,
Packit 0848f5
	    'MPICH_INTERFACE_HOSTNAME_R0' => 1,
Packit 0848f5
	    'MPICH_INTERFACE_HOSTNAME_R1' => 1,
Packit 0848f5
	    'MPICH_INTERFACE_HOSTNAME_R2' => 1,
Packit 0848f5
	    'MPICH_INTERFACE_HOSTNAME_R3' => 1,
Packit 0848f5
	    # These are suspicious
Packit 0848f5
	    'PMI_SPAWNED' => 0, 
Packit 0848f5
	    'PMI_TOTALVIEW' => 0,
Packit 0848f5
	    );
Packit 0848f5
# Other environment variables should be rejected
Packit 0848f5
Packit 0848f5
# Processes on cygwin always have SYSTEMROOT and WINDIR set
Packit 0848f5
%EnvForced = ( 'SYSTEMROOT' => 1, 'WINDIR' => 1 );
Packit 0848f5
Packit 0848f5
%EnvExpected = ();
Packit 0848f5
Packit 0848f5
print "Try some environment args\n" if $gVerbose;
Packit 0848f5
Packit 0848f5
$mpiexec = "$bindir/mpiexec" ;
Packit 0848f5
Packit 0848f5
# Do we get the environment?
Packit 0848f5
%EnvSeen = ();
Packit 0848f5
%EnvExpected = ( 'PATH' => $ENV{PATH} );
Packit 0848f5
Packit 0848f5
&Announce( "$mpiexec printenv" );
Packit 0848f5
open MOUT, "$mpiexec printenv 2>&1 |" || die "Could not run $mpiexec";
Packit 0848f5
while (<MOUT>) {
Packit 0848f5
    # We check for the error output from gforker mpiexec; we can
Packit 0848f5
    # add others here as well
Packit 0848f5
    if (/([^=]+)=(.*)/ && ! /Return code/) {
Packit 0848f5
	$EnvSeen{$1} = $2;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	&ReportError( "Unexpected output from mpiexec: $_" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
close MOUT;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
Packit 0848f5
}
Packit 0848f5
# Check that all vars in save are seen
Packit 0848f5
%copyEnv = %SaveENV;
Packit 0848f5
foreach my $key (keys(%EnvSeen)) {
Packit 0848f5
    if (defined($EnvBase{$key})) { next; }
Packit 0848f5
    delete $copyEnv{$key};
Packit 0848f5
}
Packit 0848f5
foreach my $key (keys(%copyEnv)) {
Packit 0848f5
    print "Enviroment variable $key not delivered to target program\n";
Packit 0848f5
    $errors ++;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
%EnvSeen = ();
Packit 0848f5
%EnvExpected = ( 'PATH' => $ENV{PATH} );
Packit 0848f5
&Announce( "$mpiexec -envnone -envlist PATH printenv" );
Packit 0848f5
open MOUT, "$mpiexec -envnone -envlist PATH printenv 2>&1 |" || die "Could not run $mpiexec";
Packit 0848f5
while (<MOUT>) {
Packit 0848f5
    # We check for the error output from gforker mpiexec; we can
Packit 0848f5
    # add others here as well
Packit 0848f5
    if (/([^=]+)=(.*)/ && ! /Return code/) {
Packit 0848f5
	$EnvSeen{$1} = $2;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	&ReportError( "Unexpected output from mpiexec: $_" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
close MOUT;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
Packit 0848f5
}
Packit 0848f5
# Check that only PATH and the PMI variables are set
Packit 0848f5
$errors += &CheckEnvVars;
Packit 0848f5
Packit 0848f5
%EnvSeen = ();
Packit 0848f5
%EnvExpected = ( 'PATH' => $ENV{PATH} );
Packit 0848f5
&Announce( "$mpiexec -genvnone -genvlist PATH printenv " );
Packit 0848f5
open MOUT, "$mpiexec -genvnone -genvlist PATH printenv 2>&1 |" || die "Could not run $mpiexec";
Packit 0848f5
while (<MOUT>) {
Packit 0848f5
    # We check for the error output from gforker mpiexec; we can
Packit 0848f5
    # add others here as well
Packit 0848f5
    if (/([^=]+)=(.*)/ && ! /Return code/) {
Packit 0848f5
	$EnvSeen{$1} = $2;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	&ReportError( "Unexpected output from mpiexec: $_" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
close MOUT;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
Packit 0848f5
}
Packit 0848f5
# Check that only PATH and the PMI variables are set
Packit 0848f5
$errors += &CheckEnvVars;
Packit 0848f5
Packit 0848f5
%EnvSeen = ();
Packit 0848f5
%EnvExpected = ( 'PATH' => $ENV{PATH},
Packit 0848f5
		 'TestEnvVar' => $ENV{TestEnvVar} );
Packit 0848f5
&Announce ( "$mpiexec -genvnone -genvlist PATH printenv : -envlist TestEnvVar,PATH printenv" );
Packit 0848f5
open MOUT, "$mpiexec -genvnone -genvlist PATH printenv : -envlist TestEnvVar,PATH printenv 2>&1 |" || die "Could not run $mpiexec";
Packit 0848f5
while (<MOUT>) {
Packit 0848f5
    # We check for the error output from gforker mpiexec; we can
Packit 0848f5
    # add others here as well
Packit 0848f5
    if (/Return code/) { next; }
Packit 0848f5
    if (/([^=]+)=(.*)/) {
Packit 0848f5
	$EnvSeen{$1} = $2;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	&ReportError( "Unexpected output from mpiexec: $_" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
close MOUT;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
Packit 0848f5
}
Packit 0848f5
# Check that only PATH and the PMI variables are set
Packit 0848f5
$errors += &CheckEnvVars;
Packit 0848f5
Packit 0848f5
# This test creates long env variables
Packit 0848f5
my $varvalue = "a";
Packit 0848f5
for (my $i=0; $i<11; $i++) {
Packit 0848f5
    $varvalue .= $varvalue;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
$ENV{TESTVAR} = $varvalue;
Packit 0848f5
%EnvSeen = ();
Packit 0848f5
%EnvExpected = ( 'PATH' => $ENV{PATH},
Packit 0848f5
		 'TESTVAR' => $ENV{TESTVAR},
Packit 0848f5
		 );
Packit 0848f5
&Announce( "$mpiexec -envnone -envlist PATH,TESTVAR printenv" );
Packit 0848f5
open MOUT, "$mpiexec -envnone -envlist PATH,TESTVAR printenv 2>&1 |" || die "Could not run $mpiexec";
Packit 0848f5
while (<MOUT>) {
Packit 0848f5
    # We check for the error output from gforker mpiexec; we can
Packit 0848f5
    # add others here as well
Packit 0848f5
    if (/([^=]+)=(.*)/ && ! /Return code/) {
Packit 0848f5
	$EnvSeen{$1} = $2;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	&ReportError( "Unexpected output from mpiexec: $_" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
close MOUT;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
Packit 0848f5
}
Packit 0848f5
# Check that only PATH, TESTVAR, and the PMI variables are set, and
Packit 0848f5
# that they have the correct values
Packit 0848f5
$errors += &CheckEnvVars;
Packit 0848f5
Packit 0848f5
delete $ENV{TESTVAR};
Packit 0848f5
Packit 0848f5
# Intel reports problems with
Packit 0848f5
# export TMP_ENV_VAR=1
Packit 0848f5
# mpiexec -genvlist TMP_ENV_VAR -n 1 -host host1 ./a.out : -n 1 -host host2 \
Packit 0848f5
#   ./a.out
Packit 0848f5
# or using the equivalent config file:
Packit 0848f5
# mpiexec -configfile a.out.cfgfile
Packit 0848f5
# where a.out.cfgfile contains
Packit 0848f5
#   -genvlist TMP_ENV_VAR
Packit 0848f5
#   -n 1 -host host1 ./a.out
Packit 0848f5
#   -n 1 -host host2 ./a.out
Packit 0848f5
#
Packit 0848f5
$ENV{'TMP_ENV_VAR'} = 1;
Packit 0848f5
$myhost = `hostname`;
Packit 0848f5
$myhost =~ s/\r?\n//;
Packit 0848f5
&Announce( "$mpiexec -genvlist TMP_ENV_VAR -n 1 -host $myhost ./checkenv1 : -n 1 -host $myhost ./checkenv1" );
Packit 0848f5
if (! -x "checkenv1" ) {
Packit 0848f5
    system "make checkenv1";
Packit 0848f5
    if (! -x "checkenv1") {
Packit 0848f5
	&ReportError( "Unable to build checkenv1 program\n" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
open MOUT, "$mpiexec -genvlist TMP_ENV_VAR -n 1 -host $myhost ./checkenv1 : -n 1 -host $myhost ./checkenv1 |" || die "Could not run $mpiexec";
Packit 0848f5
$foundNoErrors = 0;
Packit 0848f5
while (<MOUT>) {
Packit 0848f5
    if (/ No Errors/) {
Packit 0848f5
	$foundNoErrors = 1;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	&ReportError( "Unexpected output from mpiexec: $_" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
close MOUT;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
Packit 0848f5
}
Packit 0848f5
if (! $foundNoErrors) {
Packit 0848f5
    $errors ++;
Packit 0848f5
    &ReportError( "checkenv1 did not return No Errors\n" );
Packit 0848f5
}
Packit 0848f5
delete $ENV{'TMP_ENV_VAR'};
Packit 0848f5
Packit 0848f5
# -------------------------------------------------------------------------
Packit 0848f5
# mpiexec stdout/stderr handling
Packit 0848f5
&Announce( "$mpiexec ./stdiotest 2>err.txt 1>out.txt" );
Packit 0848f5
if (! -x "stdiotest" ) {
Packit 0848f5
    system "make stdiotest";
Packit 0848f5
    if (! -x "stdiotest") {
Packit 0848f5
	&ReportError( "Unable to build stdiotest program\n" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
if (-x "stdiotest") {
Packit 0848f5
    unlink "err.txt";
Packit 0848f5
    unlink "out.txt";
Packit 0848f5
    system "$mpiexec ./stdiotest 2>err.txt 1>out.txt";
Packit 0848f5
    # Compare the expected output
Packit 0848f5
    if (-s "err.txt" && -s "out.txt") {
Packit 0848f5
	# We check for the expected output line.  We allow (but warn about)
Packit 0848f5
	# output that was not generated by the program, since that
Packit 0848f5
	# makes it impossible to write Unix-style pipes that include
Packit 0848f5
	# parallel programs.
Packit 0848f5
        open TFD, "
Packit 0848f5
 	$sawOutput = 0;
Packit 0848f5
	$sawExtraLine = 0;
Packit 0848f5
	$sawExtraChars = 0;
Packit 0848f5
	while (<TFD>) {
Packit 0848f5
	    if (/(.*)This is stderr(.*)/) {
Packit 0848f5
		my $pre = $1;
Packit 0848f5
		my $post = $2;
Packit 0848f5
		$sawOutput++;
Packit 0848f5
		if ($pre ne "" || $post ne "") { $sawExtraChars++; }
Packit 0848f5
	    }
Packit 0848f5
	    else {
Packit 0848f5
		print STDERR "Unexpected text in stderr: $_" if $showWarnings;
Packit 0848f5
		$sawExtraLine ++;
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
	close TFD;
Packit 0848f5
	if ($sawOutput != 1) {
Packit 0848f5
	    &ReportError( "Saw expected stderr line $sawOutput times\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	open TFD, "
Packit 0848f5
 	$sawOutput = 0;
Packit 0848f5
	$sawExtraLine = 0;
Packit 0848f5
	$sawExtraChars = 0;
Packit 0848f5
	while (<TFD>) {
Packit 0848f5
	    if (/(.*)This is stdout(.*)/) {
Packit 0848f5
		my $pre = $1;
Packit 0848f5
		my $post = $2;
Packit 0848f5
		$sawOutput++;
Packit 0848f5
		if ($pre ne "" || $post ne "") { $sawExtraChars++; }
Packit 0848f5
	    }
Packit 0848f5
	    else {
Packit 0848f5
		if (/This is stderr/) {
Packit 0848f5
		    &ReportError( "stderr output in stdout file\n" );
Packit 0848f5
		    $errors++;
Packit 0848f5
		}
Packit 0848f5
		print STDERR "Unexpected text in stderr: $_" if $showWarnings;
Packit 0848f5
		$sawExtraLine ++;
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
	close TFD;
Packit 0848f5
	if ($sawOutput != 1) {
Packit 0848f5
	    &ReportError( "Saw expected stdout line $sawOutput times\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	if (! -s "out.txt") {
Packit 0848f5
	    &ReportError( "Program stdiotest did not create stdout file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	if (! -s "err.txt") {
Packit 0848f5
	    &ReportError( "Program stdiotest did not create stderr file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    unlink "err.txt";
Packit 0848f5
    unlink "out.txt";
Packit 0848f5
}
Packit 0848f5
# -------------------------------------------------------------------------
Packit 0848f5
# mpiexec stdin handling
Packit 0848f5
if ($testStdin) {
Packit 0848f5
    &Announce( "$mpiexec ./stdintest <in.txt 2>err.txt 1>out.txt" );
Packit 0848f5
    if (! -x "stdintest" ) {
Packit 0848f5
	system "make stdintest";
Packit 0848f5
	if (! -x "stdintest") {
Packit 0848f5
	    &ReportError( "Unable to build stdintest program\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    if (-x "stdintest") {
Packit 0848f5
	unlink "in.txt";
Packit 0848f5
	unlink "err.txt";
Packit 0848f5
	unlink "out.txt";
Packit 0848f5
	# Create the input file
Packit 0848f5
	open TFD, ">in.txt" || die "Cannot create test input file";
Packit 0848f5
	for (my $i = 0; $i < 1024; $i++) {
Packit 0848f5
	    print TFD "This is line $i\n";
Packit 0848f5
	}
Packit 0848f5
	close TFD;
Packit 0848f5
	
Packit 0848f5
	$rc = system "$mpiexec ./stdintest <in.txt 2>err.txt 1>out.txt";
Packit 0848f5
	if ($rc != 0) {
Packit 0848f5
	    &ReportError( "Program stdintest failed with return $rc" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	# Because some mpiexec programs fail to properly handle these stdio
Packit 0848f5
	# tests, we add a step to kill the test program if mpiexec failed
Packit 0848f5
	# to remove it.
Packit 0848f5
	if ($killall ne "true" && $myusername ne "") {
Packit 0848f5
	    system "$killall -u $myusername stdintest";
Packit 0848f5
	}
Packit 0848f5
	# Compare the expected output
Packit 0848f5
	if (-s "out.txt") {
Packit 0848f5
	    &CheckEchoedOutput;
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    &ReportError( "Program stdintest did not create stdout file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	if (-s "err.txt") {
Packit 0848f5
	    &ReportError( "Program stdintest created a non-empty stderr file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	    system "cat err.txt";
Packit 0848f5
	}
Packit 0848f5
	unlink "err.txt";
Packit 0848f5
	unlink "out.txt";
Packit 0848f5
	
Packit 0848f5
	# Try with a parallel job
Packit 0848f5
	&Announce( "$mpiexec -n 3 ./stdintest <in.txt 2>err.txt 1>out.txt" );
Packit 0848f5
	$rc = system "$mpiexec -n 3 ./stdintest <in.txt 2>err.txt 1>out.txt";
Packit 0848f5
	if ($rc != 0) {
Packit 0848f5
	    &ReportError( "Program stdintest (3 processes) failed with return $rc" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	# Because some mpiexec programs fail to properly handle these stdio
Packit 0848f5
	# tests, we add a step to kill the test program if mpiexec failed
Packit 0848f5
	# to remove it.
Packit 0848f5
	if ($killall ne "true" && $myusername ne "") {
Packit 0848f5
	    system "$killall -u $myusername stdintest";
Packit 0848f5
	}
Packit 0848f5
	# Compare the expected output
Packit 0848f5
	if (-s "out.txt") {
Packit 0848f5
	    &CheckEchoedOutput;
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    &ReportError( "Program stdintest did not create stdout file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	if (-s "err.txt") {
Packit 0848f5
	    &ReportError( "Program stdintest created a non-empty stderr file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	    system "cat err.txt";
Packit 0848f5
	}
Packit 0848f5
	unlink "err.txt";
Packit 0848f5
	unlink "out.txt";
Packit 0848f5
Packit 0848f5
	unlink "in.txt";
Packit 0848f5
    }
Packit 0848f5
    #
Packit 0848f5
    # Test for allowing stdin to have unread data
Packit 0848f5
    &Announce( "$mpiexec ./stdintest2 <in.txt 2>err.txt 1>out.txt" );
Packit 0848f5
    if (! -x "stdintest2" ) {
Packit 0848f5
	system "make stdintest2";
Packit 0848f5
	if (! -x "stdintest2") {
Packit 0848f5
	    &ReportError( "Unable to build stdintest2 program\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    if (-x "stdintest2") {
Packit 0848f5
	unlink "in.txt";
Packit 0848f5
	unlink "err.txt";
Packit 0848f5
	unlink "out.txt";
Packit 0848f5
	# Create the input file
Packit 0848f5
	open TFD, ">in.txt" || die "Cannot create test input file";
Packit 0848f5
	for (my $i = 0; $i < 1024; $i++) {
Packit 0848f5
	    print TFD "This is line $i\n";
Packit 0848f5
	}
Packit 0848f5
	close TFD;
Packit 0848f5
	$rc = system "$mpiexec ./stdintest2 <in.txt 2>err.txt 1>out.txt";
Packit 0848f5
	if ($rc != 0) {
Packit 0848f5
	    &ReportError( "Program stdintest2 failed with return $rc" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	}
Packit 0848f5
	# Because some mpiexec programs fail to properly handle these stdio
Packit 0848f5
	# tests, we add a step to kill the test program if mpiexec failed
Packit 0848f5
	# to remove it.
Packit 0848f5
	if ($killall ne "true" && $myusername ne "") {
Packit 0848f5
	    system "$killall -u $myusername stdintest2";
Packit 0848f5
	}
Packit 0848f5
	# Compare the expected output
Packit 0848f5
	if (-s "out.txt") {
Packit 0848f5
	    # Check for No Errors ONLY
Packit 0848f5
	    open TFD, "
Packit 0848f5
	    $found_no_errors = 0;
Packit 0848f5
	    my $found_other = 0;
Packit 0848f5
	    while (<TFD>) {
Packit 0848f5
		if (/No Errors/) {
Packit 0848f5
		    $found_no_errors = 1;
Packit 0848f5
		}
Packit 0848f5
		else {
Packit 0848f5
		    if (!$found_other) {
Packit 0848f5
			&ReportError( "Found unexpected text %_" );
Packit 0848f5
		    }
Packit 0848f5
		    $found_other = 1;
Packit 0848f5
		    $errors ++;
Packit 0848f5
		}
Packit 0848f5
	    }
Packit 0848f5
	    close TFD;
Packit 0848f5
	    if (! $found_no_errors) {
Packit 0848f5
		&ReportError( "Did not find No Errors" );
Packit 0848f5
		$errors++;
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
	if (-s "err.txt") {
Packit 0848f5
	    &ReportError( "Program stdintest2 created a non-empty stderr file\n" );
Packit 0848f5
	    $errors ++;
Packit 0848f5
	    system "cat err.txt";
Packit 0848f5
	}
Packit 0848f5
	unlink "err.txt";
Packit 0848f5
	unlink "out.txt";
Packit 0848f5
	unlink "in.txt";
Packit 0848f5
    }
Packit 0848f5
}
Packit 0848f5
# -------------------------------------------------------------------------
Packit 0848f5
# Compliation script testing, particularly for special command-line arguments
Packit 0848f5
$cmd = "mpicc";
Packit 0848f5
#$outlog = "/dev/null";
Packit 0848f5
$outlog = "out.log";
Packit 0848f5
unlink $outlog;
Packit 0848f5
&Announce( "$bindir/mpicc -Dtestname=\\\"foo\\\" $srcdir/rtest.c" );
Packit 0848f5
system "$bindir/mpicc -Dtestname=\\\"foo\\\" $srcdir/rtest.c > $outlog 2>&1;;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    &ReportError( "Error with escaped double quotes in $cmd\n" );
Packit 0848f5
    system( "cat $outlog" );
Packit 0848f5
    $errors ++;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
unlink $outlog;
Packit 0848f5
&Announce( "$bindir/mpicc -Dtestname='\"foo bar\"' $srcdir/rtest.c" );
Packit 0848f5
system "$bindir/mpicc -Dtestname='\"foo bar\"' $srcdir/rtest.c  > $outlog 2>&1;;
Packit 0848f5
$rc = $?;
Packit 0848f5
if ($rc != 0) {
Packit 0848f5
    &ReportError( "Error with double inside of single quotes in $cmd\n" );
Packit 0848f5
    system( "cat $outlog" );
Packit 0848f5
    $errors ++;
Packit 0848f5
}
Packit 0848f5
unlink "a.out";
Packit 0848f5
Packit 0848f5
# Run this test only if mpicxx is valid
Packit 0848f5
if ("@bindings@" =~ /cxx/) {
Packit 0848f5
    $cmd = "mpicxx";
Packit 0848f5
    unlink $outlog;
Packit 0848f5
    &Announce( "$bindir/mpicxx -Dtestname=\\\"foo\\\" $srcdir/rtestx.cxx" );
Packit 0848f5
    system "$bindir/mpicxx -Dtestname=\\\"foo\\\" $srcdir/rtestx.cxx  > $outlog 2>&1;;
Packit 0848f5
    $rc = $?;
Packit 0848f5
    if ($rc != 0) {
Packit 0848f5
	&ReportError( "Error with escaped double quotes in $cmd\n" );
Packit 0848f5
	system( "cat $outlog" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
    unlink $outlog;
Packit 0848f5
    &Announce( "$bindir/mpicxx -Dtestname='\"foo bar\"' $srcdir/rtestx.cxx" );
Packit 0848f5
    system "$bindir/mpicxx -Dtestname='\"foo bar\"' $srcdir/rtestx.cxx > $outlog 2>&1;;
Packit 0848f5
    $rc = $?;
Packit 0848f5
    if ($rc != 0) {
Packit 0848f5
	&ReportError( "Error with double inside of single quotes in $cmd\n" );
Packit 0848f5
	system( "cat $outlog" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
    unlink "a.out";
Packit 0848f5
}
Packit 0848f5
# Run this test only if mpif77 is valid
Packit 0848f5
if ("@bindings@" =~ /f77/) {
Packit 0848f5
    $cmd = "mpif77";
Packit 0848f5
    unlink $outlog;
Packit 0848f5
    &Announce( "$bindir/mpif77 -Dtestname=\\\"foo\\\" $srcdir/rtestf.F" );
Packit 0848f5
    system "$bindir/mpif77 -Dtestname=\\\"foo\\\" $srcdir/rtestf.F  > $outlog 2>&1;;
Packit 0848f5
    $rc = $?;
Packit 0848f5
    if ($rc != 0) {
Packit 0848f5
	&ReportError( "Error with escaped double quotes in $cmd\n" );
Packit 0848f5
	system( "cat $outlog" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
    unlink $outlog;
Packit 0848f5
    &Announce( "$bindir/mpif77 -Dtestname='\"foo bar\"' $srcdir/rtestf.F" );
Packit 0848f5
    system "$bindir/mpif77 -Dtestname='\"foo bar\"' $srcdir/rtestf.F > $outlog 2>&1;;
Packit 0848f5
    $rc = $?;
Packit 0848f5
    if ($rc != 0) {
Packit 0848f5
	&ReportError( "Error with double inside of single quotes in $cmd\n" );
Packit 0848f5
	system( "cat $outlog" );
Packit 0848f5
	$errors ++;
Packit 0848f5
    }
Packit 0848f5
    unlink "a.out";
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# FIXME: 
Packit 0848f5
# Still to do:
Packit 0848f5
# Tests for other options to mpiexec (other combinations of env options,
Packit 0848f5
# all MPI-2 mandated options)
Packit 0848f5
#
Packit 0848f5
# ------------------------------------------------------------------------
Packit 0848f5
# Test Summary
Packit 0848f5
if ($errors != 0) {
Packit 0848f5
    print " Found $errors errors\n";
Packit 0848f5
}
Packit 0848f5
else {
Packit 0848f5
    print " No Errors\n";
Packit 0848f5
}
Packit 0848f5
if ($xmlOutput) {
Packit 0848f5
    $newline = "\r\n";
Packit 0848f5
    my $workdir = `pwd`;
Packit 0848f5
    $workdir =~ s/\r?\n//;
Packit 0848f5
    print XMLFD "<MPITEST>$newline<NAME>cmdtest</NAME>$newline";
Packit 0848f5
    print XMLFD "<WORKDIR>$workdir</WORKDIR>$newline";
Packit 0848f5
    if ($errors != 0) {
Packit 0848f5
	print XMLFD "<STATUS>fail</STATUS>$newline";
Packit 0848f5
	$testoutput =~ s/</\*AMP\*lt;/g;
Packit 0848f5
	$testoutput =~ s/>/\*AMP\*gt;/g;
Packit 0848f5
	$testoutput =~ s/&/\*AMP\*amp;/g;
Packit 0848f5
	$testoutput =~ s/\*AMP\*/&/;;
Packit 0848f5
	print XMLFD "<TESTDIFF>$newline$testoutput</TESTDIFF>$newline";
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	print XMLFD "<STATUS>pass</STATUS>$newline";
Packit 0848f5
    }
Packit 0848f5
    print XMLFD "</MPITEST>$newline</MPITESTRESULTS>$newline";
Packit 0848f5
    close XMLFD;
Packit 0848f5
}
Packit 0848f5
exit 0;
Packit 0848f5
# ------------------------------------------------------------------------
Packit 0848f5
# Testing routines
Packit 0848f5
# Check for environment variables
Packit 0848f5
# For simplicity, uses global variables:
Packit 0848f5
#    EnvSeen - variables seen
Packit 0848f5
#    EnvBase - variables part of the PMI interface
Packit 0848f5
#    EnvExpected - other variables
Packit 0848f5
sub CheckEnvVars {
Packit 0848f5
    my $errcount = 0;
Packit 0848f5
    foreach my $key (keys(%EnvSeen)) {
Packit 0848f5
	if (defined($EnvBase{$key})) { next; }
Packit 0848f5
	if (defined($EnvExpected{$key})) { 
Packit 0848f5
	    my $expectedValue = $EnvExpected{$key};
Packit 0848f5
	    my $observedValue = $EnvSeen{$key};
Packit 0848f5
	    if ($expectedValue ne $observedValue) {
Packit 0848f5
		$errcount++;
Packit 0848f5
		&ReportError( "Environment variable $key has value $observedValue but $expectedValue expected\n" );
Packit 0848f5
	    }
Packit 0848f5
	    next; 
Packit 0848f5
	}
Packit 0848f5
	if (defined($EnvForced{$key})) { next; }
Packit 0848f5
	$value = $EnvSeen{$key};
Packit 0848f5
	&ReportError( "Unexpected environment variable $key with $value\n" );
Packit 0848f5
	$errcount ++;
Packit 0848f5
    }
Packit 0848f5
    return $errcount;
Packit 0848f5
}
Packit 0848f5
    
Packit 0848f5
sub Announce {
Packit 0848f5
    my $msg = $_[0];
Packit 0848f5
Packit 0848f5
    print STDOUT $msg . "\n";
Packit 0848f5
    $testoutput .= $msg . "\n";
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
sub ReportError {
Packit 0848f5
    my $msg = $_[0];
Packit 0848f5
    if ( !($msg =~ /\n/) ) { $msg .= "\n"; }
Packit 0848f5
    print STDERR $msg;
Packit 0848f5
    $testoutput .= $msg;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
# This routine is used to check the output from a program that reads 
Packit 0848f5
# from stdin and echos the output.
Packit 0848f5
sub CheckEchoedOutput {
Packit 0848f5
    # We check for the expected output line.  We allow (but warn about)
Packit 0848f5
    # output that was not generated by the program, since that
Packit 0848f5
    # makes it impossible to write Unix-style pipes that include
Packit 0848f5
    # parallel programs.
Packit 0848f5
    open TFD, "
Packit 0848f5
    my $sawOutput = 0;
Packit 0848f5
    my $sawExtraLine = 0;
Packit 0848f5
    my $sawExtraChars = 0;
Packit 0848f5
    my $expectedLinenum = 0;
Packit 0848f5
    my $linesSeen = 0;
Packit 0848f5
Packit 0848f5
    while (<TFD>) {
Packit 0848f5
	if (/(.*)This is line (\d+)(.*)/) {
Packit 0848f5
	    my $pre = $1;
Packit 0848f5
	    my $linenum = $2;
Packit 0848f5
	    my $post = $3;
Packit 0848f5
	    $sawOutput++;
Packit 0848f5
	    $linesSeen++;
Packit 0848f5
	    if ($pre ne "" || $post ne "") { $sawExtraChars++; }
Packit 0848f5
	    if ($linenum != $expectedLinenum) {
Packit 0848f5
		&ReportError( "Unexpected linenumber in output; expected $expectedLinenum but say $linenum\n" );
Packit 0848f5
		$errors++;
Packit 0848f5
	    }
Packit 0848f5
	    $expectedLinenum++;
Packit 0848f5
	}
Packit 0848f5
	else {
Packit 0848f5
	    print STDERR "Unexpected text in stdout: $_" if $showWarnings;
Packit 0848f5
	    $sawExtraLine ++;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    close TFD;
Packit 0848f5
    if ($linesSeen != 1024) {
Packit 0848f5
	&ReportError( "Did not see entire input file (only $linesSeen lines)\n" );
Packit 0848f5
	$errors++;
Packit 0848f5
    }
Packit 0848f5
}