diff --git a/client/mysqltest.c b/client/mysqltest.c index 18d5660d1a7..abacd73d878 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -538,7 +538,6 @@ static void free_used_memory() mysql_server_end(); if (ps_protocol) ps_free_reg(); - my_end(MY_CHECK_ERROR); DBUG_VOID_RETURN; } @@ -556,6 +555,7 @@ static void die(const char* fmt, ...) } va_end(args); free_used_memory(); + my_end(MY_CHECK_ERROR); exit(1); } @@ -568,6 +568,7 @@ static void abort_not_supported_test() if (!silent) printf("skipped\n"); free_used_memory(); + my_end(MY_CHECK_ERROR); exit(2); } @@ -3655,6 +3656,7 @@ int main(int argc, char **argv) if (!got_end_timer) timer_output(); /* No end_timer cmd, end it */ free_used_memory(); + my_end(MY_CHECK_ERROR); exit(error ? 1 : 0); return error ? 1 : 0; /* Keep compiler happy */ } diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 2263ef5bc24..8c584802b8e 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -4,13 +4,14 @@ # and is part of the translation of the Bourne shell script with the # same name. +use Carp qw(cluck); use strict; use POSIX ":sys_wait_h"; sub mtr_run ($$$$$$); sub mtr_spawn ($$$$$$); -sub mtr_stop_servers ($); +sub mtr_stop_mysqld_servers ($$); sub mtr_kill_leftovers (); # static in C @@ -77,13 +78,21 @@ sub spawn_impl ($$$$$$$) { if ( $::opt_script_debug ) { - print STDERR "-" x 78, "\n"; - print STDERR "STDIN $input\n" if $input; - print STDERR "STDOUT $output\n" if $output; - print STDERR "STDERR $error\n" if $error; - print STDERR "DAEMON\n" if !$join; - print STDERR "EXEC $path ", join(" ",@$arg_list_t), "\n"; - print STDERR "-" x 78, "\n"; + print STDERR "\n"; + print STDERR "#### ", "-" x 78, "\n"; + print STDERR "#### ", "STDIN $input\n" if $input; + print STDERR "#### ", "STDOUT $output\n" if $output; + print STDERR "#### ", "STDERR $error\n" if $error; + if ( $join ) + { + print STDERR "#### ", "run"; + } + else + { + print STDERR "#### ", "spawn"; + } + print STDERR "$path ", join(" ",@$arg_list_t), "\n"; + print STDERR "#### ", "-" x 78, "\n"; } my $pid= fork(); @@ -101,11 +110,11 @@ sub spawn_impl ($$$$$$$) { my $dumped_core= $? & 128; if ( $signal_num ) { - die("spawn got signal $signal_num"); + mtr_error("spawn got signal $signal_num"); } if ( $dumped_core ) { - die("spawn dumped core"); + mtr_error("spawn dumped core"); } return $exit_value; } @@ -127,22 +136,34 @@ sub spawn_impl ($$$$$$$) { if ( $output ) { - open(STDOUT,">",$output) or die "Can't redirect STDOUT to \"$output\": $!"; + if ( ! open(STDOUT,">",$output) ) + { + mtr_error("can't redirect STDOUT to \"$output\": $!"); + } } if ( $error ) { if ( $output eq $error ) { - open(STDERR,">&STDOUT") or die "Can't dup STDOUT: $!"; + if ( ! open(STDERR,">&STDOUT") ) + { + mtr_error("can't dup STDOUT: $!"); + } } else { - open(STDERR,">",$error) or die "Can't redirect STDERR to \"$output\": $!"; + if ( ! open(STDERR,">",$error) ) + { + mtr_error("can't redirect STDERR to \"$output\": $!"); + } } } if ( $input ) { - open(STDIN,"<",$input) or die "Can't redirect STDIN to \"$input\": $!"; + if ( ! open(STDIN,"<",$input) ) + { + mtr_error("can't redirect STDIN to \"$input\": $!"); + } } exec($path,@$arg_list_t); } @@ -163,27 +184,25 @@ sub mtr_kill_leftovers () { for ( my $idx; $idx < 2; $idx++ ) { -# if ( $::master->[$idx]->{'pid'} ) -# { - push(@args, - $::master->[$idx]->{'path_mypid'}, - $::master->[$idx]->{'path_mysock'}, - ); -# } + push(@args,{ + pid => 0, # We don't know the PID + pidfile => $::master->[$idx]->{'path_mypid'}, + sockfile => $::master->[$idx]->{'path_mysock'}, + port => $::master->[$idx]->{'path_myport'}, + }); } for ( my $idx; $idx < 3; $idx++ ) { -# if ( $::slave->[$idx]->{'pid'} ) -# { - push(@args, - $::slave->[$idx]->{'path_mypid'}, - $::slave->[$idx]->{'path_mysock'}, - ); -# } + push(@args,{ + pid => 0, # We don't know the PID + pidfile => $::slave->[$idx]->{'path_mypid'}, + sockfile => $::slave->[$idx]->{'path_mysock'}, + port => $::slave->[$idx]->{'path_myport'}, + }); } - mtr_stop_servers(\@args); + mtr_stop_mysqld_servers(\@args, 1); # We scan the "var/run/" directory for other process id's to kill my $rundir= "$::glob_mysql_test_dir/var/run"; # FIXME $path_run_dir or something @@ -211,17 +230,29 @@ sub mtr_kill_leftovers () { } closedir(RUNDIR); - my $retries= 10; # 10 seconds - do - { - kill(9, @pids); - } while ( $retries-- and kill(0, @pids) ); + start_reap_all(); - if ( kill(0, @pids) ) + if ( $::glob_cygwin_perl ) { - mtr_error("can't kill processes " . join(" ", @pids)); + # We have no (easy) way of knowing the Cygwin controlling + # process, in the PID file we only have the Windows process id. + system("kill -f " . join(" ",@pids)); # Hope for the best.... + } + else + { + my $retries= 10; # 10 seconds + do + { + kill(9, @pids); + } while ( $retries-- and kill(0, @pids) ); + + if ( kill(0, @pids) ) + { + mtr_error("can't kill processes " . join(" ", @pids)); + } } + stop_reap_all(); } } @@ -237,185 +268,200 @@ sub mtr_kill_leftovers () { # This is not perfect, there could still be other server processes # left. -sub mtr_stop_servers ($) { - my $spec= shift; +# Force flag is to be set only for killing mysqld servers this script +# didn't create in this run, i.e. initial cleanup before we start working. +# If force flag is set, we try to kill all with mysqladmin, and +# give up if we have no PIDs. +# FIXME On some operating systems, $srv->{'pid'} and $srv->{'pidfile'} +# will not be the same PID. We need to try to kill both I think. + +sub mtr_stop_mysqld_servers ($$) { + my $spec= shift; + my $force= shift; + + # ---------------------------------------------------------------------- + # If the process was not started from this file, we got no PID, + # we try to find it in the PID file. + # ---------------------------------------------------------------------- + + my $any_pid= 0; # If we have any PIDs + + foreach my $srv ( @$spec ) + { + if ( ! $srv->{'pid'} and -f $srv->{'pidfile'} ) + { + $srv->{'pid'}= mtr_get_pid_from_file($srv->{'pidfile'}); + } + if ( $srv->{'pid'} ) + { + $any_pid= 1; + } + } + + # If the processes where started from this script, and we know + # no PIDs, then we don't have to do anything. + + if ( ! $any_pid and ! $force ) + { + # cluck "This is how we got here!"; + return; + } + + # ---------------------------------------------------------------------- # First try nice normal shutdown using 'mysqladmin' + # ---------------------------------------------------------------------- + start_reap_all(); # Don't require waitpid() of children + + foreach my $srv ( @$spec ) { - my @args= @$spec; - while ( @args ) + if ( -e $srv->{'sockfile'} or $srv->{'port'} ) { - my $pidfile= shift @args; # FIXME not used here.... - my $sockfile= shift @args; + # FIXME wrong log..... + # FIXME, stderr..... + # Shutdown time must be high as slave may be in reconnect + my $args; - if ( -f $sockfile ) + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "-uroot"); + if ( -e $srv->{'sockfile'} ) { - - # FIXME wrong log..... - # FIXME, stderr..... - # Shutdown time must be high as slave may be in reconnect - my $opts= - [ - "--no-defaults", - "-uroot", - "--socket=$sockfile", - "--connect_timeout=5", - "--shutdown_timeout=70", - "shutdown", - ]; - # We don't wait for termination of mysqladmin - mtr_spawn($::exe_mysqladmin, $opts, - "", $::path_manager_log, $::path_manager_log, ""); + mtr_add_arg($args, "--socket=%s", $srv->{'sockfile'}); } + if ( $srv->{'port'} ) + { + mtr_add_arg($args, "--port=%s", $srv->{'port'}); + } + mtr_add_arg($args, "--connect_timeout=5"); + mtr_add_arg($args, "--shutdown_timeout=70"); + mtr_add_arg($args, "shutdown"); + # We don't wait for termination of mysqladmin + mtr_spawn($::exe_mysqladmin, $args, + "", $::path_manager_log, $::path_manager_log, ""); } } - # Wait for them all to remove their socket file + # Wait for them all to remove their pid and socket file - SOCKREMOVED: + PIDSOCKFILEREMOVED: for (my $loop= $::opt_sleep_time_for_delete; $loop; $loop--) { - my $sockfiles_left= 0; - my @args= @$spec; - while ( @args ) + my $pidsockfiles_left= 0; + foreach my $srv ( @$spec ) { - my $pidfile= shift @args; - my $sockfile= shift @args; - if ( -f $sockfile or -f $pidfile ) + if ( -e $srv->{'sockfile'} or -f $srv->{'pidfile'} ) { - $sockfiles_left++; # Could be that pidfile is left + $pidsockfiles_left++; # Could be that pidfile is left } } - if ( ! $sockfiles_left ) + if ( ! $pidsockfiles_left ) { - last SOCKREMOVED; - } - if ( $loop > 1 ) - { - sleep(1); # One second + last PIDSOCKFILEREMOVED; } + mtr_debug("Sleep for 1 second waiting for pid and socket file removal"); + sleep(1); # One second } + # ---------------------------------------------------------------------- + # If no known PIDs, we have nothing more to try + # ---------------------------------------------------------------------- + + if ( ! $any_pid ) + { + stop_reap_all(); + return; + } + + # ---------------------------------------------------------------------- # We may have killed all that left a socket, but we are not sure we got - # them all killed. We now check the PID file, if any - - # Try nice kill with SIG_TERM + # them all killed. If we suspect it lives, try nice kill with SIG_TERM. + # Note that for true Win32 processes, kill(0,$pid) will not return 1. + # ---------------------------------------------------------------------- + SIGNAL: + foreach my $sig (15,9) { - my @args= @$spec; - while ( @args ) + my $process_left= 0; + foreach my $srv ( @$spec ) { - my $pidfile= shift @args; - my $sockfile= shift @args; - if (-f $pidfile) + if ( $srv->{'pid'} and + ( -f $srv->{'pidfile'} or kill(0,$srv->{'pid'}) ) ) { - my $pid= mtr_get_pid_from_file($pidfile); - mtr_warning("process $pid not cooperating with mysqladmin, " . - "will send TERM signal to process"); - kill(15,$pid); # SIG_TERM + $process_left++; + mtr_warning("process $srv->{'pid'} not cooperating, " . + "will send signal $sig to process"); + kill($sig,$srv->{'pid'}); # SIG_TERM + } + if ( ! $process_left ) + { + last SIGNAL; } } + mtr_debug("Sleep for 5 seconds waiting for processes to die"); + sleep(5); # We wait longer than usual } - # Wait for them all to die - - for (my $loop= $::opt_sleep_time_for_delete; $loop; $loop--) - { - my $pidfiles_left= 0; - my @args= @$spec; - while ( @args ) - { - my $pidfile= shift @args; - my $sockfile= shift @args; - if ( -f $pidfile ) - { - $pidfiles_left++; - } - } - if ( ! $pidfiles_left ) - { - return; - } - if ( $loop > 1 ) - { - sleep(1); # One second - } - } - - # Try hard kill with SIG_KILL + # ---------------------------------------------------------------------- + # 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. + # ---------------------------------------------------------------------- { - my @args= @$spec; - while ( @args ) + my $errors= 0; + foreach my $srv ( @$spec ) { - my $pidfile= shift @args; - my $sockfile= shift @args; - if (-f $pidfile) + if ( $srv->{'pid'} ) { - my $pid= mtr_get_pid_from_file($pidfile); - mtr_warning("$pid did not die from TERM signal, ", - "will send KILL signal to process"); - kill(9,$pid); - } - } - } - - # We check with Perl "kill 0" if process still exists - - PIDFILES: - for (my $loop= $::opt_sleep_time_for_delete; $loop; $loop--) - { - my $not_terminated= 0; - my @args= @$spec; - while ( @args ) - { - my $pidfile= shift @args; - my $sockfile= shift @args; - if (-f $pidfile) - { - my $pid= mtr_get_pid_from_file($pidfile); - if ( ! kill(0,$pid) ) + if ( kill(0,$srv->{'pid'}) ) { - $not_terminated++; - mtr_warning("could't kill $pid"); + # FIXME In Cygwin there seem to be some fast reuse + # of PIDs, so dying may not be the right thing to do. + $errors++; + mtr_warning("can't kill process $srv->{'pid'}"); + } + else + { + # We managed to kill it at last + # FIXME In Cygwin, we will get here even if the process lives. + + # Not needed as we know the process is dead, but to be safe + # we unlink and check success in two steps. We first unlink + # without checking the error code, and then check if the + # file still exists. + + foreach my $file ($srv->{'pidfile'}, $srv->{'sockfile'}) + { + unlink($file); + if ( -e $file ) + { + $errors++; + mtr_warning("couldn't delete $file"); + } + } } } } - if ( ! $not_terminated ) + if ( $errors ) { - last PIDFILES; - } - if ( $loop > 1 ) - { - sleep(1); # One second + # We are in trouble, just die.... + mtr_error("we could not kill or clean up all processes"); } } - { - my $pidfiles_left= 0; - my @args= @$spec; - while ( @args ) - { - my $pidfile= shift @args; - my $sockfile= shift @args; - if ( -f $pidfile ) - { - if ( ! unlink($pidfile) ) - { - $pidfiles_left++; - mtr_warning("could't delete $pidfile"); - } - } - } - if ( $pidfiles_left ) - { - mtr_error("one or more pid files could not be deleted"); - } - } + stop_reap_all(); # FIXME We just assume they are all dead, we don't know.... } +sub start_reap_all { + $SIG{CHLD}= 'IGNORE'; # FIXME is this enough? +} + +sub stop_reap_all { + $SIG{CHLD}= 'DEFAULT'; +} 1; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 350cd993f19..0f75fc1341a 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -14,6 +14,7 @@ sub mtr_report_test_skipped($); sub mtr_show_failed_diff ($); sub mtr_report_stats ($); sub mtr_print_line (); +sub mtr_print_thick_line (); sub mtr_print_header (); sub mtr_report (@); sub mtr_warning (@); @@ -214,6 +215,10 @@ sub mtr_print_line () { print '-' x 55, "\n"; } +sub mtr_print_thick_line () { + print '=' x 55, "\n"; +} + sub mtr_print_header () { print "\n"; if ( $::opt_timer ) @@ -250,7 +255,7 @@ sub mtr_error (@) { sub mtr_debug (@) { if ( $::opt_script_debug ) { - print "mysql-test-run: DEBUG: ",join(" ", @_),"\n"; + print STDERR "####: ",join(" ", @_),"\n"; } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a69dcdce5c6..01729aa1018 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -67,6 +67,11 @@ # is to use the Devel::Trace package found at # "http://www.plover.com/~mjd/perl/Trace/" and run this script like # "perl -d:Trace mysql-test-run.pl" +# +# FIXME Save a PID file from this code as well, to record the process +# id we think it has. In Cygwin, a fork creates one Cygwin process, +# and then the real Win32 process. Cygwin Perl can only kill Cygwin +# processes. And "mysqld --bootstrap ..." doesn't save a PID file. $Devel::Trace::TRACE= 0; # Don't trace boring init stuff @@ -147,7 +152,9 @@ our @mysqld_src_dirs= # Misc global variables -our $glob_win32= 0; +our $glob_win32= 0; # OS and native Win32 executables +our $glob_win32_perl= 0; # ActiveState Win32 Perl +our $glob_cygwin_perl= 0; # Cygwin Perl our $glob_mysql_test_dir= undef; our $glob_mysql_bench_dir= undef; our $glob_hostname= undef; @@ -172,6 +179,9 @@ our $path_slave_load_tmpdir; # What is this?! our $path_my_basedir; our $opt_tmpdir; # A path but set directly on cmd line +our $opt_usage; +our $opt_suite; + our $opt_netware; our $opt_script_debug= 0; # Script debugging, enable with --script-debug @@ -290,6 +300,7 @@ sub initial_setup (); sub command_line_setup (); sub executable_setup (); sub kill_and_cleanup (); +sub collect_test_cases ($); sub sleep_until_file_created ($$); sub ndbcluster_start (); sub ndbcluster_stop (); @@ -306,6 +317,7 @@ sub stop_masters_slaves (); sub stop_masters (); sub stop_slaves (); sub run_mysqltest ($$); +sub usage ($); ###################################################################### # @@ -378,7 +390,9 @@ sub initial_setup () { $glob_scriptname= basename($0); - $glob_win32= ($^O eq "MSWin32"); + $glob_win32_perl= ($^O eq "MSWin32"); + $glob_cygwin_perl= ($^O eq "cygwin"); + $glob_win32= ($glob_win32_perl or $glob_cygwin_perl); # We require that we are in the "mysql-test" directory # to run mysql-test-run @@ -399,6 +413,12 @@ sub initial_setup () { # 'basedir' is always parent of "mysql-test" directory $glob_mysql_test_dir= cwd(); + if ( $glob_cygwin_perl ) + { + # Windows programs like 'mysqld' needs Windows paths + $glob_mysql_test_dir= `cygpath -m $glob_mysql_test_dir`; + chomp($glob_mysql_test_dir); + } $glob_basedir= dirname($glob_mysql_test_dir); $glob_mysql_bench_dir= "$glob_basedir/mysql-bench"; # FIXME make configurable @@ -423,6 +443,7 @@ sub command_line_setup () { # These are defaults for things that are set on the command line + $opt_suite= "main"; # Special default suite $opt_tmpdir= "$glob_mysql_test_dir/var/tmp"; # FIXME maybe unneded? $path_manager_log= "$glob_mysql_test_dir/var/log/manager.log"; @@ -436,61 +457,85 @@ sub command_line_setup () { my $opt_user; # Read the command line + # Note: Keep list, and the order, in sync with usage at end of this file GetOptions( - 'bench' => \$opt_bench, - 'big-test' => \$opt_big_test, - 'client-gdb' => \$opt_client_gdb, - 'compress' => \$opt_compress, - 'ddd' => \$opt_ddd, - 'debug' => \$opt_debug, - 'do-test=s' => \$opt_do_test, + # Control what engine/variation to run 'embedded-server' => \$opt_embedded_server, 'ps-protocol' => \$opt_ps_protocol, - 'extern' => \$opt_extern, - 'fast' => \$opt_fast, - 'force' => \$opt_force, - 'gcov' => \$opt_gcov, - 'gdb' => \$opt_gdb, - 'gprof' => \$opt_gprof, - 'local' => \$opt_local, - 'local-master' => \$opt_local_master, - 'manual-gdb' => \$opt_manual_gdb, - 'master-binary=s' => \$exe_master_mysqld, - 'master_port=i' => \$opt_master_myport, - 'mysqld=s' => \$opt_extra_mysqld_opt, - 'ndbcluster_port=i' => \$opt_ndbcluster_port, - 'ndbconnectstring=s' => \$opt_ndbconnectstring, - 'netware' => \$opt_netware, + 'bench' => \$opt_bench, + 'small-bench' => \$opt_small_bench, 'no-manager' => \$opt_no_manager, - 'old-master' => \$opt_old_master, - 'ps-protocol' => \$opt_ps_protocol, - 'record' => \$opt_record, - 'script-debug' => \$opt_script_debug, + + # Control what test suites or cases to run + 'force' => \$opt_force, + 'with-ndbcluster' => \$opt_with_ndbcluster, + 'do-test=s' => \$opt_do_test, + 'suite=s' => \$opt_suite, 'skip-rpl' => \$opt_skip_rpl, 'skip-test=s' => \$opt_skip_test, - 'slave-binary=s' => \$exe_slave_mysqld, + + # Specify ports + 'master_port=i' => \$opt_master_myport, 'slave_port=i' => \$opt_slave_myport, + 'ndbcluster_port=i' => \$opt_ndbcluster_port, + + # Test case authoring + 'record' => \$opt_record, + + # ??? + 'mysqld=s' => \$opt_extra_mysqld_opt, + + # Run test on running server + 'extern' => \$opt_extern, + 'ndbconnectstring=s' => \$opt_ndbconnectstring, + + # Debugging + 'gdb' => \$opt_gdb, + 'manual-gdb' => \$opt_manual_gdb, + 'client-gdb' => \$opt_client_gdb, + 'ddd' => \$opt_ddd, + 'strace-client' => \$opt_strace_client, + 'master-binary=s' => \$exe_master_mysqld, + 'slave-binary=s' => \$exe_slave_mysqld, + + # Coverage, profiling etc + 'gcov' => \$opt_gcov, + 'gprof' => \$opt_gprof, + 'valgrind' => \$opt_valgrind, + 'valgrind-all' => \$opt_valgrind_all, + 'valgrind-options=s' => \$opt_valgrind_options, + + # Misc + 'big-test' => \$opt_big_test, + 'compress' => \$opt_compress, + 'debug' => \$opt_debug, + 'fast' => \$opt_fast, + 'local' => \$opt_local, + 'local-master' => \$opt_local_master, + 'netware' => \$opt_netware, + 'old-master' => \$opt_old_master, + 'script-debug' => \$opt_script_debug, 'sleep=i' => \$opt_sleep, - 'small-bench' => \$opt_small_bench, 'socket=s' => \$opt_socket, 'start-and-exit' => \$opt_start_and_exit, 'start-from=s' => \$opt_start_from, - 'strace-client' => \$opt_strace_client, 'timer' => \$opt_timer, 'tmpdir=s' => \$opt_tmpdir, 'user-test=s' => \$opt_user_test, 'user=s' => \$opt_user, - 'valgrind' => \$opt_valgrind, - 'valgrind-all' => \$opt_valgrind_all, - 'valgrind-options=s' => \$opt_valgrind_options, 'verbose' => \$opt_verbose, 'wait-timeout=i' => \$opt_wait_timeout, 'warnings|log-warnings' => \$opt_warnings, - 'with-ndbcluster' => \$opt_with_ndbcluster, 'with-openssl' => \$opt_with_openssl, + + 'help|h' => \$opt_usage, ) or usage("Can't read options"); + if ( $opt_usage ) + { + usage(""); + } # Put this into a hash, will be a C struct @@ -593,7 +638,7 @@ sub command_line_setup () { if ( $opt_sleep ) { - $opt_sleep_time_after_restart= $opt_sleep; + $opt_sleep_time_after_restart= $opt_sleep; } if ( $opt_gcov and ! $opt_source_dist ) @@ -811,8 +856,22 @@ sub handle_int_signal () { # ############################################################################## -sub collect_test_cases () { - my $testdir= "$glob_mysql_test_dir/t"; +sub collect_test_cases ($) { + my $suite= shift; # Test suite name + + my $testdir; + my $resdir; + + if ( $suite eq "main" ) + { + $testdir= "$glob_mysql_test_dir/t"; + $resdir= "$glob_mysql_test_dir/r"; + } + else + { + $testdir= "$glob_mysql_test_dir/suite/$suite/t"; + $resdir= "$glob_mysql_test_dir/suite/$suite/r"; + } my @tests; # Array of hash, will be array of C struct @@ -839,7 +898,7 @@ sub collect_test_cases () { my $tinfo= {}; $tinfo->{'name'}= $tname; - $tinfo->{'result_file'}= "r/$tname.result"; + $tinfo->{'result_file'}= "$resdir/$tname.result"; push(@tests, $tinfo); if ( $opt_skip_test and defined mtr_match_prefix($tname,$opt_skip_test) ) @@ -947,7 +1006,7 @@ sub collect_test_cases () { if ( -f $master_sh ) { - if ( $glob_win32 ) + if ( $glob_win32_perl ) { $tinfo->{'skip'}= 1; } @@ -960,7 +1019,7 @@ sub collect_test_cases () { if ( -f $slave_sh ) { - if ( $glob_win32 ) + if ( $glob_win32_perl ) { $tinfo->{'skip'}= 1; } @@ -1071,6 +1130,7 @@ sub sleep_until_file_created ($$) { { return; } + mtr_debug("Sleep for 1 second waiting for creation of $pidfile"); sleep(1); } @@ -1180,13 +1240,22 @@ sub run_benchmarks ($) { # ############################################################################## +# FIXME how to specify several suites to run? Comma separated list? + sub run_tests () { + run_suite($opt_suite); +} - mtr_report("Finding Tests"); +sub run_suite () { + my $suite= shift; - my $tests= collect_test_cases(); + mtr_print_thick_line(); - mtr_report("Starting Tests"); + mtr_report("Finding Tests in $suite suite"); + + my $tests= collect_test_cases($suite); + + mtr_report("Starting Tests in $suite suite"); mtr_print_header(); @@ -1343,6 +1412,8 @@ sub run_testcase ($) { # the preparation. # ---------------------------------------------------------------------- + mtr_report_test_name($tinfo); + mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); do_before_start_master($tname,$tinfo->{'master_sh'}); @@ -1350,8 +1421,6 @@ sub run_testcase ($) { # Start masters # ---------------------------------------------------------------------- - mtr_report_test_name($tinfo); - if ( ! $glob_use_running_server and ! $glob_use_embedded_server ) { # FIXME give the args to the embedded server?! @@ -1861,15 +1930,17 @@ sub stop_masters () { # the mysqld process from being killed if ( $master->[$idx]->{'pid'} ) { - push(@args, - $master->[$idx]->{'path_mypid'}, - $master->[$idx]->{'path_mysock'}, - ); - $master->[$idx]->{'pid'}= 0; + push(@args,{ + pid => $master->[$idx]->{'pid'}, + pidfile => $master->[$idx]->{'path_mypid'}, + sockfile => $master->[$idx]->{'path_mysock'}, + port => $master->[$idx]->{'path_myport'}, + }); + $master->[$idx]->{'pid'}= 0; # Assume we are done with it } } - mtr_stop_servers(\@args); + mtr_stop_mysqld_servers(\@args, 0); } sub stop_slaves () { @@ -1881,15 +1952,17 @@ sub stop_slaves () { { if ( $slave->[$idx]->{'pid'} ) { - push(@args, - $slave->[$idx]->{'path_mypid'}, - $slave->[$idx]->{'path_mysock'}, - ); - $slave->[$idx]->{'pid'}= 0; + push(@args,{ + pid => $slave->[$idx]->{'pid'}, + pidfile => $slave->[$idx]->{'path_mypid'}, + sockfile => $slave->[$idx]->{'path_mysock'}, + port => $slave->[$idx]->{'path_myport'}, + }); + $slave->[$idx]->{'pid'}= 0; # Assume we are done with it } } - mtr_stop_servers(\@args); + mtr_stop_mysqld_servers(\@args, 0); } @@ -2006,3 +2079,104 @@ sub run_mysqltest ($$) { return mtr_run($exe_mysqltest,$args,$tinfo->{'path'},"",$path_timefile,""); } + +############################################################################## +# +# Usage +# +############################################################################## + +sub usage ($) +{ + print STDERR < column_iter(columns); + if (columns.elements && !revoke_grant) + { + TABLE *table; + class LEX_COLUMN *column; + List_iterator column_iter(columns); - if (!(table=open_ltable(thd,table_list,TL_READ))) - DBUG_RETURN(-1); - while ((column = column_iter++)) - { - uint unused_field_idx= NO_CACHED_FIELD_INDEX; - if (!find_field_in_table(thd,table,column->column.ptr(), - column->column.length(),0,0, - &unused_field_idx)) + if (!(table=open_ltable(thd,table_list,TL_READ))) + DBUG_RETURN(-1); + while ((column = column_iter++)) { - my_error(ER_BAD_FIELD_ERROR, MYF(0), - column->column.c_ptr(), table_list->alias); - DBUG_RETURN(-1); + uint unused_field_idx= NO_CACHED_FIELD_INDEX; + Field *f= find_field_in_table(thd,table,column->column.ptr(), + column->column.length(),1,0,&unused_field_idx); + if (!f) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), + column->column.c_ptr(), table_list->alias); + DBUG_RETURN(-1); + } + if (f == (Field*)-1) + { + DBUG_RETURN(-1); + } + column_priv|= column->rights; } - column_priv|= column->rights; + close_thread_tables(thd); } - close_thread_tables(thd); - } - else if (!(rights & CREATE_ACL) && !revoke_grant) - { - char buf[FN_REFLEN]; - sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db, - table_list->real_name); - fn_format(buf,buf,"","",4+16+32); - if (access(buf,F_OK)) + else { - my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); - DBUG_RETURN(-1); + if (!(rights & CREATE_ACL)) + { + char buf[FN_REFLEN]; + sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db, + table_list->real_name); + fn_format(buf,buf,"","",4+16+32); + if (access(buf,F_OK)) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); + DBUG_RETURN(-1); + } + } + if (table_list->grant.want_privilege) + { + char command[128]; + get_privilege_desc(command, sizeof(command), + table_list->grant.want_privilege); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + command, thd->priv_user, thd->host_or_ip, table_list->alias); + DBUG_RETURN(-1); + } } } @@ -2773,25 +2791,8 @@ err: rw_unlock(&LOCK_grant); if (!no_errors) // Not a silent skip of table { - const char *command=""; - if (want_access & SELECT_ACL) - command= "select"; - else if (want_access & INSERT_ACL) - command= "insert"; - else if (want_access & UPDATE_ACL) - command= "update"; - else if (want_access & DELETE_ACL) - command= "delete"; - else if (want_access & DROP_ACL) - command= "drop"; - else if (want_access & CREATE_ACL) - command= "create"; - else if (want_access & ALTER_ACL) - command= "alter"; - else if (want_access & INDEX_ACL) - command= "index"; - else if (want_access & GRANT_ACL) - command= "grant"; + char command[128]; + get_privilege_desc(command, sizeof(command), want_access); net_printf(thd,ER_TABLEACCESS_DENIED_ERROR, command, thd->priv_user, @@ -2906,11 +2907,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) err: rw_unlock(&LOCK_grant); err2: - const char *command= ""; - if (want_access & SELECT_ACL) - command= "select"; - else if (want_access & INSERT_ACL) - command= "insert"; + char command[128]; + get_privilege_desc(command, sizeof(command), want_access); my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, ER(ER_COLUMNACCESS_DENIED_ERROR), MYF(0),