summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <kent@mysql.com>2005-08-18 00:16:44 +0200
committerunknown <kent@mysql.com>2005-08-18 00:16:44 +0200
commit622756ecfcb0d42554e37c4d77af9b68e1e040d9 (patch)
treedd0a9f1002d51633bf23fbae8b229b6929aa53bd
parent2b4cfda2ebffcb483b2a48e6357c4c466486ed97 (diff)
downloadmariadb-git-622756ecfcb0d42554e37c4d77af9b68e1e040d9.tar.gz
mtr_timer.pl, mysql-test-run.pl, mtr_report.pl, mtr_process.pl:
Added suite and test case timeout mtr_timer.pl: new file mysql-test/lib/mtr_process.pl: Added suite and test case timeout mysql-test/lib/mtr_report.pl: Added suite and test case timeout mysql-test/mysql-test-run.pl: Added suite and test case timeout mysql-test/lib/mtr_timer.pl: Added suite and test case timeout
-rw-r--r--mysql-test/lib/mtr_process.pl21
-rw-r--r--mysql-test/lib/mtr_report.pl9
-rw-r--r--mysql-test/lib/mtr_timer.pl127
-rwxr-xr-xmysql-test/mysql-test-run.pl28
4 files changed, 180 insertions, 5 deletions
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index ec12bc3907c..c9ae92305c2 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -210,6 +210,7 @@ sub spawn_parent_impl {
# normally from running a test case?
my $exit_value= -1;
+ my $saved_exit_value;
my $ret_pid; # What waitpid() returns
while ( ($ret_pid= waitpid(-1,0)) != -1 )
@@ -219,6 +220,24 @@ sub spawn_parent_impl {
# but not $exit_value, this is flagged from
#
+ my $timer_name= mtr_timer_timeout($::glob_timers, $ret_pid);
+ if ( $timer_name )
+ {
+ if ( $timer_name eq "suite" )
+ {
+ # We give up here
+ # FIXME we should only give up the suite, not all of the run?
+ print STDERR "\n";
+ mtr_error("Test suite timeout");
+ }
+ elsif ( $timer_name eq "testcase" )
+ {
+ $saved_exit_value= 63; # Mark as timeout
+ kill(9, $pid); # Kill mysqltest
+ next; # Go on and catch the termination
+ }
+ }
+
if ( $ret_pid == $pid )
{
# We got termination of mysqltest, we are done
@@ -270,7 +289,7 @@ sub spawn_parent_impl {
}
}
- return $exit_value;
+ return $saved_exit_value || $exit_value;
}
}
else
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index b9dab6b8d32..5e1a8308505 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -109,7 +109,14 @@ sub mtr_report_test_failed ($) {
my $tinfo= shift;
$tinfo->{'result'}= 'MTR_RES_FAILED';
- print "[ fail ]\n";
+ if ( $tinfo->{'timeout'} )
+ {
+ print "[ fail ] timeout\n";
+ }
+ else
+ {
+ print "[ fail ]\n";
+ }
# FIXME Instead of this test, and meaningless error message in 'else'
# we should write out into $::path_timefile when the error occurs.
diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl
new file mode 100644
index 00000000000..aab57d1bc52
--- /dev/null
+++ b/mysql-test/lib/mtr_timer.pl
@@ -0,0 +1,127 @@
+# -*- cperl -*-
+
+# This is a library file used by the Perl version of mysql-test-run,
+# and is part of the translation of the Bourne shell script with the
+# same name.
+
+use Carp qw(cluck);
+use Socket;
+use Errno;
+use strict;
+
+#use POSIX ":sys_wait_h";
+use POSIX 'WNOHANG';
+
+sub mtr_init_timers ();
+sub mtr_timer_start($$$);
+sub mtr_timer_stop($$);
+sub mtr_timer_waitpid($$$);
+
+##############################################################################
+#
+# Initiate a structure shared by all timers
+#
+##############################################################################
+
+sub mtr_init_timers () {
+ my $timers = { timers => {}, pids => {}};
+ return $timers;
+}
+
+
+##############################################################################
+#
+# Start, stop and poll a timer
+#
+# As alarm() isn't portable to Windows, we use separate processes to
+# implement timers. That is why there is a mtr_timer_waitpid(), as this
+# is where we catch a timeout.
+#
+##############################################################################
+
+sub mtr_timer_start($$$) {
+ my ($timers,$name,$duration)= @_;
+
+ if ( exists $timers->{'timers'}->{$name} )
+ {
+ # We have an old running timer, kill it
+ mtr_timer_stop($timers,$name);
+ }
+
+ FORK:
+ {
+ my $tpid= fork();
+
+ if ( ! defined $tpid )
+ {
+ if ( $! == $!{EAGAIN} ) # See "perldoc Errno"
+ {
+ mtr_debug("Got EAGAIN from fork(), sleep 1 second and redo");
+ sleep(1);
+ redo FORK;
+ }
+ else
+ {
+ mtr_error("can't fork");
+ }
+ }
+
+ if ( $tpid )
+ {
+ # Parent, record the information
+ $timers->{'timers'}->{$name}->{'pid'}= $tpid;
+ $timers->{'timers'}->{$name}->{'duration'}= $duration;
+ $timers->{'pids'}->{$tpid}= $name;
+ }
+ else
+ {
+ # Child, redirect output and exec
+ # FIXME do we need to redirect streams?
+ $0= "mtr_timer(timers,$name,$duration)";
+ sleep($duration);
+ exit(0);
+ }
+ }
+}
+
+
+sub mtr_timer_stop ($$) {
+ my ($timers,$name)= @_;
+
+ if ( exists $timers->{'timers'}->{$name} )
+ {
+ my $tpid= $timers->{'timers'}->{$name}->{'pid'};
+
+ # FIXME as Cygwin reuses pids fast, maybe check that is
+ # the expected process somehow?!
+ kill(9, $tpid);
+
+ # As the timers are so simple programs, we trust them to terminate,
+ # and use blocking wait for it. We wait just to avoid a zombie.
+ waitpid($tpid,0);
+
+ delete $timers->{'timers'}->{$name}; # Remove the timer information
+ delete $timers->{'pids'}->{$tpid}; # and PID reference
+
+ return 1;
+ }
+ else
+ {
+ mtr_debug("Asked to stop timer \"$name\" not started");
+ return 0;
+ }
+}
+
+
+sub mtr_timer_timeout ($$) {
+ my ($timers,$pid)= @_;
+
+ return "" unless exists $timers->{'pids'}->{$pid};
+
+ # We got a timeout
+ my $name= $timers->{'pids'}->{$pid};
+ mtr_timer_stop($timers, $timers->{'timers'}->{$name});
+ return $name;
+}
+
+1;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index f3e42ecf755..456f481ce86 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -90,6 +90,7 @@ use strict;
require "lib/mtr_cases.pl";
require "lib/mtr_process.pl";
+require "lib/mtr_timer.pl";
require "lib/mtr_io.pl";
require "lib/mtr_gcov.pl";
require "lib/mtr_gprof.pl";
@@ -137,6 +138,7 @@ our $glob_mysql_test_dir= undef;
our $glob_mysql_bench_dir= undef;
our $glob_hostname= undef;
our $glob_scriptname= undef;
+our $glob_timers= undef;
our $glob_use_running_server= 0;
our $glob_use_running_ndbcluster= 0;
our $glob_use_embedded_server= 0;
@@ -232,8 +234,10 @@ our $opt_skip_test;
our $opt_sleep;
our $opt_ps_protocol;
-our $opt_sleep_time_after_restart= 1;
+our $opt_sleep_time_after_restart= 1;
our $opt_sleep_time_for_delete= 10;
+our $opt_testcase_timeout= 5; # 5 min max
+our $opt_suite_timeout= 120; # 2 hours max
our $opt_socket;
@@ -435,6 +439,8 @@ sub initial_setup () {
$path_my_basedir=
$opt_source_dist ? $glob_mysql_test_dir : $glob_basedir;
+
+ $glob_timers= mtr_init_timers();
}
@@ -530,6 +536,8 @@ sub command_line_setup () {
'vardir=s' => \$opt_vardir,
'verbose' => \$opt_verbose,
'wait-timeout=i' => \$opt_wait_timeout,
+ 'testcase-timeout=i' => \$opt_testcase_timeout,
+ 'suite-timeout=i' => \$opt_suite_timeout,
'warnings|log-warnings' => \$opt_warnings,
'with-openssl' => \$opt_with_openssl,
@@ -1197,6 +1205,8 @@ sub run_suite () {
mtr_report("Finding Tests in the '$suite' suite");
+ mtr_timer_start($glob_timers,"suite", 60 * $opt_suite_timeout);
+
my $tests= collect_test_cases($suite);
mtr_report("Starting Tests in the '$suite' suite");
@@ -1205,7 +1215,9 @@ sub run_suite () {
foreach my $tinfo ( @$tests )
{
+ mtr_timer_start($glob_timers,"testcase", 60 * $opt_testcase_timeout);
run_testcase($tinfo);
+ mtr_timer_stop($glob_timers,"testcase");
}
mtr_print_line();
@@ -1226,6 +1238,8 @@ sub run_suite () {
}
mtr_report_stats($tests);
+
+ mtr_timer_stop($glob_timers,"suite");
}
@@ -1523,6 +1537,11 @@ sub run_testcase ($) {
# Testcase itself tell us to skip this one
mtr_report_test_skipped($tinfo);
}
+ elsif ( $res == 63 )
+ {
+ $tinfo->{'timeout'}= 1; # Mark as timeout
+ report_failure_and_restart($tinfo);
+ }
else
{
# Test case failed, if in control mysqltest returns 1
@@ -1657,8 +1676,6 @@ sub mysqld_arguments ($$$$$) {
my $extra_opt= shift;
my $slave_master_info= shift;
-# print STDERR Dumper($extra_opt);
-
my $sidx= ""; # Index as string, 0 is empty string
if ( $idx > 0 )
{
@@ -2262,6 +2279,10 @@ Misc options
help Get this help text
unified-diff | udiff When presenting differences, use unified diff
+ testcase-timeout=MINUTES Max test case run time (default 5)
+ suite-timeout=MINUTES Max test suite run time (default 120)
+
+
Options not yet described, or that I want to look into more
big-test
@@ -2281,4 +2302,5 @@ Options not yet described, or that I want to look into more
HERE
mtr_exit(1);
+
}