From d9e1826f6de1c628ab428f863b10558940b449f8 Mon Sep 17 00:00:00 2001 From: psmith Date: Sat, 14 Jul 2007 02:57:46 +0000 Subject: [PATCH] Fix Savannah bug #20452. Add a new feature to the test suite suggested by Icarus Sparry: set a timer before invoking a test, so that if it loops infinitely we will wake up and have a chance to kill the process and continue. --- ChangeLog | 7 +++++ file.c | 4 ++- tests/ChangeLog | 20 ++++++++++++++ tests/run_make_tests.pl | 17 +++++++++--- tests/scripts/features/parallelism | 3 +- tests/scripts/options/dash-l | 3 +- tests/test_driver.pl | 56 ++++++++++++++++++++++++++------------ 7 files changed, 85 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9709fc..9c9ed3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-07-13 Paul Smith + + * file.c (expand_deps): Use variable_buffer as the start of the + buffer, not the original pointer (in case it was reallocated). + Fix suggested by Rafi Einstein . + Fixes Savannah bug #20452. + 2007-07-04 Paul Smith * (ALL FILES): Update to GPLv3. diff --git a/file.c b/file.c index 96aad1d..303f192 100644 --- a/file.c +++ b/file.c @@ -483,6 +483,7 @@ expand_deps (struct file *f) { p = variable_expand (""); variable_buffer_output (p, d->name, strlen (d->name) + 1); + p = variable_buffer; } else { @@ -495,7 +496,8 @@ expand_deps (struct file *f) o = subst_expand (buffer, d->name, "%", "$*", 1, 2, 0); - d->name = strcache_add_len (buffer, o - buffer); + d->name = strcache_add_len (variable_buffer, + o - variable_buffer); d->staticpattern = 0; /* Clear staticpattern so that we don't re-expand %s below. */ } diff --git a/tests/ChangeLog b/tests/ChangeLog index 93a9e3b..6e53dc7 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,23 @@ +2007-07-13 Paul Smith + + Install a timeout so tests can never loop infinitely. + Original idea and patch for a single-test version provided by + Icarus Sparry + + * test_driver.pl (_run_command): New function: this is called by + other functions to actually run a command. Before we run it, + install a SIGALRM handler and set up a timer to go off in the + future (default is 5s; this can be overridden by individual tests). + (run_command): Call it. + (run_command_with_output): Call it. + + * run_make_tests.pl (run_make_with_options): Override the default + timeout if the caller requests it. + (run_make_test): Pass any timeout override to run_make_with_options. + + * scripts/features/parallelism: Increase the timeout for long tests. + * scripts/options/dash-l: Ditto. + 2006-10-01 Paul Smith * run_make_tests.pl (set_more_defaults): Remove setting of LANG in diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl index 48be41b..0adb172 100755 --- a/tests/run_make_tests.pl +++ b/tests/run_make_tests.pl @@ -82,7 +82,7 @@ $old_makefile = undef; sub run_make_test { - local ($makestring, $options, $answer, $err_code) = @_; + local ($makestring, $options, $answer, $err_code, $timeout) = @_; # If the user specified a makefile string, create a new makefile to contain # it. If the first value is not defined, use the last one (if there is @@ -121,7 +121,8 @@ sub run_make_test $answer =~ s/#MAKE#/$make_name/g; $answer =~ s/#PWD#/$pwd/g; - &run_make_with_options($makefile, $options, &get_logfile(0), $err_code); + run_make_with_options($makefile, $options, &get_logfile(0), + $err_code, $timeout); &compare_output($answer, &get_logfile(1)); $old_makefile = $makefile; @@ -130,7 +131,7 @@ sub run_make_test # The old-fashioned way... sub run_make_with_options { - local ($filename,$options,$logname,$expected_code) = @_; + local ($filename,$options,$logname,$expected_code,$timeout) = @_; local($code); local($command) = $make_path; @@ -151,7 +152,15 @@ sub run_make_with_options { print VALGRIND "\n\nExecuting: $command\n"; } - $code = &run_command_with_output($logname,$command); + + { + my $old_timeout = $test_timeout; + $test_timeout = $timeout if $timeout; + + $code = &run_command_with_output($logname,$command); + + $test_timeout = $old_timeout; + } # Check to see if we have Purify errors. If so, keep the logfile. # For this to work you need to build with the Purify flag -exit-status=yes diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism index abe49a5..432c088 100644 --- a/tests/scripts/features/parallelism +++ b/tests/scripts/features/parallelism @@ -69,6 +69,7 @@ unlink('1.inc', '2.inc'); # function in an exported recursive variable. I added some code to check # for this situation and print a message if it occurred. This test used # to trigger this code when I added it but no longer does after the fix. +# We have to increase the timeout from the default (5s) on this test. run_make_test(" export HI = \$(shell \$(\$\@.CMD)) @@ -79,7 +80,7 @@ second.CMD = $sleep_command 4; echo hi all: first second first second: ; \@echo \$\@; $sleep_command 1; echo \$\@", - '-j2', "first\nfirst\nsecond\nsecond"); + '-j2', "first\nfirst\nsecond\nsecond", 0, 7); # Michael Matz reported a bug where if make is running in # parallel without -k and two jobs die in a row, but not too close to each diff --git a/tests/scripts/options/dash-l b/tests/scripts/options/dash-l index 58216f9..0b0f196 100644 --- a/tests/scripts/options/dash-l +++ b/tests/scripts/options/dash-l @@ -45,7 +45,8 @@ close(MAKEFILE); $mkoptions = "-l 0.0001"; $mkoptions .= " -j 4" if ($parallel_jobs); -&run_make_with_options($makefile, $mkoptions, &get_logfile); +# We have to wait longer than the default (5s). +&run_make_with_options($makefile, $mkoptions, &get_logfile, 0, 8); $slurp = &read_file_into_string (&get_logfile(1)); if ($slurp !~ /cannot enforce load limit/) { diff --git a/tests/test_driver.pl b/tests/test_driver.pl index a8bce8f..8a75cd6 100644 --- a/tests/test_driver.pl +++ b/tests/test_driver.pl @@ -29,7 +29,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.22 2007/07/04 19:35:22 psmith Exp $ +# $Id: test_driver.pl,v 1.23 2007/07/14 02:57:46 psmith Exp $ # The number of test categories we've run @@ -50,6 +50,10 @@ $tests_passed = 0; $test_passed = 1; +# Timeout in seconds. If the test takes longer than this we'll fail it. +$test_timeout = 5; + + # %makeENV is the cleaned-out environment. %makeENV = (); @@ -766,21 +770,43 @@ sub detach_default_output || &error ("ddo: $! closing SAVEDOSerr\n", 1); } -# run one command (passed as a list of arg 0 - n), returning 0 on success -# and nonzero on failure. - -sub run_command +# This runs a command without any debugging info. +sub _run_command { - local ($code); + my $code; # We reset this before every invocation. On Windows I think there is only # one environment, not one per process, so I think that variables set in # test scripts might leak into subsequent tests if this isn't reset--??? resetENV(); + eval { + local $SIG{ALRM} = sub { die "timeout\n"; }; + alarm $test_timeout; + $code = system @_; + alarm 0; + }; + if ($@) { + # The eval failed. If it wasn't SIGALRM then die. + $@ eq "timeout\n" or die; + + # Timed out. Resend the alarm to our process group to kill the children. + $SIG{ALRM} = 'IGNORE'; + kill -14, $$; + $code = 14; + } + + return $code; +} + +# run one command (passed as a list of arg 0 - n), returning 0 on success +# and nonzero on failure. + +sub run_command +{ print "\nrun_command: @_\n" if $debug; - $code = system @_; - print "run_command: \"@_\" returned $code.\n" if $debug; + my $code = _run_command(@_); + print "run_command returned $code.\n" if $debug; return $code; } @@ -792,19 +818,13 @@ sub run_command sub run_command_with_output { - local ($filename) = shift; - local ($code); - - # We reset this before every invocation. On Windows I think there is only - # one environment, not one per process, so I think that variables set in - # test scripts might leak into subsequent tests if this isn't reset--??? - resetENV(); + my $filename = shift; + print "\nrun_command_with_output($filename): @_\n" if $debug; &attach_default_output ($filename); - $code = system @_; + my $code = _run_command(@_); &detach_default_output; - - print "run_command_with_output: '@_' returned $code.\n" if $debug; + print "run_command_with_output returned $code.\n" if $debug; return $code; } -- 2.11.4.GIT