#! /usr/bin/env perl # -*- Mode: perl; -*- # checkbuilds. Generated from checkbuilds.in by configure. # # Configure and build mpich with some of the options # # Set default values $projects_dir = "/home/MPI/testing/tsuites"; # alt is for systems that have /homes instead of /home $altprojects_dir = "/homes/MPI/testing/tsuites"; if (! -d $projects_dir && -d $altprojects_dir ) { $projects_dir = $altprojects_dir; } $srcdir = "/home/MPI/testing/mpich2/mpich2"; $logname = $ENV{"LOGNAME"}; $tmpdir = "/sandbox/$logname"; # rundir is the directory in which to run the tests. $rundir = ""; # By default, use random arguments for the tests $use_rand_args = 1; # $is_xml = 0; # Set the default compilers. These can be overridden by setting the CC # and FC environment variables. $ccname = "gcc"; $fcname = "f77"; # # Set whether the C++ and Fortran bindings have been built. $has_f77 = 1; $has_cxx = 1; # Set this for the make option to enable the execution of multiple job # steps at once. Do not use this if the archive step (ar) is not setup # to avoid concurrent, conflicting updates to the same archive. $parallelBuild = "-j 8"; #$parallelBuild = ""; # # Some process managers require separate startup and rundown steps. The # following variables are used to handle this $StartDemon = ""; # Name of routine to start demons $StopDemon = ""; # Name of routine to stop demons $hasDemon = 0; # # Set available options. For enable and with, the values are # {with,enable}-name[;possiblevalues]* # We need a way to keep these consistent with the arguments recognized by # configure @enable_array = ( 'error-checking;no;runtime;all', 'error-messages;all;generic;class;none', 'timer-type;linux86_cycle;gethrtime;clock_gettime;gettimeofday', 'timing;none;all;runtime;log;log_detailed', 'g;none;all;handle;dbg;log;meminit;handlealloc;instr;mem;mutex;mutexnesting;memarena', 'fast;nochkmsg;notiming;ndebug;all', 'f77', 'fc', 'cxx', 'romio', 'coverage', 'check-compiler-flags', 'smpcoll', 'strict;c99;posix', #;posix 'debuginfo', # Message queues 'weak-symbols;no;yes', 'threads;single;multiple;runtime', 'thread-cs;global;per-object;lock-free', 'refcount;lock;lock-free;none', 'mutex-timing', 'multi-aliases', 'wrapper-rpath', 'predefined-refcount', 'alloca', 'yield;sched_yield;yield;select;usleep;sleep', 'checkpointing', 'runtimevalues', # Fortran true/false ); %chosenEnable = (); @with_array = ( 'logging;none;rlog', 'pmi;simple', #; uni no longer supported 'pm;gforker', #;remshell 'namepublisher;no;file', #;ldap:ldapserver', 'device;ch3;ch3:sock', ); %chosenWith = (); @env_array = ( # 'CC;gcc;cc;pgcc;ecc;xlc', # 'FC;f77;pgf77;efc;xlf', # 'CXX;gcc;CC;pgCC;ecc;xlC', # 'CFLAGS;-g;-O', ); # Also cross;sample-cross-files, but we need the files first # Also missing are levels of thread support. $n_enable = $#enable_array + 1; $n_with = $#with_array + 1; $n_env = $#env_array + 1; $show = 0; $debug = 0; $echoSteps = 0; # Set to one to echo each run program to stdout $report_signals = 1; # Set to one to generate a message about signals # received by a program $max_count = 5; $OUTFD = OUTFD; # # The following variable separate the various sections $TestStart = "-----------------------------------------------------------\n"; $TestEnd = "-----------------------------------------------------------\n"; $TestDateStart = "Run on "; $TestDateEnd = "\n"; $TestHostStart = "Run on host "; $TestHostEnd = "\n"; $TestUserStart = "Run by "; $TestUserEnd = "\n"; $ConfigStart = " -- Begin Configure Step -- \n"; $ConfigEnd = " -- End Configure Step -- \n"; $MakeStart = " -- Begin Make Step --\n"; $MakeEnd = " -- End Make Step --\n"; $GlobNameStart = " -- Begin Check of global names --\n"; $GlobNameEnd = " -- End Check of global names --\n"; $UsedNameStart = " -- Begin Check of used names --\n"; $UsedNameEnd = " -- End Check of used names --\n"; $MakeInstStart = " -- Begin Make Install Step --\n"; $MakeInstEnd = " -- End Make Install Step --\n"; $MakeInstcheckStart = " -- Begin Make Installcheck Step --\n"; $MakeInstcheckEnd = " -- End Make Installcheck Step --\n"; $RunTestStart = " -- Begin Run Test Step --\n"; $RunTestEnd = " -- End Run Test Step --\n"; $SumStart = ""; $SumEnd = ""; $SumConfigStart = "Config status = "; $SumConfigEnd = "\n"; $SumMakeStart = "Make status = "; $SumMakeEnd = "\n"; $SumGlobStart = "Global name check status = "; $SumGlobEnd = "\n"; $SumInstStart = "Install status = "; $SumInstEnd = "\n"; $SumTestRunStart = "Test status = "; $SumTestRunEnd = "\n"; # Defaults $config_args = ""; $with_args = ""; $enable_args = ""; $env_args = ""; $outfile = ""; $builddir = ""; $instdir = ""; # Read the arguments foreach $_ (@ARGV) { if (/--?enable-n=(\d*)/) { $n_enable = $1; } elsif (/--?with-n=(\d*)/) { $n_with = $1; } elsif (/--?show/) { $show = 1; } elsif (/--?debug/) { $debug = 1; } elsif (/--?envopt=(.*)/) { # Add a list of possible env values $env_array[$#env_array+1] = $1; $n_env = $#env_array + 1; } elsif (/--?srcdir=(.*)/) { $srcdir = $1; } elsif (/--?instdir=(.*)/) { $instdir = $1; } elsif (/--?rundir=(.*)/) { $rundir = $1; } elsif (/--?projectsdir=(.*)/) { $projects_dir = $1; } elsif (/--?maxcount=(.*)/) { # max count. Set to -1 for infinity $max_count = $1; } elsif (/--?maxtime=(.*)/) { # max time in seconds set_time_left( $1 ); } elsif (/--?tests=(.*)/) { $tests = ":" . $1 . ":"; } elsif (/--?outfile=(.*)/) { $outfile = $1; } elsif (/--?tmpdir=(.*)/) { $tmpdir = $1; } elsif (/--?builddir=(.*)/) { $builddir = $1; } elsif (/--?xml/) { &XMLStyle; $is_xml = 1; } elsif (/--?norand/) { $use_rand_args = 0; } elsif (/--?enable=(.*)/) { $use_rand_args = 0; $enable_args .= "$1 "; } elsif (/--?with=(.*)/) { $use_rand_args = 0; $with_args .= "$1 "; } elsif (/--?env=(.*)/) { $use_rand_args = 0; $envval=$1; $envval =~ s/ //g; $env_args .= "--env-$envval "; } elsif (/--?configarg=(.*)/) { # Use this to add a special arg (such as -host) to the # configure call $config_args .= "$1 "; } elsif (/--?help/) { print STDERR "\ checkbuilds [ -enable-n=d ] [ -with-n=d ] [ -show ] [-envopt=name;value;... ] [-srcdir=SRCDIR] [-instdir=INSTALLDIR] [-builddir=BUILDDIR] [-maxcount=MAXCNT] [-maxtime=MAXTIME] [-norand ] [-enable=enable-args] [-with=with-args] [-tmpdir=dir] -enable-n=d sets the number of --enable options to try -with=n=d set the number of --with options to try -envopt=name;value;... adds an environment variable with possible values (quote the text so that the semicolons do not cause trouble) -maxcount sets the number of builds to try -maxtime sets the maximum length of time to run Example: checkbuilds -envopt=\"CC;gcc;pgcc;ecc\"\n"; exit(0); } else { print STDERR "checkbuilds: Unrecognized argument $_\n"; exit(1); } } # # Set directories that have not been chosen. if ($instdir eq "") { $instdir = "$tmpdir/cb/mpi2-inst"; } if ($mpich1_dir eq "") { $mpich1_dir = "$projects_dir/mpich1test"; } # Make the builddir compatible with the installation directory if ($builddir eq "") { $builddir = "$tmpdir/cb/mpich2"; } # --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- # Run one instance of the configuration sub RunTest { my $makepgm; $rc = chdir $builddir; if (!$rc) { print STDERR "Cannot change to $builddir\n"; return; } # Clean the installation and build directories # Even better would be to remove the installation directory alltogether, # but we should only do that if explicitly requested (we could # *require* an empty directory for the tests instead) if (-d "$instdir/lib") { system "rm -f $instdir/lib/libmpi*.* $instdir/lib/libmpifort*.*"; system "rm -f $instdir/lib/libmpe*.a"; } if (-d "$instdir/bin") { system "rm -f $instdir/bin/mpi*"; } if (-d "$builddir/lib") { system "rm -f $builddir/lib/libmpi*.* $builddir/lib/libmpifort*.*"; system "rm -f $builddir/lib/libmpe*.a"; } # # Create the with and enable options #$enable_args = "--enable-strict"; # Only if compiler is gcc # Chosen *without* replacement. If an option is chosen twice, # then there will be fewer options %chosenWith = (); %chosenEnable = (); if ($use_rand_args) { $enable_args = &RandArgs( $n_enable, "enable_array", "enable", "disable" ); $with_args = &RandArgs ( $n_with, "with_array", "with", "without" ); # To set the environment, use the same code to set things up, # then process the env array to set the environment $env_args = &RandArgs( $n_env, "env_array", "env" ); } foreach my $en (split(/\s+/,$enable_args)) { if ($en =~ /--enable-([-A-Za-z0-9=]*)/) { my $name = $1; if ($name =~ /(.*)=(.*)/) { $chosenEnable{$1} = $2; $name = $1; } else { $chosenEnable{$name} = "yes"; } print STDERR "setting chosen enable of $name to $chosenEnable{$name}\n" if $debug; } } foreach my $en (split(/\s+/,$with_args)) { if ($en =~ /--with-([-A-Za-z0-9=]*)/) { my $name = $1; if ($name =~ /(.*)=(.*)/) { $chosenWith{$1} = $2; $name = $1; } else { $chosenWith{$name} = "yes"; } print STDERR "setting chosen with of $name to $chosenWith{$name}\n" if $debug; } } $envset = ""; %saveENV = %ENV; foreach $_ (split(/ /,$env_args)) { if (/--env-([^=]*)=(.*)/) { $name = $1; $value = $2; # Replace with blanks $value =~ s// /g; # Grrr is a bad choice, since <> are shell metacharacters. # Allow --SP-- as an alternative $value =~ s/--SP--/ /g; print "Env $name = $value\n" if $debug; # Since most of these so far are programs, we should check to # see if they're available. Instead, we'll make the user # specify the valid values (see -envopt above) $ENV{$name} = $value; $envset .= "$name = $value; "; } } # Get the version of make to use if (defined($ENV{"MAKE"})) { $makepgm = $ENV{"MAKE"}; } else { $makepgm = "make"; } # Check configure location if ( ! (-x "$srcdir/configure") && (-x "./configure") ) { $srcdir = "."; } $config_status = "none"; $make_status = "none"; $globcheck_status = "none"; # usedname is from the old test to check for which routines # were loaded for the simplest MPI Hello World program. #$usedname_status = "none"; $install_status = "none"; $installcheck_status = "none"; $test_status = "none"; if ($show) { print "Configure: $enable_args $with_args $config_args\n"; if ($envset ne "") { print "Environment = $envset\n"; } } else { # $enable_args .= " --enable-echo"; print $OUTFD $TestStart; my $host = `uname -n`; print $OUTFD "$TestHostStart$host$TestHostEnd"; my $user = $ENV{"LOGNAME"}; print $OUTFD "$TestUserStart$user$TestUserEnd"; my $date = `date "+%Y-%m-%d-%H-%M"`; print $OUTFD "$TestDateStart$date$TestDateEnd"; unlink "Makefile"; print $OUTFD $ConfigStart; @config = split( /\s+/, "$srcdir/configure --prefix=$instdir $enable_args $with_args $config_args" ); print $OUTFD "Configure: " . join(" ", @config) . "\n"; if ($envset ne "") { print $OUTFD "Environment = $envset\n"; } $rc = &RunProgram( @config ); $config_status = $rc; if (! -s "Makefile" && $rc == 0) { $config_status = "No Makefile"; $rc = 1; } print $OUTFD $ConfigEnd; # print "rc = $rc\n"; if ($rc == 0) { print $OUTFD $MakeStart; $rc = &RunProgram( "$makepgm $parallelBuild" ); print $OUTFD $MakeEnd; $make_status = $rc; if ($rc == 0) { # Only perform these steps if the make succeeded # FIXME: Restore the tests for nonconforming global systems and for # minimum memory and routing footprint # Deleted this test because it is no longer a design goal for MPICH # that it have no nonconforming global symbols # Deleted this test because it is no longer a design goal for MPICH2 # to have a minimum memory and routine footprint. # Install the libraries print $OUTFD $MakeInstStart; # Clean the install directory $install_status = &RunProgram( "$makepgm install" ); if ($install_status) { my $cwd = `pwd`; chomp $cwd; print $OUTFD "Current directory is $cwd\n"; } print $OUTFD $MakeInstEnd; if ($install_status == 0) { # Try the install check target print $OUTFD $MakeInstcheckStart; $installcheck_status = &RunProgram( "$makepgm installcheck" ); print $OUTFD $MakeInstcheckEnd; # Run the tests $test_status = &RunTestSuites; } } } print $OUTFD $TestEnd; } %ENV = %saveENV; print $OUTFD $SumStart; print $OUTFD $SumConfigStart; print $OUTFD $config_status; print $OUTFD $SumConfigEnd; print $OUTFD $SumMakeStart; print $OUTFD $make_status; print $OUTFD $SumMakeEnd; print $OUTFD $SumGlobStart; print $OUTFD $globcheck_status; print $OUTFD $SumGlobEnd; print $OUTFD $SumInstStart; print $OUTFD $install_status; print $OUTFD $SumInstEnd; print $OUTFD $SumTestRunStart; print $OUTFD $test_status; print $OUTFD $SumTestRunEnd; print $OUTFD $SumEnd; } # --------------------------------------------------------------------------- # Chosen *without* replacement. If an option is chosen twice, # then there will be fewer options sub RandArgs { my ($n_choice, $array_name, $optname, $negoptname ) = @_; my @chosen = ( ); my $args = ""; my $array_len = $#$array_name; my $idx; print "select $n_choice\n" if $debug; for (my $i=0; $i<$n_choice; $i++) { $idx = int( rand (1 + $array_len) ); print "Found $idx\n" if $debug; if ($chosen[$idx]) { next; } $chosen[$idx] = 1; @args = split( /;/, $$array_name[$idx] ); print "Trying $$array_name[$idx]\n" if $debug; $name = $args[0]; if ($#args == 0) { # Only the name is provided. Choose one of three # choices: # No option (skip this one) # just --$optname-$name # just --$negoptname-$name (if non-null) $idx = int ( rand ( 3 ) ); if ($idx == 0) { $args .= " --$optname-$name"; } elsif ($idx == 1 && $negoptname ne "") { $args .= " --$negoptname-$name"; } else { # skip ; } } else { $idx = 1 + int( rand $#args ); $value = $args[$idx]; if ($value ne "") { $args .= " --$optname-$name=$value"; } else { $args .= " --$optname-$name"; } } } return $args; } # --------------------------------------------------------------------------- # Timer support. Time_left returns 1 if time remains, 0 otherwise $final_time = -1; sub set_time_left { my $delta_time = $_[0]; $final_time = time + $delta_time; } sub time_left { if ($final_time eq "" || $final_time == -1) { return 1; } if (time > $final_time) { return 0; } else { return 1; } } # --------------------------------------------------------------------------- # cb for check build # # Eventually, we'll need # bootstep # compiler names # unbootstep # for each test. # sub RunTestSuites { my $run_status = 0; my $r_status = 0; # Start by adding "notest" files to any optional tests if (!$has_cxx) { &SkipCxxTestSuite; } foreach my $testname (split(':',$tests)) { if ($testname eq "") { next; } print $OUTFD $RunTestStart; if ($is_xml) { print $OUTFD "$testname\n"; print $OUTFD "\n"; } else { print $OUTFD "Running test $testname...\n"; } # Eventually, we should store the test routines in a hash, # with the key the test name and the value the name of the # routine. if ($testname eq "mpich") { &RunMpichTestSuite; } elsif ($testname eq "intel") { &RunIntelTestSuite; } elsif ($testname eq "testmpio") { &RunTestMPIOSuite; } elsif ($testname eq "mpicxx" && $has_cxx) { &RunCxxTestSuite; } elsif ($testname eq "mpich2") { &RunMPICH2TestSuite; } else { print $OUTFD "checkbuilds: Unrecognized test $testname\n"; } if ($is_xml) { print $OUTFD "\n"; } print $OUTFD $RunTestEnd; if ($run_status != 0) { # If any test fails, record its status. $r_status = $run_status; } } return $r_status; } # --------------------------------------------------------------------------- sub RunMpichTestSuite { my $nargs; $cwd = `pwd`; chomp $cwd; my @config; if ($mpich_test_dir eq "") { $mpich_test_dir = "$tmpdir/cb/mpitest"; } # Make sure that the tests run past a failure to build an # executable. Without this, the summary doesn't include # any tests in the same directory that completed. $ENV{"MPITEST_CONTINUE"} = "always"; $rc = chdir $mpich_test_dir; if (!$rc) { #print STDERR "Cannot change to $mpich_test_dir\n"; return; } # A special hack for the io part # If there is no link or io directory, create one and populate it if (! -f "io/Mfile.in") { if (-s "$mpich1_dir/io/Mfile.in") { if (! -d "io" && ! -l "io") { `mkdir "io"`; } `cp $mpich1_dir/io/*.in io`; } elsif (-s "$srcdir/src/mpi/romio/test/Mfile.in") { if (! -d "io" && ! -l "io") { `mkdir "io"`; } `cp $srcdir/src/mpi/romio/test/*.in io`; } # Else, we can't find the IO tests, so we don't create the io # directory } # Create the arguments for the configure step $nargs = 0; $config[$nargs++] = "$mpich1_dir/configure"; $config[$nargs++] = "--prefix=$instdir"; $config[$nargs++] = "-mpilibname=mpich"; if (defined($chosenEnable{"romio"})) { $config[$nargs++] = "--enable-io"; } # f77 is now the default, so we should run with the f77 tests # unless we did not build f77 if (! $has_f77) { # !defined($chosenEnable{"f77"}) $config[$nargs++] = "--disable-f77"; } # This isn't right, since these need to use the compilation # scripts. We'll approximate this by trying to use the # compilation scripts if they're found if (defined($ENV{"CC"})) { $ccname = $ENV{"CC"}; } if (defined($ENV{"FC"})) { $fcname = $ENV{"FC"}; } # Note that there are no quotes in the following because # they are not needed (no shell evaluation here) if (-x "$instdir/bin/mpicc" ) { $config[$nargs++] = "-cc=$instdir/bin/mpicc"; } else { $config[$nargs++] = "-cc=$ccname -I$instdir/include -L$instdir/lib"; } if (-x "$instdir/bin/mpifort" ) { $config[$nargs++] = "-fc=$instdir/bin/mpifort"; } else { $config[$nargs++] = "-fc=$fcname -I$instdir/include -L$instdir/lib"; } # Add $config[$nargs++] = "--enable-coverage"; # if we build mpich2 with the coverage switch. if (defined($ENV{"MAKE"})) { $makepgm = $ENV{"MAKE"}; $config[$nargs++] = "-make=$makepgm"; } else { $makepgm = "make"; } #$config[$nargs++] = "--enable-echo"; %saveENV = %ENV; $ENV{MPIRUN} = "$instdir/bin/mpiexec"; # This timeout needs to be made uniform for all mpiruns # 3 minutes is enough for some of our slower machines $ENV{MPIEXEC_TIMEOUT} = "180"; $rc = &RunProgram( @config ); if ($rc == 0) { if ($hasDemon) { &$StartDemon; } $rc = &RunProgram( "$makepgm testing" ); $test_status = $rc; if ($run_status == 0 && $rc != 0) { $run_status = $rc; } if ($hasDemon) { &$StopDemon; } } else { $run_status = $rc; print $OUTFD "Configure step for test failed\n"; print $OUTFD "Could not execute " . join(" ", @config) . "\n"; print $OUTFD "Environment was\n"; foreach $key (keys(%ENV)) { my $line = "$key = $ENV{$key}"; if ($is_xml) { $line = &XMLify( $line ); } print $OUTFD "$line\n"; } } %ENV = %saveENV; chdir $cwd; } # --------------------------------------------------------------------------- sub SkipCxxTestSuite { if ($mpicxx_test_dir eq "") { $mpicxx_test_dir = "$tmpdir/cb/mpicxxtest"; } `date > $mpicxx_test_dir/notest`; } sub RunCxxTestSuite { my $nargs = 0; $cwd = `pwd`; chomp $cwd; my @config; if ($mpicxx_test_dir eq "") { $mpicxx_test_dir = "$tmpdir/cb/mpicxxtest"; } # # First, check for the mpicxx program if (! -x "$instdir/bin/mpicxx" || !defined($chosenEnable{"cxx"})) { # Probably built without C++ support $run_status = 0; &SkipCxxTestSuite; return; } $rc = chdir $mpicxx_test_dir; if (!$rc) { #print STDERR "Cannot change to $mpicxx_test_dir\n"; return; } # Remove any "notest" file if (-s "notest") { unlink "notest"; } $config[$nargs++] = "$projects_dir/mpicxxtest/configure"; $config[$nargs++] = "--with-mpich=$instdir"; $config[$nargs++] = "--enable-xml"; if (defined($ENV{"MAKE"})) { $makepgm = $ENV{"MAKE"}; } else { $makepgm = "make"; } %saveENV = %ENV; # This timeout needs to be made uniform for all mpiruns # 3 minutes is enough for some of our slower machines $ENV{MPIEXEC_TIMEOUT} = "180"; $rc = &RunProgram( @config ); if ($rc == 0) { if ($hasDemon) { &$StartDemon; } $rc = &RunProgram( "$makepgm run-tests" ); $test_status = $rc; if ($run_status == 0 && $rc != 0) { $run_status = $rc; } # This step converts the summary.xml file into a valid XML file # by adding the appropriate header and footer $rc = &RunProgram( "$makepgm get-summary" ); if ($hasDemon) { &$StopDemon; } } else { $run_status = $rc; print $OUTFD "Configure step for test failed\n"; print $OUTFD "Could not execute " . join(" ", @config) . "\n"; print $OUTFD "Environment was\n"; foreach $key (keys(%ENV)) { my $line = "$key = $ENV{$key}"; if ($is_xml) { $line = &XMLify( $line ); } print $OUTFD "$line\n"; } } %ENV = %saveENV; chdir $cwd; } # Run the LLNL IO Test suite sub RunTestMPIOSuite { my $nargs = 0; my $testname = "testing"; $cwd = `pwd`; chomp $cwd; my @config; if ($testmpio_test_dir eq "") { $testmpio_test_dir = "$tmpdir/cb/testmpio"; } $rc = chdir $testmpio_test_dir; if (!$rc) { print $OUTFD "Cannot change to $testmpio_test_dir\n"; return; } # Switch to using the checked-in version of the Testmpio test if (-x "$projects_dir/testmpio/configure") { $config[$nargs++] = "$projects_dir/testmpio/configure"; } elsif (-x "$projects_dir/Testmpio/configure") { $config[$nargs++] = "$projects_dir/Testmpio/configure"; } else { print $OUTFD "Cannot find testmpio source directory!"; return; } $config[$nargs++] = "--enable-xml"; $config[$nargs++] = "CC=$instdir/bin/mpicc"; $config[$nargs++] = "MPIEXEC=$instdir/bin/mpiexec"; if (defined($ENV{"MAKE"})) { $makepgm = $ENV{"MAKE"}; } else { $makepgm = "make"; } %saveENV = %ENV; # This timeout needs to be made uniform for all mpiruns # 3 minutes is enough for some of our slower machines $ENV{MPIEXEC_TIMEOUT} = "180"; $rc = &RunProgram( @config ); if ($rc == 0) { if ($hasDemon) { &$StartDemon; } $rc = &RunProgram( "$makepgm $testname" ); $test_status = $rc; if ($run_status == 0 && $rc != 0) { $run_status = $rc; } if ($hasDemon) { &$StopDemon; } if ($test_status != 0) { # Try to figure out what went wrong. if (-s "Test/test.results") { &CopyFileToOutput( "Test/test.results" ); } } } else { $run_status = $rc; print $OUTFD "Configure step for test failed\n"; print $OUTFD "Could not execute " . join(" ", @config) . "\n"; print $OUTFD "Environment was\n"; foreach $key (keys(%ENV)) { my $line = "$key = $ENV{$key}"; if ($is_xml) { $line = &XMLify( $line ); } print $OUTFD "$line\n"; } } %ENV = %saveENV; chdir $cwd; } sub RunIntelTestSuite { my $nargs = 0; my $testname = "newtestl"; $cwd = `pwd`; chomp $cwd; my @config; if ($intel_test_dir eq "") { $intel_test_dir = "$tmpdir/cb/MPITEST"; } $rc = chdir $intel_test_dir; if (!$rc) { #print STDERR "Cannot change to $intel_test_dir\n"; return; } # Switch to using the checked-in version of the Intel test $config[$nargs++] = "$projects_dir/IntelMPITEST/configure"; $config[$nargs++] = "--with-mpich2=$instdir"; # The Absoft Fortran compiler fails some tests if MAX_RANKS # (used to dimension some arrays) is too large. Since the # default tests never use more than 6 processes, setting a # maximum of 16 is safe. $config[$nargs++] = "--enable-maxprocs=16"; # f77 is now the default, so we should run with the f77 tests # unless we did not build f77 if (!$has_f77) { # defined($chosenEnable{"f77"}) # Only run the C tests if we did not build fortran $config[$nargs++] = "--disable-f77"; $testname = "newtestl_c"; } if (defined($ENV{"MAKE"})) { $makepgm = $ENV{"MAKE"}; } else { $makepgm = "make"; } %saveENV = %ENV; # This timeout needs to be made uniform for all mpiruns # 3 minutes is enough for some of our slower machines $ENV{MPIEXEC_TIMEOUT} = "180"; $rc = &RunProgram( @config ); if ($rc == 0) { if ($hasDemon) { &$StartDemon; } $rc = &RunProgram( "$makepgm $testname" ); $test_status = $rc; if ($run_status == 0 && $rc != 0) { $run_status = $rc; } if ($hasDemon) { &$StopDemon; } if ($test_status != 0) { # Try to figure out what went wrong. if (-s "Test/test.results") { &CopyFileToOutput( "Test/test.results" ); } if (! -s "lib/libmpitestf_mpich2.a" && -s "lib/makeflib.log") { &CopyFileToOutput( "lib/makeflib.log" ); } if (! -s "lib/libmpitest_mpich2.a" && -s "lib/makeclib.log") { &CopyFileToOutput( "lib/makeclib.log" ); } } } else { $run_status = $rc; print $OUTFD "Configure step for test failed\n"; print $OUTFD "Could not execute " . join(" ", @config) . "\n"; print $OUTFD "Environment was\n"; foreach $key (keys(%ENV)) { my $line = "$key = $ENV{$key}"; if ($is_xml) { $line = &XMLify( $line ); } print $OUTFD "$line\n"; } } %ENV = %saveENV; chdir $cwd; } sub RunMPICH2TestSuite { my $nargs = 0; my $makepgm; $cwd = `pwd`; chomp $cwd; # This must match the directory into which mpich2 was built for # us to use the configure there. if ($mpich2_test_dir eq "") { $mpich2_test_dir = "$builddir/test/mpi"; } $rc = chdir $mpich2_test_dir; if (!$rc) { #print STDERR "Cannot change to $mpich2_test_dir\n"; return; } # MPICH2 tests are already built, so no configure step required %saveENV = %ENV; # # Make sure that there a no leftovers # Get the version of make to use if (defined($ENV{"MAKE"})) { $makepgm = $ENV{"MAKE"}; } else { $makepgm = "make"; } &RunProgram( "$makepgm clean" ); # This timeout needs to be made uniform for all mpiruns # 3 minutes is enough for some of our slower machines $ENV{MPIEXEC_TIMEOUT} = "180"; if ($hasDemon) { &$StartDemon; } # The MPICH2 test suite has a program for running the tests $rc = &RunProgram( "./runtests -mpiexec=$instdir/bin/mpiexec -srcdir=$srcdir/test/mpi -tests=testlist -xmlfile=summary.xml" ); $test_status = $rc; if ($run_status == 0 && $rc != 0) { $run_status = $rc; } if ($hasDemon) { &$StopDemon; } %ENV = %saveENV; chdir $cwd; } # --------------------------------------------------------------------------- # RunProgram LIST sub RunProgram { my $signal_num = 0; if ($echoSteps) { my $cmd = join(' ',@_); my $curdir = `pwd`; chomp $curdir; print STDOUT "Running $cmd in $curdir\n"; } # perl does not correctly handle ">>foo 2>&1" redirection in system # correctly (some stderr escapes to the prior stderr). This # code attempts to do the correct thing. # By reopening stdout and stderr, we can ensure that all of the # output goes to the specified files. Unfortunately, we can't # force perl to correctly flush files without open/close, so # we close the output file before the fork. This guarantees that # the data is flushed. We reopen it after the fork (which is implicit # in the open) if ($outfile ne "") { close $OUTFD; } # We now use a different approach that uses a open that creates a # fork and associates file handle (CFD for Child FD). @args = @_; $pid = open(CFD,"-|"); if ($pid == 0) { # we're the child open STDIN, '/dev/null'; # Do we want to allow an output filter, e.g., to convert the # output into well-formed XML? open STDERR, ">>&STDOUT"; exec @args; die "Could not exec program $args[0]\n"; } else { # Read from the child if ($outfile ne "") { open( $OUTFD, ">>$outfile" ) || die "Could not reopen $outfile for appending\n"; } while () { if ($is_xml) { $_ = &XMLify( $_ ); } print $OUTFD $_; } # Closing a pipe implicitly waits for the command on the other # end to complete, and puts the exit status into $? close CFD; # end of read from the child # Note that this status is usually shifted right by 8, so # we check for that $rc = $?; $signal_num = $rc & 127; if ($rc > 255) { $rc = $rc >> 8; } if ($signal_num != 0 && $report_signals) { print OUTFD "Process exited with signal $signal_num\n"; } } if ($echoSteps) { print STDOUT "Completed command with status $rc\n"; } return $rc; } # # Change output style sub XMLStyle { $TestStart = "\n"; $TestEnd = "\n"; $TestDateStart = "\n"; $TestDateEnd = "\n"; $TestHostStart = "\n"; $TestHostEnd = "\n"; $TestUserStart = "\n"; $TestUserEnd = "\n"; $ConfigStart = "\n"; $ConfigEnd = "\n"; $MakeStart = "\n"; $MakeEnd = "\n"; $GlobNameStart = "\n"; $GlobNameEnd = "\n"; $UsedNameStart = "\n"; $UsedNameEnd = "\n"; $MakeInstStart = "\n"; $MakeInstEnd = "\n"; $MakeInstcheckStart = "\n"; $MakeInstcheckEnd = "\n"; $RunTestStart = "\n"; $RunTestEnd = "\n"; $SumStart = "\n"; $SumEnd = "\n"; $SumConfigStart = ""; $SumConfigEnd = "\n"; $SumMakeStart = ""; $SumMakeEnd = "\n"; $SumGlobStart = ""; $SumGlobEnd = "\n"; $SumInstStart = ""; $SumInstEnd = "\n"; $SumTestRunStart = ""; $SumTestRunEnd = "\n"; } # --------------------------------------------------------------------------- # # Other options # --enable-threads={single, multiple} # --------------------------------------------------------------------------- # Here's the real code to execute # --------------------------------------------------------------------------- if ($rundir ne "") { chdir $rundir || die "could not change directory to $rundir\n"; } # Select the output file if ($outfile ne "") { if (! ($outfile =~ /^\//) ) { # Ensure that we have an absolute directory for the output file my $curdir = `pwd`; chop $curdir; $outfile = "$curdir/$outfile"; } open( $OUTFD, ">$outfile" ) || die "Could not open $outfile for writing\n"; # Setting autoflush is not enough to ensure that output is # correctly ordered when child processes also write to the file. # All of the shells get this right but unfortunately perl does not. #autoflush $OUTFD 1; if ($is_xml) { print $OUTFD "\n"; print $OUTFD "\n"; print $OUTFD "\n"; } } else { $OUTFD = STDOUT; } # --------------------------------------------------------------------------- # # There are several ways to run the tests. They are # For a fixed number of times # For a fixed length of time for ($test_count = 0; ($max_count < 0 || $test_count < $max_count) && &time_left; $test_count++) { if ($is_xml) { } else { print $OUTFD "\nRunning test $test_count\n\n"; } &RunTest; } if ($is_xml) { print $OUTFD "\n"; } close $OUTFD; sub CopyFileToOutput { my $filename = $_[0]; my $linecount = 256; if (open( TESTFD, "<$filename" )) { print $OUTFD "First $linecount lines of $filename\n"; while () { if ($linecount <= 0) { last; } if ($is_xml) { $_ = &XMLify( $_ ); } print $OUTFD $_; $linecount --; } close (TESTFD); } } sub XMLify { my $line = $_[0]; my $itcount = 0; # xml-ify the line by escaping the special characters $line =~ s//\*AMP\*gt;/g; $line =~ s/&/\*AMP\*amp;/g; $line =~ s/\*AMP\*/&/g; # Handle non-printing ascii characters (e.g., ones that emacs would # print as \200). XML may refuse to display non-printing characters # BUG IN PERL: The negated POSIX character class does not work! # It isn't clear whether ANY of the POSIX character classes work # while ($line =~ /^([:print:]*)([:^print:])(.*)/s) { # Instead, we use an explicit ASCII range, and include tab characters while ($line =~ /^([ -~\t]*)([^ -~\t\n])(.*)/s) { # Grr. This doesn't work either. The character conversion # gets lost. However, this is still better than including # a nonprinting character in the output $char = $2; $hexversion = sprintf( "\\%03x", $char ); $line = $1 . $hexversion . $3; if ($itcount++ > 100) { last; } } return $line; }