summaryrefslogtreecommitdiff
path: root/mysql-test/mysql-test-run.pl
diff options
context:
space:
mode:
authorunknown <kent@mysql.com>2004-12-30 16:34:01 +0100
committerunknown <kent@mysql.com>2004-12-30 16:34:01 +0100
commit4ad77748b3ad558d4807d9aa31174eb8f72b90be (patch)
tree65585f5960d98e1389fb5a92970f63f36688e09c /mysql-test/mysql-test-run.pl
parent49501611aa534efcd18d3ee3bf94ec1ba13aa6f2 (diff)
downloadmariadb-git-4ad77748b3ad558d4807d9aa31174eb8f72b90be.tar.gz
Many files:
Perl version of mysql-test-run new file mysql-test/lib/init_db.sql: Perl version of mysql-test-run mysql-test/lib/mtr_gcov.pl: Perl version of mysql-test-run mysql-test/lib/mtr_gprof.pl: Perl version of mysql-test-run mysql-test/lib/mtr_io.pl: Perl version of mysql-test-run mysql-test/lib/mtr_match.pl: Perl version of mysql-test-run mysql-test/lib/mtr_misc.pl: Perl version of mysql-test-run mysql-test/lib/mtr_process.pl: Perl version of mysql-test-run mysql-test/lib/mtr_report.pl: Perl version of mysql-test-run mysql-test/mysql-test-run.pl: Perl version of mysql-test-run
Diffstat (limited to 'mysql-test/mysql-test-run.pl')
-rwxr-xr-xmysql-test/mysql-test-run.pl1975
1 files changed, 1975 insertions, 0 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
new file mode 100755
index 00000000000..c90ebf22dad
--- /dev/null
+++ b/mysql-test/mysql-test-run.pl
@@ -0,0 +1,1975 @@
+#!/usr/bin/perl
+# -*- cperl -*-
+
+# This is a transformation of the "mysql-test-run" Bourne shell script
+# to Perl. This is just an intermediate step, the goal is to rewrite
+# the Perl script to C. The complexity of the mysql-test-run script
+# makes it a bit hard to write and debug it as a C program directly,
+# so this is considered a prototype.
+#
+# Because of this the Perl coding style may in some cases look a bit
+# funny. The rules used are
+#
+# - The coding style is as close as possible to the C/C++ MySQL
+# coding standard.
+#
+# - Where NULL is to be returned, the undefined value is used.
+#
+# - Regexp comparisons are simple and can be translated to strcmp
+# and other string functions. To ease this transformation matching
+# is done in the lib "lib/mtr_match.pl", i.e. regular expressions
+# should be avoided in the main program.
+#
+# - The "unless" construct is not to be used. It is the same as "if !".
+#
+# - opendir/readdir/closedir is used instead of glob()/<*>.
+#
+# - All lists of arguments to send to commands are Perl lists/arrays,
+# not strings we append args to. Within reason, most string
+# concatenation for arguments should be avoided.
+#
+# - sprintf() is to be used, within reason, for all string creation.
+# This mtr_add_arg() function is also based on sprintf(), i.e. you
+# use a format string and put the variable argument in the argument
+# list.
+#
+# - Functions defined in the main program are not to be prefixed,
+# functions in "library files" are to be prefixed with "mtr_" (for
+# Mysql-Test-Run). There are some exceptions, code that fits best in
+# the main program, but are put into separate files to avoid
+# clutter, may be without prefix.
+#
+# - All stat/opendir/-f/ is to be kept in collect_test_cases(). It
+# will create a struct that the rest of the program can use to get
+# 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
+# collect_test_cases() - is to do its best to select what tests
+# to run, dig out options, if needs restart etc.
+# run_testcase() - is to run a single testcase, and follow the
+# logic set in both above. No, or rare file
+# system operations. If a test seems complex,
+# it should probably not be here.
+#
+# A nice way to trace the execution of this script while debugging
+# is to use the Devel::Trace package found at
+# "http://www.plover.com/~mjd/perl/Trace/" and run this script like
+# "perl -d:Trace mysql-test-run.pl"
+
+$Devel::Trace::TRACE= 0; # Don't trace boring init stuff
+
+#require 5.6.1;
+use File::Path;
+use File::Basename;
+use Cwd;
+use Getopt::Long;
+use Sys::Hostname;
+#use Carp;
+use IO::Socket;
+use IO::Socket::INET;
+use Data::Dumper;
+use strict;
+#use diagnostics;
+
+require "lib/mtr_process.pl";
+require "lib/mtr_io.pl";
+require "lib/mtr_gcov.pl";
+require "lib/mtr_gprof.pl";
+require "lib/mtr_report.pl";
+require "lib/mtr_match.pl";
+require "lib/mtr_misc.pl";
+
+$Devel::Trace::TRACE= 1;
+
+my @skip_if_embedded_server=
+ (
+ "bdb-deadlock",
+ "connect",
+ "flush_block_commit",
+ "grant2",
+ "grant_cache",
+ "grant",
+ "init_connect",
+ "innodb-deadlock",
+ "innodb-lock",
+ "mix_innodb_myisam_binlog",
+ "mysqlbinlog2",
+ "mysqlbinlog",
+ "mysqldump",
+ "mysql_protocols",
+ "ps_1general",
+ "rename",
+ "show_check",
+ "system_mysql_db_fix",
+ "user_var",
+ "variables",
+ );
+
+# Used by gcov
+our @mysqld_src_dirs=
+ (
+ "strings",
+ "mysys",
+ "include",
+ "extra",
+ "regex",
+ "isam",
+ "merge",
+ "myisam",
+ "myisammrg",
+ "heap",
+ "sql",
+ );
+
+##############################################################################
+#
+# Default settings
+#
+##############################################################################
+
+# We are to use handle_options() in "mysys/my_getopt.c" for the C version
+#
+# In the C version we want to use structs and, in some cases, arrays of
+# structs. We let each struct be a separate hash.
+
+# Misc global variables
+
+our $glob_win32= 0;
+our $glob_mysql_test_dir= undef;
+our $glob_hostname= undef;
+our $glob_scriptname= undef;
+our $glob_use_running_server= 0;
+our $glob_use_running_ndbcluster= 0;
+our $glob_user= 'test';
+our $glob_use_embedded_server= 0;
+
+our $glob_basedir;
+our $glob_do_test;
+
+# The total result
+
+our $path_charsetsdir;
+our $path_client_bindir;
+our $path_language;
+our $path_tests_bindir;
+our $path_timefile;
+our $path_manager_log; # Used by mysqldadmin
+our $path_slave_load_tmpdir; # What is this?!
+our $path_my_basedir;
+our $opt_tmpdir; # A path but set directly on cmd line
+
+our $opt_netware;
+
+our $opt_script_debug= 0; # Script debugging, enable with --script-debug
+
+# Options FIXME not all....
+
+our $exe_master_mysqld;
+our $exe_mysql;
+our $exe_mysqladmin;
+our $exe_mysqlbinlog;
+our $exe_mysqld;
+our $exe_mysqldump; # Called from test case
+our $exe_mysqltest;
+our $exe_slave_mysqld;
+
+our $opt_bench= 0;
+our $opt_small_bench= 0;
+our $opt_big_test= 0; # Send --big-test to mysqltest
+
+our $opt_extra_mysqld_opt; # FIXME not handled
+
+our $opt_compress;
+our $opt_current_test;
+our $opt_ddd;
+our $opt_debug;
+our $opt_do_test;
+our $opt_embedded_server;
+our $opt_extern;
+our $opt_fast;
+our $opt_force;
+
+our $opt_gcov;
+our $opt_gcov_err;
+our $opt_gcov_msg;
+
+our $opt_gdb;
+our $opt_client_gdb;
+our $opt_manual_gdb;
+
+our $opt_gprof;
+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 $slave;
+
+our $opt_ndbcluster_port;
+our $opt_ndbconnectstring;
+
+our $opt_no_manager; # Does nothing now, we never use manager
+
+our $opt_old_master;
+
+our $opt_record;
+
+our $opt_result_ext;
+
+our $opt_skip;
+our $opt_skip_rpl;
+our $opt_skip_test;
+
+our $opt_sleep;
+
+# FIXME all of the sleep time handling needs cleanup
+our $opt_sleep_time_after_restart= 1;
+our $opt_sleep_time_for_delete= 10;
+our $opt_sleep_time_for_first_master= 400; # enough time create innodb tables
+our $opt_sleep_time_for_second_master= 400;
+our $opt_sleep_time_for_first_slave= 400;
+our $opt_sleep_time_for_second_slave= 30;
+
+our $opt_socket;
+
+our $opt_source_dist;
+
+our $opt_start_and_exit;
+our $opt_start_from;
+
+our $opt_strace_client;
+
+our $opt_timer;
+
+
+our $opt_user_test;
+
+our $opt_valgrind;
+our $opt_valgrind_all;
+our $opt_valgrind_options;
+
+our $opt_verbose;
+
+our $opt_wait_for_master;
+our $opt_wait_for_slave;
+our $opt_wait_timeout= 10;
+
+our $opt_warnings;
+
+our $opt_with_ndbcluster;
+our $opt_with_openssl;
+
+
+######################################################################
+#
+# Function declarations
+#
+######################################################################
+
+sub main ();
+sub initial_setup ();
+sub command_line_setup ();
+sub executable_setup ();
+sub kill_and_cleanup ();
+sub sleep_until_file_created ($$);
+sub ndbcluster_start ();
+sub ndbcluster_stop ();
+sub run_benchmarks ($);
+sub run_tests ();
+sub mysql_install_db ();
+sub install_db ($$);
+sub run_testcase ($);
+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 run_mysqltest ($);
+
+######################################################################
+#
+# Main program
+#
+######################################################################
+
+main();
+
+sub main () {
+
+ initial_setup();
+ command_line_setup();
+ executable_setup();
+ signal_setup();
+
+ if ( $opt_gcov )
+ {
+ gcov_prepare();
+ }
+
+ if ( $opt_gprof )
+ {
+ gprof_prepare();
+ }
+
+ if ( ! $glob_use_running_server )
+ {
+ kill_and_cleanup();
+ mysql_install_db();
+
+ if ( $opt_with_ndbcluster and ! $glob_use_running_ndbcluster )
+ {
+ ndbcluster_start(); # We start the cluster storage engine
+ }
+
+# mysql_loadstd(); FIXME copying from "std_data" .frm and
+# .MGR but there are none?!
+ }
+
+ if ( $opt_start_and_exit )
+ {
+ mtr_report("Servers started, exiting");
+ }
+ else
+ {
+ if ( $opt_bench )
+ {
+ run_benchmarks(shift); # Shift what? Extra arguments?!
+ }
+ else
+ {
+ run_tests();
+ }
+ }
+
+ exit(0);
+}
+
+##############################################################################
+#
+# Initial setup independent on command line arguments
+#
+##############################################################################
+
+sub initial_setup () {
+
+ select(STDOUT);
+ $| = 1; # Make unbuffered
+
+ $glob_scriptname= basename($0);
+
+ $glob_win32= ($^O eq "MSWin32");
+
+ # 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" )
+ {
+ $opt_source_dist= 1;
+ }
+
+ $glob_hostname= mtr_full_hostname();
+
+ # 'basedir' is always parent of "mysql-test" directory
+ $glob_mysql_test_dir= cwd();
+ $glob_basedir= dirname($glob_mysql_test_dir);
+
+ $path_timefile= "$glob_mysql_test_dir/var/log/mysqltest-time";
+
+ # 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;
+}
+
+
+
+##############################################################################
+#
+# Default settings
+#
+##############################################################################
+
+sub command_line_setup () {
+
+ # These are defaults for things that are set on the command line
+
+ $opt_tmpdir= "$glob_mysql_test_dir/var/tmp";
+ # FIXME maybe unneded?
+ $path_manager_log= "$glob_mysql_test_dir/var/log/manager.log";
+ $opt_current_test= "$glob_mysql_test_dir/var/log/current_test";
+
+ my $opt_master_myport= 9306;
+ my $opt_slave_myport= 9308;
+ $opt_ndbcluster_port= 9350;
+ $opt_sleep_time_for_delete= 10;
+
+ my $opt_user;
+
+ # Read the command line
+
+ GetOptions(
+ 'bench' => \$opt_bench,
+ 'big-test' => \$opt_big_test,
+ 'client-gdb' => \$opt_client_gdb,
+ 'compress' => \$opt_compress,
+ 'ddd' => \$opt_ddd,
+ 'debug' => \$opt_debug,
+ 'do-test=s' => \$opt_do_test,
+ 'embedded-server' => \$opt_embedded_server,
+ 'extern' => \$opt_extern,
+ 'fast' => \$opt_fast,
+ 'force' => \$opt_force,
+ 'gcov' => \$opt_gcov,
+ 'gdb' => \$opt_gdb,
+ 'gprof' => \$opt_gprof,
+ 'local' => \$opt_local,
+ 'local-master' => \$opt_local_master,
+ 'manual-gdb' => \$opt_manual_gdb,
+ 'master-binary=s' => \$exe_master_mysqld,
+ 'master_port=i' => \$opt_master_myport,
+ 'mysqld=s' => \$opt_extra_mysqld_opt,
+ 'ndbcluster_port=i' => \$opt_ndbcluster_port,
+ 'ndbconnectstring=s' => \$opt_ndbconnectstring,
+ 'netware' => \$opt_netware,
+ 'no-manager' => \$opt_no_manager,
+ 'old-master' => \$opt_old_master,
+ 'record' => \$opt_record,
+ 'script-debug' => \$opt_script_debug,
+ 'skip-rpl' => \$opt_skip_rpl,
+ 'skip-test=s' => \$opt_skip_test,
+ 'slave-binary=s' => \$exe_slave_mysqld,
+ 'slave_port=i' => \$opt_slave_myport,
+ 'sleep=i' => \$opt_sleep,
+ 'small-bench' => \$opt_small_bench,
+ 'socket=s' => \$opt_socket,
+ 'start-and-exit' => \$opt_start_and_exit,
+ 'start-from=s' => \$opt_start_from,
+ 'strace-client' => \$opt_strace_client,
+ 'timer' => \$opt_timer,
+ 'tmpdir=s' => \$opt_tmpdir,
+ 'user-test=s' => \$opt_user_test,
+ 'user=s' => \$opt_user,
+ 'valgrind' => \$opt_valgrind,
+ 'valgrind-all' => \$opt_valgrind_all,
+ 'valgrind-options=s' => \$opt_valgrind_options,
+ 'verbose' => \$opt_verbose,
+ 'wait-timeout=i' => \$opt_wait_timeout,
+ 'warnings|log-warnings' => \$opt_warnings,
+ 'with-ndbcluster' => \$opt_with_ndbcluster,
+ 'with-openssl' => \$opt_with_openssl,
+ ) or usage("Can't read options");
+
+
+ # Put this into a hash, will be a C struct
+
+ $master->[0]->{'path_myddir'}= "$glob_mysql_test_dir/var/master-data";
+ $master->[0]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/master.err";
+ $master->[0]->{'path_mylog'}= "$glob_mysql_test_dir/var/log/master.log";
+ $master->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/master.pid";
+ $master->[0]->{'path_mysock'}= "$opt_tmpdir/master.sock";
+ $master->[0]->{'path_myport'}= $opt_master_myport;
+
+ $master->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/master1-data";
+ $master->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/master1.err";
+ $master->[1]->{'path_mylog'}= "$glob_mysql_test_dir/var/log/master1.log";
+ $master->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/master1.pid";
+ $master->[1]->{'path_mysock'}= "$opt_tmpdir/master1.sock";
+ $master->[1]->{'path_myport'}= $opt_master_myport + 1;
+
+ $slave->[0]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave-data";
+ $slave->[0]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave.err";
+ $slave->[0]->{'path_mylog'}= "$glob_mysql_test_dir/var/log/slave.log";
+ $slave->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave.pid";
+ $slave->[0]->{'path_mysock'}= "$opt_tmpdir/slave.sock";
+ $slave->[0]->{'path_myport'}= $opt_slave_myport;
+
+ $slave->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave1-data";
+ $slave->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave1.err";
+ $slave->[1]->{'path_mylog'}= "$glob_mysql_test_dir/var/log/slave1.log";
+ $slave->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave1.pid";
+ $slave->[1]->{'path_mysock'}= "$opt_tmpdir/slave1.sock";
+ $slave->[1]->{'path_myport'}= $opt_slave_myport + 1;
+
+ $slave->[2]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave2-data";
+ $slave->[2]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave2.err";
+ $slave->[2]->{'path_mylog'}= "$glob_mysql_test_dir/var/log/slave2.log";
+ $slave->[2]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave2.pid";
+ $slave->[2]->{'path_mysock'}= "$opt_tmpdir/slave2.sock";
+ $slave->[2]->{'path_myport'}= $opt_slave_myport + 2;
+
+ # Do sanity checks of command line arguments
+
+ if ( $opt_extern and $opt_local )
+ {
+ die "Can't use --extern and --local at the same time";
+ }
+
+ if ( ! $opt_socket )
+ { # FIXME set default before reading options?
+# $opt_socket= '@MYSQL_UNIX_ADDR@';
+ $opt_socket= "/tmp/mysql.sock"; # FIXME
+ }
+
+ 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;
+ }
+
+ # --------------------------------------------------------------------------
+ # Set LD_LIBRARY_PATH if we are using shared libraries
+ # --------------------------------------------------------------------------
+ $ENV{'LD_LIBRARY_PATH'}=
+ "$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
+ ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
+ $ENV{'DYLD_LIBRARY_PATH'}=
+ "$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
+ ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : "");
+
+ # --------------------------------------------------------------------------
+ # Look at the command line options and set script flags
+ # --------------------------------------------------------------------------
+
+ if ( $opt_record and ! @ARGV)
+ {
+ mtr_error("Will not run in record mode without a specific test case");
+ }
+
+ if ( $opt_embedded_server )
+ {
+ $glob_use_embedded_server= 1;
+ $opt_skip_rpl= 1; # We never run replication with embedded
+
+ if ( $opt_extern )
+ {
+ die "Can't use --extern with --embedded-server";
+ }
+ $opt_result_ext= ".es";
+ }
+
+ # FIXME don't understand what this is
+# if ( $opt_local_master )
+# {
+# $opt_master_myport= 3306;
+# }
+
+ if ( $opt_small_bench )
+ {
+ $opt_bench= 1;
+ }
+
+ if ( $opt_sleep )
+ {
+ $opt_sleep_time_after_restart= $opt_sleep;
+ }
+
+ if ( $opt_gcov )
+ {
+ if ( $opt_source_dist )
+ {
+ die "Coverage test needs the source - please use source dist";
+ }
+ }
+
+ if ( $opt_gdb )
+ {
+ $opt_wait_timeout= 300;
+ if ( $opt_extern )
+ {
+ die "Can't use --extern with --gdb";
+ }
+ }
+
+ if ( $opt_manual_gdb )
+ {
+ $opt_gdb= 1;
+ if ( $opt_extern )
+ {
+ die "Can't use --extern with --manual-gdb";
+ }
+ }
+
+ if ( $opt_ddd )
+ {
+ if ( $opt_extern )
+ {
+ die "Can't use --extern with --ddd";
+ }
+ }
+
+ if ( $opt_ndbconnectstring )
+ {
+ $glob_use_running_ndbcluster= 1;
+ $opt_with_ndbcluster= 1;
+ }
+
+ # FIXME
+
+ #if ( $opt_valgrind or $opt_valgrind_all )
+ #{
+ # VALGRIND=`which valgrind` # this will print an error if not found FIXME
+ # Give good warning to the user and stop
+ # if ( ! $VALGRIND )
+ # {
+ # print "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org.\n"
+ # exit 1
+ # }
+ # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr
+ # valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
+ # VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
+ # $opt_extra_mysqld_opt.= " --skip-safemalloc --skip-bdb";
+ # SLEEP_TIME_AFTER_RESTART=10
+ # $opt_sleep_time_for_delete= 60
+ # $glob_use_running_server= ""
+ # if ( "$1"= "--valgrind-all" )
+ # {
+ # VALGRIND="$VALGRIND -v --show-reachable=yes"
+ # }
+ #}
+
+ if ( $opt_user )
+ {
+ $glob_user= $opt_user;
+ }
+ elsif ( $glob_use_running_server )
+ {
+ $glob_user= "test";
+ }
+ else
+ {
+ $glob_user= "root"; # We want to do FLUSH xxx commands
+ }
+
+}
+
+
+##############################################################################
+#
+# Set paths to various executable programs
+#
+##############################################################################
+
+sub executable_setup () {
+
+ if ( $opt_source_dist )
+ {
+ if ( $glob_use_embedded_server )
+ {
+ if ( -f "$glob_basedir/libmysqld/examples/mysqltest" )
+ {
+ $exe_mysqltest= "$glob_basedir/libmysqld/examples/mysqltest";
+ }
+ else
+ {
+ mtr_error("Cannot find embedded server 'mysqltest'");
+ }
+ }
+ else
+ {
+ $exe_mysqld= "$glob_basedir/sql/mysqld";
+ if ( -f "$glob_basedir/client/.libs/lt-mysqltest" )
+ {
+ $exe_mysqltest= "$glob_basedir/client/.libs/lt-mysqltest";
+ }
+ elsif ( -f "$glob_basedir/client/.libs/mysqltest" )
+ {
+ $exe_mysqltest= "$glob_basedir/client/.libs/mysqltest";
+ }
+ else
+ {
+ $exe_mysqltest= "$glob_basedir/client/mysqltest";
+ }
+ }
+ if ( -f "$glob_basedir/client/.libs/mysqldump" )
+ {
+ $exe_mysqldump= "$glob_basedir/client/.libs/mysqldump";
+ }
+ else
+ {
+ $exe_mysqldump= "$glob_basedir/client/mysqldump";
+ }
+ if ( -f "$glob_basedir/client/.libs/mysqlbinlog" )
+ {
+ $exe_mysqlbinlog= "$glob_basedir/client/.libs/mysqlbinlog";
+ }
+ else
+ {
+ $exe_mysqlbinlog= "$glob_basedir/client/mysqlbinlog";
+ }
+
+ $path_client_bindir= "$glob_basedir/client";
+ $path_tests_bindir= "$glob_basedir/tests";
+ $exe_mysqladmin= "$path_client_bindir/mysqladmin";
+ $exe_mysql= "$path_client_bindir/mysql";
+ $path_language= "$glob_basedir/sql/share/english/";
+ $path_charsetsdir= "$glob_basedir/sql/share/charsets";
+ }
+ else
+ {
+ $path_client_bindir= "$glob_basedir/bin";
+ $path_tests_bindir= "$glob_basedir/tests";
+ $exe_mysqltest= "$path_client_bindir/mysqltest";
+ $exe_mysqldump= "$path_client_bindir/mysqldump";
+ $exe_mysqlbinlog= "$path_client_bindir/mysqlbinlog";
+ $exe_mysqladmin= "$path_client_bindir/mysqladmin";
+ $exe_mysql= "$path_client_bindir/mysql";
+ if ( -d "$glob_basedir/share/mysql/english" )
+ {
+ $path_language ="$glob_basedir/share/mysql/english/";
+ $path_charsetsdir ="$glob_basedir/share/mysql/charsets";
+ }
+ else
+ {
+ $path_language ="$glob_basedir/share/english/";
+ $path_charsetsdir ="$glob_basedir/share/charsets";
+ }
+
+ if ( -x "$glob_basedir/libexec/mysqld" )
+ {
+ $exe_mysqld= "$glob_basedir/libexec/mysqld";
+ }
+ else
+ {
+ $exe_mysqld= "$glob_basedir/bin/mysqld";
+ }
+
+ }
+
+ # FIXME special $exe_master_mysqld and $exe_slave_mysqld
+ # are not used that much....
+
+ if ( ! $exe_master_mysqld )
+ {
+ $exe_master_mysqld= $exe_mysqld;
+ }
+
+ if ( ! $exe_slave_mysqld )
+ {
+ $exe_slave_mysqld= $exe_mysqld;
+ }
+}
+
+
+##############################################################################
+#
+# If we get a ^C, we try to clean up before termination
+#
+##############################################################################
+# FIXME check restrictions what to do in a signal handler
+
+sub signal_setup () {
+ $SIG{INT}= \&handle_int_signal;
+}
+
+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();
+ exit(1);
+}
+
+
+##############################################################################
+#
+# Collect information about test cases we are to run
+#
+##############################################################################
+
+sub collect_test_cases () {
+ my $testdir= "$glob_mysql_test_dir/t";
+
+ my @tests; # Array of hash, will be array of C struct
+
+ opendir(TESTDIR, $testdir) or die "Can't open dir \"$testdir\": $!";
+
+ foreach my $elem ( sort readdir(TESTDIR) ) {
+ my $tname= mtr_match_extension($elem,"test");
+ next if ! defined $tname;
+ next if $opt_do_test and ! defined mtr_match_prefix($elem,$opt_do_test);
+ my $path= "$testdir/$elem";
+
+ # ----------------------------------------------------------------------
+ # Skip some tests silently
+ # ----------------------------------------------------------------------
+
+ if ( $opt_start_from and $tname lt $opt_start_from )
+ {
+ next;
+ }
+
+ # ----------------------------------------------------------------------
+ # Skip some tests but include in list, just mark them to skip
+ # ----------------------------------------------------------------------
+
+ my $tinfo= {};
+ $tinfo->{'name'}= $tname;
+ $tinfo->{'result_file'}= "r/$tname.result";
+ push(@tests, $tinfo);
+
+ if ( $opt_skip_test and defined mtr_match_prefix($tname,$opt_skip_test) )
+ {
+ $tinfo->{'skip'}= 1;
+ next;
+ }
+
+ # FIXME temporary solution, we have a hard coded list of test cases to
+ # skip if we are using the embedded server
+
+ if ( $glob_use_embedded_server and
+ mtr_match_any_exact($tname,\@skip_if_embedded_server) )
+ {
+ $tinfo->{'skip'}= 1;
+ next;
+ }
+
+ # ----------------------------------------------------------------------
+ # Collect information about test case
+ # ----------------------------------------------------------------------
+
+ $tinfo->{'path'}= $path;
+
+ if ( defined mtr_match_prefix($tname,"rpl") )
+ {
+ if ( $opt_skip_rpl )
+ {
+ $tinfo->{'skip'}= 1;
+ next;
+ }
+
+ # FIXME currently we always restart slaves
+ $tinfo->{'slave_restart'}= 1;
+
+ if ( $tname eq 'rpl_failsafe' or $tname eq 'rpl_chain_temp_table' )
+ {
+ $tinfo->{'slave_num'}= 3;
+ }
+ else
+ {
+ $tinfo->{'slave_num'}= 1;
+ }
+ }
+
+ # FIXME what about embedded_server + ndbcluster, skip ?!
+
+ my $master_opt_file= "$testdir/$tname-master.opt";
+ my $slave_opt_file= "$testdir/$tname-slave.opt";
+ my $slave_mi_file= "$testdir/$tname.slave-mi";
+ my $master_sh= "$testdir/$tname-master.sh";
+ my $slave_sh= "$testdir/$tname-slave.sh";
+
+ if ( -f $master_opt_file )
+ {
+ $tinfo->{'master_restart'}= 1; # We think so for now
+ # This is a dirty hack from old mysql-test-run, we use the opt file
+ # to flag other things as well, it is not a opt list at all
+ my $extra_master_opt= mtr_get_opts_from_file($master_opt_file);
+
+ foreach my $opt (@$extra_master_opt)
+ {
+ my $value;
+
+ $value= mtr_match_prefix($opt, "--timezone=");
+
+ if ( defined $value )
+ {
+ $ENV{'TZ'}= $value; # FIXME pass this on somehow....
+ $extra_master_opt= [];
+ $tinfo->{'master_restart'}= 0;
+ last;
+ }
+
+ $value= mtr_match_prefix($opt, "--result-file=");
+
+ if ( defined $value )
+ {
+ $tinfo->{'result_file'}= "r/$value.result";
+ if ( $opt_result_ext and $opt_record or
+ -f "$tinfo->{'result_file'}$opt_result_ext")
+ {
+ $tinfo->{'result_file'}.= $opt_result_ext;
+ }
+ $extra_master_opt= [];
+ $tinfo->{'master_restart'}= 0;
+ last;
+ }
+ }
+
+ $tinfo->{'master_opt'}= $extra_master_opt;
+ }
+
+ if ( -f $slave_opt_file )
+ {
+ $tinfo->{'slave_opt'}= mtr_get_opts_from_file($slave_opt_file);
+ $tinfo->{'slave_restart'}= 1;
+ }
+
+ if ( -f $slave_mi_file )
+ {
+ $tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file);
+ $tinfo->{'slave_restart'}= 1;
+ }
+
+ if ( -f $master_sh )
+ {
+ if ( $glob_win32 )
+ {
+ $tinfo->{'skip'}= 1;
+ }
+ else
+ {
+ $tinfo->{'master_sh'}= $master_sh;
+ $tinfo->{'master_restart'}= 1;
+ }
+ }
+
+ if ( -f $slave_sh )
+ {
+ if ( $glob_win32 )
+ {
+ $tinfo->{'skip'}= 1;
+ }
+ else
+ {
+ $tinfo->{'slave_sh'}= $slave_sh;
+ $tinfo->{'slave_restart'}= 1;
+ }
+ }
+
+ # We can't restart a running server that may be in use
+
+ if ( $glob_use_running_server and
+ ( $tinfo->{'master_restart'} or $tinfo->{'slave_restart'} ) )
+ {
+ $tinfo->{'skip'}= 1;
+ }
+
+ }
+
+ closedir TESTDIR;
+
+ return \@tests;
+}
+
+
+##############################################################################
+#
+# Handle left overs from previous runs
+#
+##############################################################################
+
+sub kill_and_cleanup () {
+
+ 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'});
+ }
+ else
+ {
+ # Ensure that no old mysqld test servers are running
+ # This is different from terminating processes we have
+ # started from ths run of the script, this is terminating
+ # leftovers from previous runs.
+
+ mtr_report("Killing Possible Leftover Processes");
+ mtr_kill_leftovers();
+ }
+
+ if ( $opt_with_ndbcluster and ! $glob_use_running_ndbcluster )
+ {
+ ndbcluster_stop();
+ }
+
+ mtr_report("Removing Stale Files");
+
+ rmtree("$glob_mysql_test_dir/var/log");
+ rmtree("$glob_mysql_test_dir/var/ndbcluster");
+ rmtree("$glob_mysql_test_dir/var/run");
+ rmtree("$glob_mysql_test_dir/var/tmp");
+
+ mkpath("$glob_mysql_test_dir/var/log");
+ mkpath("$glob_mysql_test_dir/var/ndbcluster");
+ mkpath("$glob_mysql_test_dir/var/run");
+ mkpath("$glob_mysql_test_dir/var/tmp");
+ mkpath($opt_tmpdir);
+
+ rmtree("$master->[0]->{'path_myddir'}");
+ mkpath("$master->[0]->{'path_myddir'}/mysql"); # Need to create subdir?!
+ mkpath("$master->[0]->{'path_myddir'}/test");
+
+ rmtree("$master->[1]->{'path_myddir'}");
+ mkpath("$master->[1]->{'path_myddir'}/mysql"); # Need to create subdir?!
+ mkpath("$master->[1]->{'path_myddir'}/test");
+
+ rmtree("$slave->[0]->{'path_myddir'}");
+ mkpath("$slave->[0]->{'path_myddir'}/mysql"); # Need to create subdir?!
+ mkpath("$slave->[0]->{'path_myddir'}/test");
+
+ rmtree("$slave->[1]->{'path_myddir'}");
+ mkpath("$slave->[1]->{'path_myddir'}/mysql"); # Need to create subdir?!
+ mkpath("$slave->[1]->{'path_myddir'}/test");
+
+ rmtree("$slave->[2]->{'path_myddir'}");
+ mkpath("$slave->[2]->{'path_myddir'}/mysql"); # Need to create subdir?!
+ mkpath("$slave->[2]->{'path_myddir'}/test");
+
+ $opt_wait_for_master= $opt_sleep_time_for_first_master;
+ $opt_wait_for_slave= $opt_sleep_time_for_first_slave;
+}
+
+
+# FIXME
+
+sub sleep_until_file_created ($$) {
+ my $pidfile= shift;
+ my $timeout= shift;
+
+ my $loop= $timeout * 2;
+ while ( $loop-- )
+ {
+ if ( -r $pidfile )
+ {
+ return;
+ }
+ sleep(1);
+ }
+
+ if ( ! -r $pidfile )
+ {
+ die "No $pidfile was created";
+ }
+}
+
+
+##############################################################################
+#
+# Start the ndb cluster
+#
+##############################################################################
+
+# FIXME why is there a different start below?!
+
+sub ndbcluster_start () {
+
+ mtr_report("Starting ndbcluster");
+ my $ndbcluster_opts= $opt_bench ? "" : "--small";
+ # FIXME check result code?!
+ mtr_run("./ndb/ndbcluster",
+ ["--port-base=$opt_ndbcluster_port",
+ $ndbcluster_opts,
+ "--diskless",
+ "--initial",
+ "--data-dir=$glob_mysql_test_dir/var"],
+ "", "", "", "");
+}
+
+sub ndbcluster_stop () {
+ mtr_run("./ndb/ndbcluster",
+ ["--data-dir=$glob_mysql_test_dir/var",
+ "--port-base=$opt_ndbcluster_port",
+ "--stop"],
+ "", "", "", "");
+}
+
+
+##############################################################################
+#
+# Run the benchmark suite
+#
+##############################################################################
+
+sub run_benchmarks ($) {
+ my $benchmark= shift;
+
+ my $args;
+
+ if ( ! $glob_use_embedded_server and ! $opt_local_master )
+ {
+ $master->[0]->{'pid'}= mysqld_start('master',0,[],[]);
+ }
+
+ mtr_init_args(\$args);
+
+ mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'});
+ mtr_add_arg($args, "--user=root");
+
+ if ( $opt_small_bench )
+ {
+ mtr_add_arg($args, "--small-test");
+ mtr_add_arg($args, "--small-tables");
+ }
+
+ if ( $opt_with_ndbcluster )
+ {
+ mtr_add_arg($args, "--create-options=TYPE=ndb");
+ }
+
+ my $benchdir= "$glob_basedir/sql-bench";
+ chdir($benchdir); # FIXME check error
+
+ # FIXME write shorter....
+
+ if ( ! $benchmark )
+ {
+ mtr_add_arg($args, "--log");
+ mtr_run("./run-all-tests", $args, "", "", "", "");
+ # FIXME check result code?!
+ }
+ elsif ( -x $benchmark )
+ {
+ mtr_run("./$benchmark", $args, "", "", "", "");
+ # FIXME check result code?!
+ }
+ else
+ {
+ mtr_error("benchmark $benchmark not found");
+ }
+
+ chdir($glob_mysql_test_dir); # Go back
+
+ if ( ! $glob_use_embedded_server )
+ {
+ stop_masters();
+ }
+}
+
+
+##############################################################################
+#
+# Run the test suite
+#
+##############################################################################
+
+sub run_tests () {
+
+ my $tests= collect_test_cases();
+
+ mtr_report("Starting Tests");
+
+ mtr_print_header();
+
+ foreach my $tinfo ( @$tests )
+ {
+ run_testcase($tinfo);
+ }
+
+ mtr_print_line();
+
+ if ( ! $opt_gdb and ! $glob_use_running_server and
+ ! $opt_ddd and ! $glob_use_embedded_server )
+ {
+ stop_masters_slaves();
+ }
+
+ if ( $opt_with_ndbcluster and ! $glob_use_running_ndbcluster )
+ {
+ ndbcluster_stop();
+ }
+
+ if ( $opt_gcov )
+ {
+ gcov_collect(); # collect coverage information
+ }
+ if ( $opt_gprof )
+ {
+ gprof_collect(); # collect coverage information
+ }
+
+ mtr_report_stats($tests);
+}
+
+
+##############################################################################
+#
+# Initiate the test databases
+#
+##############################################################################
+
+sub mysql_install_db () {
+
+ mtr_report("Installing Test Databases");
+
+ install_db('master', $master->[0]->{'path_myddir'});
+ install_db('slave', $slave->[0]->{'path_myddir'});
+
+ return 0;
+}
+
+
+sub install_db ($$) {
+ my $type= shift;
+ my $data_dir= shift;
+
+ my $init_db_sql= "lib/init_db.sql"; # FIXME this is too simple maybe
+ my $args;
+
+ mtr_report("Installing \u$type Databases");
+
+ mtr_init_args(\$args);
+
+ mtr_add_arg($args, "--no-defaults");
+ mtr_add_arg($args, "--bootstrap");
+ mtr_add_arg($args, "--skip-grant-tables");
+ mtr_add_arg($args, "--basedir=%s", $path_my_basedir);
+ 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");
+
+ if ( ! $opt_netware )
+ {
+ mtr_add_arg($args, "--language=%s", $path_language);
+ mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
+ }
+
+ if ( mtr_run($exe_mysqld, $args, $init_db_sql,
+ $path_manager_log, $path_manager_log, "") != 0 )
+ {
+ mtr_error("error executing mysqld --bootstrap\n" .
+ "Could not install $type test DBs");
+ }
+}
+
+
+##############################################################################
+#
+# 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($opt_current_test,"$tname\n"); # Always tell where we are
+
+ # ----------------------------------------------------------------------
+ # If marked to skip, just print out and return.
+ # Note that a test case not marked as 'skip' can still be
+ # skipped later, because of the test case itself in cooperation
+ # with the mysqltest program tells us so.
+ # ----------------------------------------------------------------------
+
+ if ( $tinfo->{'skip'} )
+ {
+ mtr_report_test_skipped($tinfo);
+ return;
+ }
+
+ # ----------------------------------------------------------------------
+ # 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 ( ! $glob_use_running_server and ! $glob_use_embedded_server )
+ {
+ if ( $tinfo->{'master_restart'} or $master->[0]->{'uses_special_flags'} )
+ {
+ stop_masters();
+ $master->[0]->{'uses_special_flags'}= 0; # Forget about why we stopped
+ }
+
+ # ----------------------------------------------------------------------
+ # Always terminate all slaves, if any. Else we may have useless
+ # reconnection attempts and error messages in case the slave and
+ # master servers restart.
+ # ----------------------------------------------------------------------
+
+ stop_slaves();
+
+ # ----------------------------------------------------------------------
+ # Start masters
+ # ----------------------------------------------------------------------
+
+ mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
+ do_before_start_master($tname,$tinfo->{'master_sh'});
+
+ # 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.
+
+ if ( ! $opt_local_master )
+ {
+ if ( ! $master->[0]->{'pid'} )
+ {
+ $master->[0]->{'pid'}=
+ mysqld_start('master',0,$tinfo->{'master_opt'},[]);
+ }
+ if ( $opt_with_ndbcluster and ! $master->[1]->{'pid'} )
+ {
+ $master->[1]->{'pid'}=
+ mysqld_start('master',1,$tinfo->{'master_opt'},[]);
+ }
+
+ if ( $tinfo->{'master_opt'} )
+ {
+ $master->[0]->{'uses_special_flags'}= 1;
+ }
+ }
+
+ # ----------------------------------------------------------------------
+ # Start slaves - if needed
+ # ----------------------------------------------------------------------
+
+ if ( $tinfo->{'slave_num'} )
+ {
+ mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
+
+ do_before_start_slave($tname,$tinfo->{'slave_sh'});
+
+ 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'});
+ }
+ }
+ }
+ }
+
+ # ----------------------------------------------------------------------
+ # Run the test case
+ # ----------------------------------------------------------------------
+
+ {
+ unlink("r/$tname.reject");
+ unlink($path_timefile);
+
+ mtr_report_test_name($tinfo);
+
+ my $res= run_mysqltest($tinfo);
+
+ if ( $res == 0 )
+ {
+ mtr_report_test_passed($tinfo);
+ }
+ elsif ( $res == 2 )
+ {
+ # Testcase itself tell us to skip this one
+ mtr_report_test_skipped($tinfo);
+ }
+ else
+ {
+ # Test case failed
+ if ( $res > 2 )
+ {
+ mtr_tofile($path_timefile,
+ "mysqltest returned unexpected code $res, " .
+ "it has probably crashed");
+ }
+ mtr_report_test_failed($tinfo);
+ mtr_show_failed_diff($tname);
+ print "\n";
+ if ( ! $opt_force )
+ {
+ print "Aborting: $tname failed. To continue, re-run with '--force'.";
+ print "\n";
+ if ( ! $opt_gdb and ! $glob_use_running_server and
+ ! $opt_ddd and ! $glob_use_embedded_server )
+ {
+ stop_masters_slaves();
+ }
+ exit(1);
+ }
+
+ # FIXME always terminate on failure?!
+ if ( ! $opt_gdb and ! $glob_use_running_server and
+ ! $opt_ddd and ! $glob_use_embedded_server )
+ {
+ stop_masters_slaves();
+ }
+ print "Resuming Tests\n\n";
+ }
+ }
+}
+
+
+##############################################################################
+#
+# Start and stop servers
+#
+##############################################################################
+
+# 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 $master_init_script= shift;
+
+ # 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")
+ {
+ # FIXME we really want separate dir for binlogs
+ `rm -fr $glob_mysql_test_dir/var/log/master-bin.*`;
+# unlink("$glob_mysql_test_dir/var/log/master-bin.*");
+ }
+
+ # Remove old master.info and relay-log.info files
+ unlink("$glob_mysql_test_dir/var/master-data/master.info");
+ unlink("$glob_mysql_test_dir/var/master-data/relay-log.info");
+ unlink("$glob_mysql_test_dir/var/master1-data/master.info");
+ unlink("$glob_mysql_test_dir/var/master1-data/relay-log.info");
+
+ #run master initialization shell script if one exists
+
+ if ( $master_init_script and
+ mtr_run($master_init_script, [], "", "", "", "") != 0 )
+ {
+ mtr_error("can't run $master_init_script");
+ }
+ # for gcov FIXME needed? If so we need more absolute paths
+# chdir($glob_basedir);
+}
+
+sub do_before_start_slave ($$) {
+ my $tname= shift;
+ my $slave_init_script= shift;
+
+ # When testing fail-safe replication, we will have more than one slave
+ # in this case, we start secondary slaves with an argument
+
+ # 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" )
+ {
+ # FIXME we really want separate dir for binlogs
+ `rm -fr $glob_mysql_test_dir/var/log/slave*-bin.*`;
+# unlink("$glob_mysql_test_dir/var/log/slave*-bin.*"); # FIXME idx???
+ # FIXME really master?!
+ unlink("$glob_mysql_test_dir/var/slave-data/master.info");
+ unlink("$glob_mysql_test_dir/var/slave-data/relay-log.info");
+ }
+
+ #run slave initialization shell script if one exists
+ if ( $slave_init_script and
+ mtr_run($slave_init_script, [], "", "", "", "") != 0 )
+ {
+ mtr_error("can't run $slave_init_script");
+ }
+
+ unlink("$glob_mysql_test_dir/var/slave-data/log.*");
+}
+
+sub mysqld_arguments ($$$$$) {
+ my $args= shift;
+ my $type= shift; # master/slave/bootstrap
+ my $idx= shift;
+ my $extra_opt= shift;
+ my $slave_master_info= shift;
+
+ my $sidx= ""; # Index as string, 0 is empty string
+ if ( $idx > 0 )
+ {
+ $sidx= sprintf("%d", $idx); # sprintf not needed in Perl for this
+ }
+
+ my $prefix= ""; # If mysqltest server arg
+
+ if ( $glob_use_embedded_server )
+ {
+ $prefix= "--server-arg=";
+ }
+
+ mtr_add_arg($args, "%s--no-defaults", $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--default-character-set=latin1", $prefix);
+ mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
+ mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
+
+ if ( $opt_valgrind )
+ {
+ mtr_add_arg($args, "%s--skip-safemalloc", $prefix);
+ mtr_add_arg($args, "%s--skip-bdb", $prefix);
+ }
+
+ my $pidfile;
+
+ if ( $type eq 'master' )
+ {
+ mtr_add_arg($args, "%s--log-bin=%s/var/log/master-bin", $prefix,
+ $glob_mysql_test_dir);
+ mtr_add_arg($args, "%s--pid-file=%s", $prefix,
+ $master->[$idx]->{'path_mypid'});
+ mtr_add_arg($args, "%s--port=%d", $prefix,
+ $master->[$idx]->{'path_myport'});
+ mtr_add_arg($args, "%s--server-id=1", $prefix);
+ mtr_add_arg($args, "%s--socket=%s", $prefix,
+ $master->[$idx]->{'path_mysock'});
+ mtr_add_arg($args, "%s--innodb_data_file_path=ibdata1:50M", $prefix);
+ mtr_add_arg($args, "%s--local-infile", $prefix);
+ mtr_add_arg($args, "%s--datadir=%s", $prefix,
+ $master->[$idx]->{'path_myddir'});
+ }
+
+ if ( $type eq 'slave' )
+ {
+ my $slave_server_id= 2 + $idx;
+ my $slave_rpl_rank= $idx > 0 ? 2 : $slave_server_id;
+
+ mtr_add_arg($args, "%s--datadir=%s", $prefix,
+ $slave->[$idx]->{'path_myddir'});
+ 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/var/log/slave%s-bin", $prefix,
+ $glob_mysql_test_dir, $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_myerr'});
+ mtr_add_arg($args, "%s--master-retry-count=10", $prefix);
+ mtr_add_arg($args, "%s--pid-file=%s", $prefix,
+ $slave->[$idx]->{'path_mypid'});
+ mtr_add_arg($args, "%s--port=%d", $prefix,
+ $slave->[$idx]->{'path_myport'});
+ mtr_add_arg($args, "%s--relay-log=%s/var/log/slave%s-relay-bin", $prefix,
+ $glob_mysql_test_dir, $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'});
+ 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);
+ mtr_add_arg($args, "%s--skip-slave-start", $prefix);
+ mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix,
+ $path_slave_load_tmpdir);
+ mtr_add_arg($args, "%s--socket=%s", $prefix,
+ $slave->[$idx]->{'path_mysock'});
+ mtr_add_arg($args, "%s--set-variable=slave_net_timeout=10", $prefix);
+
+ if ( @$slave_master_info )
+ {
+ foreach my $arg ( @$slave_master_info )
+ {
+ mtr_add_arg($args, "%s%s", $prefix, $arg);
+ }
+ }
+ else
+ {
+ mtr_add_arg($args, "%s--master-user=root", $prefix);
+ mtr_add_arg($args, "%s--master-connect-retry=1", $prefix);
+ 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
+ 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);
+ }
+ } # end slave
+
+ if ( $opt_debug )
+ {
+ if ( $type eq 'master' )
+ {
+ mtr_add_arg($args, "--debug=d:t:i:A,%s/var/log/master%s.trace",
+ $prefix, $glob_mysql_test_dir, $sidx);
+ }
+ if ( $type eq 'slave' )
+ {
+ mtr_add_arg($args, "--debug=d:t:i:A,%s/var/log/slave%s.trace",
+ $prefix, $glob_mysql_test_dir, $sidx);
+ }
+ }
+
+ if ( $opt_with_ndbcluster )
+ {
+ mtr_add_arg($args, "%s--ndbcluster", $prefix);
+
+ if ( $glob_use_running_ndbcluster )
+ {
+ mtr_add_arg($args,"--ndb-connectstring=%s", $prefix,
+ $opt_ndbconnectstring);
+ }
+ else
+ {
+ mtr_add_arg($args,"--ndb-connectstring=host=localhost:%d",
+ $prefix, $opt_ndbcluster_port);
+ }
+ }
+
+ # FIXME always set nowdays??? SMALL_SERVER
+ 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);
+
+ if ( $opt_with_openssl )
+ {
+ mtr_add_arg($args, "%s--ssl-ca=%s/SSL/cacert.pem", $prefix, $glob_basedir);
+ mtr_add_arg($args, "%s--ssl-cert=%s/SSL/server-cert.pem", $prefix,
+ $glob_basedir);
+ mtr_add_arg($args, "%s--ssl-key=%s/SSL/server-key.pem", $prefix,
+ $glob_basedir);
+ }
+
+ if ( $opt_warnings )
+ {
+ mtr_add_arg($args, "%s--log-warnings", $prefix);
+ }
+
+ if ( $opt_gdb or $opt_client_gdb or $opt_manual_gdb or $opt_ddd)
+ {
+ mtr_add_arg($args, "%s--gdb", $prefix);
+ }
+
+ # If we should run all tests cases, we will use a local server for that
+
+ if ( -w "/" )
+ {
+ # We are running as root; We need to add the --root argument
+ mtr_add_arg($args, "%s--user=root", $prefix);
+ }
+
+ if ( $type eq 'master' )
+ {
+
+ if ( ! $opt_old_master )
+ {
+ mtr_add_arg($args, "%s--rpl-recovery-rank=1", $prefix);
+ mtr_add_arg($args, "%s--init-rpl-role=master", $prefix);
+ }
+
+ # FIXME strange,.....
+ if ( $opt_local_master )
+ {
+ mtr_add_arg($args, "%s--host=127.0.0.1", $prefix);
+ mtr_add_arg($args, "%s--port=%s", $prefix, $ENV{'MYSQL_MYPORT'});
+ }
+ }
+
+ foreach my $arg ( @$extra_opt )
+ {
+ mtr_add_arg($args, "%s%s", $prefix, $arg);
+ }
+
+ if ( $opt_bench )
+ {
+ mtr_add_arg($args, "%s--rpl-recovery-rank=1", $prefix);
+ mtr_add_arg($args, "%s--init-rpl-role=master", $prefix);
+ }
+ else
+ {
+ mtr_add_arg($args, "%s--exit-info=256", $prefix);
+ mtr_add_arg($args, "%s--open-files-limit=1024", $prefix);
+
+ if ( $type eq 'master' )
+ {
+ mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'});
+ }
+ if ( $type eq 'slave' )
+ {
+ mtr_add_arg($args, "%s--log=%s", $prefix, $slave->[0]->{'path_mylog'});
+ }
+ }
+
+ return $args;
+}
+
+# FIXME
+# if ( $type eq 'master' and $glob_use_embedded_server )
+# {
+# # Add a -A to each argument to pass it to embedded server
+# my @mysqltest_opt= map {("-A",$_)} @args;
+# $opt_extra_mysqltest_opt= \@mysqltest_opt;
+# return;
+# }
+
+##############################################################################
+#
+# Start mysqld and return the PID
+#
+##############################################################################
+
+sub mysqld_start ($$$$) {
+ my $type= shift; # master/slave/bootstrap
+ my $idx= shift;
+ my $extra_opt= shift;
+ my $slave_master_info= shift;
+
+ my $args; # Arg vector
+ my $exe;
+ my $pid;
+
+ # FIXME code duplication, make up your mind....
+ if ( $opt_source_dist )
+ {
+ $exe= "$glob_basedir/sql/mysqld";
+ }
+ else
+ {
+ $exe ="$glob_basedir/libexec/mysqld";
+ if ( ! -x $exe )
+ {
+ $exe ="$glob_basedir/bin/mysqld";
+ }
+ }
+
+ mtr_init_args(\$args);
+
+ if ( $opt_valgrind )
+ {
+
+ mtr_add_arg($args, "--tool=memcheck");
+ mtr_add_arg($args, "--alignment=8");
+ mtr_add_arg($args, "--leak-check=yes");
+ mtr_add_arg($args, "--num-callers=16");
+
+ if ( $opt_valgrind_all )
+ {
+ mtr_add_arg($args, "-v");
+ mtr_add_arg($args, "--show-reachable=yes");
+ }
+
+ if ( $opt_valgrind_options )
+ {
+ # FIXME split earlier and put into @glob_valgrind_*
+ mtr_add_arg($args, split(' ', $opt_valgrind_options));
+ }
+
+ mtr_add_arg($args, $exe);
+
+ $exe= $opt_valgrind;
+ }
+
+ mysqld_arguments($args,$type,$idx,$extra_opt,$slave_master_info);
+
+ if ( $type eq 'master' )
+ {
+ if ( $pid= mtr_spawn($exe, $args, "",
+ $master->[$idx]->{'path_myerr'},
+ $master->[$idx]->{'path_myerr'}, "") )
+ {
+ sleep_until_file_created($master->[$idx]->{'path_mypid'},
+ $opt_wait_for_master);
+ $opt_wait_for_master= $opt_sleep_time_for_second_master;
+ return $pid;
+ }
+ }
+
+ if ( $type eq 'slave' )
+ {
+ if ( $pid= mtr_spawn($exe, $args, "",
+ $slave->[$idx]->{'path_myerr'},
+ $slave->[$idx]->{'path_myerr'}, "") )
+ {
+ sleep_until_file_created($slave->[$idx]->{'path_mypid'},
+ $opt_wait_for_slave);
+ $opt_wait_for_slave= $opt_sleep_time_for_second_slave;
+ return $pid;
+ }
+ }
+
+ die "Can't start mysqld FIXME";
+}
+
+sub stop_masters_slaves () {
+
+ print "Ending Tests\n";
+ print "Shutting-down MySQL daemon\n\n";
+ stop_masters();
+ print "Master(s) shutdown finished\n";
+ stop_slaves();
+ print "Slave(s) shutdown finished\n";
+}
+
+sub stop_masters () {
+
+ my @args;
+
+ for ( my $idx; $idx < 2; $idx++ )
+ {
+ # FIXME if we hit ^C before fully started, this test will prevent
+ # the mysqld process from being killed
+ if ( $master->[$idx]->{'pid'} )
+ {
+ push(@args,
+ $master->[$idx]->{'path_mypid'},
+ $master->[$idx]->{'path_mysock'},
+ );
+ $master->[$idx]->{'pid'}= 0;
+ }
+ }
+
+ mtr_stop_servers(\@args);
+}
+
+sub stop_slaves () {
+ my $force= shift;
+
+ my @args;
+
+ for ( my $idx; $idx < 3; $idx++ )
+ {
+ if ( $slave->[$idx]->{'pid'} )
+ {
+ push(@args,
+ $slave->[$idx]->{'path_mypid'},
+ $slave->[$idx]->{'path_mysock'},
+ );
+ $slave->[$idx]->{'pid'}= 0;
+ }
+ }
+
+ mtr_stop_servers(\@args);
+}
+
+
+sub run_mysqltest ($) {
+ my $tinfo= shift;
+
+ # FIXME set where????
+ my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
+ "--socket=$master->[0]->{'path_mysock'} --password=";
+ if ( $opt_debug )
+ {
+ $cmdline_mysqldump .=
+ " --debug=d:t:A,$glob_mysql_test_dir/var/log/mysqldump.trace";
+ }
+
+ my $cmdline_mysqlbinlog=
+ "$exe_mysqlbinlog --no-defaults --local-load=$opt_tmpdir";
+
+ if ( $opt_debug )
+ {
+ $cmdline_mysqlbinlog .=
+ " --debug=d:t:A,$glob_mysql_test_dir/var/log/mysqlbinlog.trace";
+ }
+
+ my $cmdline_mysql=
+ "$exe_mysql --host=localhost --port=$master->[0]->{'path_myport'} " .
+ "--socket=$master->[0]->{'path_mysock'} --user=root --password=";
+
+ $ENV{'MYSQL'}= $exe_mysql;
+ $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
+ $ENV{'MYSQL_BINLOG'}= $exe_mysqlbinlog;
+ $ENV{'CLIENT_BINDIR'}= $path_client_bindir;
+ $ENV{'TESTS_BINDIR'}= $path_tests_bindir;
+
+ my $exe= $exe_mysqltest;
+ my $args; # Arg vector
+
+ mtr_init_args(\$args);
+
+ if ( $opt_strace_client )
+ {
+ $exe= "strace"; # FIXME there are ktrace, ....
+ mtr_add_arg($args, "-o");
+ mtr_add_arg($args, "%s/var/log/mysqltest.strace", $glob_mysql_test_dir);
+ mtr_add_arg($args, "$exe_mysqltest");
+ }
+
+ mtr_add_arg($args, "--no-defaults");
+ mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'});
+ mtr_add_arg($args, "--database=test");
+ mtr_add_arg($args, "--user=%s", $glob_user);
+ mtr_add_arg($args, "--password=");
+ mtr_add_arg($args, "--silent");
+ mtr_add_arg($args, "-v");
+ mtr_add_arg($args, "--skip-safemalloc");
+ mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
+ mtr_add_arg($args, "--port=%d", $master->[0]->{'path_myport'});
+
+ if ( $opt_timer )
+ {
+ mtr_add_arg($args, "--timer-file=var/log/timer");
+ }
+
+ if ( $opt_big_test )
+ {
+ mtr_add_arg($args, "--big-test");
+ }
+
+ if ( $opt_record )
+ {
+ mtr_add_arg($args, "--record");
+ }
+
+ if ( $opt_compress )
+ {
+ mtr_add_arg($args, "--compress");
+ }
+
+ if ( $opt_sleep )
+ {
+ mtr_add_arg($args, "--sleep=%d", $opt_sleep);
+ }
+
+ if ( $opt_debug )
+ {
+ mtr_add_arg($args, "--debug=d:t:A,%s/var/log/mysqltest.trace",
+ $glob_mysql_test_dir);
+ }
+
+ if ( $opt_with_openssl )
+ {
+ mtr_add_arg($args, "--ssl-ca=%s/SSL/cacert.pem", $glob_basedir);
+ mtr_add_arg($args, "--ssl-cert=%s/SSL/client-cert.pem", $glob_basedir);
+ mtr_add_arg($args, "--ssl-key=%s/SSL/client-key.pem", $glob_basedir);
+ }
+
+ mtr_add_arg($args, "-R");
+ mtr_add_arg($args, $tinfo->{'result_file'});
+
+ if ( $glob_use_embedded_server )
+ {
+ mysqld_arguments($args,'master',0,$tinfo->{'master_opt'},[]);
+ }
+
+ return mtr_run($exe_mysqltest,$args,$tinfo->{'path'},"",$path_timefile,"");
+}