diff options
Diffstat (limited to 'mysql-test/mysql-test-run.pl')
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 3416 |
1 files changed, 2326 insertions, 1090 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 44380a70218..1470a596e63 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1,30 +1,24 @@ #!/usr/bin/perl # -*- cperl -*- -# This is a transformation of the "mysql-test-run" Bourne shell script -# to Perl. There are reasons this rewrite is not the prettiest Perl -# you have seen # -# - The original script is huge and for most part uncommented, -# not even a usage description of the flags. +############################################################################## +# +# mysql-test-run.pl +# +# Tool used for executing a suite of .test file # -# - There has been an attempt to write a replacement in C for the -# original Bourne shell script. It was kind of working but lacked -# lot of functionality to really be a replacement. Not to redo -# that mistake and catch all the obscure features of the original -# script, the rewrite in Perl is more close to the original script -# meaning it also share some of the ugly parts as well. +# See the "MySQL Test framework manual" for more information +# http://dev.mysql.com/doc/mysqltest/en/index.html # -# - The original intention was that this script was to be a prototype -# to be the base for a new C version with full functionality. Since -# then it was decided that the Perl version should replace the -# Bourne shell version, but the Perl style still reflects the wish -# to make the Perl to C step easy. +# Please keep the test framework tools identical in all versions! +# +############################################################################## # -# Some coding style from the original intent has been kept +# Coding style directions for this perl script # # - To make this Perl script easy to alter even for those that not -# code Perl that often, the coding style is as close as possible to +# code Perl that often, keeep the coding style as close as possible to # the C/C++ MySQL coding standard. # # - All lists of arguments to send to commands are Perl lists/arrays, @@ -42,15 +36,6 @@ # the information. This separates the "find information" from the # "do the work" and makes the program more easy to maintain. # -# - At the moment, there are tons of "global" variables that control -# this script, even accessed from the files in "lib/*.pl". This -# will change over time, for now global variables are used instead -# of using %opt, %path and %exe hashes, because I want more -# compile time checking, that hashes would not give me. Once this -# script is debugged, hashes will be used and passed as parameters -# to functions, to more closely mimic how it would be coded in C -# using structs. -# # - The rule when it comes to the logic of this program is # # command_line_setup() - is to handle the logic between flags @@ -66,10 +51,6 @@ # "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 @@ -80,12 +61,20 @@ use File::Copy; use Cwd; use Getopt::Long; use Sys::Hostname; -#use Carp; use IO::Socket; use IO::Socket::INET; use Data::Dumper; use strict; -#use diagnostics; +use warnings; +use diagnostics; + +select(STDOUT); +$| = 1; # Automatically flush STDOUT + +our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl +our $glob_cygwin_perl= ($^O eq "cygwin"); # Cygwin Perl +our $glob_win32= ($glob_win32_perl or $glob_cygwin_perl); +our $glob_netware= ($^O eq "NetWare"); # NetWare require "lib/mtr_cases.pl"; require "lib/mtr_im.pl"; @@ -102,22 +91,6 @@ require "lib/mtr_stress.pl"; $Devel::Trace::TRACE= 1; -# Used by gcov -our @mysqld_src_dirs= - ( - "strings", - "mysys", - "include", - "extra", - "regex", - "isam", - "merge", - "myisam", - "myisammrg", - "heap", - "sql", - ); - ############################################################################## # # Default settings @@ -130,10 +103,7 @@ our @mysqld_src_dirs= # structs. We let each struct be a separate hash. # Misc global variables - -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 $mysql_version_id; our $glob_mysql_test_dir= undef; our $glob_mysql_bench_dir= undef; our $glob_hostname= undef; @@ -141,36 +111,38 @@ our $glob_scriptname= undef; our $glob_timers= undef; our $glob_use_running_server= 0; our $glob_use_running_ndbcluster= 0; +our $glob_use_running_ndbcluster_slave= 0; our $glob_use_embedded_server= 0; our @glob_test_mode; -our $using_ndbcluster_master= 0; - our $glob_basedir; -# The total result - our $path_charsetsdir; our $path_client_bindir; our $path_language; our $path_timefile; our $path_snapshot; -our $path_slave_load_tmpdir; # What is this?! our $path_mysqltest_log; our $path_current_test_log; our $path_my_basedir; + our $opt_vardir; # A path but set directly on cmd line -our $opt_vardir_trace; # unix formatted opt_vardir for trace files +our $path_vardir_trace; # unix formatted opt_vardir for trace files our $opt_tmpdir; # A path but set directly on cmd line +# Visual Studio produces executables in different sub-directories based on the +# configuration used to build them. To make life easier, an environment +# variable or command-line option may be specified to control which set of +# executables will be used by the test suite. +our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; + +our $default_vardir; + our $opt_usage; our $opt_suite; -our $opt_netware; - our $opt_script_debug= 0; # Script debugging, enable with --script-debug - -# Options FIXME not all.... +our $opt_verbose= 0; # Verbose output, enable with --verbose our $exe_master_mysqld; our $exe_mysql; @@ -178,12 +150,15 @@ our $exe_mysqladmin; our $exe_mysqlbinlog; our $exe_mysql_client_test; our $exe_mysqld; -our $exe_mysqlcheck; # Called from test case -our $exe_mysqldump; # Called from test case -our $exe_mysqlimport; # Called from test case -our $exe_mysqlshow; # Called from test case +our $exe_mysqlcheck; +our $exe_mysqldump; +our $exe_mysqlslap; +our $exe_mysqlimport; +our $exe_mysqlshow; our $exe_mysql_fix_system_tables; our $exe_mysqltest; +our $exe_ndbd; +our $exe_ndb_mgmd; our $exe_slave_mysqld; our $exe_im; our $exe_my_print_defaults; @@ -197,7 +172,6 @@ our $opt_big_test= 0; # Send --big-test to mysqltest our @opt_extra_mysqld_opt; -our $opt_comment; our $opt_compress; our $opt_ssl; our $opt_skip_ssl; @@ -214,7 +188,9 @@ our $opt_embedded_server; our $opt_extern; our $opt_fast; our $opt_force; -our $opt_reorder; +our $opt_reorder= 0; +our $opt_enable_disabled; +our $opt_mem; our $opt_gcov; our $opt_gcov_err; @@ -236,27 +212,24 @@ our $opt_gprof_dir; our $opt_gprof_master; our $opt_gprof_slave; -our $opt_local; -our $opt_local_master; - -our $master; # Will be struct in C +our $master; our $slave; +our $clusters; our $instance_manager; our $opt_ndbcluster_port; our $opt_ndbconnectstring; - -our $opt_old_master; +our $opt_ndbcluster_port_slave; +our $opt_ndbconnectstring_slave; our $opt_record; our $opt_check_testcases; -our $opt_result_ext; - our $opt_skip; our $opt_skip_rpl; our $max_slave_num= 0; +our $use_innodb; our $opt_skip_test; our $opt_skip_im; @@ -279,7 +252,7 @@ our $opt_start_from; our $opt_strace_client; -our $opt_timer; +our $opt_timer= 1; our $opt_user; our $opt_user_test; @@ -287,9 +260,10 @@ our $opt_user_test; our $opt_valgrind= 0; our $opt_valgrind_mysqld= 0; our $opt_valgrind_mysqltest= 0; -our $default_valgrind_options= "-v --show-reachable=yes"; +our $default_valgrind_options= "--show-reachable=yes"; our $opt_valgrind_options; our $opt_valgrind_path; +our $opt_callgrind; our $opt_stress= ""; our $opt_stress_suite= "main"; @@ -309,20 +283,31 @@ our $opt_warnings; our $opt_udiff; -our $opt_skip_ndbcluster; -our $opt_with_ndbcluster; -our $opt_with_ndbcluster_only= 0; # dummy, ignored - -our $opt_with_openssl; +our $opt_skip_ndbcluster= 0; +our $opt_skip_ndbcluster_slave= 0; +our $opt_with_ndbcluster= 0; +our $opt_with_ndbcluster_only= 0; +our $glob_ndbcluster_supported= 0; +our $opt_ndb_extra_test= 0; +our $opt_skip_master_binlog= 0; +our $opt_skip_slave_binlog= 0; our $exe_ndb_mgm; +our $exe_ndb_waiter; our $path_ndb_tools_dir; -our $path_ndb_data_dir; -our $file_ndb_testrun_log; -our $flag_ndb_status_ok= 1; +our $path_ndb_examples_dir; +our $exe_ndb_example; +our $path_ndb_testrun_log; our @data_dir_lst; +our $used_binlog_format; +our $debug_compiled_binaries; +our $glob_tot_real_time= 0; + +our %mysqld_variables; + + ###################################################################### # # Function declarations @@ -332,30 +317,36 @@ our @data_dir_lst; sub main (); sub initial_setup (); sub command_line_setup (); -sub snapshot_setup (); +sub datadir_setup (); sub executable_setup (); sub environment_setup (); -sub kill_running_server (); +sub kill_running_servers (); sub cleanup_stale_files (); -sub check_ssl_support (); +sub check_ssl_support ($); sub check_running_as_root(); -sub check_ndbcluster_support (); -sub ndbcluster_install (); -sub ndbcluster_start ($); -sub ndbcluster_stop (); +sub check_ndbcluster_support ($); +sub rm_ndbcluster_tables ($); +sub ndbcluster_start_install ($); +sub ndbcluster_start ($$); +sub ndbcluster_wait_started ($$); +sub mysqld_wait_started($); sub run_benchmarks ($); sub initialize_servers (); sub mysql_install_db (); sub install_db ($$); +sub copy_install_db ($$); sub run_testcase ($); +sub run_testcase_stop_servers ($$$); +sub run_testcase_start_servers ($); +sub run_testcase_check_skip_test($); sub report_failure_and_restart ($); -sub do_before_start_master ($$); -sub do_before_start_slave ($$); -sub mysqld_start ($$$$$); -sub mysqld_arguments ($$$$$$); -sub stop_masters_slaves (); -sub stop_masters (); -sub stop_slaves (); +sub do_before_start_master ($); +sub do_before_start_slave ($); +sub ndbd_start ($$$); +sub ndb_mgmd_start ($); +sub mysqld_start ($$$); +sub mysqld_arguments ($$$$$); +sub stop_all_servers (); sub run_mysqltest ($); sub usage ($); @@ -369,12 +360,13 @@ main(); sub main () { - initial_setup(); command_line_setup(); - executable_setup(); - check_ndbcluster_support(); # We check whether to actually use it later - check_ssl_support(); + check_ndbcluster_support(\%mysqld_variables); + check_ssl_support(\%mysqld_variables); + check_debug_support(\%mysqld_variables); + + executable_setup(); environment_setup(); signal_setup(); @@ -408,6 +400,8 @@ sub main () { my ($need_ndbcluster,$need_im); foreach my $test (@$tests) { + next if $test->{skip}; + $need_ndbcluster||= $test->{ndb_test}; $need_im||= $test->{component_id} eq 'im'; @@ -417,75 +411,37 @@ sub main () { $max_slave_num= $test->{slave_num}; mtr_error("Too many slaves") if $max_slave_num > 3; } + $use_innodb||= $test->{'innodb_test'}; } - $opt_with_ndbcluster= 0 unless $need_ndbcluster; - $opt_skip_im= 1 unless $need_im; - - snapshot_setup(); - initialize_servers(); - - run_suite($opt_suite, $tests); - } - - mtr_exit(0); -} -############################################################################## -# -# Initial setup independent on command line arguments -# -############################################################################## - -sub initial_setup () { - - select(STDOUT); - $| = 1; # Make unbuffered - - $glob_scriptname= basename($0); - - $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 + # Check if cluster can be skipped + if ( !$need_ndbcluster ) + { + $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster_slave= 1; + } - if (! -f $glob_scriptname) - { - mtr_error("Can't find the location for the mysql-test-run script\n" . - "Go to to the mysql-test directory and execute the script " . - "as follows:\n./$glob_scriptname"); - } + # Check if slave cluster can be skipped + if ($max_slave_num == 0) + { + $opt_skip_ndbcluster_slave= 1; + } - if ( -d "../sql" ) - { - $opt_source_dist= 1; - } + # Check if im can be skipped + if ( ! $need_im ) + { + $opt_skip_im= 1; + } - $glob_hostname= mtr_short_hostname(); + initialize_servers(); - # '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); + run_suite($opt_suite, $tests); } - $glob_basedir= dirname($glob_mysql_test_dir); - $glob_mysql_bench_dir= "$glob_basedir/mysql-bench"; # FIXME make configurable - # needs to be same length to test logging (FIXME what???) - $path_slave_load_tmpdir= "../../var/tmp"; - - $path_my_basedir= - $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; - - $glob_timers= mtr_init_timers(); + mtr_exit(0); } - ############################################################################## # # Default settings @@ -497,12 +453,15 @@ sub command_line_setup () { # These are defaults for things that are set on the command line $opt_suite= "main"; # Special default suite - my $opt_master_myport= 9306; - my $opt_slave_myport= 9308; - $opt_ndbcluster_port= 9350; - my $im_port= 9311; - my $im_mysqld1_port= 9312; - my $im_mysqld2_port= 9314; + my $opt_comment; + + my $opt_master_myport= 9306; + my $opt_slave_myport= 9308; + $opt_ndbcluster_port= 9310; + $opt_ndbcluster_port_slave= 9311; + my $im_port= 9312; + my $im_mysqld1_port= 9313; + my $im_mysqld2_port= 9314; # # To make it easier for different devs to work on the same host, @@ -521,12 +480,13 @@ sub command_line_setup () { if ( $ENV{'MTR_BUILD_THREAD'} ) { # Up to two masters, up to three slaves - $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 10 + 10000; # and 1 - $opt_slave_myport= $opt_master_myport + 2; # and 3 4 - $opt_ndbcluster_port= $opt_master_myport + 5; - $im_port= $opt_master_myport + 6; - $im_mysqld1_port= $opt_master_myport + 7; - $im_mysqld2_port= $opt_master_myport + 8; + $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 10 + 10000; # and 1 + $opt_slave_myport= $opt_master_myport + 2; # and 3 4 + $opt_ndbcluster_port= $opt_master_myport + 5; + $opt_ndbcluster_port_slave= $opt_master_myport + 6; + $im_port= $opt_master_myport + 7; + $im_mysqld1_port= $opt_master_myport + 8; + $im_mysqld2_port= $opt_master_myport + 9; } if ( $opt_master_myport < 5001 or $opt_master_myport + 10 >= 32767 ) @@ -557,22 +517,31 @@ sub command_line_setup () { 'compress' => \$opt_compress, 'bench' => \$opt_bench, 'small-bench' => \$opt_small_bench, + 'with-ndbcluster' => \$opt_with_ndbcluster, + 'vs-config' => \$opt_vs_config, # Control what test suites or cases to run 'force' => \$opt_force, - 'with-ndbcluster' => \$opt_with_ndbcluster, - 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, 'with-ndbcluster-only' => \$opt_with_ndbcluster_only, + 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, + 'skip-ndbcluster-slave|skip-ndb-slave' + => \$opt_skip_ndbcluster_slave, + 'ndb-extra-test' => \$opt_ndb_extra_test, + 'skip-master-binlog' => \$opt_skip_master_binlog, + 'skip-slave-binlog' => \$opt_skip_slave_binlog, 'do-test=s' => \$opt_do_test, + 'start-from=s' => \$opt_start_from, 'suite=s' => \$opt_suite, 'skip-rpl' => \$opt_skip_rpl, 'skip-im' => \$opt_skip_im, 'skip-test=s' => \$opt_skip_test, + 'big-test' => \$opt_big_test, # Specify ports 'master_port=i' => \$opt_master_myport, 'slave_port=i' => \$opt_slave_myport, - 'ndbcluster_port=i' => \$opt_ndbcluster_port, + 'ndbcluster-port|ndbcluster_port=i' => \$opt_ndbcluster_port, + 'ndbcluster-port-slave=i' => \$opt_ndbcluster_port_slave, 'im-port=i' => \$im_port, # Instance Manager port. 'im-mysqld1-port=i' => \$im_mysqld1_port, # Port of mysqld, controlled by IM 'im-mysqld2-port=i' => \$im_mysqld2_port, # Port of mysqld, controlled by IM @@ -581,12 +550,13 @@ sub command_line_setup () { 'record' => \$opt_record, 'check-testcases' => \$opt_check_testcases, - # ??? + # Extra options used when starting mysqld 'mysqld=s' => \@opt_extra_mysqld_opt, # Run test on running server 'extern' => \$opt_extern, - 'ndbconnectstring=s' => \$opt_ndbconnectstring, + 'ndb-connectstring=s' => \$opt_ndbconnectstring, + 'ndb-connectstring-slave=s' => \$opt_ndbconnectstring_slave, # Debugging 'gdb' => \$opt_gdb, @@ -609,6 +579,7 @@ sub command_line_setup () { 'valgrind-mysqld' => \$opt_valgrind_mysqld, 'valgrind-options=s' => \$opt_valgrind_options, 'valgrind-path=s' => \$opt_valgrind_path, + 'callgrind' => \$opt_callgrind, # Stress testing 'stress' => \$opt_stress, @@ -624,24 +595,22 @@ sub command_line_setup () { # Directories 'tmpdir=s' => \$opt_tmpdir, 'vardir=s' => \$opt_vardir, + 'benchdir=s' => \$glob_mysql_bench_dir, + 'mem' => \$opt_mem, # Misc - 'big-test' => \$opt_big_test, 'comment=s' => \$opt_comment, 'debug' => \$opt_debug, 'fast' => \$opt_fast, - 'local' => \$opt_local, - 'local-master' => \$opt_local_master, - 'netware' => \$opt_netware, - 'old-master' => \$opt_old_master, 'reorder' => \$opt_reorder, + 'enable-disabled' => \$opt_enable_disabled, 'script-debug' => \$opt_script_debug, + 'verbose' => \$opt_verbose, 'sleep=i' => \$opt_sleep, 'socket=s' => \$opt_socket, 'start-dirty' => \$opt_start_dirty, 'start-and-exit' => \$opt_start_and_exit, - 'start-from=s' => \$opt_start_from, - 'timer' => \$opt_timer, + 'timer!' => \$opt_timer, 'unified-diff|udiff' => \$opt_udiff, 'user-test=s' => \$opt_user_test, 'user=s' => \$opt_user, @@ -653,11 +622,70 @@ sub command_line_setup () { 'help|h' => \$opt_usage, ) or usage("Can't read options"); - if ( $opt_usage ) + usage("") if $opt_usage; + + $glob_scriptname= basename($0); + + # We require that we are in the "mysql-test" directory + # to run mysql-test-run + if (! -f $glob_scriptname) + { + mtr_error("Can't find the location for the mysql-test-run script\n" . + "Go to to the mysql-test directory and execute the script " . + "as follows:\n./$glob_scriptname"); + } + + if ( -d "../sql" ) { - usage(""); + $opt_source_dist= 1; } + $glob_hostname= mtr_short_hostname(); + + # '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); + + # Expect mysql-bench to be located adjacent to the source tree, by default + $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench" + unless defined $glob_mysql_bench_dir; + + $path_my_basedir= + $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; + + $glob_timers= mtr_init_timers(); + + # + # Find the mysqld executable to be able to find the mysqld version + # number as early as possible + # + + # Look for the client binaries + $path_client_bindir= mtr_path_exists(vs_config_dirs('client', ''), + "$glob_basedir/client_release", + "$glob_basedir/client_debug", + "$glob_basedir/client"); + + $exe_mysqld= mtr_exe_exists (vs_config_dirs('sql', 'mysqld'), + "$glob_basedir/sql/mysqld", + "$path_client_bindir/mysqld-max-nt", + "$path_client_bindir/mysqld-max", + "$path_client_bindir/mysqld-nt", + "$path_client_bindir/mysqld", + "$path_client_bindir/mysqld-debug", + "$path_client_bindir/mysqld-max", + "$glob_basedir/libexec/mysqld", + "$glob_basedir/bin/mysqld"); + + # Use the mysqld found above to find out what features are available + collect_mysqld_features(); + if ( $opt_comment ) { print "\n"; @@ -666,11 +694,6 @@ sub command_line_setup () { print '#' x 78, "\n\n"; } - if ( $opt_with_ndbcluster_only ) - { - print "# Option '--with-ndbcluster-only' is ignored in this release.\n"; - } - foreach my $arg ( @ARGV ) { if ( $arg =~ /^--skip-/ ) @@ -694,16 +717,77 @@ sub command_line_setup () { } # -------------------------------------------------------------------------- - # Set the "var/" directory, as it is the base for everything else + # Find out type of logging that are being used # -------------------------------------------------------------------------- + # NOTE if the default binlog format is changed, this has to be changed + $used_binlog_format= "stmt"; + if ( $mysql_version_id >= 50100 ) + { + $used_binlog_format= "mixed"; # Default value for binlog format + foreach my $arg ( @opt_extra_mysqld_opt ) + { + if ( $arg =~ /binlog-format=(\S+)/ ) + { + $used_binlog_format= $1; + } + } + mtr_report("Using binlog format '$used_binlog_format'"); + } + + # -------------------------------------------------------------------------- + # Check if we should speed up tests by trying to run on tmpfs + # -------------------------------------------------------------------------- + if ( $opt_mem ) + { + mtr_error("Can't use --mem and --vardir at the same time ") + if $opt_vardir; + mtr_error("Can't use --mem and --tmpdir at the same time ") + if $opt_tmpdir; + + # Use /dev/shm as the preferred location for vardir and + # thus implicitly also tmpdir. Add other locations to list + my @tmpfs_locations= ("/dev/shm"); + # One could maybe use "mount" to find tmpfs location(s) + foreach my $fs (@tmpfs_locations) + { + if ( -d $fs ) + { + mtr_report("Using tmpfs in $fs"); + $opt_mem= "$fs/var"; + $opt_mem .= $ENV{'MTR_BUILD_THREAD'} if $ENV{'MTR_BUILD_THREAD'}; + last; + } + } + } + + # -------------------------------------------------------------------------- + # Set the "var/" directory, as it is the base for everything else + # -------------------------------------------------------------------------- + $default_vardir= "$glob_mysql_test_dir/var"; if ( ! $opt_vardir ) { - $opt_vardir= "$glob_mysql_test_dir/var"; + $opt_vardir= $default_vardir; + } + elsif ( $mysql_version_id < 50000 and + $opt_vardir ne $default_vardir) + { + # Version 4.1 and --vardir was specified + # Only supported as a symlink from var/ + # by setting up $opt_mem that symlink will be created + if ( ! $glob_win32 ) + { + # Only platforms that have native symlinks can use the vardir trick + $opt_mem= $opt_vardir; + mtr_report("Using 4.1 vardir trick"); + } + + $opt_vardir= $default_vardir; } - $opt_vardir_trace= $opt_vardir; + + $path_vardir_trace= $opt_vardir; # Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/... - $opt_vardir_trace=~ s/^\w://; + $path_vardir_trace=~ s/^\w://; # We make the path absolute, as the server will do a chdir() before usage unless ( $opt_vardir =~ m,^/, or @@ -714,42 +798,53 @@ sub command_line_setup () { } # -------------------------------------------------------------------------- - # If not set, set these to defaults + # Set tmpdir # -------------------------------------------------------------------------- - $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir; $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any # -------------------------------------------------------------------------- - # Do sanity checks of command line arguments + # Set socket # -------------------------------------------------------------------------- + if (!$opt_socket) + { + $opt_socket= $mysqld_variables{'socket'}; + } - if ( $opt_extern and $opt_local ) + # -------------------------------------------------------------------------- + # Check im suport + # -------------------------------------------------------------------------- + if ( $mysql_version_id < 50000 ) { - mtr_error("Can't use --extern and --local at the same time"); + # Instance manager is not supported until 5.0 + $opt_skip_im= 1; + } - if ( ! $opt_socket ) - { # FIXME set default before reading options? -# $opt_socket= '@MYSQL_UNIX_ADDR@'; - $opt_socket= "/tmp/mysql.sock"; # FIXME + if ( $glob_win32 ) + { + mtr_report("Disable Instance manager - not supported on Windows"); + $opt_skip_im= 1; } # -------------------------------------------------------------------------- - # Look at the command line options and set script flags + # Record flag # -------------------------------------------------------------------------- - if ( $opt_record and ! @opt_cases ) { mtr_error("Will not run in record mode without a specific test case"); } + # -------------------------------------------------------------------------- + # Embedded server flag + # -------------------------------------------------------------------------- if ( $opt_embedded_server ) { $glob_use_embedded_server= 1; push(@glob_test_mode, "embedded"); $opt_skip_rpl= 1; # We never run replication with embedded - $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster + $opt_skip_ssl= 1; # Turn off use of SSL if ( $opt_extern ) { @@ -757,33 +852,80 @@ sub command_line_setup () { } } + + # -------------------------------------------------------------------------- + # ps protcol flag + # -------------------------------------------------------------------------- if ( $opt_ps_protocol ) { push(@glob_test_mode, "ps-protocol"); } - # FIXME don't understand what this is -# if ( $opt_local_master ) -# { -# $opt_master_myport= 3306; -# } + # -------------------------------------------------------------------------- + # Ndb cluster flags + # -------------------------------------------------------------------------- + if ( $opt_with_ndbcluster and !$opt_bench) + { + mtr_error("Can only use --with-ndbcluster togheter with --bench"); + } + if ( $opt_ndbconnectstring ) + { + $glob_use_running_ndbcluster= 1; + mtr_error("Can't specify --ndb-connectstring and --skip-ndbcluster") + if $opt_skip_ndbcluster; + mtr_error("Can't specify --ndb-connectstring and --ndbcluster-port") + if $opt_ndbcluster_port; + } + else + { + # Set default connect string + $opt_ndbconnectstring= "host=localhost:$opt_ndbcluster_port"; + } + + if ( $opt_ndbconnectstring_slave ) + { + $glob_use_running_ndbcluster_slave= 1; + mtr_error("Can't specify ndb-connectstring_slave and " . + "--skip-ndbcluster-slave") + if $opt_skip_ndbcluster; + mtr_error("Can't specify --ndb-connectstring-slave and " . + "--ndbcluster-port-slave") + if $opt_ndbcluster_port_slave; + } + else + { + # Set default connect string + $opt_ndbconnectstring_slave= "host=localhost:$opt_ndbcluster_port_slave"; + } + + # -------------------------------------------------------------------------- + # Bench flags + # -------------------------------------------------------------------------- if ( $opt_small_bench ) { $opt_bench= 1; } + # -------------------------------------------------------------------------- + # Sleep flag + # -------------------------------------------------------------------------- if ( $opt_sleep ) { $opt_sleep_time_after_restart= $opt_sleep; } + # -------------------------------------------------------------------------- + # Gcov flag + # -------------------------------------------------------------------------- if ( $opt_gcov and ! $opt_source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } + # -------------------------------------------------------------------------- # Check debug related options + # -------------------------------------------------------------------------- if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd || $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug || $opt_debugger || $opt_client_debugger ) @@ -798,29 +940,15 @@ sub command_line_setup () { } } - if ( $opt_ndbconnectstring ) - { - $glob_use_running_ndbcluster= 1; - $opt_with_ndbcluster= 1; - } - else - { - $opt_ndbconnectstring= "host=localhost:$opt_ndbcluster_port"; - } - - if ( $opt_skip_ndbcluster ) - { - $opt_with_ndbcluster= 0; - } - - # Check IM arguments - if ( $glob_win32 ) - { - mtr_report("Disable Instance manager - not supported on Windows"); - $opt_skip_im= 1; - } + # -------------------------------------------------------------------------- + # Check if special exe was selected for master or slave + # -------------------------------------------------------------------------- + $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; + $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; + # -------------------------------------------------------------------------- # Check valgrind arguments + # -------------------------------------------------------------------------- if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options) { mtr_report("Turning on valgrind for all executables"); @@ -835,10 +963,21 @@ sub command_line_setup () { } elsif ( $opt_valgrind_mysqltest ) { - mtr_report("Turning on valgrind for mysqltest only"); + mtr_report("Turning on valgrind for mysqltest and mysql_client_test only"); $opt_valgrind= 1; } + if ( $opt_callgrind ) + { + mtr_report("Turning on valgrind with callgrind for mysqld(s)"); + $opt_valgrind= 1; + $opt_valgrind_mysqld= 1; + + # Set special valgrind options unless options passed on command line + $opt_valgrind_options="--trace-children=yes" + unless defined $opt_valgrind_options; + } + if ( $opt_valgrind ) { # Set valgrind_options to default unless already defined @@ -889,59 +1028,83 @@ sub command_line_setup () { $master->[0]= { + pid => 0, + type => "master", + idx => 0, path_myddir => "$opt_vardir/master-data", path_myerr => "$opt_vardir/log/master.err", path_mylog => "$opt_vardir/log/master.log", - path_mypid => "$opt_vardir/run/master.pid", - path_mysock => "$sockdir/master.sock", - path_myport => $opt_master_myport, + path_pid => "$opt_vardir/run/master.pid", + path_sock => "$sockdir/master.sock", + port => $opt_master_myport, start_timeout => 400, # enough time create innodb tables - - ndbcluster => 1, # ndbcluster not started + cluster => 0, # index in clusters list + start_opts => [], }; $master->[1]= { + pid => 0, + type => "master", + idx => 1, path_myddir => "$opt_vardir/master1-data", path_myerr => "$opt_vardir/log/master1.err", path_mylog => "$opt_vardir/log/master1.log", - path_mypid => "$opt_vardir/run/master1.pid", - path_mysock => "$sockdir/master1.sock", - path_myport => $opt_master_myport + 1, + path_pid => "$opt_vardir/run/master1.pid", + path_sock => "$sockdir/master1.sock", + port => $opt_master_myport + 1, start_timeout => 400, # enough time create innodb tables + cluster => 0, # index in clusters list + start_opts => [], }; $slave->[0]= { + pid => 0, + type => "slave", + idx => 0, path_myddir => "$opt_vardir/slave-data", path_myerr => "$opt_vardir/log/slave.err", path_mylog => "$opt_vardir/log/slave.log", - path_mypid => "$opt_vardir/run/slave.pid", - path_mysock => "$sockdir/slave.sock", - path_myport => $opt_slave_myport, + path_pid => "$opt_vardir/run/slave.pid", + path_sock => "$sockdir/slave.sock", + port => $opt_slave_myport, start_timeout => 400, + + cluster => 1, # index in clusters list + start_opts => [], }; $slave->[1]= { + pid => 0, + type => "slave", + idx => 1, path_myddir => "$opt_vardir/slave1-data", path_myerr => "$opt_vardir/log/slave1.err", path_mylog => "$opt_vardir/log/slave1.log", - path_mypid => "$opt_vardir/run/slave1.pid", - path_mysock => "$sockdir/slave1.sock", - path_myport => $opt_slave_myport + 1, + path_pid => "$opt_vardir/run/slave1.pid", + path_sock => "$sockdir/slave1.sock", + port => $opt_slave_myport + 1, start_timeout => 300, + cluster => -1, # index in clusters list + start_opts => [], }; $slave->[2]= { + pid => 0, + type => "slave", + idx => 2, path_myddir => "$opt_vardir/slave2-data", path_myerr => "$opt_vardir/log/slave2.err", path_mylog => "$opt_vardir/log/slave2.log", - path_mypid => "$opt_vardir/run/slave2.pid", - path_mysock => "$sockdir/slave2.sock", - path_myport => $opt_slave_myport + 2, + path_pid => "$opt_vardir/run/slave2.pid", + path_sock => "$sockdir/slave2.sock", + port => $opt_slave_myport + 2, start_timeout => 300, + cluster => -1, # index in clusters list + start_opts => [], }; $instance_manager= @@ -967,7 +1130,8 @@ sub command_line_setup () { path_datadir => "$opt_vardir/im_mysqld_1.data", path_sock => "$sockdir/mysqld_1.sock", path_pid => "$opt_vardir/run/mysqld_1.pid", - start_timeout => 400, # enough time create innodb tables + start_timeout => 400, # enough time create innodb tables + old_log_format => 1 }; $instance_manager->{'instances'}->[1]= @@ -978,24 +1142,68 @@ sub command_line_setup () { path_sock => "$sockdir/mysqld_2.sock", path_pid => "$opt_vardir/run/mysqld_2.pid", nonguarded => 1, - start_timeout => 400, # enough time create innodb tables + start_timeout => 400, # enough time create innodb tables + old_log_format => 1 }; + my $data_dir= "$opt_vardir/ndbcluster-$opt_ndbcluster_port"; + $clusters->[0]= + { + name => "Master", + nodes => 2, + port => "$opt_ndbcluster_port", + data_dir => "$data_dir", + connect_string => "$opt_ndbconnectstring", + path_pid => "$data_dir/ndb_3.pid", # Nodes + 1 + pid => 0, # pid of ndb_mgmd + installed_ok => 0, + }; + + $data_dir= "$opt_vardir/ndbcluster-$opt_ndbcluster_port_slave"; + $clusters->[1]= + { + name => "Slave", + nodes => 1, + port => "$opt_ndbcluster_port_slave", + data_dir => "$data_dir", + connect_string => "$opt_ndbconnectstring_slave", + path_pid => "$data_dir/ndb_2.pid", # Nodes + 1 + pid => 0, # pid of ndb_mgmd + installed_ok => 0, + }; + + # Init pids of ndbd's + foreach my $cluster ( @{$clusters} ) + { + for ( my $idx= 0; $idx < $cluster->{'nodes'}; $idx++ ) + { + my $nodeid= $idx+1; + $cluster->{'ndbds'}->[$idx]= + { + pid => 0, + nodeid => $nodeid, + path_pid => "$cluster->{'data_dir'}/ndb_${nodeid}.pid", + path_fs => "$cluster->{'data_dir'}/ndb_${nodeid}_fs", + }; + } + } + if ( $opt_extern ) { $glob_use_running_server= 1; $opt_skip_rpl= 1; # We don't run rpl test cases - $master->[0]->{'path_mysock'}= $opt_socket; + $master->[0]->{'path_sock'}= $opt_socket; } $path_timefile= "$opt_vardir/log/mysqltest-time"; $path_mysqltest_log= "$opt_vardir/log/mysqltest.log"; $path_current_test_log= "$opt_vardir/log/current_test"; + $path_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log"; $path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/"; } -sub snapshot_setup () { +sub datadir_setup () { # Make a list of all data_dirs @data_dir_lst = ( @@ -1023,6 +1231,135 @@ sub snapshot_setup () { # ############################################################################## + +sub collect_mysqld_features () { + # + # Execute "mysqld --no-defaults --help --verbose", that will + # print out version and a list of all features and settings + # + my $found_variable_list_start= 0; + my $spec_file= "$glob_mysql_test_dir/mysqld.spec.$$"; + if ( mtr_run($exe_mysqld, + ["--no-defaults", + "--verbose", + "--help"], + "", "$spec_file", "$spec_file", "") != 0 ) + { + mtr_error("Failed to get version and list of features from %s", + $exe_mysqld); + } + + my $F= IO::File->new($spec_file) or + mtr_error("can't open file \"$spec_file\": $!"); + + while ( my $line= <$F> ) + { + # First look for version + if ( !$mysql_version_id ) + { + # Look for version + my $exe_name= basename($exe_mysqld); + mtr_verbose("exe_name: $exe_name"); + if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ ) + { + #print "Major: $1 Minor: $2 Build: $3\n"; + $mysql_version_id= $1*10000 + $2*100 + $3; + #print "mysql_version_id: $mysql_version_id\n"; + mtr_report("MySQL Version $1.$2.$3"); + } + } + else + { + if (!$found_variable_list_start) + { + # Look for start of variables list + if ( $line =~ /[\-]+\s[\-]+/ ) + { + $found_variable_list_start= 1; + } + } + else + { + # Put variables into hash + if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) + { + # print "$1=\"$2\"\n"; + $mysqld_variables{$1}= $2; + } + else + { + # The variable list is ended with a blank line + if ( $line =~ /^[\s]*$/ ) + { + last; + } + else + { + # Send out a warning, we should fix the variables that has no + # space between variable name and it's value + # or should it be fixed width column parsing? It does not + # look like that in function my_print_variables in my_getopt.c + mtr_warning("Could not parse variable list line : $line"); + } + } + } + } + } + unlink($spec_file); + mtr_error("Could not find version of MySQL") unless $mysql_version_id; + mtr_error("Could not find variabes list") unless $found_variable_list_start; + +} + + +sub executable_setup_im () { + + # Look for instance manager binary - mysqlmanager + $exe_im= + mtr_exe_maybe_exists( + "$glob_basedir/server-tools/instance-manager/mysqlmanager", + "$glob_basedir/libexec/mysqlmanager"); + + return ($exe_im eq ""); +} + +sub executable_setup_ndb () { + + # Look for ndb tols and binaries + my $ndb_path= mtr_file_exists("$glob_basedir/ndb", + "$glob_basedir/storage/ndb", + "$glob_basedir/bin"); + + $exe_ndbd= + mtr_exe_maybe_exists("$ndb_path/src/kernel/ndbd", + "$ndb_path/ndbd"); + $exe_ndb_mgm= + mtr_exe_maybe_exists("$ndb_path/src/mgmclient/ndb_mgm", + "$ndb_path/ndb_mgm"); + $exe_ndb_mgmd= + mtr_exe_maybe_exists("$ndb_path/src/mgmsrv/ndb_mgmd", + "$ndb_path/ndb_mgmd"); + $exe_ndb_waiter= + mtr_exe_maybe_exists("$ndb_path/tools/ndb_waiter", + "$ndb_path/ndb_waiter"); + + # May not exist + $path_ndb_tools_dir= mtr_file_exists("$ndb_path/tools", + "$ndb_path"); + # May not exist + $path_ndb_examples_dir= + mtr_file_exists("$ndb_path/ndbapi-examples", + "$ndb_path/examples"); + # May not exist + $exe_ndb_example= + mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + + return ( $exe_ndbd eq "" or + $exe_ndb_mgm eq "" or + $exe_ndb_mgmd eq "" or + $exe_ndb_waiter eq ""); +} + sub executable_setup () { # @@ -1040,164 +1377,167 @@ sub executable_setup () { } } - if ( $opt_source_dist ) - { - if ( $glob_win32 ) - { - $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", - "$glob_basedir/client_debug", - "$glob_basedir/client/release", - "$glob_basedir/client/debug", - "$glob_basedir/bin",); - $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-max-nt", - "$path_client_bindir/mysqld-max", - "$path_client_bindir/mysqld-nt", - "$path_client_bindir/mysqld", - "$path_client_bindir/mysqld-debug", - "$path_client_bindir/mysqld-max", - "$glob_basedir/sql/release/mysqld", - "$glob_basedir/sql/debug/mysqld"); - $path_language= mtr_path_exists("$glob_basedir/share/english/", - "$glob_basedir/sql/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets", - "$glob_basedir/sql/share/charsets/"); - $exe_my_print_defaults= - mtr_exe_exists("$path_client_bindir/my_print_defaults", - "$glob_basedir/extra/release/my_print_defaults", - "$glob_basedir/extra/debug/my_print_defaults"); - $exe_perror= - mtr_exe_exists("$path_client_bindir/perror", - "$glob_basedir/extra/release/perror", - "$glob_basedir/extra/debug/perror"); - } - else - { - $path_client_bindir= mtr_path_exists("$glob_basedir/client"); - $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld"); - $path_language= mtr_path_exists("$glob_basedir/sql/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/sql/share/charsets"); + # Look for language files and charsetsdir, use same share + my $path_share= mtr_path_exists("$glob_basedir/share/mysql", + "$glob_basedir/sql/share", + "$glob_basedir/share"); - $exe_im= mtr_exe_exists( - "$glob_basedir/server-tools/instance-manager/mysqlmanager"); - $exe_my_print_defaults= - mtr_exe_exists("$glob_basedir/extra/my_print_defaults"); - $exe_perror= - mtr_exe_exists("$glob_basedir/extra/perror"); - } + $path_language= mtr_path_exists("$path_share/english"); + $path_charsetsdir= mtr_path_exists("$path_share/charsets"); - if ( $glob_use_embedded_server ) - { - my $path_examples= "$glob_basedir/libmysqld/examples"; - $exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest_embedded"); - $exe_mysql_client_test= - mtr_exe_exists("$path_examples/mysql_client_test_embedded", - "/usr/bin/false"); - } - else - { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test", - "$path_client_bindir/mysql_client_test", - "$glob_basedir/tests/release/mysql_client_test", - "$glob_basedir/tests/debug/mysql_client_test", - "$path_client_bindir/mysql_client_test", - "/usr/bin/false"); - } - $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); - $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); - $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); - $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); - $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); - $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); - $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); - $exe_mysql_fix_system_tables= - mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", - "/usr/bin/false"); - $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools"); - $exe_ndb_mgm= "$glob_basedir/ndb/src/mgmclient/ndb_mgm"; - $lib_udf_example= - mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so", - "$glob_basedir/sql/release/udf_example.dll", - "$glob_basedir/sql/debug/udf_example.dll"); + # Look for my_print_defaults + $exe_my_print_defaults= + mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'), + "$path_client_bindir/my_print_defaults", + "$glob_basedir/extra/my_print_defaults"); + + # Look for perror + $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'), + "$glob_basedir/extra/perror", + "$path_client_bindir/perror"); + + # Look for the client binaries + $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); + $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); + $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); + $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); + $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); + $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); + $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); + if ( $mysql_version_id >= 50100 ) + { + $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap"); } - else + + if ( ! $glob_win32 ) { - $path_client_bindir= mtr_path_exists("$glob_basedir/bin"); - $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); - $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); - $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); - $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); - $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); - $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); - $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); + # Look for mysql_fix_system_table script $exe_mysql_fix_system_tables= - mtr_script_exists("$path_client_bindir/mysql_fix_privilege_tables", - "$glob_basedir/scripts/mysql_fix_privilege_tables", - "/usr/bin/false"); - $exe_my_print_defaults= - mtr_exe_exists("$path_client_bindir/my_print_defaults"); - $exe_perror= - mtr_exe_exists("$path_client_bindir/perror"); + mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", + "$path_client_bindir/mysql_fix_privilege_tables"); + } - $path_language= mtr_path_exists("$glob_basedir/share/mysql/english/", - "$glob_basedir/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets", - "$glob_basedir/share/charsets"); - if ( $glob_win32 ) - { - $exe_mysqld= mtr_exe_exists ("$glob_basedir/bin/mysqld-nt", - "$glob_basedir/bin/mysqld", - "$glob_basedir/bin/mysqld-debug",); - } - else - { - $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld", - "$glob_basedir/bin/mysqld"); - } - $exe_im= mtr_exe_exists("$glob_basedir/libexec/mysqlmanager", - "$glob_basedir/bin/mysqlmanager"); - if ( $glob_use_embedded_server ) - { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest_embedded"); - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test_embedded", - "$path_client_bindir/mysql_client_test_embedded", - "/usr/bin/false"); - } - else + if ( ! $opt_skip_ndbcluster and executable_setup_ndb()) + { + mtr_warning("Could not find all required ndb binaries, " . + "all ndb tests will fail, use --skip-ndbcluster to " . + "skip testing it."); + + foreach my $cluster (@{$clusters}) { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest", - "$glob_basedir/client/release/mysqltest", - "$glob_basedir/client/debug/mysqltest"); - $exe_mysql_client_test= - mtr_exe_exists("$path_client_bindir/mysql_client_test", - "/usr/bin/false"); # FIXME temporary + $cluster->{"executable_setup_failed"}= 1; } + } - $path_ndb_tools_dir= "$glob_basedir/bin"; - $exe_ndb_mgm= "$glob_basedir/bin/ndb_mgm"; + if ( ! $opt_skip_im and executable_setup_im()) + { + mtr_warning("Could not find all required instance manager binaries, " . + "all im tests will fail, use --skip-im to " . + "continue without instance manager"); + $instance_manager->{"executable_setup_failed"}= 1; } - $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; - $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; + # Look for the udf_example library + $lib_udf_example= + mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'), + "$glob_basedir/sql/.libs/udf_example.so",); - $path_ndb_data_dir= "$opt_vardir/ndbcluster-$opt_ndbcluster_port"; - $file_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log"; + # Look for mysqltest executable + if ( $glob_use_embedded_server ) + { + $exe_mysqltest= + mtr_exe_exists(vs_config_dirs('libmysqld/examples', 'mysqltest_embedded'), + "$glob_basedir/libmysqld/examples/mysqltest_embedded", + "$path_client_bindir/mysqltest_embedded"); + } + else + { + $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); + } + + # Look for mysql_client_test executable which may _not_ exist in + # some versions, test using it should be skipped + if ( $glob_use_embedded_server ) + { + $exe_mysql_client_test= + mtr_exe_maybe_exists( + vs_config_dirs('libmysqld/examples', 'mysql_client_test_embedded'), + "$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); + } + else + { + $exe_mysql_client_test= + mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'), + "$glob_basedir/tests/mysql_client_test", + "$glob_basedir/bin"); + } +} + + +sub generate_cmdline_mysqldump ($) { + my($mysqld) = @_; + return + "$exe_mysqldump --no-defaults -uroot " . + "--port=$mysqld->{'port'} " . + "--socket=$mysqld->{'path_sock'} --password="; } ############################################################################## # -# Set environment to be used by childs of this process +# Set environment to be used by childs of this process for +# things that are constant duting the whole lifetime of mysql-test-run.pl # ############################################################################## +sub mysql_client_test_arguments() +{ + my $exe= $exe_mysql_client_test; + + my $args; + mtr_init_args(\$args); + if ( $opt_valgrind_mysqltest ) + { + valgrind_arguments($args, \$exe); + } + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--testcase"); + mtr_add_arg($args, "--user=root"); + mtr_add_arg($args, "--port=$master->[0]->{'port'}"); + mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}"); + + if ( $mysql_version_id >= 50000 ) + { + mtr_add_arg($args, "--vardir=$opt_vardir") + } + + if ( $opt_debug ) + { + mtr_add_arg($args, + "--debug=d:t:A,$path_vardir_trace/log/mysql_client_test.trace"); + } + + if ( $glob_use_embedded_server ) + { + mtr_add_arg($args, + " -A --language=$path_language"); + mtr_add_arg($args, + " -A --datadir=$slave->[0]->{'path_myddir'}"); + mtr_add_arg($args, + " -A --character-sets-dir=$path_charsetsdir"); + } + + return join(" ", $exe, @$args); +} + # Note that some env is setup in spawn/run, in "mtr_process.pl" sub environment_setup () { + umask(022); + my @ld_library_paths; # -------------------------------------------------------------------------- @@ -1206,11 +1546,20 @@ sub environment_setup () { # -------------------------------------------------------------------------- if ( $opt_source_dist ) { - push(@ld_library_paths, "$glob_basedir/libmysql/.libs/") + push(@ld_library_paths, "$glob_basedir/libmysql/.libs/", + "$glob_basedir/libmysql_r/.libs/"); } else { - push(@ld_library_paths, "$glob_basedir/lib") + push(@ld_library_paths, "$glob_basedir/lib"); + } + + # -------------------------------------------------------------------------- + # Add the path where libndbclient can be found + # -------------------------------------------------------------------------- + if ( $glob_ndbcluster_supported ) + { + push(@ld_library_paths, "$glob_basedir/storage/ndb/src/.libs"); } # -------------------------------------------------------------------------- @@ -1222,7 +1571,7 @@ sub environment_setup () { } # -------------------------------------------------------------------------- - #Valgrind need to be run with debug libraries otherwise it's almost + # Valgrind need to be run with debug libraries otherwise it's almost # impossible to add correct supressions, that means if "/usr/lib/debug" # is available, it should be added to # LD_LIBRARY_PATH @@ -1234,17 +1583,21 @@ sub environment_setup () { } $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', $ENV{'LD_LIBRARY_PATH'})); + $ENV{'LD_LIBRARY_PATHS'} ? + split(':', $ENV{'LD_LIBRARY_PATH'}) : ()); mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}"); $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', $ENV{'DYLD_LIBRARY_PATH'})); + $ENV{'DYLD_LIBRARY_PATH'} ? + split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ()); mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}"); + # -------------------------------------------------------------------------- # Also command lines in .opt files may contain env vars # -------------------------------------------------------------------------- + $ENV{'CHARSETSDIR'}= $path_charsetsdir; $ENV{'UMASK'}= "0660"; # The octal *string* $ENV{'UMASK_DIR'}= "0770"; # The octal *string* $ENV{'LC_COLLATE'}= "C"; @@ -1252,49 +1605,259 @@ sub environment_setup () { $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir; $ENV{'MYSQLTEST_VARDIR'}= $opt_vardir; $ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir; - $ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_mysock'}; - $ENV{'MASTER_MYSOCK1'}= $master->[1]->{'path_mysock'}; - $ENV{'MASTER_MYPORT'}= $master->[0]->{'path_myport'}; - $ENV{'MASTER_MYPORT1'}= $master->[1]->{'path_myport'}; - $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'path_myport'}; - $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'path_myport'}; - $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'path_myport'}; -# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME - $ENV{'MYSQL_TCP_PORT'}= 3306; - - $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; - $ENV{'NDB_STATUS_OK'}= "YES"; - - $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid}; - $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid}; - $ENV{'IM_PORT'}= $instance_manager->{port}; + $ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_sock'}; + $ENV{'MASTER_MYSOCK1'}= $master->[1]->{'path_sock'}; + $ENV{'MASTER_MYPORT'}= $master->[0]->{'port'}; + $ENV{'MASTER_MYPORT1'}= $master->[1]->{'port'}; + $ENV{'SLAVE_MYSOCK'}= $slave->[0]->{'path_sock'}; + $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'port'}; + $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'port'}; + $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'}; + $ENV{'MYSQL_TCP_PORT'}= $mysqld_variables{'port'}; + $ENV{'IM_PATH_SOCK'}= $instance_manager->{path_sock}; $ENV{'IM_USERNAME'}= $instance_manager->{admin_login}; $ENV{'IM_PASSWORD'}= $instance_manager->{admin_password}; - - $ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock}; - $ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port}; - $ENV{'IM_MYSQLD1_PATH_PID'}=$instance_manager->{instances}->[0]->{path_pid}; - $ENV{'IM_MYSQLD2_SOCK'}= $instance_manager->{instances}->[1]->{path_sock}; - $ENV{'IM_MYSQLD2_PORT'}= $instance_manager->{instances}->[1]->{port}; - $ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid}; + $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set $ENV{'EXE_MYSQL'}= $exe_mysql; - $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set + # ---------------------------------------------------- + # Setup env for NDB + # ---------------------------------------------------- + if ( ! $opt_skip_ndbcluster ) + { + $ENV{'NDB_MGM'}= $exe_ndb_mgm; + + $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; + $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave; + + $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test; + + $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; + $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; + $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; + + if ( $mysql_version_id >= 50000 ) + { + $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; + $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; + } + $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; + } + + # ---------------------------------------------------- + # Setup env for IM + # ---------------------------------------------------- + if ( ! $opt_skip_im ) + { + $ENV{'IM_EXE'}= $exe_im; + $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid}; + $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid}; + $ENV{'IM_PORT'}= $instance_manager->{port}; + $ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file}; + $ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file}; + + $ENV{'IM_MYSQLD1_SOCK'}= + $instance_manager->{instances}->[0]->{path_sock}; + $ENV{'IM_MYSQLD1_PORT'}= + $instance_manager->{instances}->[0]->{port}; + $ENV{'IM_MYSQLD1_PATH_PID'}= + $instance_manager->{instances}->[0]->{path_pid}; + $ENV{'IM_MYSQLD2_SOCK'}= + $instance_manager->{instances}->[1]->{path_sock}; + $ENV{'IM_MYSQLD2_PORT'}= + $instance_manager->{instances}->[1]->{port}; + $ENV{'IM_MYSQLD2_PATH_PID'}= + $instance_manager->{instances}->[1]->{path_pid}; + } + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlcheck + # ---------------------------------------------------- + my $cmdline_mysqlcheck= + "$exe_mysqlcheck --no-defaults -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password="; + + if ( $opt_debug ) + { + $cmdline_mysqlcheck .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlcheck.trace"; + } + $ENV{'MYSQL_CHECK'}= $cmdline_mysqlcheck; + + # ---------------------------------------------------- + # Setup env to childs can execute myqldump + # ---------------------------------------------------- + my $cmdline_mysqldump= generate_cmdline_mysqldump($master->[0]); + my $cmdline_mysqldumpslave= generate_cmdline_mysqldump($slave->[0]); + + if ( $opt_debug ) + { + $cmdline_mysqldump .= + " --debug=d:t:A,$path_vardir_trace/log/mysqldump-master.trace"; + $cmdline_mysqldumpslave .= + " --debug=d:t:A,$path_vardir_trace/log/mysqldump-slave.trace"; + } + $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump; + $ENV{'MYSQL_DUMP_SLAVE'}= $cmdline_mysqldumpslave; + + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlslap + # ---------------------------------------------------- + if ( $exe_mysqlslap ) + { + my $cmdline_mysqlslap= + "$exe_mysqlslap -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password= " . + "--lock-directory=$opt_tmpdir"; + + if ( $opt_debug ) + { + $cmdline_mysqlslap .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; + } + $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap; + } + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlimport + # ---------------------------------------------------- + my $cmdline_mysqlimport= + "$exe_mysqlimport -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password="; + + if ( $opt_debug ) + { + $cmdline_mysqlimport .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlimport.trace"; + } + $ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport; + + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlshow + # ---------------------------------------------------- + my $cmdline_mysqlshow= + "$exe_mysqlshow -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password="; + + if ( $opt_debug ) + { + $cmdline_mysqlshow .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlshow.trace"; + } + $ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow; + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlbinlog + # ---------------------------------------------------- + my $cmdline_mysqlbinlog= + "$exe_mysqlbinlog" . + " --no-defaults --local-load=$opt_tmpdir"; + if ( $mysql_version_id >= 50000 ) + { + $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir"; + } + + if ( $opt_debug ) + { + $cmdline_mysqlbinlog .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlbinlog.trace"; + } + $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog; + + # ---------------------------------------------------- + # Setup env so childs can execute mysql + # ---------------------------------------------------- + my $cmdline_mysql= + "$exe_mysql --no-defaults --host=localhost --user=root --password= " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} ". + "--character-sets-dir=$path_charsetsdir"; + + $ENV{'MYSQL'}= $cmdline_mysql; + # ---------------------------------------------------- + # Setup env so childs can execute mysql_client_test + # ---------------------------------------------------- + $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments(); + + # ---------------------------------------------------- + # Setup env so childs can execute mysql_fix_system_tables + # ---------------------------------------------------- + if ( ! $glob_win32 ) + { + my $cmdline_mysql_fix_system_tables= + "$exe_mysql_fix_system_tables --no-defaults --host=localhost " . + "--user=root --password= " . + "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'}"; + $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; + } + + # ---------------------------------------------------- + # Setup env so childs can execute my_print_defaults + # ---------------------------------------------------- + $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; + + + # ---------------------------------------------------- + # Setup env so childs can execute perror + # ---------------------------------------------------- + $ENV{'MY_PERROR'}= $exe_perror; + + # ---------------------------------------------------- + # Add the path where mysqld will find udf_example.so + # ---------------------------------------------------- + $ENV{'UDF_EXAMPLE_LIB'}= + ($lib_udf_example ? basename($lib_udf_example) : ""); + + $ENV{'LD_LIBRARY_PATH'}= + ($lib_udf_example ? dirname($lib_udf_example) : "") . + ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); + + + # ---------------------------------------------------- # We are nice and report a bit about our settings - print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; - print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; - print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; - print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; - print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; - print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; - print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; - print "Using IM_PORT = $ENV{IM_PORT}\n"; - print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n"; - print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; + # ---------------------------------------------------- + if (!$opt_extern) + { + print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; + print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; + print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; + print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; + print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; + if ( ! $opt_skip_ndbcluster ) + { + print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; + if ( ! $opt_skip_ndbcluster_slave ) + { + print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n"; + } + } + if ( ! $opt_skip_im ) + { + print "Using IM_PORT = $ENV{IM_PORT}\n"; + print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n"; + print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; + } + } + + # Create an environment variable to make it possible + # to detect that valgrind is being used from test cases + $ENV{'VALGRIND_TEST'}= $opt_valgrind; + } @@ -1313,7 +1876,7 @@ sub signal_setup () { sub handle_int_signal () { $SIG{INT}= 'DEFAULT'; # If we get a ^C again, we die... mtr_warning("got INT signal, cleaning up....."); - stop_masters_slaves(); + stop_all_servers(); mtr_error("We die from ^C signal from user"); } @@ -1324,16 +1887,16 @@ sub handle_int_signal () { # ############################################################################## -sub kill_running_server () { +sub kill_running_servers () { if ( $opt_fast or $glob_use_embedded_server ) { # FIXME is embedded server really using PID files?! - unlink($master->[0]->{'path_mypid'}); - unlink($master->[1]->{'path_mypid'}); - unlink($slave->[0]->{'path_mypid'}); - unlink($slave->[1]->{'path_mypid'}); - unlink($slave->[2]->{'path_mypid'}); + unlink($master->[0]->{'path_pid'}); + unlink($master->[1]->{'path_pid'}); + unlink($slave->[0]->{'path_pid'}); + unlink($slave->[1]->{'path_pid'}); + unlink($slave->[2]->{'path_pid'}); } else { @@ -1342,32 +1905,55 @@ sub kill_running_server () { # started from this run of the script, this is terminating # leftovers from previous runs. + if ( ! -d $opt_vardir ) + { + if ( -l $opt_vardir and ! -d readlink($opt_vardir) ) + { + mtr_report("Removing $opt_vardir symlink without destination"); + unlink($opt_vardir); + } + # The "var" dir does not exist already + # the processes that mtr_kill_leftovers start will write + # their log files to var/log so it should be created + mkpath("$opt_vardir/log"); + } mtr_kill_leftovers(); - - $using_ndbcluster_master= $opt_with_ndbcluster; - ndbcluster_stop(); - $master->[0]->{'ndbcluster'}= 1; - } + } } sub cleanup_stale_files () { + my $created_by_mem_file= "$glob_mysql_test_dir/var/created_by_mem"; + mtr_report("Removing Stale Files"); - if ( $opt_vardir eq "$glob_mysql_test_dir/var" ) + if ( $opt_vardir eq $default_vardir ) { # # Running with "var" in mysql-test dir # - if ( -l "$glob_mysql_test_dir/var" ) + if ( -l $opt_vardir) { - # Some users creates a soft link in mysql-test/var to another area - # - allow it - mtr_report("WARNING: Using the 'mysql-test/var' symlink"); - rmtree("$opt_vardir/log"); - rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port"); - rmtree("$opt_vardir/run"); - rmtree("$opt_vardir/tmp"); + # var is a symlink + if (-f $created_by_mem_file) + { + # Remove the directory which the link points at + rmtree(readlink($opt_vardir)); + # Remove the entire "var" dir + rmtree("$opt_vardir/"); + # Remove the "var" symlink + unlink($opt_vardir); + } + else + { + # Some users creates a soft link in mysql-test/var to another area + # - allow it + mtr_report("WARNING: Using the 'mysql-test/var' symlink"); + rmtree("$opt_vardir/log"); + rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port"); + rmtree("$opt_vardir/run"); + rmtree("$opt_vardir/tmp"); + } } else { @@ -1383,12 +1969,23 @@ sub cleanup_stale_files () { # Remove the var/ dir in mysql-test dir if any # this could be an old symlink that shouldn't be there - rmtree("$glob_mysql_test_dir/var"); + rmtree($default_vardir); # Remove the "var" dir rmtree("$opt_vardir/"); } + if ( $opt_mem ) + { + # Runinng with var as a link to some "memory" location, normally tmpfs + rmtree($opt_mem); + mkpath($opt_mem); + mtr_report("Creating symlink from $opt_vardir to $opt_mem"); + symlink($opt_mem, $opt_vardir); + # Put a small file to recognize this dir was created by --mem + mtr_tofile($created_by_mem_file, $opt_mem); + } + mkpath("$opt_vardir/log"); mkpath("$opt_vardir/run"); mkpath("$opt_vardir/tmp"); @@ -1449,10 +2046,10 @@ sub check_running_as_root () { } +sub check_ssl_support ($) { + my $mysqld_variables= shift; -sub check_ssl_support () { - - if ($opt_skip_ssl) + if ($opt_skip_ssl || $opt_extern) { mtr_report("Skipping SSL"); $opt_ssl_supported= 0; @@ -1460,13 +2057,7 @@ sub check_ssl_support () { return; } - # check ssl support by testing using a switch - # that is only available in that case - if ( mtr_run($exe_mysqld, - ["--no-defaults", - "--ssl", - "--help"], - "", "/dev/null", "/dev/null", "") != 0 ) + if ( ! $mysqld_variables->{'ssl'} ) { if ( $opt_ssl) { @@ -1483,120 +2074,333 @@ sub check_ssl_support () { } +sub check_debug_support ($) { + my $mysqld_variables= shift; + + if ( ! $mysqld_variables->{'debug'} ) + { + #mtr_report("Binaries are not debug compiled"); + $debug_compiled_binaries= 0; + + if ( $opt_debug ) + { + mtr_error("Can't use --debug, binaries does not support it"); + } + return; + } + mtr_report("Binaries are debug compiled"); + $debug_compiled_binaries= 1; +} + +############################################################################## +# +# Helper function to handle configuration-based subdirectories which Visual +# Studio uses for storing binaries. If opt_vs_config is set, this returns +# a path based on that setting; if not, it returns paths for the default +# /release/ and /debug/ subdirectories. +# +# $exe can be undefined, if the directory itself will be used +# +############################################################################### + +sub vs_config_dirs ($$) { + my ($path_part, $exe) = @_; + + $exe = "" if not defined $exe; + + if ($opt_vs_config) + { + return ("$glob_basedir/$path_part/$opt_vs_config/$exe"); + } + + return ("$glob_basedir/$path_part/release/$exe", + "$glob_basedir/$path_part/debug/$exe"); +} + ############################################################################## # # Start the ndb cluster # ############################################################################## -sub check_ndbcluster_support () { +sub check_ndbcluster_support ($) { + my $mysqld_variables= shift; if ($opt_skip_ndbcluster) { mtr_report("Skipping ndbcluster"); - $opt_with_ndbcluster= 0; + $opt_skip_ndbcluster_slave= 1; return; } - if ($opt_with_ndbcluster) + if ( ! $mysqld_variables->{'ndb-connectstring'} ) { - mtr_report("Using ndbcluster if necessary"); + mtr_report("Skipping ndbcluster, mysqld not compiled with ndbcluster"); + $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster_slave= 1; return; } + $glob_ndbcluster_supported= 1; + mtr_report("Using ndbcluster when necessary, mysqld supports it"); - # check ndbcluster support by testing using a switch - # that is only available in that case - if ( mtr_run($exe_mysqld, - ["--no-defaults", - "--ndb-use-exact-count", - "--help"], - "", "/dev/null", "/dev/null", "") != 0 ) + if ( $mysql_version_id < 50100 ) { - mtr_report("Skipping ndbcluster, mysqld not compiled with ndbcluster"); - $opt_with_ndbcluster= 0; - return; + # Slave cluster is not supported until 5.1 + $opt_skip_ndbcluster_slave= 1; + } - mtr_report("Using ndbcluster if necessary, mysqld supports it"); - $opt_with_ndbcluster= 1; + return; } -sub ndbcluster_install () { +sub ndbcluster_start_install ($) { + my $cluster= shift; + + mtr_report("Installing $cluster->{'name'} Cluster"); + + mkdir($cluster->{'data_dir'}); + + # Create a config file from template + my $ndb_no_ord=512; + my $ndb_no_attr=2048; + my $ndb_con_op=105000; + my $ndb_dmem="80M"; + my $ndb_imem="24M"; + my $ndb_pbmem="32M"; + my $nodes= $cluster->{'nodes'}; + my $ndb_host= "localhost"; + my $ndb_diskless= 0; - if ( ! $opt_with_ndbcluster or $glob_use_running_ndbcluster ) + if (!$opt_bench) { - return 0; + # Use a smaller configuration + if ( $mysql_version_id < 50100 ) + { + # 4.1 and 5.0 is using a "larger" --small configuration + $ndb_no_ord=128; + $ndb_con_op=10000; + $ndb_dmem="40M"; + $ndb_imem="12M"; + } + else + { + $ndb_no_ord=32; + $ndb_con_op=5000; + $ndb_dmem="20M"; + $ndb_imem="1M"; + $ndb_pbmem="4M"; + } } - mtr_report("Install ndbcluster"); - my $ndbcluster_opts= $opt_bench ? "" : "--small"; - if ( mtr_run("$glob_mysql_test_dir/ndb/ndbcluster", - ["--port=$opt_ndbcluster_port", - "--data-dir=$opt_vardir", - $ndbcluster_opts, - "--initial"], - "", "", "", "") ) + + my $config_file_template= "ndb/ndb_config_${nodes}_node.ini"; + my $config_file= "$cluster->{'data_dir'}/config.ini"; + + open(IN, $config_file_template) + or mtr_error("Can't open $config_file_template: $!"); + open(OUT, ">", $config_file) + or mtr_error("Can't write to $config_file: $!"); + while (<IN>) { - return 1; + chomp; + + s/CHOOSE_MaxNoOfAttributes/$ndb_no_attr/; + s/CHOOSE_MaxNoOfOrderedIndexes/$ndb_no_ord/; + s/CHOOSE_MaxNoOfConcurrentOperations/$ndb_con_op/; + s/CHOOSE_DataMemory/$ndb_dmem/; + s/CHOOSE_IndexMemory/$ndb_imem/; + s/CHOOSE_Diskless/$ndb_diskless/; + s/CHOOSE_HOSTNAME_.*/$ndb_host/; + s/CHOOSE_FILESYSTEM/$cluster->{'data_dir'}/; + s/CHOOSE_PORT_MGM/$cluster->{'port'}/; + if ( $mysql_version_id < 50000 ) + { + my $base_port= $cluster->{'port'} + 1; + s/CHOOSE_PORT_TRANSPORTER/$base_port/; + } + s/CHOOSE_DiskPageBufferMemory/$ndb_pbmem/; + + print OUT "$_ \n"; } + close OUT; + close IN; + - $using_ndbcluster_master= 1; - ndbcluster_stop(); - $master->[0]->{'ndbcluster'}= 1; + # Start cluster with "--initial" + + ndbcluster_start($cluster, "--initial"); return 0; } -sub ndbcluster_start ($) { - my $use_ndbcluster= shift; +sub ndbcluster_wait_started($$){ + my $cluster= shift; + my $ndb_waiter_extra_opt= shift; + my $path_waiter_log= "$cluster->{'data_dir'}/ndb_waiter.log"; + my $args; + + mtr_init_args(\$args); - if ( ! $use_ndbcluster ) + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--ndb-connectstring=%s", $cluster->{'connect_string'}); + mtr_add_arg($args, "--timeout=60"); + + if ($ndb_waiter_extra_opt) { - $using_ndbcluster_master= 0; - return 0; + mtr_add_arg($args, "$ndb_waiter_extra_opt"); + } + + # Start the ndb_waiter which will connect to the ndb_mgmd + # and poll it for state of the ndbd's, will return when + # all nodes in the cluster is started + my $res= mtr_run($exe_ndb_waiter, $args, + "", $path_waiter_log, $path_waiter_log, ""); + mtr_verbose("ndbcluster_wait_started, returns: $res") if $res; + return $res; +} + + + +sub mysqld_wait_started($){ + my $mysqld= shift; + + my $res= sleep_until_file_created($mysqld->{'path_pid'}, + $mysqld->{'start_timeout'}, + $mysqld->{'pid'}); + return $res == 0; +} + + +sub ndb_mgmd_wait_started($) { + my ($cluster)= @_; + + my $retries= 100; + while (ndbcluster_wait_started($cluster, "--no-contact") and + $retries) + { + # Millisceond sleep emulated with select + select(undef, undef, undef, (0.1)); + + $retries--; } + + return $retries == 0; + +} + +sub ndb_mgmd_start ($) { + my $cluster= shift; + + my $args; # Arg vector + my $pid= -1; + + mtr_init_args(\$args); + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--nodaemon"); + mtr_add_arg($args, "--config-file=%s", "$cluster->{'data_dir'}/config.ini"); + + + my $path_ndb_mgmd_log= "$cluster->{'data_dir'}/\l$cluster->{'name'}_ndb_mgmd.log"; + $pid= mtr_spawn($exe_ndb_mgmd, $args, "", + $path_ndb_mgmd_log, + $path_ndb_mgmd_log, + "", + { append_log_file => 1 }); + + # FIXME Should not be needed + # Unfortunately the cluster nodes will fail to start + # if ndb_mgmd has not started properly + if (ndb_mgmd_wait_started($cluster)) + { + mtr_error("Failed to wait for start of ndb_mgmd"); + } + + # Remember pid of ndb_mgmd + $cluster->{'pid'}= $pid; + + mtr_verbose("ndb_mgmd_start, pid: $pid"); + + return $pid; +} + + +sub ndbd_start ($$$) { + my $cluster= shift; + my $idx= shift; + my $extra_args= shift; + + my $args; # Arg vector + my $pid= -1; + + mtr_init_args(\$args); + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--ndb-connectstring=%s", "$cluster->{'connect_string'}"); + if ( $mysql_version_id >= 50000) + { + mtr_add_arg($args, "--character-sets-dir=%s", "$path_charsetsdir"); + } + mtr_add_arg($args, "--nodaemon"); + mtr_add_arg($args, "$extra_args"); + + my $nodeid= $cluster->{'ndbds'}->[$idx]->{'nodeid'}; + my $path_ndbd_log= "$cluster->{'data_dir'}/ndb_${nodeid}.log"; + $pid= mtr_spawn($exe_ndbd, $args, "", + $path_ndbd_log, + $path_ndbd_log, + "", + { append_log_file => 1 }); + + # Add pid to list of pids for this cluster + $cluster->{'ndbds'}->[$idx]->{'pid'}= $pid; + + # Rememeber options used when starting + $cluster->{'ndbds'}->[$idx]->{'start_extra_args'}= $extra_args; + $cluster->{'ndbds'}->[$idx]->{'idx'}= $idx; + + mtr_verbose("ndbd_start, pid: $pid"); + + return $pid; +} + + +sub ndbcluster_start ($$) { + my $cluster= shift; + my $extra_args= shift; + + mtr_verbose("ndbcluster_start '$cluster->{'name'}'"); + if ( $glob_use_running_ndbcluster ) { - $using_ndbcluster_master= 1; return 0; } - if ( $using_ndbcluster_master ) + + if ( $cluster->{'pid'} ) { - # Master already started - return 0; + mtr_error("Cluster '$cluster->{'name'}' already started"); } - # FIXME, we want to _append_ output to file $file_ndb_testrun_log instead of /dev/null - if ( mtr_run("$glob_mysql_test_dir/ndb/ndbcluster", - ["--port=$opt_ndbcluster_port", - "--data-dir=$opt_vardir", - "--character-sets-dir=$path_charsetsdir"], - "", "/dev/null", "", "") ) + + ndb_mgmd_start($cluster); + + for ( my $idx= 0; $idx < $cluster->{'nodes'}; $idx++ ) { - mtr_error("Error ndbcluster_start"); - return 1; + ndbd_start($cluster, $idx, $extra_args); } - $using_ndbcluster_master= 1; return 0; } -sub ndbcluster_stop () { - if ( ! $using_ndbcluster_master or $glob_use_running_ndbcluster ) +sub rm_ndbcluster_tables ($) { + my $dir= shift; + foreach my $bin ( glob("$dir/cluster/apply_status*"), + glob("$dir/cluster/schema*") ) { - $using_ndbcluster_master= 0; - return; + unlink($bin); } - # FIXME, we want to _append_ output to file $file_ndb_testrun_log instead of /dev/null - mtr_run("$glob_mysql_test_dir/ndb/ndbcluster", - ["--port=$opt_ndbcluster_port", - "--data-dir=$opt_vardir", - "--stop"], - "", "/dev/null", "", ""); - - $using_ndbcluster_master= 0; - return; } @@ -1611,10 +2415,9 @@ sub run_benchmarks ($) { my $args; - if ( ! $glob_use_embedded_server and ! $opt_local_master ) + if ( ! $glob_use_embedded_server ) { - $master->[0]->{'pid'}= mysqld_start('master',0,[],[], - $using_ndbcluster_master); + mysqld_start($master->[0],[],[]); if ( ! $master->[0]->{'pid'} ) { mtr_error("Can't start the mysqld server"); @@ -1623,7 +2426,7 @@ sub run_benchmarks ($) { mtr_init_args(\$args); - mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'}); + mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); mtr_add_arg($args, "--user=%s", $opt_user); if ( $opt_small_bench ) @@ -1637,10 +2440,8 @@ sub run_benchmarks ($) { mtr_add_arg($args, "--create-options=TYPE=ndb"); } - my $benchdir= "$glob_basedir/sql-bench"; - chdir($benchdir); # FIXME check error - - # FIXME write shorter.... + chdir($glob_mysql_bench_dir) + or mtr_error("Couldn't chdir to '$glob_mysql_bench_dir': $!"); if ( ! $benchmark ) { @@ -1673,24 +2474,26 @@ sub run_benchmarks ($) { # ############################################################################## -# FIXME how to specify several suites to run? Comma separated list? - - sub run_suite () { my ($suite, $tests)= @_; mtr_print_thick_line(); - mtr_report("Finding Tests in the '$suite' suite"); - mtr_timer_start($glob_timers,"suite", 60 * $opt_suite_timeout); mtr_report("Starting Tests in the '$suite' suite"); + mtr_report_tests_not_skipped_though_disabled($tests); + mtr_print_header(); foreach my $tinfo ( @$tests ) { + if (run_testcase_check_skip_test($tinfo)) + { + next; + } + mtr_timer_start($glob_timers,"testcase", 60 * $opt_testcase_timeout); run_testcase($tinfo); mtr_timer_stop($glob_timers,"testcase"); @@ -1702,7 +2505,7 @@ sub run_suite () { ! $glob_use_running_server and ! $glob_use_embedded_server ) { - stop_masters_slaves(); + stop_all_servers(); } if ( $opt_gcov ) @@ -1727,11 +2530,14 @@ sub run_suite () { ############################################################################## sub initialize_servers () { + + datadir_setup(); + if ( ! $glob_use_running_server ) { - kill_running_server(); + kill_running_servers(); - unless ( $opt_start_dirty ) + if ( ! $opt_start_dirty ) { cleanup_stale_files(); mysql_install_db(); @@ -1746,8 +2552,10 @@ sub initialize_servers () { sub mysql_install_db () { - install_db('master1', $master->[0]->{'path_myddir'}); - copy_install_db('master2', $master->[1]->{'path_myddir'}); + install_db('master', $master->[0]->{'path_myddir'}); + + # FIXME check if testcase really is using second master + copy_install_db('master', $master->[1]->{'path_myddir'}); # Install the number of slave databses needed for (my $idx= 0; $idx < $max_slave_num; $idx++) @@ -1760,21 +2568,57 @@ sub mysql_install_db () { im_prepare_env($instance_manager); } - if ( ndbcluster_install() ) + my $cluster_started_ok= 1; # Assume it can be started + + if ($opt_skip_ndbcluster || $glob_use_running_ndbcluster || + $clusters->[0]->{executable_setup_failed}) { - if ( $opt_force) + # Don't install master cluster + } + elsif (ndbcluster_start_install($clusters->[0])) + { + mtr_warning("Failed to start install of $clusters->[0]->{name}"); + $cluster_started_ok= 0; + } + + if ($max_slave_num == 0 || + $opt_skip_ndbcluster_slave || $glob_use_running_ndbcluster_slave || + $clusters->[1]->{executable_setup_failed}) + { + # Don't install slave cluster + } + elsif (ndbcluster_start_install($clusters->[1])) + { + mtr_warning("Failed to start install of $clusters->[1]->{name}"); + $cluster_started_ok= 0; + } + + foreach my $cluster (@{$clusters}) + { + + next if !$cluster->{'pid'}; + + $cluster->{'installed_ok'}= 1; # Assume install suceeds + + if (ndbcluster_wait_started($cluster, "")) { # failed to install, disable usage and flag that its no ok - mtr_report("ndbcluster_install failed, continuing without cluster"); - $opt_with_ndbcluster= 0; - $flag_ndb_status_ok= 0; - $ENV{'NDB_STATUS_OK'}= "NO"; + mtr_report("ndbcluster_install of $cluster->{'name'} failed"); + $cluster->{"installed_ok"}= 0; + + $cluster_started_ok= 0; + } + } + + if ( ! $cluster_started_ok ) + { + if ( $opt_force) + { + # Continue without cluster } else { - print "Aborting: Failed to install ndb cluster\n"; - print "To continue, re-run with '--force'.\n"; - mtr_exit(1); + mtr_error("To continue, re-run with '--force'."); } } @@ -1793,6 +2637,7 @@ sub copy_install_db ($$) { } + sub install_db ($$) { my $type= shift; my $data_dir= shift; @@ -1837,15 +2682,16 @@ sub install_db ($$) { mtr_add_arg($args, "--datadir=%s", $data_dir); mtr_add_arg($args, "--skip-innodb"); mtr_add_arg($args, "--skip-ndbcluster"); - mtr_add_arg($args, "--skip-bdb"); + mtr_add_arg($args, "--tmpdir=."); + mtr_add_arg($args, "--core-file"); if ( $opt_debug ) { mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap_%s.trace", - $opt_vardir_trace, $type); + $path_vardir_trace, $type); } - if ( ! $opt_netware ) + if ( ! $glob_netware ) { mtr_add_arg($args, "--language=%s", $path_language); mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir); @@ -1935,12 +2781,18 @@ basedir = $path_my_basedir server_id = $server_id skip-stack-trace skip-innodb -skip-bdb skip-ndbcluster EOF ; - + if ( $mysql_version_id < 50100 ) + { + print OUT "skip-bdb\n"; + } print OUT "nonguarded\n" if $instance->{'nonguarded'}; + if ( $mysql_version_id >= 50100 ) + { + print OUT "log-output=FILE\n" if $instance->{'old_log_format'}; + } print OUT "\n"; } @@ -1960,16 +2812,17 @@ sub im_prepare_data_dir($) { } + # # Restore snapshot of the installed slave databases # if the snapshot exists # -sub restore_slave_databases () { +sub restore_slave_databases ($) { + my ($num_slaves)= @_; if ( -d $path_snapshot) { - # Restore the number of slave databases being used - for (my $idx= 0; $idx < $max_slave_num; $idx++) + for (my $idx= 0; $idx < $num_slaves; $idx++) { my $data_dir= $slave->[$idx]->{'path_myddir'}; my $name= basename($data_dir); @@ -1980,31 +2833,9 @@ sub restore_slave_databases () { } -############################################################################## -# -# Run a single test case -# -############################################################################## - -# When we get here, we have already filtered out test cases that doesn't -# apply to the current setup, for example if we use a running server, test -# cases that restart the server are dropped. So this function should mostly -# be about doing things, not a lot of logic. - -# We don't start and kill the servers for each testcase. But some -# testcases needs a restart, because they specify options to start -# mysqld with. After that testcase, we need to restart again, to set -# back the normal options. - -sub run_testcase ($) { - my $tinfo= shift; - - my $tname= $tinfo->{'name'}; - - mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are - - # output current test to ndbcluster log file to enable diagnostics - mtr_tofile($file_ndb_testrun_log,"CURRENT TEST $tname\n"); +sub run_testcase_check_skip_test($) +{ + my ($tinfo)= @_; # ---------------------------------------------------------------------- # If marked to skip, just print out and return. @@ -2017,194 +2848,241 @@ sub run_testcase ($) { { mtr_report_test_name($tinfo); mtr_report_test_skipped($tinfo); - return; + return 1; } - if ( $tinfo->{'ndb_test'} and ! $flag_ndb_status_ok ) + if ($tinfo->{'ndb_test'}) { - mtr_report_test_name($tinfo); - mtr_report_test_failed($tinfo); - return; - } + foreach my $cluster (@{$clusters}) + { + last if ($opt_skip_ndbcluster_slave and + $cluster->{'name'} eq 'Slave'); - # ---------------------------------------------------------------------- - # If not using a running servers we may need to stop and restart. - # We restart in the case we have initiation scripts, server options - # etc to run. But we also restart again after the test first restart - # and test is run, to get back to normal server settings. - # - # To make the code a bit more clean, we actually only stop servers - # here, and mark this to be done. Then a generic "start" part will - # start up the needed servers again. - # ---------------------------------------------------------------------- + # If test needs this cluster, check binaries was found ok + if ( $cluster->{'executable_setup_failed'} ) + { + mtr_report_test_name($tinfo); + $tinfo->{comment}= + "Failed to find cluster binaries"; + mtr_report_test_failed($tinfo); + return 1; + } - if ( ! $glob_use_running_server and ! $glob_use_embedded_server ) - { - # We try to find out if we are to restart the server - my $do_restart= 0; # Assumes we don't have to + # If test needs this cluster, check it was installed ok + if ( !$cluster->{'installed_ok'} ) + { + mtr_report_test_name($tinfo); + $tinfo->{comment}= + "Cluster $cluster->{'name'} was not installed ok"; + mtr_report_test_failed($tinfo); + return 1; + } - if ( $tinfo->{'master_sh'} ) - { - $do_restart= 1; # Always restart if script to run - } - elsif ( $opt_with_ndbcluster and $tinfo->{'ndb_test'} != $using_ndbcluster_master ) - { - $do_restart= 1; # Restart without cluster - } - elsif ( $master->[0]->{'running_master_is_special'} and - $master->[0]->{'running_master_is_special'}->{'timezone'} eq - $tinfo->{'timezone'} and - mtr_same_opts($master->[0]->{'running_master_is_special'}->{'master_opt'}, - $tinfo->{'master_opt'}) ) - { - # If running master was started with special settings, but - # the current test requuires the same ones, we *don't* restart. - $do_restart= 0; - } - elsif ( $tinfo->{'master_restart'} or - $master->[0]->{'running_master_is_special'} ) - { - $do_restart= 1; } + } - if ( $do_restart ) + if ( $tinfo->{'component_id'} eq 'im' ) + { + # If test needs im, check binaries was found ok + if ( $instance_manager->{'executable_setup_failed'} ) { - stop_masters(); - delete $master->[0]->{'running_master_is_special'}; # Forget history + mtr_report_test_name($tinfo); + $tinfo->{comment}= + "Failed to find MySQL manager binaries"; + mtr_report_test_failed($tinfo); + return 1; } + } - # ---------------------------------------------------------------------- - # Always terminate all slaves, if any. Else we may have useless - # reconnection attempts and error messages in case the slave and - # master servers restart. - # ---------------------------------------------------------------------- + return 0; +} - stop_slaves(); - restore_slave_databases(); - } - # ---------------------------------------------------------------------- - # Prepare to start masters. Even if we use embedded, we want to run - # the preparation. - # ---------------------------------------------------------------------- +sub do_before_run_mysqltest($) +{ + my $tinfo= shift; + my $tname= $tinfo->{'name'}; - $ENV{'TZ'}= $tinfo->{'timezone'}; + # Remove old files produced by mysqltest + my $result_dir= "r"; + if ( $opt_suite ne "main" ) + { + $result_dir= "suite/$opt_suite/r"; + } + unlink("$result_dir/$tname.reject"); + unlink("$result_dir/$tname.progress"); + unlink("$result_dir/$tname.log"); + unlink("$result_dir/$tname.warnings"); + + mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are - mtr_report_test_name($tinfo); + # output current test to ndbcluster log file to enable diagnostics + mtr_tofile($path_ndb_testrun_log,"CURRENT TEST $tname\n"); mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + if ( $master->[1]->{'pid'} ) + { + mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + } - # FIXME test cases that depend on each other, prevent this from - # being at this location. - # do_before_start_master($tname,$tinfo->{'master_sh'}); + if ( $mysql_version_id < 50000 ) + { + # Set envirnoment variable NDB_STATUS_OK to 1 + # if script decided to run mysqltest cluster _is_ installed ok + $ENV{'NDB_STATUS_OK'} = "1"; + } + elsif ( $mysql_version_id < 50100 ) + { + # Set envirnoment variable NDB_STATUS_OK to YES + # if script decided to run mysqltest cluster _is_ installed ok + $ENV{'NDB_STATUS_OK'} = "YES"; + } +} - # ---------------------------------------------------------------------- - # If any mysqld servers running died, we have to know - # ---------------------------------------------------------------------- +sub do_after_run_mysqltest($) +{ + my $tinfo= shift; + my $tname= $tinfo->{'name'}; - mtr_record_dead_children(); + mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n"); - # ---------------------------------------------------------------------- - # Start masters - # ---------------------------------------------------------------------- + # Save info from this testcase run to mysqltest.log + mtr_appendfile_to_file($path_timefile, $path_mysqltest_log) + if -f $path_timefile; - if ( ! $glob_use_running_server and ! $glob_use_embedded_server ) - { - # FIXME give the args to the embedded server?! - # FIXME what does $opt_local_master mean?! - # FIXME split up start and check that started so that can do - # starts in parallel, masters and slaves at the same time. + # Remove the file that mysqltest writes info to + unlink($path_timefile); - if ( $tinfo->{'component_id'} eq 'mysqld' and ! $opt_local_master ) - { - if ( $opt_with_ndbcluster and $master->[0]->{'ndbcluster'} ) - { - # Cluster is not started +} - # Call ndbcluster_start to check if test case needs cluster - # Start it if not already started - $master->[0]->{'ndbcluster'}= ndbcluster_start($tinfo->{'ndb_test'}); - if ( $master->[0]->{'ndbcluster'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - if ( ! $master->[0]->{'pid'} ) - { - # FIXME not correct location for do_before_start_master() - do_before_start_master($tname,$tinfo->{'master_sh'}); - $master->[0]->{'pid'}= - mysqld_start('master',0,$tinfo->{'master_opt'},[], - $using_ndbcluster_master); - if ( ! $master->[0]->{'pid'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - if ( $using_ndbcluster_master and ! $master->[1]->{'pid'} ) - { - # Test needs cluster, start an extra mysqld connected to cluster - $master->[1]->{'pid'}= - mysqld_start('master',1,$tinfo->{'master_opt'},[], - $using_ndbcluster_master); - if ( ! $master->[1]->{'pid'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - if ( $tinfo->{'master_restart'} ) - { - # Save this test case information, so next can examine it - $master->[0]->{'running_master_is_special'}= $tinfo; - } - } - elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' ) +sub find_testcase_skipped_reason($) +{ + my ($tinfo)= @_; + + # Open mysqltest.log + my $F= IO::File->new($path_timefile) or + mtr_error("can't open file \"$path_timefile\": $!"); + my $reason; + + while ( my $line= <$F> ) + { + # Look for "reason: <reason fo skiping test>" + if ( $line =~ /reason: (.*)/ ) { - # We have to create defaults file every time, in order to ensure that it - # will be the same for each test. The problem is that test can change the - # file (by SET/UNSET commands), so w/o recreating the file, execution of - # one test can affect the other. + $reason= $1; + } + } + + if ( ! $reason ) + { + mtr_warning("Could not find reason for skipping test in $path_timefile"); + $reason= "Detected by testcase(reason unknown) "; + } + $tinfo->{'comment'}= $reason; +} + + +sub analyze_testcase_failure_sync_with_master($) +{ + my ($tinfo)= @_; + + my $args; + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--silent"); + mtr_add_arg($args, "-v"); + mtr_add_arg($args, "--skip-safemalloc"); + mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); - im_create_defaults_file($instance_manager); + mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $master->[0]->{'port'}); + mtr_add_arg($args, "--database=test"); + mtr_add_arg($args, "--user=%s", $opt_user); + mtr_add_arg($args, "--password="); + + # Run the test file and append output to log file + mtr_run_test($exe_mysqltest,$args, + "include/analyze_failure_sync_with_master.test", + "$path_timefile", "$path_timefile","", + { append_log_file => 1 }); + +} - unless ( mtr_im_start($instance_manager, $tinfo->{im_opts}) ) +sub analyze_testcase_failure($) +{ + my ($tinfo)= @_; + + # Open mysqltest.log + my $F= IO::File->new($path_timefile) or + mtr_error("can't open file \"$path_timefile\": $!"); + + while ( my $line= <$F> ) + { + # Look for "mysqltest: At line nnn: <error> + if ( $line =~ /mysqltest: At line [0-9]*: (.*)/ ) + { + my $error= $1; + # Look for "could not sync with master" + if ( $error =~ /could not sync with master/ ) { - report_failure_and_restart($tinfo); - mtr_report("Failed to start Instance Manager. " . - "The test '$tname' is marked as failed."); - return; + analyze_testcase_failure_sync_with_master($tinfo); } } + } +} - # ---------------------------------------------------------------------- - # Start slaves - if needed - # ---------------------------------------------------------------------- +############################################################################## +# +# Run a single test case +# +############################################################################## - if ( $tinfo->{'slave_num'} ) - { - mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); +# When we get here, we have already filtered out test cases that doesn't +# apply to the current setup, for example if we use a running server, test +# cases that restart the server are dropped. So this function should mostly +# be about doing things, not a lot of logic. - do_before_start_slave($tname,$tinfo->{'slave_sh'}); +# We don't start and kill the servers for each testcase. But some +# testcases needs a restart, because they specify options to start +# mysqld with. After that testcase, we need to restart again, to set +# back the normal options. - for ( my $idx= 0; $idx < $tinfo->{'slave_num'}; $idx++ ) - { - if ( ! $slave->[$idx]->{'pid'} ) - { - $slave->[$idx]->{'pid'}= - mysqld_start('slave',$idx, - $tinfo->{'slave_opt'}, $tinfo->{'slave_mi'}, - 0); - if ( ! $slave->[$idx]->{'pid'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - } +sub run_testcase ($) { + my $tinfo= shift; + + # ------------------------------------------------------- + # Init variables that can change between each test case + # ------------------------------------------------------- + + $ENV{'TZ'}= $tinfo->{'timezone'}; + mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}"); + + my $master_restart= run_testcase_need_master_restart($tinfo); + my $slave_restart= run_testcase_need_slave_restart($tinfo); + + if ($master_restart or $slave_restart) + { + # Can't restart a running server that may be in use + if ( $glob_use_running_server ) + { + mtr_report_test_name($tinfo); + $tinfo->{comment}= "Can't restart a running server"; + mtr_report_test_skipped($tinfo); + return; + } + + run_testcase_stop_servers($tinfo, $master_restart, $slave_restart); + } + my $died= mtr_record_dead_children(); + if ($died or $master_restart or $slave_restart) + { + if (run_testcase_start_servers($tinfo)) + { + mtr_report_test_name($tinfo); + report_failure_and_restart($tinfo); + return 1; } } @@ -2212,31 +3090,18 @@ sub run_testcase ($) { # If --start-and-exit or --start-dirty given, stop here to let user manually # run tests # ---------------------------------------------------------------------- - if ( $opt_start_and_exit or $opt_start_dirty ) { + mtr_timer_stop_all($glob_timers); mtr_report("\nServers started, exiting"); exit(0); } - # ---------------------------------------------------------------------- - # Run the test case - # ---------------------------------------------------------------------- - { - # remove the old reject file - if ( $opt_suite eq "main" ) - { - unlink("r/$tname.reject"); - } - else - { - unlink("suite/$opt_suite/r/$tname.reject"); - } - unlink($path_timefile); + do_before_run_mysqltest($tinfo); my $res= run_mysqltest($tinfo); - + mtr_report_test_name($tinfo); if ( $res == 0 ) { mtr_report_test_passed($tinfo); @@ -2244,6 +3109,9 @@ sub run_testcase ($) { elsif ( $res == 62 ) { # Testcase itself tell us to skip this one + + # Try to get reason from mysqltest.log + find_testcase_skipped_reason($tinfo); mtr_report_test_skipped($tinfo); } elsif ( $res == 63 ) @@ -2251,33 +3119,33 @@ sub run_testcase ($) { $tinfo->{'timeout'}= 1; # Mark as timeout report_failure_and_restart($tinfo); } - else + elsif ( $res == 1 ) { - # Test case failed, if in control mysqltest returns 1 - if ( $res != 1 ) + if ( $opt_force ) { - mtr_tofile($path_timefile, - "mysqltest returned unexpected code $res, " . - "it has probably crashed"); + analyze_testcase_failure($tinfo); } + # Test case failure reported by mysqltest + report_failure_and_restart($tinfo); + } + else + { + # mysqltest failed, probably crashed + $tinfo->{comment}= + "mysqltest returned unexpected code $res, it has probably crashed"; report_failure_and_restart($tinfo); } - # Save info from this testcase run to mysqltest.log - my $testcase_log= mtr_fromfile($path_timefile) if -f $path_timefile; - mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n"); - mtr_tofile($path_mysqltest_log, $testcase_log); + + do_after_run_mysqltest($tinfo); } # ---------------------------------------------------------------------- # Stop Instance Manager if we are processing an IM-test case. # ---------------------------------------------------------------------- - - if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' ) + if ( $tinfo->{'component_id'} eq 'im' and + !mtr_im_stop($instance_manager, $tinfo->{'name'}) ) { - unless ( mtr_im_stop($instance_manager) ) - { - mtr_error("Failed to stop Instance Manager.") - } + mtr_error("Failed to stop Instance Manager.") } } @@ -2328,8 +3196,6 @@ sub restore_installed_db ($) { if ( -d $path_snapshot) { - kill_running_server (); - mtr_report("Restoring snapshot of databases"); foreach my $data_dir (@data_dir_lst) @@ -2339,21 +3205,24 @@ sub restore_installed_db ($) { rmtree("$data_dir"); mtr_copy_dir("$path_snapshot/$name", "$data_dir"); } - if ($opt_with_ndbcluster) + + # Remove the ndb_*_fs dirs for all ndbd nodes + # forcing a clean start of ndb + foreach my $cluster (@{$clusters}) { - # Remove the ndb_*_fs dirs, forcing a clean start of ndb - rmtree("$path_ndb_data_dir/ndb_1_fs"); - rmtree("$path_ndb_data_dir/ndb_2_fs"); + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + rmtree("$ndbd->{'path_fs'}" ); + } } } else { - # No snapshot existed, just stop all processes - stop_masters_slaves(); + # No snapshot existed + mtr_error("No snapshot existed"); } } - sub report_failure_and_restart ($) { my $tinfo= shift; @@ -2362,6 +3231,9 @@ sub report_failure_and_restart ($) { print "\n"; if ( $opt_force ) { + # Stop all servers that are known to be running + stop_all_servers(); + # Restore the snapshot of the installed test db restore_installed_db($tinfo->{'name'}); print "Resuming Tests\n\n"; @@ -2375,7 +3247,7 @@ sub report_failure_and_restart ($) { ! $glob_use_running_server and ! $glob_use_embedded_server ) { - stop_masters_slaves(); + stop_all_servers(); } mtr_exit(1); @@ -2389,24 +3261,17 @@ sub report_failure_and_restart ($) { ############################################################################## -# The embedded server needs the cleanup so we do some of the start work -# but stop before actually running mysqld or anything. -sub do_before_start_master ($$) { - my $tname= shift; - my $init_script= shift; +sub do_before_start_master ($) { + my ($tinfo)= @_; + + my $tname= $tinfo->{'name'}; + my $init_script= $tinfo->{'master_sh'}; # FIXME what about second master..... - # Remove stale binary logs except for 2 tests which need them FIXME here???? - if ( $tname ne "rpl_crash_binlog_ib_1b" and - $tname ne "rpl_crash_binlog_ib_2b" and - $tname ne "rpl_crash_binlog_ib_3b") + foreach my $bin ( glob("$opt_vardir/log/master*-bin*") ) { - # FIXME we really want separate dir for binlogs - foreach my $bin ( glob("$opt_vardir/log/master*-bin*") ) - { - unlink($bin); - } + unlink($bin); } # FIXME only remove the ones that are tied to this master @@ -2426,31 +3291,23 @@ sub do_before_start_master ($$) { # mtr_warning("$init_script exited with code $ret"); } } - # for gcov FIXME needed? If so we need more absolute paths - # chdir($glob_basedir); } -sub do_before_start_slave ($$) { - my $tname= shift; - my $init_script= shift; +sub do_before_start_slave ($) { + my ($tinfo)= @_; - # Remove stale binary logs and old master.info files - # except for too tests which need them - if ( $tname ne "rpl_crash_binlog_ib_1b" and - $tname ne "rpl_crash_binlog_ib_2b" and - $tname ne "rpl_crash_binlog_ib_3b" ) + my $tname= $tinfo->{'name'}; + my $init_script= $tinfo->{'master_sh'}; + + foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") ) { - # FIXME we really want separate dir for binlogs - foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") ) - { - unlink($bin); - } - # FIXME really master?! - unlink("$slave->[0]->{'path_myddir'}/master.info"); - unlink("$slave->[0]->{'path_myddir'}/relay-log.info"); + unlink($bin); } + unlink("$slave->[0]->{'path_myddir'}/master.info"); + unlink("$slave->[0]->{'path_myddir'}/relay-log.info"); + # Run slave initialization shell script if one exists if ( $init_script ) { @@ -2469,18 +3326,17 @@ sub do_before_start_slave ($$) { } -sub mysqld_arguments ($$$$$$) { +sub mysqld_arguments ($$$$$) { my $args= shift; - my $type= shift; # master/slave + my $type= shift; my $idx= shift; my $extra_opt= shift; my $slave_master_info= shift; - my $using_ndbcluster= shift; my $sidx= ""; # Index as string, 0 is empty string if ( $idx > 0 ) { - $sidx= sprintf("%d", $idx); # sprintf not needed in Perl for this + $sidx= "$idx"; } my $prefix= ""; # If mysqltest server arg @@ -2490,14 +3346,18 @@ sub mysqld_arguments ($$$$$$) { $prefix= "--server-arg="; } else { # We can't pass embedded server --no-defaults - mtr_add_arg($args, "%s--no-defaults", $prefix); + mtr_add_arg($args, "--no-defaults"); } mtr_add_arg($args, "%s--console", $prefix); mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir); mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir); - mtr_add_arg($args, "%s--core", $prefix); - mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix); + + if ( $mysql_version_id >= 50000 ) + { + mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix); + } + mtr_add_arg($args, "%s--default-character-set=latin1", $prefix); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); @@ -2505,7 +3365,6 @@ sub mysqld_arguments ($$$$$$) { if ( $opt_valgrind_mysqld ) { mtr_add_arg($args, "%s--skip-safemalloc", $prefix); - mtr_add_arg($args, "%s--skip-bdb", $prefix); } my $pidfile; @@ -2514,26 +3373,31 @@ sub mysqld_arguments ($$$$$$) { { my $id= $idx > 0 ? $idx + 101 : 1; - mtr_add_arg($args, "%s--log-bin=%s/log/master-bin%s", $prefix, - $opt_vardir, $sidx); + if (! $opt_skip_master_binlog) + { + mtr_add_arg($args, "%s--log-bin=%s/log/master-bin%s", $prefix, + $opt_vardir, $sidx); + } mtr_add_arg($args, "%s--pid-file=%s", $prefix, - $master->[$idx]->{'path_mypid'}); + $master->[$idx]->{'path_pid'}); mtr_add_arg($args, "%s--port=%d", $prefix, - $master->[$idx]->{'path_myport'}); + $master->[$idx]->{'port'}); mtr_add_arg($args, "%s--server-id=%d", $prefix, $id); mtr_add_arg($args, "%s--socket=%s", $prefix, - $master->[$idx]->{'path_mysock'}); - mtr_add_arg($args, "%s--innodb_data_file_path=ibdata1:128M:autoextend", $prefix); + $master->[$idx]->{'path_sock'}); + mtr_add_arg($args, "%s--innodb_data_file_path=ibdata1:10M:autoextend", $prefix); mtr_add_arg($args, "%s--local-infile", $prefix); mtr_add_arg($args, "%s--datadir=%s", $prefix, $master->[$idx]->{'path_myddir'}); - if ( $idx > 0 ) + if ( $idx > 0 or !$use_innodb) { mtr_add_arg($args, "%s--skip-innodb", $prefix); } - if ( $opt_skip_ndbcluster || !$using_ndbcluster) + my $cluster= $clusters->[$master->[$idx]->{'cluster'}]; + if ( $opt_skip_ndbcluster || + !$cluster->{'pid'}) { mtr_add_arg($args, "%s--skip-ndbcluster", $prefix); } @@ -2541,7 +3405,11 @@ sub mysqld_arguments ($$$$$$) { { mtr_add_arg($args, "%s--ndbcluster", $prefix); mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, - $opt_ndbconnectstring); + $cluster->{'connect_string'}); + if ( $mysql_version_id >= 50100 ) + { + mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + } } } @@ -2552,25 +3420,26 @@ sub mysqld_arguments ($$$$$$) { mtr_add_arg($args, "%s--datadir=%s", $prefix, $slave->[$idx]->{'path_myddir'}); - # FIXME slave get this option twice?! - mtr_add_arg($args, "%s--exit-info=256", $prefix); mtr_add_arg($args, "%s--init-rpl-role=slave", $prefix); - mtr_add_arg($args, "%s--log-bin=%s/log/slave%s-bin", $prefix, - $opt_vardir, $sidx); # FIXME use own dir for binlogs - mtr_add_arg($args, "%s--log-slave-updates", $prefix); - # FIXME option duplicated for slave + if (! $opt_skip_slave_binlog) + { + mtr_add_arg($args, "%s--log-bin=%s/log/slave%s-bin", $prefix, + $opt_vardir, $sidx); # FIXME use own dir for binlogs + mtr_add_arg($args, "%s--log-slave-updates", $prefix); + } + mtr_add_arg($args, "%s--log=%s", $prefix, $slave->[$idx]->{'path_mylog'}); mtr_add_arg($args, "%s--master-retry-count=10", $prefix); mtr_add_arg($args, "%s--pid-file=%s", $prefix, - $slave->[$idx]->{'path_mypid'}); + $slave->[$idx]->{'path_pid'}); mtr_add_arg($args, "%s--port=%d", $prefix, - $slave->[$idx]->{'path_myport'}); + $slave->[$idx]->{'port'}); mtr_add_arg($args, "%s--relay-log=%s/log/slave%s-relay-bin", $prefix, $opt_vardir, $sidx); mtr_add_arg($args, "%s--report-host=127.0.0.1", $prefix); mtr_add_arg($args, "%s--report-port=%d", $prefix, - $slave->[$idx]->{'path_myport'}); + $slave->[$idx]->{'port'}); mtr_add_arg($args, "%s--report-user=root", $prefix); mtr_add_arg($args, "%s--skip-innodb", $prefix); mtr_add_arg($args, "%s--skip-ndbcluster", $prefix); @@ -2579,10 +3448,11 @@ sub mysqld_arguments ($$$$$$) { # Directory where slaves find the dumps generated by "load data" # on the server. The path need to have constant length otherwise # test results will vary, thus a relative path is used. + my $slave_load_path= "../tmp"; mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix, - "../tmp"); + $slave_load_path); mtr_add_arg($args, "%s--socket=%s", $prefix, - $slave->[$idx]->{'path_mysock'}); + $slave->[$idx]->{'path_sock'}); mtr_add_arg($args, "%s--set-variable=slave_net_timeout=10", $prefix); if ( @$slave_master_info ) @@ -2599,10 +3469,27 @@ sub mysqld_arguments ($$$$$$) { mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix); mtr_add_arg($args, "%s--master-password=", $prefix); mtr_add_arg($args, "%s--master-port=%d", $prefix, - $master->[0]->{'path_myport'}); # First master + $master->[0]->{'port'}); # First master mtr_add_arg($args, "%s--server-id=%d", $prefix, $slave_server_id); mtr_add_arg($args, "%s--rpl-recovery-rank=%d", $prefix, $slave_rpl_rank); } + + if ( $opt_skip_ndbcluster_slave || + $slave->[$idx]->{'cluster'} == -1 || + !$clusters->[$slave->[$idx]->{'cluster'}]->{'pid'} ) + { + mtr_add_arg($args, "%s--skip-ndbcluster", $prefix); + } + else + { + mtr_add_arg($args, "%s--ndbcluster", $prefix); + mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, + $clusters->[$slave->[$idx]->{'cluster'}]->{'connect_string'}); + if ( $mysql_version_id >= 50100 ) + { + mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + } + } } # end slave if ( $opt_debug ) @@ -2610,12 +3497,12 @@ sub mysqld_arguments ($$$$$$) { if ( $type eq 'master' ) { mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/master%s.trace", - $prefix, $opt_vardir_trace, $sidx); + $prefix, $path_vardir_trace, $sidx); } if ( $type eq 'slave' ) { mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/slave%s.trace", - $prefix, $opt_vardir_trace, $sidx); + $prefix, $path_vardir_trace, $sidx); } } @@ -2623,7 +3510,6 @@ sub mysqld_arguments ($$$$$$) { mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix); mtr_add_arg($args, "%s--sort_buffer=256K", $prefix); mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix); - mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix); if ( $opt_ssl_supported ) { @@ -2654,27 +3540,22 @@ sub mysqld_arguments ($$$$$$) { mtr_add_arg($args, "%s--user=root", $prefix); } - if ( $type eq 'master' ) + my $found_skip_core= 0; + foreach my $arg ( @opt_extra_mysqld_opt, @$extra_opt ) { - - if ( ! $opt_old_master ) + # Allow --skip-core-file to be set in master.opt file + if ($arg eq "--skip-core-file") { - mtr_add_arg($args, "%s--rpl-recovery-rank=1", $prefix); - mtr_add_arg($args, "%s--init-rpl-role=master", $prefix); + $found_skip_core= 1; } - - # FIXME strange,..... - # FIXME MYSQL_MYPORT is not set anythere?! - if ( $opt_local_master ) + else { - mtr_add_arg($args, "%s--host=127.0.0.1", $prefix); - mtr_add_arg($args, "%s--port=%s", $prefix, $ENV{'MYSQL_MYPORT'}); + mtr_add_arg($args, "%s%s", $prefix, $arg); } } - - foreach my $arg ( @opt_extra_mysqld_opt, @$extra_opt ) + if ( !$found_skip_core ) { - mtr_add_arg($args, "%s%s", $prefix, $arg); + mtr_add_arg($args, "%s%s", $prefix, "--core-file"); } if ( $opt_bench ) @@ -2684,7 +3565,6 @@ sub mysqld_arguments ($$$$$$) { } elsif ( $type eq 'master' ) { - mtr_add_arg($args, "%s--exit-info=256", $prefix); mtr_add_arg($args, "%s--open-files-limit=1024", $prefix); mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'}); } @@ -2699,17 +3579,21 @@ sub mysqld_arguments ($$$$$$) { # ############################################################################## -sub mysqld_start ($$$$$) { - my $type= shift; # master/slave - my $idx= shift; +sub mysqld_start ($$$) { + my $mysqld= shift; my $extra_opt= shift; my $slave_master_info= shift; - my $using_ndbcluster= shift; - my $args; # Arg vector my $exe; my $pid= -1; + my $wait_for_pid_file= 1; + + my $type= $mysqld->{'type'}; + my $idx= $mysqld->{'idx'}; + + mtr_error("Internal error: mysqld should never be started for embedded") + if $glob_use_embedded_server; if ( $type eq 'master' ) { @@ -2721,7 +3605,7 @@ sub mysqld_start ($$$$$) { } else { - mtr_error("Unknown 'type' passed to mysqld_start"); + mtr_error("Unknown 'type' \"$type\" passed to mysqld_start"); } mtr_init_args(\$args); @@ -2731,8 +3615,7 @@ sub mysqld_start ($$$$$) { valgrind_arguments($args, \$exe); } - mysqld_arguments($args,$type,$idx,$extra_opt,$slave_master_info, - $using_ndbcluster); + mysqld_arguments($args,$type,$idx,$extra_opt,$slave_master_info); if ( $opt_gdb || $opt_manual_gdb) { @@ -2757,118 +3640,516 @@ sub mysqld_start ($$$$$) { # Indicate the exe should not be started $exe= undef; } + else + { + # Default to not wait until pid file has been created + $wait_for_pid_file= 0; + } - if ($exe_libtool and $opt_valgrind) + if ( defined $exe ) { - # Add "libtool --mode-execute" - # if running in valgrind(to avoid valgrinding bash) - unshift(@$args, "--mode=execute", $exe); - $exe= $exe_libtool; + $pid= mtr_spawn($exe, $args, "", + $mysqld->{'path_myerr'}, + $mysqld->{'path_myerr'}, + "", + { append_log_file => 1 }); } - if ( $type eq 'master' ) + if ( $wait_for_pid_file && !sleep_until_file_created($mysqld->{'path_pid'}, + $mysqld->{'start_timeout'}, + $pid)) + { + + mtr_error("Failed to start mysqld $mysqld->{'type'}"); + } + + + # Remember pid of the started process + $mysqld->{'pid'}= $pid; + + # Remember options used when starting + $mysqld->{'start_opts'}= $extra_opt; + $mysqld->{'start_slave_master_info'}= $slave_master_info; + + mtr_verbose("mysqld pid: $pid"); + return $pid; +} + + +sub stop_all_servers () { + + print "Stopping All Servers\n"; + + if ( ! $opt_skip_im ) { - if ( ! defined $exe or - $pid= mtr_spawn($exe, $args, "", - $master->[$idx]->{'path_myerr'}, - $master->[$idx]->{'path_myerr'}, - "", - { append_log_file => 1 }) ) + print "Shutting-down Instance Manager\n"; + unless (mtr_im_stop($instance_manager, "stop_all_servers")) { - return sleep_until_file_created($master->[$idx]->{'path_mypid'}, - $master->[$idx]->{'start_timeout'}, - $pid); + mtr_error("Failed to stop Instance Manager.") } } - if ( $type eq 'slave' ) + my %admin_pids; # hash of admin processes that requests shutdown + my @kill_pids; # list of processes to shutdown/kill + my $pid; + + # Start shutdown of all started masters + foreach my $mysqld (@{$master}, @{$slave}) { - if ( ! defined $exe or - $pid= mtr_spawn($exe, $args, "", - $slave->[$idx]->{'path_myerr'}, - $slave->[$idx]->{'path_myerr'}, - "", - { append_log_file => 1 }) ) + if ( $mysqld->{'pid'} ) { - return sleep_until_file_created($slave->[$idx]->{'path_mypid'}, - $master->[$idx]->{'start_timeout'}, - $pid); + $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70); + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $mysqld->{'pid'}, + pidfile => $mysqld->{'path_pid'}, + sockfile => $mysqld->{'path_sock'}, + port => $mysqld->{'port'}, + }); + + $mysqld->{'pid'}= 0; # Assume we are done with it } } - return 0; + # Start shutdown of clusters + foreach my $cluster (@{$clusters}) + { + if ( $cluster->{'pid'} ) + { + $pid= mtr_ndbmgm_start($cluster, "shutdown"); + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + if ( $ndbd->{'pid'} ) + { + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; + } + } + } + } + + # Wait blocking until all shutdown processes has completed + mtr_wait_blocking(\%admin_pids); + + # Make sure that process has shutdown else try to kill them + mtr_check_stop_servers(\@kill_pids); + + foreach my $mysqld (@{$master}, @{$slave}) + { + rm_ndbcluster_tables($mysqld->{'path_myddir'}); + } } -sub stop_masters_slaves () { +sub run_testcase_need_master_restart($) +{ + my ($tinfo)= @_; - print "Ending Tests\n"; + # We try to find out if we are to restart the master(s) + my $do_restart= 0; # Assumes we don't have to - print "Shutting-down Instance Manager\n"; - unless ( mtr_im_stop($instance_manager) ) + if ( $glob_use_embedded_server ) { - mtr_error("Failed to stop Instance Manager.") + mtr_verbose("Never start or restart for embedded server"); + return $do_restart; + } + elsif ( $tinfo->{'master_sh'} ) + { + $do_restart= 1; # Always restart if script to run + mtr_verbose("Restart master: Always restart if script to run"); + } + if ( $tinfo->{'force_restart'} ) + { + $do_restart= 1; # Always restart if --force-restart in -opt file + mtr_verbose("Restart master: Restart forced with --force-restart"); + } + elsif ( ! $opt_skip_ndbcluster and + !$tinfo->{'ndb_test'} and + $clusters->[0]->{'pid'} != 0 ) + { + $do_restart= 1; # Restart without cluster + mtr_verbose("Restart master: Test does not need cluster"); + } + elsif ( ! $opt_skip_ndbcluster and + $tinfo->{'ndb_test'} and + $clusters->[0]->{'pid'} == 0 ) + { + $do_restart= 1; # Restart with cluster + mtr_verbose("Restart master: Test need cluster"); + } + elsif( $tinfo->{'component_id'} eq 'im' ) + { + $do_restart= 1; + mtr_verbose("Restart master: Always restart for im tests"); + } + elsif ( $master->[0]->{'running_master_options'} and + $master->[0]->{'running_master_options'}->{'timezone'} ne + $tinfo->{'timezone'}) + { + $do_restart= 1; + mtr_verbose("Restart master: Different timezone"); + } + # Check that running master was started with same options + # as the current test requires + elsif (! mtr_same_opts($master->[0]->{'start_opts'}, + $tinfo->{'master_opt'}) ) + { + $do_restart= 1; + mtr_verbose("Restart master: running with different options '" . + join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . + join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); + } + elsif( ! $master->[0]->{'pid'} ) + { + $do_restart= 1; + mtr_verbose("Restart master: master is not started"); } - print "Shutting-down MySQL daemon\n\n"; - stop_masters(); - print "Master(s) shutdown finished\n"; - stop_slaves(); - print "Slave(s) shutdown finished\n"; + return $do_restart; } +sub run_testcase_need_slave_restart($) +{ + my ($tinfo)= @_; -sub stop_masters () { + # We try to find out if we are to restart the slaves + my $do_slave_restart= 0; # Assumes we don't have to - my @args; + if ( $glob_use_embedded_server ) + { + mtr_verbose("Never start or restart for embedded server"); + return $do_slave_restart; + } + elsif ( $max_slave_num == 0) + { + mtr_verbose("Skip slave restart: No testcase use slaves"); + } + else + { + + # Check if any slave is currently started + my $any_slave_started= 0; + foreach my $mysqld (@{$slave}) + { + if ( $mysqld->{'pid'} ) + { + $any_slave_started= 1; + last; + } + } + + if ($any_slave_started) + { + mtr_verbose("Restart slave: Slave is started, always restart"); + $do_slave_restart= 1; + } + elsif ( $tinfo->{'slave_num'} ) + { + mtr_verbose("Restart slave: Test need slave"); + $do_slave_restart= 1; + } + } + + return $do_slave_restart; + +} - for ( my $idx= 0; $idx < 2; $idx++ ) +# ---------------------------------------------------------------------- +# If not using a running servers we may need to stop and restart. +# We restart in the case we have initiation scripts, server options +# etc to run. But we also restart again after the test first restart +# and test is run, to get back to normal server settings. +# +# To make the code a bit more clean, we actually only stop servers +# here, and mark this to be done. Then a generic "start" part will +# start up the needed servers again. +# ---------------------------------------------------------------------- + +sub run_testcase_stop_servers($$$) { + my ($tinfo, $do_restart, $do_slave_restart)= @_; + my $pid; + my %admin_pids; # hash of admin processes that requests shutdown + my @kill_pids; # list of processes to shutdown/kill + + # Remember if we restarted for this test case (count restarts) + $tinfo->{'restarted'}= $do_restart; + + if ( $do_restart ) { - # FIXME if we hit ^C before fully started, this test will prevent - # the mysqld process from being killed - if ( $master->[$idx]->{'pid'} ) + delete $master->[0]->{'running_master_options'}; # Forget history + + # Start shutdown of all started masters + foreach my $mysqld (@{$master}) { - 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 + if ( $mysqld->{'pid'} ) + { + $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70); + + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $mysqld->{'pid'}, + pidfile => $mysqld->{'path_pid'}, + sockfile => $mysqld->{'path_sock'}, + port => $mysqld->{'port'}, + }); + + $mysqld->{'pid'}= 0; # Assume we are done with it + } + } + + # Start shutdown of master cluster + my $cluster= $clusters->[0]; + if ( $cluster->{'pid'} ) + { + $pid= mtr_ndbmgm_start($cluster, "shutdown"); + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; # Assume we are done with it + } } } - if ( ! $master->[0]->{'ndbcluster'} ) + if ( $do_restart || $do_slave_restart ) { - ndbcluster_stop(); - $master->[0]->{'ndbcluster'}= 1; + + delete $slave->[0]->{'running_slave_options'}; # Forget history + + # Start shutdown of all started slaves + foreach my $mysqld (@{$slave}) + { + if ( $mysqld->{'pid'} ) + { + $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70); + + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $mysqld->{'pid'}, + pidfile => $mysqld->{'path_pid'}, + sockfile => $mysqld->{'path_sock'}, + port => $mysqld->{'port'}, + }); + + + $mysqld->{'pid'}= 0; # Assume we are done with it + } + } + + # Start shutdown of slave cluster + my $cluster= $clusters->[1]; + if ( $cluster->{'pid'} ) + { + $pid= mtr_ndbmgm_start($cluster, "shutdown"); + + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}} ) + { + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; # Assume we are done with it + } + } } - mtr_stop_mysqld_servers(\@args); + # ---------------------------------------------------------------------- + # Shutdown has now been started and lists for the shutdown processes + # and the processes to be killed has been created + # ---------------------------------------------------------------------- + + # Wait blocking until all shutdown processes has completed + mtr_wait_blocking(\%admin_pids); + + + # Make sure that process has shutdown else try to kill them + mtr_check_stop_servers(\@kill_pids); + + foreach my $mysqld (@{$master}, @{$slave}) + { + if ( ! $mysqld->{'pid'} ) + { + # Remove ndbcluster tables if server is stopped + rm_ndbcluster_tables($mysqld->{'path_myddir'}); + } + } } -sub stop_slaves () { - my $force= shift; +# +# run_testcase_start_servers +# +# Start the servers needed by this test case +# +# RETURN +# 0 OK +# 1 Start failed +# + +sub run_testcase_start_servers($) { + my $tinfo= shift; + my $tname= $tinfo->{'name'}; + + if ( $tinfo->{'component_id'} eq 'mysqld' ) + { + if ( ! $opt_skip_ndbcluster and + !$clusters->[0]->{'pid'} and + $tinfo->{'ndb_test'} ) + { + # Test need cluster, cluster is not started, start it + ndbcluster_start($clusters->[0], ""); + } + + if ( !$master->[0]->{'pid'} ) + { + # Master mysqld is not started + do_before_start_master($tinfo); + + mysqld_start($master->[0],$tinfo->{'master_opt'},[]); + + } + + if ( $clusters->[0]->{'pid'} and ! $master->[1]->{'pid'} ) + { + # Test needs cluster, start an extra mysqld connected to cluster + + if ( $mysql_version_id >= 50100 ) + { + # First wait for first mysql server to have created ndb system + # tables ok FIXME This is a workaround so that only one mysqld + # create the tables + if ( ! sleep_until_file_created( + "$master->[0]->{'path_myddir'}/cluster/apply_status.ndb", + $master->[0]->{'start_timeout'}, + $master->[0]->{'pid'})) + { + + $tinfo->{'comment'}= "Failed to create 'cluster/apply_status' table"; + return 1; + } + } + mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - my @args; + mysqld_start($master->[1],$tinfo->{'master_opt'},[]); + } - for ( my $idx= 0; $idx < $max_slave_num; $idx++ ) + # Save this test case information, so next can examine it + $master->[0]->{'running_master_options'}= $tinfo; + } + elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' ) { - if ( $slave->[$idx]->{'pid'} ) + # We have to create defaults file every time, in order to ensure that it + # will be the same for each test. The problem is that test can change the + # file (by SET/UNSET commands), so w/o recreating the file, execution of + # one test can affect the other. + + im_create_defaults_file($instance_manager); + + if ( ! mtr_im_start($instance_manager, $tinfo->{im_opts}) ) { - 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 + $tinfo->{'comment'}= "Failed to start Instance Manager. "; + return 1; } } - mtr_stop_mysqld_servers(\@args); + # ---------------------------------------------------------------------- + # Start slaves - if needed + # ---------------------------------------------------------------------- + if ( $tinfo->{'slave_num'} ) + { + mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + + restore_slave_databases($tinfo->{'slave_num'}); + + do_before_start_slave($tinfo); + + if ( ! $opt_skip_ndbcluster_slave and + !$clusters->[1]->{'pid'} and + $tinfo->{'ndb_test'} ) + { + # Test need slave cluster, cluster is not started, start it + ndbcluster_start($clusters->[1], ""); + } + + for ( my $idx= 0; $idx < $tinfo->{'slave_num'}; $idx++ ) + { + if ( ! $slave->[$idx]->{'pid'} ) + { + mysqld_start($slave->[$idx],$tinfo->{'slave_opt'}, + $tinfo->{'slave_mi'}); + + } + } + + # Save this test case information, so next can examine it + $slave->[0]->{'running_slave_options'}= $tinfo; + } + + # Wait for clusters to start + foreach my $cluster (@{$clusters}) + { + + next if !$cluster->{'pid'}; + + if (ndbcluster_wait_started($cluster, "")) + { + # failed to start + $tinfo->{'comment'}= "Start of $cluster->{'name'} cluster failed"; + return 1; + } + } + + # Wait for mysqld's to start + foreach my $mysqld (@{$master},@{$slave}) + { + + next if !$mysqld->{'pid'}; + + if (mysqld_wait_started($mysqld)) + { + # failed to start + $tinfo->{'comment'}= + "Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}"; + return 1; + } + } + return 0; } # @@ -2876,9 +4157,16 @@ sub stop_slaves () { # Before a testcase, run in record mode, save result file to var # After testcase, run and compare with the recorded file, they should be equal! # -sub run_check_testcase ($) { +# RETURN VALUE +# 0 OK +# 1 Check failed +# +sub run_check_testcase ($$) { my $mode= shift; + my $mysqld= shift; + + my $name= "check-" . $mysqld->{'type'} . $mysqld->{'idx'}; my $args; mtr_init_args(\$args); @@ -2889,14 +4177,14 @@ sub run_check_testcase ($) { mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); - mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'}); - mtr_add_arg($args, "--port=%d", $master->[0]->{'path_myport'}); + mtr_add_arg($args, "--socket=%s", $mysqld->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $mysqld->{'port'}); mtr_add_arg($args, "--database=test"); mtr_add_arg($args, "--user=%s", $opt_user); mtr_add_arg($args, "--password="); mtr_add_arg($args, "-R"); - mtr_add_arg($args, "$opt_vardir/tmp/check-testcase.result"); + mtr_add_arg($args, "$opt_vardir/tmp/$name.result"); if ( $mode eq "before" ) { @@ -2906,116 +4194,24 @@ sub run_check_testcase ($) { my $res = mtr_run_test($exe_mysqltest,$args, "include/check-testcase.test", "", "", ""); - if ( $res == 1 and $mode = "after") + if ( $res == 1 and $mode eq "after") { mtr_run("diff",["-u", - "$opt_vardir/tmp/check-testcase.result", - "$opt_vardir/tmp/check-testcase.reject"], + "$opt_vardir/tmp/$name.result", + "$opt_vardir/tmp/$name.reject"], "", "", "", ""); } elsif ( $res ) { mtr_error("Could not execute 'check-testcase' $mode testcase"); } + return $res; } -sub run_mysqltest ($) { - my $tinfo= shift; - - my $cmdline_mysqlcheck= "$exe_mysqlcheck --no-defaults -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqlcheck .= - " --debug=d:t:A,$opt_vardir_trace/log/mysqlcheck.trace"; - } - - my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqldump .= - " --debug=d:t:A,$opt_vardir_trace/log/mysqldump.trace"; - } - my $cmdline_mysqlimport= "$exe_mysqlimport -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqlimport .= - " --debug=d:t:A,$opt_vardir_trace/log/mysqlimport.trace"; - } - - my $cmdline_mysqlshow= "$exe_mysqlshow -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqlshow .= - " --debug=d:t:A,$opt_vardir_trace/log/mysqlshow.trace"; - } - - my $cmdline_mysqlbinlog= - "$exe_mysqlbinlog" . - " --no-defaults --local-load=$opt_tmpdir" . - " --character-sets-dir=$path_charsetsdir"; - - if ( $opt_debug ) - { - $cmdline_mysqlbinlog .= - " --debug=d:t:A,$opt_vardir_trace/log/mysqlbinlog.trace"; - } - - my $cmdline_mysql= - "$exe_mysql --host=localhost --user=root --password= " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} ". - "--character-sets-dir=$path_charsetsdir"; - - my $cmdline_mysql_client_test= - "$exe_mysql_client_test --no-defaults --testcase --user=root --silent " . - "--port=$master->[0]->{'path_myport'} " . - "--vardir=$opt_vardir " . - "--socket=$master->[0]->{'path_mysock'}"; - - if ( $glob_use_embedded_server ) - { - $cmdline_mysql_client_test.= - " -A --language=$path_language" . - " -A --datadir=$slave->[0]->{'path_myddir'}" . - " -A --character-sets-dir=$path_charsetsdir"; - } - - my $cmdline_mysql_fix_system_tables= - "$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " . - "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'}"; - - $ENV{'MYSQL'}= $cmdline_mysql; - $ENV{'MYSQL_CHECK'}= $cmdline_mysqlcheck; - $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump; - $ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport; - $ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow; - $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog; - $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; - $ENV{'MYSQL_CLIENT_TEST'}= $cmdline_mysql_client_test; - $ENV{'CHARSETSDIR'}= $path_charsetsdir; - $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; - $ENV{'UDF_EXAMPLE_LIB'}= - ($lib_udf_example ? basename($lib_udf_example) : ""); - $ENV{'MY_PERROR'}= $exe_perror; - - $ENV{'NDB_MGM'}= $exe_ndb_mgm; - $ENV{'NDB_BACKUP_DIR'}= $path_ndb_data_dir; - $ENV{'NDB_DATA_DIR'}= $path_ndb_data_dir; - $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; - $ENV{'NDB_TOOLS_OUTPUT'}= $file_ndb_testrun_log; - $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; +sub run_mysqltest ($) { + my ($tinfo)= @_; my $exe= $exe_mysqltest; my $args; @@ -3036,8 +4232,8 @@ sub run_mysqltest ($) { } else # component_id == mysqld { - mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'}); - mtr_add_arg($args, "--port=%d", $master->[0]->{'path_myport'}); + mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $master->[0]->{'port'}); mtr_add_arg($args, "--database=test"); mtr_add_arg($args, "--user=%s", $opt_user); mtr_add_arg($args, "--password="); @@ -3093,7 +4289,8 @@ sub run_mysqltest ($) { if ( $opt_debug ) { - mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", $opt_vardir_trace); + mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", + $path_vardir_trace); } if ( $opt_ssl_supported ) @@ -3106,9 +4303,9 @@ sub run_mysqltest ($) { $glob_mysql_test_dir); } - # Turn on SSL for all test cases if ( $opt_ssl ) { + # Turn on SSL for _all_ test cases if option --ssl was used mtr_add_arg($args, "--ssl", $glob_mysql_test_dir); } @@ -3124,7 +4321,7 @@ sub run_mysqltest ($) { if ( $glob_use_embedded_server ) { - mysqld_arguments($args,'master',0,$tinfo->{'master_opt'},[],0); + mysqld_arguments($args,'master',0,$tinfo->{'master_opt'},[]); } # ---------------------------------------------------------------------- @@ -3171,24 +4368,32 @@ sub run_mysqltest ($) { debugger_arguments(\$args, \$exe, "client"); } - if ($exe_libtool and $opt_valgrind) - { - # Add "libtool --mode-execute" before the test to execute - # if running in valgrind(to avoid valgrinding bash) - unshift(@$args, "--mode=execute", $exe); - $exe= $exe_libtool; - } - if ( $opt_check_testcases ) { - run_check_testcase("before"); + foreach my $mysqld (@{$master}, @{$slave}) + { + if ($mysqld->{'pid'}) + { + run_check_testcase("before", $mysqld); + } + } } my $res = mtr_run_test($exe,$args,"","",$path_timefile,""); if ( $opt_check_testcases ) { - run_check_testcase("after"); + foreach my $mysqld (@{$master}, @{$slave}) + { + if ($mysqld->{'pid'}) + { + if (run_check_testcase("after", $mysqld)) + { + # Check failed, mark the test case with that info + $tinfo->{'check_testcase_failed'}= 1; + } + } + } } return $res; @@ -3367,12 +4572,20 @@ sub valgrind_arguments { my $args= shift; my $exe= shift; - mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option - mtr_add_arg($args, "--alignment=8"); - mtr_add_arg($args, "--leak-check=yes"); - mtr_add_arg($args, "--num-callers=16"); - mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) - if -f "$glob_mysql_test_dir/valgrind.supp"; + if ( $opt_callgrind) + { + mtr_add_arg($args, "--tool=callgrind"); + mtr_add_arg($args, "--base=$opt_vardir/log"); + } + else + { + mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option + mtr_add_arg($args, "--alignment=8"); + mtr_add_arg($args, "--leak-check=yes"); + mtr_add_arg($args, "--num-callers=16"); + mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) + if -f "$glob_mysql_test_dir/valgrind.supp"; + } # Add valgrind options, can be overriden by user mtr_add_arg($args, '%s', $_) for (split(' ', $opt_valgrind_options)); @@ -3380,6 +4593,14 @@ sub valgrind_arguments { mtr_add_arg($args, $$exe); $$exe= $opt_valgrind_path || "valgrind"; + + if ($exe_libtool) + { + # Add "libtool --mode-execute" before the test to execute + # if running in valgrind(to avoid valgrinding bash) + unshift(@$args, "--mode=execute", $$exe); + $$exe= $exe_libtool; + } } @@ -3399,9 +4620,7 @@ sub usage ($) { print STDERR <<HERE; -mysql-test-run [ OPTIONS ] [ TESTCASE ] - -FIXME when is TESTCASE arg used or not?! +$0 [ OPTIONS ] [ TESTCASE ] Options to control what engine/variation to run @@ -3414,33 +4633,47 @@ Options to control what engine/variation to run compress Use the compressed protocol between client and server ssl Use ssl protocol between client and server skip-ssl Dont start server with support for ssl connections - bench Run the benchmark suite FIXME - small-bench FIXME + bench Run the benchmark suite + small-bench Run the benchmarks with --small-tests --small-tables + with-ndbcluster Use cluster as default table type for benchmark + vs-config Visual Studio configuration used to create executables + (default: MTR_VS_CONFIG environment variable) Options to control directories to use - vardir=DIR The directory where files generated from the test run - is stored(default: ./var). Specifying a ramdisk or tmpfs - will speed up tests. + benchdir=DIR The directory where the benchmark suite is stored + (default: ../../mysql-bench) tmpdir=DIR The directory where temporary files are stored (default: ./var/tmp). + vardir=DIR The directory where files generated from the test run + is stored (default: ./var). Specifying a ramdisk or + tmpfs will speed up tests. + mem=DIR Run testsuite in "memory" using tmpfs if + available(default: /dev/shm) + Options to control what test suites or cases to run force Continue to run the suite after failure - with-ndbcluster Use cluster, and enable test cases that requres it - skip-ndb[cluster] Skip the ndb test cases, don't start cluster + with-ndbcluster-only Run only tests that include "ndb" in the filename + skip-ndb[cluster] Skip all tests that need cluster + skip-ndb[cluster]-slave Skip all tests that need a slave cluster + ndb-extra Run extra tests from ndb directory do-test=PREFIX Run test cases which name are prefixed with PREFIX start-from=PREFIX Run test cases starting from test prefixed with PREFIX suite=NAME Run the test suite named NAME. The default is "main" skip-rpl Skip the replication test cases. skip-im Don't start IM, and skip the IM test cases skip-test=PREFIX Skip test cases which name are prefixed with PREFIX + big-test Pass "--big-test" to mysqltest which will set the + environment variable BIG_TEST, which can be checked + from test cases. Options that specify ports master_port=PORT Specify the port number used by the first master slave_port=PORT Specify the port number used by the first slave - ndbcluster_port=PORT Specify the port number used by cluster + ndbcluster-port=PORT Specify the port number used by cluster + ndbcluster-port-slave=PORT Specify the port number used by slave cluster Options for test case authoring @@ -3454,22 +4687,26 @@ Options that pass on options Options to run test on running server extern Use running server for tests FIXME DANGEROUS - ndbconnectstring=STR Use running cluster, and connect using STR + ndb-connectstring=STR Use running cluster, and connect using STR + ndb-connectstring-slave=STR Use running slave cluster, and connect using STR user=USER User for connect to server Options for debugging the product - gdb Start the mysqld(s) in gdb - manual-gdb Let user manually start mysqld in gdb, before running test(s) - manual-debug Let user manually start mysqld in debugger, before running test(s) + client-ddd Start mysqltest client in ddd + client-debugger=NAME Start mysqltest in the selected debugger client-gdb Start mysqltest client in gdb ddd Start mysqld in ddd - client-ddd Start mysqltest client in ddd + debug Dump trace output for all servers and client programs debugger=NAME Start mysqld in the selected debugger - client-debugger=NAME Start mysqltest in the selected debugger - strace-client FIXME + gdb Start the mysqld(s) in gdb + manual-debug Let user manually start mysqld in debugger, before + running test(s) + manual-gdb Let user manually start mysqld in gdb, before running + test(s) master-binary=PATH Specify the master "mysqld" to use slave-binary=PATH Specify the slave "mysqld" to use + strace-client Create strace output for mysqltest client Options for coverage, profiling etc @@ -3478,16 +4715,19 @@ Options for coverage, profiling etc valgrind Run the "mysqltest" and "mysqld" executables using valgrind with options($default_valgrind_options) valgrind-all Synonym for --valgrind - valgrind-mysqltest Run the "mysqltest" executable with valgrind + valgrind-mysqltest Run the "mysqltest" and "mysql_client_test" executable + with valgrind valgrind-mysqld Run the "mysqld" executable with valgrind valgrind-options=ARGS Options to give valgrind, replaces default options valgrind-path=[EXE] Path to the valgrind executable + callgrind Instruct valgrind to use callgrind Misc options comment=STR Write STR to the output + notimer Don't show test case execution time script-debug Debug this script itself - timer Show test case execution time + verbose More verbose output start-and-exit Only initialize and start the servers, using the startup settings for the specified test case (if any) start-dirty Only start the servers (without initialization) for @@ -3497,27 +4737,23 @@ 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) + testcase-timeout=MINUTES Max test case run time (default $default_testcase_timeout) + suite-timeout=MINUTES Max test suite run time (default $default_suite_timeout) + Deprecated options with-openssl Deprecated option for ssl Options not yet described, or that I want to look into more - - big-test - debug - local - local-master - netware - old-master - sleep=SECONDS - socket=PATH - user-test=s - wait-timeout=SECONDS - warnings - log-warnings + local + netware + sleep=SECONDS + socket=PATH + user-test=s + wait-timeout=SECONDS + warnings + log-warnings HERE mtr_exit(1); |