diff options
Diffstat (limited to 'mysql-test/lib')
-rw-r--r-- | mysql-test/lib/init_db.sql | 2 | ||||
-rw-r--r-- | mysql-test/lib/mtr_cases.pl | 27 | ||||
-rw-r--r-- | mysql-test/lib/mtr_misc.pl | 9 | ||||
-rw-r--r-- | mysql-test/lib/mtr_process.pl | 89 | ||||
-rw-r--r-- | mysql-test/lib/mtr_report.pl | 10 | ||||
-rw-r--r-- | mysql-test/lib/mtr_timer.pl | 127 |
6 files changed, 226 insertions, 38 deletions
diff --git a/mysql-test/lib/init_db.sql b/mysql-test/lib/init_db.sql index a71de229ee9..37353e5974f 100644 --- a/mysql-test/lib/init_db.sql +++ b/mysql-test/lib/init_db.sql @@ -518,7 +518,7 @@ CREATE TABLE proc ( security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob DEFAULT '' NOT NULL, returns char(64) DEFAULT '' NOT NULL, - body blob DEFAULT '' NOT NULL, + body longblob DEFAULT '' NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 12714ddc1ad..158fd602ef8 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -53,21 +53,20 @@ sub collect_test_cases ($) { else { # ---------------------------------------------------------------------- - # Skip some tests listed in disabled.def + # Disable some tests listed in disabled.def # ---------------------------------------------------------------------- - my %skiplist; - my $skipfile= "$testdir/disabled.def"; - if ( open(SKIPFILE, $skipfile) ) + my %disabled; + if ( open(DISABLED, "$testdir/disabled.def" ) ) { - while ( <SKIPFILE> ) + while ( <DISABLED> ) { chomp; if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ ) { - $skiplist{$1}= $2; + $disabled{$1}= $2; } } - close SKIPFILE; + close DISABLED; } foreach my $elem ( sort readdir(TESTDIR) ) { @@ -75,7 +74,7 @@ sub collect_test_cases ($) { next if ! defined $tname; next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test); - collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%skiplist); + collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled); } closedir TESTDIR; } @@ -119,7 +118,7 @@ sub collect_one_test_case($$$$$$) { my $tname= shift; my $elem= shift; my $cases= shift; - my $skiplist=shift; + my $disabled=shift; my $path= "$testdir/$elem"; @@ -188,7 +187,7 @@ sub collect_one_test_case($$$$$$) { my $slave_mi_file= "$testdir/$tname.slave-mi"; my $master_sh= "$testdir/$tname-master.sh"; my $slave_sh= "$testdir/$tname-slave.sh"; - my $disabled= "$testdir/$tname.disabled"; + my $disabled_file= "$testdir/$tname.disabled"; $tinfo->{'master_opt'}= $::glob_win32 ? ["--default-time-zone=+3:00"] : []; $tinfo->{'slave_opt'}= $::glob_win32 ? ["--default-time-zone=+3:00"] : []; @@ -292,18 +291,18 @@ sub collect_one_test_case($$$$$$) { } # FIXME why this late? - if ( $skiplist->{$tname} ) + if ( $disabled->{$tname} ) { $tinfo->{'skip'}= 1; $tinfo->{'disable'}= 1; # Sub type of 'skip' - $tinfo->{'comment'}= $skiplist->{$tname} if $skiplist->{$tname}; + $tinfo->{'comment'}= $disabled->{$tname} if $disabled->{$tname}; } - if ( -f $disabled ) + if ( -f $disabled_file ) { $tinfo->{'skip'}= 1; $tinfo->{'disable'}= 1; # Sub type of 'skip' - $tinfo->{'comment'}= mtr_fromfile($disabled); + $tinfo->{'comment'}= mtr_fromfile($disabled_file); } # We can't restart a running server that may be in use diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index c1aab340a16..9a12d842998 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -7,6 +7,7 @@ use strict; sub mtr_full_hostname (); +sub mtr_short_hostname (); sub mtr_init_args ($); sub mtr_add_arg ($$); sub mtr_path_exists(@); @@ -21,6 +22,7 @@ sub mtr_exe_exists(@); # We want the fully qualified host name and hostname() may have returned # only the short name. So we use the resolver to find out. +# Note that this might fail on some platforms sub mtr_full_hostname () { @@ -35,6 +37,13 @@ sub mtr_full_hostname () { return $hostname; } +sub mtr_short_hostname () { + + my $hostname= hostname(); + $hostname =~ s/\..+$//; + return $hostname; +} + # FIXME move to own lib sub mtr_init_args ($) { diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 1eb4f6b7c58..c9ae92305c2 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -185,10 +185,6 @@ sub spawn_parent_impl { if ( $mode eq 'run' or $mode eq 'test' ) { - my $exit_value= -1; - my $signal_num= 0; - my $dumped_core= 0; - if ( $mode eq 'run' ) { # Simple run of command, we wait for it to return @@ -199,11 +195,7 @@ sub spawn_parent_impl { mtr_error("$path ($pid) got lost somehow"); } - $exit_value= $? >> 8; - $signal_num= $? & 127; - $dumped_core= $? & 128; - - return $exit_value; + return mtr_process_exit_status($?); } else { @@ -217,6 +209,8 @@ sub spawn_parent_impl { # FIXME is this as it should be? Can't mysqld terminate # 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 ) @@ -226,12 +220,28 @@ 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 - $exit_value= $? >> 8; - $signal_num= $? & 127; - $dumped_core= $? & 128; + $exit_value= mtr_process_exit_status($?); last; } @@ -279,7 +289,7 @@ sub spawn_parent_impl { } } - return $exit_value; + return $saved_exit_value || $exit_value; } } else @@ -290,6 +300,23 @@ sub spawn_parent_impl { } +# ---------------------------------------------------------------------- +# We try to emulate how an Unix shell calculates the exit code +# ---------------------------------------------------------------------- + +sub mtr_process_exit_status { + my $raw_status= shift; + + if ( $raw_status & 127 ) + { + return ($raw_status & 127) + 128; # Signal num + 128 + } + else + { + return $raw_status >> 8; # Exit code + } +} + ############################################################################## # @@ -329,7 +356,7 @@ sub mtr_kill_leftovers () { }); } - mtr_mysqladmin_shutdown(\@args); + mtr_mysqladmin_shutdown(\@args, 20); # We now have tried to terminate nice. We have waited for the listen # port to be free, but can't really tell if the mysqld process died @@ -439,7 +466,8 @@ sub mtr_stop_mysqld_servers ($) { # First try nice normal shutdown using 'mysqladmin' # ---------------------------------------------------------------------- - mtr_mysqladmin_shutdown($spec); + # Shutdown time must be high as slave may be in reconnect + mtr_mysqladmin_shutdown($spec, 70); # ---------------------------------------------------------------------- # We loop with waitpid() nonblocking to see how many of the ones we @@ -473,6 +501,7 @@ sub mtr_stop_mysqld_servers ($) { } else { + # Server is dead, we remove the pidfile if any # Race, could have been removed between I tested with -f # and the unlink() below, so I better check again with -f @@ -502,10 +531,12 @@ sub mtr_stop_mysqld_servers ($) { # that for true Win32 processes, kill(0,$pid) will not return 1. # ---------------------------------------------------------------------- + start_reap_all(); # Avoid zombies + SIGNAL: foreach my $sig (15,9) { - my $retries= 10; # 10 seconds + my $retries= 20; # FIXME 20 seconds, this is silly! kill($sig, keys %mysqld_pids); while ( $retries-- and kill(0, keys %mysqld_pids) ) { @@ -514,6 +545,8 @@ sub mtr_stop_mysqld_servers ($) { } } + stop_reap_all(); # Get into control again + # ---------------------------------------------------------------------- # Now, we check if all we can find using kill(0,$pid) are dead, # and just assume the rest are. We cleanup socket and PID files. @@ -584,8 +617,9 @@ sub mtr_stop_mysqld_servers ($) { # ############################################################################## -sub mtr_mysqladmin_shutdown () { +sub mtr_mysqladmin_shutdown { my $spec= shift; + my $adm_shutdown_tmo= shift; my %mysql_admin_pids; my @to_kill_specs; @@ -624,7 +658,7 @@ sub mtr_mysqladmin_shutdown () { mtr_add_arg($args, "--protocol=tcp"); # Needed if no --socket } mtr_add_arg($args, "--connect_timeout=5"); - mtr_add_arg($args, "--shutdown_timeout=20"); + mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo"); mtr_add_arg($args, "shutdown"); # We don't wait for termination of mysqladmin my $pid= mtr_spawn($::exe_mysqladmin, $args, @@ -632,7 +666,8 @@ sub mtr_mysqladmin_shutdown () { $mysql_admin_pids{$pid}= 1; } - # We wait blocking, we wait for the last one anyway + # As mysqladmin is such a simple program, we trust it to terminate. + # I.e. we wait blocking, and wait wait for them all before we go on. while (keys %mysql_admin_pids) { foreach my $pid (keys %mysql_admin_pids) @@ -651,7 +686,8 @@ sub mtr_mysqladmin_shutdown () { my $timeout= 20; # 20 seconds max my $res= 1; # If we just fall through, we are done - + # in the sense that the servers don't + # listen to their ports any longer TIME: while ( $timeout-- ) { @@ -669,6 +705,8 @@ sub mtr_mysqladmin_shutdown () { last; # If we got here, we are done } + $timeout or mtr_debug("At least one server is still listening to its port"); + sleep(5) if $::glob_win32; # FIXME next startup fails if no sleep return $res; @@ -752,6 +790,7 @@ sub mtr_ping_mysqld_server () { # ############################################################################## +# FIXME check that the pidfile contains the expected pid! sub sleep_until_file_created ($$$) { my $pidfile= shift; @@ -762,7 +801,7 @@ sub sleep_until_file_created ($$$) { { if ( -r $pidfile ) { - return 1; + return $pid; } # Check if it died after the fork() was successful @@ -793,10 +832,18 @@ sub sleep_until_file_created ($$$) { # ############################################################################## +# FIXME something is wrong, we sometimes terminate with "Hangup" written +# to tty, and no STDERR output telling us why. + +# FIXME for some readon, setting HUP to 'IGNORE' will cause exit() to +# write out "Hangup", and maybe loose some output. We insert a sleep... + sub mtr_exit ($) { my $code= shift; +# cluck("Called mtr_exit()"); local $SIG{HUP} = 'IGNORE'; kill('HUP', -$$); + sleep 2; exit($code); } diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 0af34d11a3f..5e1a8308505 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -10,7 +10,6 @@ sub mtr_report_test_name($); sub mtr_report_test_passed($); sub mtr_report_test_failed($); sub mtr_report_test_skipped($); -sub mtr_report_test_disabled($); sub mtr_show_failed_diff ($); sub mtr_report_stats ($); @@ -110,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; |