diff options
Diffstat (limited to 'tests/test_driver.pl')
-rw-r--r-- | tests/test_driver.pl | 355 |
1 files changed, 181 insertions, 174 deletions
diff --git a/tests/test_driver.pl b/tests/test_driver.pl index dec869d..2f83270 100644 --- a/tests/test_driver.pl +++ b/tests/test_driver.pl @@ -5,9 +5,7 @@ # Written 91-12-02 through 92-01-01 by Stephen McGee. # Modified 92-02-11 through 92-02-22 by Chris Arthur to further generalize. # -# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -# 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1991-2013 Free Software Foundation, Inc. # This file is part of GNU Make. # # GNU Make is free software; you can redistribute it and/or modify it under @@ -30,7 +28,7 @@ # this routine controls the whole mess; each test suite sets up a few # variables and then calls &toplevel, which does all the real work. -# $Id: test_driver.pl,v 1.30 2010/07/28 05:39:50 psmith Exp $ +# $Id$ # The number of test categories we've run @@ -89,6 +87,7 @@ sub toplevel foreach (# UNIX-specific things 'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH', + 'LD_LIBRARY_PATH', # Purify things 'PURIFYOPTIONS', # Windows NT-specific stuff @@ -131,7 +130,7 @@ sub toplevel &parse_command_line (@ARGV); - print "OS name = `$osname'\n" if $debug; + print "OS name = '$osname'\n" if $debug; $workpath = "$cwdslash$workdir"; $scriptpath = "$cwdslash$scriptdir"; @@ -166,7 +165,7 @@ sub toplevel $dir = $1; push (@rmdirs, $dir); -d "$workpath/$dir" - || mkdir ("$workpath/$dir", 0777) + || mkdir ("$workpath/$dir", 0777) || &error ("Couldn't mkdir $workpath/$dir: $!\n"); } } @@ -175,7 +174,7 @@ sub toplevel { print "Finding tests...\n"; opendir (SCRIPTDIR, $scriptpath) - || &error ("Couldn't opendir $scriptpath: $!\n"); + || &error ("Couldn't opendir $scriptpath: $!\n"); @dirs = grep (!/^(\..*|CVS|RCS)$/, readdir (SCRIPTDIR) ); closedir (SCRIPTDIR); foreach $dir (@dirs) @@ -185,13 +184,13 @@ sub toplevel mkdir ("$workpath/$dir", 0777) || &error ("Couldn't mkdir $workpath/$dir: $!\n"); opendir (SCRIPTDIR, "$scriptpath/$dir") - || &error ("Couldn't opendir $scriptpath/$dir: $!\n"); + || &error ("Couldn't opendir $scriptpath/$dir: $!\n"); @files = grep (!/^(\..*|CVS|RCS|.*~)$/, readdir (SCRIPTDIR) ); closedir (SCRIPTDIR); foreach $test (@files) { -d $test and next; - push (@TESTS, "$dir/$test"); + push (@TESTS, "$dir/$test"); } } } @@ -203,7 +202,7 @@ sub toplevel print "\n"; - &run_each_test; + run_all_tests(); foreach $dir (@rmdirs) { @@ -221,7 +220,7 @@ sub toplevel print "s" unless $total_tests_failed == 1; print " in $categories_failed Categor"; print ($categories_failed == 1 ? "y" : "ies"); - print " Failed (See .$diffext files in $workdir dir for details) :-(\n\n"; + print " Failed (See .$diffext* files in $workdir dir for details) :-(\n\n"; return 0; } else @@ -276,15 +275,15 @@ sub get_osname eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)"; if ($osname =~ /not found/i) { - $osname = "(something posixy with no uname)"; + $osname = "(something posixy with no uname)"; } elsif ($@ ne "" || $?) { eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)"; if ($@ ne "" || $?) { - $osname = "(something posixy)"; - } + $osname = "(something posixy)"; + } } $vos = 0; $pathsep = "/"; @@ -416,128 +415,133 @@ sub print_banner print "\n"; } -sub run_each_test +sub run_all_tests { - $categories_run = 0; + $categories_run = 0; + + foreach $testname (sort @TESTS) { + $suite_passed = 1; # reset by test on failure + $num_of_logfiles = 0; + $num_of_tmpfiles = 0; + $description = ""; + $details = ""; + $old_makefile = undef; + $testname =~ s/^$scriptpath$pathsep//; + $perl_testname = "$scriptpath$pathsep$testname"; + $testname =~ s/(\.pl|\.perl)$//; + $testpath = "$workpath$pathsep$testname"; + # Leave enough space in the extensions to append a number, even + # though it needs to fit into 8+3 limits. + if ($short_filenames) { + $logext = 'l'; + $diffext = 'd'; + $baseext = 'b'; + $runext = 'r'; + $extext = ''; + } else { + $logext = 'log'; + $diffext = 'diff'; + $baseext = 'base'; + $runext = 'run'; + $extext = '.'; + } + $log_filename = "$testpath.$logext"; + $diff_filename = "$testpath.$diffext"; + $base_filename = "$testpath.$baseext"; + $run_filename = "$testpath.$runext"; + $tmp_filename = "$testpath.$tmpfilesuffix"; - foreach $testname (sort @TESTS) - { - ++$categories_run; - $suite_passed = 1; # reset by test on failure - $num_of_logfiles = 0; - $num_of_tmpfiles = 0; - $description = ""; - $details = ""; - $old_makefile = undef; - $testname =~ s/^$scriptpath$pathsep//; - $perl_testname = "$scriptpath$pathsep$testname"; - $testname =~ s/(\.pl|\.perl)$//; - $testpath = "$workpath$pathsep$testname"; - # Leave enough space in the extensions to append a number, even - # though it needs to fit into 8+3 limits. - if ($short_filenames) { - $logext = 'l'; - $diffext = 'd'; - $baseext = 'b'; - $runext = 'r'; - $extext = ''; - } else { - $logext = 'log'; - $diffext = 'diff'; - $baseext = 'base'; - $runext = 'run'; - $extext = '.'; - } - $log_filename = "$testpath.$logext"; - $diff_filename = "$testpath.$diffext"; - $base_filename = "$testpath.$baseext"; - $run_filename = "$testpath.$runext"; - $tmp_filename = "$testpath.$tmpfilesuffix"; + setup_for_test(); - &setup_for_test; # suite-defined + $output = "........................................................ "; - $output = "........................................................ "; + substr($output,0,length($testname)) = "$testname "; - substr($output,0,length($testname)) = "$testname "; + print $output; - print $output; + $tests_run = 0; + $tests_passed = 0; - # Run the actual test! - $tests_run = 0; - $tests_passed = 0; + # Run the test! + $code = do $perl_testname; - $code = do $perl_testname; + ++$categories_run; + $total_tests_run += $tests_run; + $total_tests_passed += $tests_passed; - $total_tests_run += $tests_run; - $total_tests_passed += $tests_passed; + # How did it go? + if (!defined($code)) { + # Failed to parse or called die + if (length ($@)) { + warn "\n*** Test died ($testname): $@\n"; + } else { + warn "\n*** Couldn't parse $perl_testname\n"; + } + $status = "FAILED ($tests_passed/$tests_run passed)"; + } - # How did it go? - if (!defined($code)) - { - $suite_passed = 0; - if (length ($@)) { - warn "\n*** Test died ($testname): $@\n"; - } else { - warn "\n*** Couldn't run $perl_testname\n"; - } - } - elsif ($code == -1) { - $suite_passed = 0; - } - elsif ($code != 1 && $code != -1) { - $suite_passed = 0; - warn "\n*** Test returned $code\n"; - } + elsif ($code == -1) { + # Skipped... not supported + $status = "N/A"; + --$categories_run; + } - if ($suite_passed) { - ++$categories_passed; - $status = "ok ($tests_passed passed)"; - for ($i = $num_of_tmpfiles; $i; $i--) - { - &rmfiles ($tmp_filename . &num_suffix ($i) ); - } + elsif ($code != 1) { + # Bad result... this shouldn't really happen. Usually means that + # the suite forgot to end with "1;". + warn "\n*** Test returned $code\n"; + $status = "FAILED ($tests_passed/$tests_run passed)"; + } - for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) - { - &rmfiles ($log_filename . &num_suffix ($i) ); - &rmfiles ($base_filename . &num_suffix ($i) ); - } - } - elsif (!defined $code || $code > 0) { - $status = "FAILED ($tests_passed/$tests_run passed)"; - } - elsif ($code < 0) { - $status = "N/A"; - --$categories_run; - } + elsif ($tests_run == 0) { + # Nothing was done!! + $status = "FAILED (no tests found!)"; + } - # If the verbose option has been specified, then a short description - # of each test is printed before displaying the results of each test - # describing WHAT is being tested. + elsif ($tests_run > $tests_passed) { + # Lose! + $status = "FAILED ($tests_passed/$tests_run passed)"; + } - if ($verbose) - { - if ($detail) - { - print "\nWHAT IS BEING TESTED\n"; - print "--------------------"; - } - print "\n\n$description\n\n"; - } + else { + # Win! + ++$categories_passed; + $status = "ok ($tests_passed passed)"; + + # Clean up + for ($i = $num_of_tmpfiles; $i; $i--) { + rmfiles($tmp_filename . num_suffix($i)); + } + for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) { + rmfiles($log_filename . num_suffix($i)); + rmfiles($base_filename . num_suffix($i)); + } + } - # If the detail option has been specified, then the details of HOW - # the test is testing what it says it is testing in the verbose output - # will be displayed here before the results of the test are displayed. + # If the verbose option has been specified, then a short description + # of each test is printed before displaying the results of each test + # describing WHAT is being tested. - if ($detail) - { - print "\nHOW IT IS TESTED\n"; - print "----------------"; - print "\n\n$details\n\n"; - } + if ($verbose) { + if ($detail) { + print "\nWHAT IS BEING TESTED\n"; + print "--------------------"; + } + print "\n\n$description\n\n"; + } - print "$status\n"; - } + # If the detail option has been specified, then the details of HOW + # the test is testing what it says it is testing in the verbose output + # will be displayed here before the results of the test are displayed. + + if ($detail) { + print "\nHOW IT IS TESTED\n"; + print "----------------"; + print "\n\n$details\n\n"; + } + + print "$status\n"; + } } # If the keep flag is not set, this subroutine deletes all filenames that @@ -654,38 +658,43 @@ sub compare_output local($answer,$logfile) = @_; local($slurp, $answer_matched) = ('', 0); - print "Comparing Output ........ " if $debug; + ++$tests_run; - $slurp = &read_file_into_string ($logfile); + if (! defined $answer) { + print "Ignoring output ........ " if $debug; + $answer_matched = 1; + } else { + print "Comparing Output ........ " if $debug; - # For make, get rid of any time skew error before comparing--too bad this - # has to go into the "generic" driver code :-/ - $slurp =~ s/^.*modification time .*in the future.*\n//gm; - $slurp =~ s/^.*Clock skew detected.*\n//gm; + $slurp = &read_file_into_string ($logfile); - ++$tests_run; + # For make, get rid of any time skew error before comparing--too bad this + # has to go into the "generic" driver code :-/ + $slurp =~ s/^.*modification time .*in the future.*\n//gm; + $slurp =~ s/^.*Clock skew detected.*\n//gm; - if ($slurp eq $answer) { - $answer_matched = 1; - } else { - # See if it is a slash or CRLF problem - local ($answer_mod, $slurp_mod) = ($answer, $slurp); + if ($slurp eq $answer) { + $answer_matched = 1; + } else { + # See if it is a slash or CRLF problem + local ($answer_mod, $slurp_mod) = ($answer, $slurp); - $answer_mod =~ tr,\\,/,; - $answer_mod =~ s,\r\n,\n,gs; + $answer_mod =~ tr,\\,/,; + $answer_mod =~ s,\r\n,\n,gs; - $slurp_mod =~ tr,\\,/,; - $slurp_mod =~ s,\r\n,\n,gs; + $slurp_mod =~ tr,\\,/,; + $slurp_mod =~ s,\r\n,\n,gs; - $answer_matched = ($slurp_mod eq $answer_mod); + $answer_matched = ($slurp_mod eq $answer_mod); - # If it still doesn't match, see if the answer might be a regex. - if (!$answer_matched && $answer =~ m,^/(.+)/$,) { - $answer_matched = ($slurp =~ /$1/); - if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) { - $answer_matched = ($slurp_mod =~ /$1/); + # If it still doesn't match, see if the answer might be a regex. + if (!$answer_matched && $answer =~ m,^/(.+)/$,) { + $answer_matched = ($slurp =~ /$1/); + if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) { + $answer_matched = ($slurp_mod =~ /$1/); + } + } } - } } if ($answer_matched && $test_passed) @@ -707,11 +716,8 @@ sub compare_output local($command) = "diff -c " . &get_basefile . " " . $logfile; &run_command_with_output(&get_difffile,$command); - } else { - &rmfiles (); } - $suite_passed = 0; return 0; } @@ -731,6 +737,9 @@ sub read_file_into_string return $slurp; } +my @OUTSTACK = (); +my @ERRSTACK = (); + sub attach_default_output { local ($filename) = @_; @@ -743,17 +752,16 @@ sub attach_default_output return 1; } - open ("SAVEDOS" . $default_output_stack_level . "out", ">&STDOUT") - || &error ("ado: $! duping STDOUT\n", 1); - open ("SAVEDOS" . $default_output_stack_level . "err", ">&STDERR") - || &error ("ado: $! duping STDERR\n", 1); + my $dup = undef; + open($dup, '>&', STDOUT) or error("ado: $! duping STDOUT\n", 1); + push @OUTSTACK, $dup; - open (STDOUT, "> " . $filename) - || &error ("ado: $filename: $!\n", 1); - open (STDERR, ">&STDOUT") - || &error ("ado: $filename: $!\n", 1); + $dup = undef; + open($dup, '>&', STDERR) or error("ado: $! duping STDERR\n", 1); + push @ERRSTACK, $dup; - $default_output_stack_level++; + open(STDOUT, '>', $filename) or error("ado: $filename: $!\n", 1); + open(STDERR, ">&STDOUT") or error("ado: $filename: $!\n", 1); } # close the current stdout/stderr, and restore the previous ones from @@ -770,23 +778,13 @@ sub detach_default_output return 1; } - if (--$default_output_stack_level < 0) - { - &error ("default output stack has flown under!\n", 1); - } - - close (STDOUT); - close (STDERR); + @OUTSTACK or error("default output stack has flown under!\n", 1); - open (STDOUT, ">&SAVEDOS" . $default_output_stack_level . "out") - || &error ("ddo: $! duping STDOUT\n", 1); - open (STDERR, ">&SAVEDOS" . $default_output_stack_level . "err") - || &error ("ddo: $! duping STDERR\n", 1); + close(STDOUT); + close(STDERR); - close ("SAVEDOS" . $default_output_stack_level . "out") - || &error ("ddo: $! closing SCSDOSout\n", 1); - close ("SAVEDOS" . $default_output_stack_level . "err") - || &error ("ddo: $! closing SAVEDOSerr\n", 1); + open (STDOUT, '>&', pop @OUTSTACK) or error("ddo: $! duping STDOUT\n", 1); + open (STDERR, '>&', pop @ERRSTACK) or error("ddo: $! duping STDERR\n", 1); } # This runs a command without any debugging info. @@ -800,14 +798,19 @@ sub _run_command resetENV(); eval { - local $SIG{ALRM} = sub { die "timeout\n"; }; + my $pid = fork(); + if (! $pid) { + exec(@_) or die "Cannot execute $_[0]\n"; + } + local $SIG{ALRM} = sub { my $e = $ERRSTACK[0]; print $e "\nTest timed out after $test_timeout seconds\n"; die "timeout\n"; }; alarm $test_timeout; - $code = system(@_); + waitpid($pid, 0) > 0 or die "No such pid: $pid\n"; + $code = $?; alarm 0; }; if ($@) { # The eval failed. If it wasn't SIGALRM then die. - $@ eq "timeout\n" or die; + $@ eq "timeout\n" or die "Command failed: $@"; # Timed out. Resend the alarm to our process group to kill the children. $SIG{ALRM} = 'IGNORE'; @@ -841,8 +844,12 @@ sub run_command_with_output print "\nrun_command_with_output($filename,$runname): @_\n" if $debug; &attach_default_output ($filename); - my $code = _run_command(@_); + my $code = eval { _run_command(@_) }; + my $err = $@; &detach_default_output; + + $err and die $err; + print "run_command_with_output returned $code.\n" if $debug; return $code; @@ -942,7 +949,7 @@ sub touch foreach $file (@_) { (open(T, ">> $file") && print(T "\n") && close(T)) - || &error("Couldn't touch $file: $!\n", 1); + || &error("Couldn't touch $file: $!\n", 1); } } |