mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
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
This commit is contained in:
parent
085c8d3042
commit
d1bdd18eb4
4 changed files with 180 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
127
mysql-test/lib/mtr_timer.pl
Normal file
127
mysql-test/lib/mtr_timer.pl
Normal file
|
@ -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;
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue