t/op/alarm.t: reduce intermittent failures
authorDavid Mitchell <davem@iabyn.com>
Thu, 9 Jun 2011 14:51:54 +0000 (15:51 +0100)
committerDavid Mitchell <davem@iabyn.com>
Thu, 9 Jun 2011 14:56:58 +0000 (15:56 +0100)
Fix a race condition where the alarm is reset *after* the handler
and an eval have been removed.

Also, make the points at which time is measured closer to the things
they need to measure, to reduce timing noise on a heavily-loaded system.

Hopefully these measures will reduce the number of random smoke failures,
although I couldn't reproduce the failures, even on a heavily-loaded
machine.

t/op/alarm.t

index 118ee9d..82691c5 100644 (file)
@@ -16,30 +16,35 @@ BEGIN {
 plan tests => 5;
 my $Perl = which_perl();
 
-my $start_time = time;
+my ($start_time, $end_time);
+
 eval {
-    local $SIG{ALRM} = sub { die "ALARM!\n" };
+    local $SIG{ALRM} = sub { $end_time = time; die "ALARM!\n" };
+    $start_time = time;
     alarm 3;
 
     # perlfunc recommends against using sleep in combination with alarm.
-    1 while (time - $start_time < 6);
+    1 while (($end_time = time) - $start_time < 6);
+    alarm 0;
 };
 alarm 0;
-my $diff = time - $start_time;
+my $diff = $end_time - $start_time;
 
 # alarm time might be one second less than you said.
 is( $@, "ALARM!\n",             'alarm w/$SIG{ALRM} vs inf loop' );
-ok( abs($diff - 3) <= 1,   "   right time" );
+ok( abs($diff - 3) <= 1,   "   right time (waited $diff secs for 3-sec alarm)" );
 
 
-my $start_time = time;
 eval {
-    local $SIG{ALRM} = sub { die "ALARM!\n" };
+    local $SIG{ALRM} = sub { $end_time = time; die "ALARM!\n" };
+    $start_time = time;
     alarm 3;
     system(qq{$Perl -e "sleep 6"});
+    $end_time = time;
+    alarm 0;
 };
 alarm 0;
-$diff = time - $start_time;
+$diff = $end_time - $start_time;
 
 # alarm time might be one second less than you said.
 is( $@, "ALARM!\n",             'alarm w/$SIG{ALRM} vs system()' );
@@ -53,7 +58,7 @@ is( $@, "ALARM!\n",             'alarm w/$SIG{ALRM} vs system()' );
 
 {
     local $SIG{"ALRM"} = sub { die };
-    eval { alarm(1); my $x = qx($Perl -e "sleep 3") };
+    eval { alarm(1); my $x = qx($Perl -e "sleep 3"); alarm(0); };
     chomp (my $foo = "foo\n");
     ok($foo eq "foo", '[perl #33928] chomp() fails after alarm(), `sleep`');
 }