From a7f3f23c846f4fd664a718235fdb2ad97992c26e Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Tue, 2 Sep 2025 17:00:32 -0600 Subject: [PATCH] Turn off watchdog when done in tests If you set a watchdog timer, you should clear it when its no longer needed. Otherwise it can go off, aborting your test script. In these twenty test files, it hasn't mostly been a problem because the script finishes before the timer goes off. But I bet that some heisenbugs have been the result of not clearing it. It actually shouldn't be necessary to clear the timer when that is the final statement in the test file, but we may want to add a porting test that makes sure watchdogs are cleared, and always adding a clear enables such a test to properly work. --- ext/XS-APItest/t/keyword_plugin_threads.t | 2 ++ ext/re/t/re_funcs_u.t | 3 ++- t/io/closepid.t | 2 ++ t/io/openpid.t | 1 + t/mro/package_aliases.t | 1 + t/mro/package_aliases_utf8.t | 1 + t/op/sigdispatch.t | 2 ++ t/op/signame_canonical.t | 2 ++ t/op/study.t | 2 ++ t/op/threads.t | 1 + t/op/time.t | 2 ++ t/op/time_loop.t | 2 ++ t/op/waitpid.t | 1 + t/perf/speed.t | 2 ++ t/perf/taint.t | 2 ++ t/re/fold_grind.pl | 1 + t/re/pat_psycho.t | 2 ++ t/re/speed.t | 2 ++ t/re/subst.t | 1 + t/win32/popen.t | 2 ++ 20 files changed, 33 insertions(+), 1 deletion(-) diff --git a/ext/XS-APItest/t/keyword_plugin_threads.t b/ext/XS-APItest/t/keyword_plugin_threads.t index db23ce7d58..972445b7a8 100644 --- a/ext/XS-APItest/t/keyword_plugin_threads.t +++ b/ext/XS-APItest/t/keyword_plugin_threads.t @@ -26,6 +26,8 @@ for my $t (1 .. 3) { })->join; } +watchdog(0); + print "all is well\n"; ---- all is well diff --git a/ext/re/t/re_funcs_u.t b/ext/re/t/re_funcs_u.t index 70820df3c3..1a42fe55d5 100644 --- a/ext/re/t/re_funcs_u.t +++ b/ext/re/t/re_funcs_u.t @@ -128,7 +128,7 @@ if ('1234'=~/(?:(?\d)|(?!))(?\d)(?\d)(?\d)/){ # New tests go here ^^^ { # Keep these tests last, as whole script will be interrupted if times out - # Bug #72998; this can loop + # Bug #72998; this can loop watchdog(10); eval '"\x{100}\x{FB00}" =~ /\x{100}\N{U+66}+/i'; pass("Didn't loop"); @@ -137,6 +137,7 @@ if ('1234'=~/(?:(?\d)|(?!))(?\d)(?\d)(?\d)/){ no warnings; # Because the 8 may be warned on eval 'qr/\18/'; pass(q"qr/\18/ didn't loop"); + watchdog(0); } done_testing(); diff --git a/t/io/closepid.t b/t/io/closepid.t index c05ef8c12f..cdc6d256e4 100644 --- a/t/io/closepid.t +++ b/t/io/closepid.t @@ -42,3 +42,5 @@ SKIP: kill $killsig, $pid; open STDIN, "<&", $savein; } + +watchdog(0); diff --git a/t/io/openpid.t b/t/io/openpid.t index 8b4833a16c..5b92ab01de 100644 --- a/t/io/openpid.t +++ b/t/io/openpid.t @@ -102,3 +102,4 @@ print "# waiting for process $pid4 to exit\n"; $reap_pid = waitpid $pid4, 0; is( $reap_pid, $pid4, 'fourth process reaped' ); +watchdog(0); diff --git a/t/mro/package_aliases.t b/t/mro/package_aliases.t index dd811a62f8..2b742f5b11 100644 --- a/t/mro/package_aliases.t +++ b/t/mro/package_aliases.t @@ -300,6 +300,7 @@ watchdog 3; *foo:: = \%::; *Acme::META::Acme:: = \*Acme::; # indirect self-reference pass("mro_package_moved and self-referential packages"); +watchdog 0; # Deleting a glob whose name does not indicate its location in the symbol # table but which nonetheless *is* in the symbol table. diff --git a/t/mro/package_aliases_utf8.t b/t/mro/package_aliases_utf8.t index 0fc762d2d5..8bb97029b4 100644 --- a/t/mro/package_aliases_utf8.t +++ b/t/mro/package_aliases_utf8.t @@ -368,6 +368,7 @@ watchdog 3; *ᕘ:: = \%::; *Aᶜme::Mῌ::Aᶜme:: = \*Aᶜme::; # indirect self-reference pass("mro_package_moved and self-referential packages"); +watchdog 0; # Deleting a glob whose name does not indicate its location in the symbol # table but which nonetheless *is* in the symbol table. diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t index 242fb8ec58..30fdb26ae4 100644 --- a/t/op/sigdispatch.t +++ b/t/op/sigdispatch.t @@ -167,3 +167,5 @@ like $@, qr/No such hook: __DIE__\\0whoops at/; is($int_called, 1); is($@, "died"); } + +watchdog(0); diff --git a/t/op/signame_canonical.t b/t/op/signame_canonical.t index 241b57a5f4..009817887a 100644 --- a/t/op/signame_canonical.t +++ b/t/op/signame_canonical.t @@ -73,3 +73,5 @@ foreach my $dupe (@duplicate_signals) { is( $SIG{$canonical_name}, undef, "The signal $canonical_name is cleared after local goes out of scope." ); } +watchdog(0); + diff --git a/t/op/study.t b/t/op/study.t index c84724962f..8f7b630023 100644 --- a/t/op/study.t +++ b/t/op/study.t @@ -158,3 +158,5 @@ TODO: { push @got, $_ foreach $a =~ /[^x]d(?{$a .= ''})[^x]d/g; is("@got", 'ydyd ydyd', '#92696 $a .= \'\' inside (?{}), $a studied'); } + +watchdog(0); diff --git a/t/op/threads.t b/t/op/threads.t index 35ddad1872..04f4bcaf3f 100644 --- a/t/op/threads.t +++ b/t/op/threads.t @@ -149,6 +149,7 @@ watchdog(180, "process"); $_->join for @t; ok(1, '[perl #45053]'); } +watchdog(0); sub matchit { is (ref $_[1], "Regexp"); diff --git a/t/op/time.t b/t/op/time.t index 9fdc7b8cf6..d9e06d40dd 100644 --- a/t/op/time.t +++ b/t/op/time.t @@ -248,3 +248,5 @@ SKIP: { is scalar gmtime("NaN"), undef, '[perl #123495] gmtime(NaN)'; is scalar localtime("NaN"), undef, 'localtime(NaN)'; } + +watchdog(0); diff --git a/t/op/time_loop.t b/t/op/time_loop.t index 6f4acdc1f9..710b01ee91 100644 --- a/t/op/time_loop.t +++ b/t/op/time_loop.t @@ -14,3 +14,5 @@ watchdog(2); local $SIG{__WARN__} = sub {}; is gmtime(2**69), undef; is localtime(2**69), undef; + +watchdog(0); diff --git a/t/op/waitpid.t b/t/op/waitpid.t index 497fc26cb6..d3b8806d63 100644 --- a/t/op/waitpid.t +++ b/t/op/waitpid.t @@ -35,5 +35,6 @@ watchdog(10); pass("didn't block on waitpid(0, ...)"); } +watchdog(0); done_testing(); diff --git a/t/perf/speed.t b/t/perf/speed.t index bab29d441a..7df4b4e9a9 100644 --- a/t/perf/speed.t +++ b/t/perf/speed.t @@ -42,4 +42,6 @@ SKIP: { pass("COW 1Mb strings"); } +watchdog(0); + 1; diff --git a/t/perf/taint.t b/t/perf/taint.t index 275611897f..d69f1746f7 100644 --- a/t/perf/taint.t +++ b/t/perf/taint.t @@ -61,4 +61,6 @@ my $taint = substr($ENV{PATH}, 0, 0); # and empty tainted string pass("RT #130584 pos on tainted utf8 string"); } +watchdog(0); + 1; diff --git a/t/re/fold_grind.pl b/t/re/fold_grind.pl index 2922b25dc5..7e00dfee36 100644 --- a/t/re/fold_grind.pl +++ b/t/re/fold_grind.pl @@ -1101,6 +1101,7 @@ foreach my $test (sort { numerically } keys %{$tests_ref}) { } } +watchdog(0); plan($count); 1 diff --git a/t/re/pat_psycho.t b/t/re/pat_psycho.t index 336039521d..341a605cfc 100644 --- a/t/re/pat_psycho.t +++ b/t/re/pat_psycho.t @@ -35,6 +35,8 @@ plan tests => 15; # Update this when adding/deleting tests. run_tests() unless caller; +watchdog(0); + # # Tests start here. # diff --git a/t/re/speed.t b/t/re/speed.t index b61009c3b4..5ba77f885c 100644 --- a/t/re/speed.t +++ b/t/re/speed.t @@ -161,6 +161,8 @@ PROG like("!\xdf", eval 'qr/\pp(?aai)\xdf/', 'Compiling qr/\pp(?aai)\xdf/ doesn\'t loop'); + watchdog(0); + } # End of sub run_tests 1; diff --git a/t/re/subst.t b/t/re/subst.t index 6035b260e7..e669ae07a7 100644 --- a/t/re/subst.t +++ b/t/re/subst.t @@ -882,6 +882,7 @@ fresh_perl_is( '$_="abcdefg123456"; s/(?<=...\G)?(\d)/($1)/; print' => 'abcdefg( ::is($fc, 1, '$tied_ref =~ s/non-utf8/utf8/ fetch count'); ::like("$s", qr/^\x{101}AR\(0x.*\)\z/, '$tied_ref =~ s/non-utf8/utf8/ result'); + ::watchdog(0); } # RT #97954 diff --git a/t/win32/popen.t b/t/win32/popen.t index 07ac390a51..a0c72a9ece 100644 --- a/t/win32/popen.t +++ b/t/win32/popen.t @@ -24,4 +24,6 @@ for(1..100) { } PERL +watchdog(0); + done_testing();