summaryrefslogtreecommitdiff
path: root/mysql-test/lib
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/lib')
-rw-r--r--mysql-test/lib/init_db.sql2
-rw-r--r--mysql-test/lib/mtr_cases.pl27
-rw-r--r--mysql-test/lib/mtr_misc.pl9
-rw-r--r--mysql-test/lib/mtr_process.pl89
-rw-r--r--mysql-test/lib/mtr_report.pl10
-rw-r--r--mysql-test/lib/mtr_timer.pl127
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;