1#!/usr/bin/env perl
2# -*- cperl -*-
3
4# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; version 2 of the License.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
18
19##############################################################################
20#
21#  mysql-test-run.pl
22#
23#  Tool used for executing a suite of .test file
24#
25#  See the "MySQL Test framework manual" for more information
26#  https://mariadb.com/kb/en/library/mysqltest/
27#
28#  Please keep the test framework tools identical in all versions!
29#
30##############################################################################
31#
32# Coding style directions for this perl script
33#
34#   - To make this Perl script easy to alter even for those that not
35#     code Perl that often, keeep the coding style as close as possible to
36#     the C/C++ MySQL coding standard.
37#
38#   - All lists of arguments to send to commands are Perl lists/arrays,
39#     not strings we append args to. Within reason, most string
40#     concatenation for arguments should be avoided.
41#
42#   - Functions defined in the main program are not to be prefixed,
43#     functions in "library files" are to be prefixed with "mtr_" (for
44#     Mysql-Test-Run). There are some exceptions, code that fits best in
45#     the main program, but are put into separate files to avoid
46#     clutter, may be without prefix.
47#
48#   - All stat/opendir/-f/ is to be kept in collect_test_cases(). It
49#     will create a struct that the rest of the program can use to get
50#     the information. This separates the "find information" from the
51#     "do the work" and makes the program more easy to maintain.
52#
53#   - The rule when it comes to the logic of this program is
54#
55#       command_line_setup() - is to handle the logic between flags
56#       collect_test_cases() - is to do its best to select what tests
57#                              to run, dig out options, if needs restart etc.
58#       run_testcase()       - is to run a single testcase, and follow the
59#                              logic set in both above. No, or rare file
60#                              system operations. If a test seems complex,
61#                              it should probably not be here.
62#
63# A nice way to trace the execution of this script while debugging
64# is to use the Devel::Trace package found at
65# "http://www.plover.com/~mjd/perl/Trace/" and run this script like
66# "perl -d:Trace mysql-test-run.pl"
67#
68
69
70use lib "lib/v1/";
71
72$Devel::Trace::TRACE= 0;       # Don't trace boring init stuff
73
74#require 5.6.1;
75use File::Path;
76use File::Basename;
77use File::Copy;
78use File::Temp qw /tempdir/;
79use File::Spec::Functions qw /splitdir/;
80use Cwd;
81use Getopt::Long;
82use IO::Socket;
83use IO::Socket::INET;
84use strict;
85use warnings;
86
87select(STDOUT);
88$| = 1; # Automatically flush STDOUT
89
90our $glob_win32_perl=  ($^O eq "MSWin32"); # ActiveState Win32 Perl
91our $glob_cygwin_perl= ($^O eq "cygwin");  # Cygwin Perl
92our $glob_win32=       ($glob_win32_perl or $glob_cygwin_perl);
93
94require "lib/v1/mtr_cases.pl";
95require "lib/v1/mtr_process.pl";
96require "lib/v1/mtr_timer.pl";
97require "lib/v1/mtr_io.pl";
98require "lib/v1/mtr_gcov.pl";
99require "lib/v1/mtr_gprof.pl";
100require "lib/v1/mtr_report.pl";
101require "lib/v1/mtr_match.pl";
102require "lib/v1/mtr_misc.pl";
103require "lib/v1/mtr_stress.pl";
104require "lib/v1/mtr_unique.pl";
105
106$Devel::Trace::TRACE= 1;
107
108##############################################################################
109#
110#  Default settings
111#
112##############################################################################
113
114# Misc global variables
115our $mysql_version_id;
116our $glob_mysql_test_dir=         undef;
117our $glob_mysql_bench_dir=        undef;
118our $glob_scriptname=             undef;
119our $glob_timers=                 undef;
120our $glob_use_embedded_server=    0;
121our @glob_test_mode;
122
123our $glob_basedir;
124our $glob_bindir;
125
126our $path_charsetsdir;
127our $path_client_bindir;
128our $path_client_libdir;
129our $path_share;
130our $path_language;
131our $path_timefile;
132our $path_snapshot;
133our $path_mysqltest_log;
134our $path_current_test_log;
135
136our $opt_vardir;                 # A path but set directly on cmd line
137our $path_vardir_trace;          # unix formatted opt_vardir for trace files
138our $opt_tmpdir;                 # A path but set directly on cmd line
139
140# Visual Studio produces executables in different sub-directories based on the
141# configuration used to build them.  To make life easier, an environment
142# variable or command-line option may be specified to control which set of
143# executables will be used by the test suite.
144our $multiconfig = $ENV{'MTR_VS_CONFIG'};
145
146our $default_vardir;
147
148our $opt_usage;
149our $opt_list_options;
150our $opt_suites;
151our $opt_suites_default= "main,binlog,rpl,maria"; # Default suites to run
152our $opt_script_debug= 0;  # Script debugging, enable with --script-debug
153our $opt_verbose= 0;  # Verbose output, enable with --verbose
154
155our $exe_master_mysqld;
156our $exe_mysql;
157our $exe_mysqladmin;
158our $exe_mysql_upgrade;
159our $exe_mysqlbinlog;
160our $exe_mysql_client_test;
161our $exe_bug25714;
162our $exe_mysqld;
163our $exe_mysqlcheck;
164our $exe_mysqldump;
165our $exe_mysqlslap;
166our $exe_mysqlimport;
167our $exe_mysqlshow;
168our $file_mysql_fix_privilege_tables;
169our $exe_mysqltest;
170our $exe_slave_mysqld;
171our $exe_my_print_defaults;
172our $exe_perror;
173our $lib_udf_example;
174our $lib_example_plugin;
175our $exe_libtool;
176
177our $opt_bench= 0;
178our $opt_small_bench= 0;
179our $opt_big_test= 0;
180
181our @opt_combinations;
182our $opt_skip_combination;
183
184our @opt_extra_mysqld_opt;
185our @opt_extra_mysqltest_opt;
186
187our $opt_compress;
188our $opt_ssl;
189our $opt_skip_ssl;
190our $opt_ssl_supported;
191our $opt_ps_protocol;
192our $opt_sp_protocol;
193our $opt_cursor_protocol;
194our $opt_view_protocol;
195
196our $opt_debug;
197our $opt_do_test;
198our @opt_cases;                  # The test cases names in argv
199our $opt_embedded_server;
200
201our $opt_extern= 0;
202our $opt_socket;
203
204our $opt_fast;
205our $opt_force;
206our $opt_reorder= 0;
207our $opt_enable_disabled;
208our $opt_mem= $ENV{'MTR_MEM'};
209
210our $opt_gcov;
211our $opt_gcov_err;
212our $opt_gcov_msg;
213
214our $glob_debugger= 0;
215our $opt_gdb;
216our $opt_client_gdb;
217our $opt_ddd;
218our $opt_client_ddd;
219our $opt_manual_gdb;
220our $opt_manual_ddd;
221our $opt_manual_debug;
222our $opt_mtr_build_thread=0;
223our $opt_debugger;
224our $opt_client_debugger;
225
226our $opt_gprof;
227our $opt_gprof_dir;
228our $opt_gprof_master;
229our $opt_gprof_slave;
230
231our $master;
232our $slave;
233
234our $opt_master_myport;
235our $opt_slave_myport;
236
237our $opt_record;
238my $opt_report_features;
239our $opt_check_testcases;
240our $opt_mark_progress;
241
242our $opt_skip_rpl;
243our $max_slave_num= 0;
244our $max_master_num= 1;
245our $use_innodb;
246our $opt_skip_test;
247
248our $opt_sleep;
249
250our $opt_testcase_timeout;
251our $opt_suite_timeout;
252my  $default_testcase_timeout=     15; # 15 min max
253my  $default_suite_timeout=       300; # 5 hours max
254
255our $opt_start_and_exit;
256our $opt_start_dirty;
257our $opt_start_from;
258
259our $opt_strace_client;
260
261our $opt_timer= 1;
262
263our $opt_user;
264
265my $opt_valgrind= 0;
266my $opt_valgrind_mysqld= 0;
267my $opt_valgrind_mysqltest= 0;
268my @default_valgrind_args= ("--show-reachable=yes");
269my @valgrind_args;
270my $opt_valgrind_path;
271my $opt_callgrind;
272
273our $opt_stress=               "";
274our $opt_stress_suite=     "main";
275our $opt_stress_mode=    "random";
276our $opt_stress_threads=        5;
277our $opt_stress_test_count=     0;
278our $opt_stress_loop_count=     0;
279our $opt_stress_test_duration=  0;
280our $opt_stress_init_file=     "";
281our $opt_stress_test_file=     "";
282
283our $opt_warnings;
284
285our $opt_skip_master_binlog= 0;
286our $opt_skip_slave_binlog= 0;
287
288our $path_sql_dir;
289
290our @data_dir_lst;
291
292our $used_binlog_format;
293our $used_default_engine;
294our $debug_compiled_binaries;
295
296our %mysqld_variables;
297
298my $source_dist= 0;
299
300our $opt_max_save_core= 5;
301my $num_saved_cores= 0;  # Number of core files saved in vardir/log/ so far.
302
303######################################################################
304#
305#  Function declarations
306#
307######################################################################
308
309sub main ();
310sub initial_setup ();
311sub command_line_setup ();
312sub set_mtr_build_thread_ports($);
313sub datadir_list_setup ();
314sub executable_setup ();
315sub environment_setup ();
316sub kill_running_servers ();
317sub remove_stale_vardir ();
318sub setup_vardir ();
319sub check_ssl_support ($);
320sub check_running_as_root();
321sub mysqld_wait_started($);
322sub run_benchmarks ($);
323sub initialize_servers ();
324sub mysql_install_db ();
325sub install_db ($$);
326sub copy_install_db ($$);
327sub run_testcase ($);
328sub run_testcase_stop_servers ($$$);
329sub run_testcase_start_servers ($);
330sub run_testcase_check_skip_test($);
331sub report_failure_and_restart ($);
332sub do_before_start_master ($);
333sub do_before_start_slave ($);
334sub mysqld_start ($$$);
335sub mysqld_arguments ($$$$);
336sub stop_all_servers ();
337sub run_mysqltest ($);
338sub usage ($);
339
340
341######################################################################
342#
343#  Main program
344#
345######################################################################
346
347main();
348
349sub main () {
350
351  command_line_setup();
352
353  check_ssl_support(\%mysqld_variables);
354  check_debug_support(\%mysqld_variables);
355
356  executable_setup();
357
358  environment_setup();
359  signal_setup();
360
361  if ( $opt_gcov )
362  {
363    gcov_prepare();
364  }
365
366  if ( $opt_gprof )
367  {
368    gprof_prepare();
369  }
370
371  if ( $opt_bench )
372  {
373    initialize_servers();
374    run_benchmarks(shift);      # Shift what? Extra arguments?!
375  }
376  elsif ( $opt_stress )
377  {
378    initialize_servers();
379    run_stress_test()
380  }
381  else
382  {
383    # Figure out which tests we are going to run
384    if (!$opt_suites)
385    {
386      $opt_suites= $opt_suites_default;
387    }
388
389    my $tests= collect_test_cases($opt_suites);
390
391    my ($need_debug);
392    foreach my $test (@$tests)
393    {
394      next if $test->{skip};
395
396      if (!$opt_extern)
397      {
398        $need_debug||=$test->{need_debug};
399
400	# Count max number of slaves used by a test case
401	if ( $test->{slave_num} > $max_slave_num) {
402	  $max_slave_num= $test->{slave_num};
403	  mtr_error("Too many slaves") if $max_slave_num > 3;
404	}
405
406	# Count max number of masters used by a test case
407	if ( $test->{master_num} > $max_master_num) {
408	  $max_master_num= $test->{master_num};
409	  mtr_error("Too many masters") if $max_master_num > 2;
410	  mtr_error("Too few masters") if $max_master_num < 1;
411	}
412      }
413      $use_innodb||= $test->{'innodb_test'};
414    }
415
416    if ( !$need_debug && !$opt_debug)
417    {
418      $opt_debug=0;
419    }
420
421    initialize_servers();
422
423    if ( $opt_report_features ) {
424      run_report_features();
425    }
426
427    run_tests($tests);
428  }
429
430  mtr_exit(0);
431}
432
433##############################################################################
434#
435#  Default settings
436#
437##############################################################################
438
439#
440# When an option is no longer used by this program, it must be explicitly
441# ignored or else it will be passed through to mysqld.  GetOptions will call
442# this subroutine once for each such option on the command line.  See
443# Getopt::Long documentation.
444#
445
446sub warn_about_removed_option {
447  my ($option, $value, $hash_value) = @_;
448
449  warn "WARNING: This option is no longer used, and is ignored: --$option\n";
450}
451
452sub command_line_setup () {
453
454  # These are defaults for things that are set on the command line
455
456  my $opt_comment;
457
458  # Magic number -69.4 results in traditional test ports starting from 9306.
459  set_mtr_build_thread_ports(-69.4);
460
461  # If so requested, we try to avail ourselves of a unique build thread number.
462  if ( $ENV{'MTR_BUILD_THREAD'} ) {
463    if ( lc($ENV{'MTR_BUILD_THREAD'}) eq 'auto' ) {
464      print "Requesting build thread... ";
465      $ENV{'MTR_BUILD_THREAD'} = mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299);
466      print "got ".$ENV{'MTR_BUILD_THREAD'}."\n";
467    }
468  }
469
470  if ( $ENV{'MTR_BUILD_THREAD'} )
471  {
472    set_mtr_build_thread_ports($ENV{'MTR_BUILD_THREAD'});
473  }
474
475  # This is needed for test log evaluation in "gen-build-status-page"
476  # in all cases where the calling tool does not log the commands
477  # directly before it executes them, like "make test-force-pl" in RPM builds.
478  print "Logging: $0 ", join(" ", @ARGV), "\n";
479
480  # Read the command line
481  # Note: Keep list, and the order, in sync with usage at end of this file
482
483  # Options that are no longer used must still be processed, because all
484  # unprocessed options are passed directly to mysqld.  The user will be
485  # warned that the option is being ignored.
486  #
487  # Put the complete option string here.  For example, to remove the --suite
488  # option, remove it from GetOptions() below and put 'suite|suites=s' here.
489  my @removed_options = (
490  );
491
492  Getopt::Long::Configure("pass_through");
493  my %options=(
494             # Control what engine/variation to run
495             'embedded-server'          => \$opt_embedded_server,
496             'ps-protocol'              => \$opt_ps_protocol,
497             'sp-protocol'              => \$opt_sp_protocol,
498             'view-protocol'            => \$opt_view_protocol,
499             'cursor-protocol'          => \$opt_cursor_protocol,
500             'ssl|with-openssl'         => \$opt_ssl,
501             'skip-ssl'                 => \$opt_skip_ssl,
502             'compress'                 => \$opt_compress,
503             'bench'                    => \$opt_bench,
504             'small-bench'              => \$opt_small_bench,
505             'vs-config'            => \$multiconfig,
506
507             # Control what test suites or cases to run
508             'force'                    => \$opt_force,
509             'skip-master-binlog'       => \$opt_skip_master_binlog,
510             'skip-slave-binlog'        => \$opt_skip_slave_binlog,
511             'do-test=s'                => \$opt_do_test,
512             'start-from=s'             => \$opt_start_from,
513             'suite|suites=s'           => \$opt_suites,
514             'skip-rpl'                 => \$opt_skip_rpl,
515             'skip-test=s'              => \$opt_skip_test,
516             'big-test'                 => \$opt_big_test,
517             'combination=s'            => \@opt_combinations,
518             'skip-combination'         => \$opt_skip_combination,
519
520             # Specify ports
521             'master_port=i'            => \$opt_master_myport,
522             'slave_port=i'             => \$opt_slave_myport,
523	     'mtr-build-thread=i'       => \$opt_mtr_build_thread,
524
525             # Test case authoring
526             'record'                   => \$opt_record,
527             'check-testcases'          => \$opt_check_testcases,
528             'mark-progress'            => \$opt_mark_progress,
529
530             # Extra options used when starting mysqld
531             'mysqld=s'                 => \@opt_extra_mysqld_opt,
532
533             # Extra options used when starting mysqld
534             'mysqltest=s'                 => \@opt_extra_mysqltest_opt,
535
536             # Run test on running server
537             'extern'                   => \$opt_extern,
538
539             # Debugging
540             'gdb'                      => \$opt_gdb,
541             'client-gdb'               => \$opt_client_gdb,
542             'manual-gdb'               => \$opt_manual_gdb,
543             'manual-debug'             => \$opt_manual_debug,
544             'ddd'                      => \$opt_ddd,
545             'client-ddd'               => \$opt_client_ddd,
546             'manual-ddd'               => \$opt_manual_ddd,
547	     'debugger=s'               => \$opt_debugger,
548	     'client-debugger=s'        => \$opt_client_debugger,
549             'strace-client'            => \$opt_strace_client,
550             'master-binary=s'          => \$exe_master_mysqld,
551             'slave-binary=s'           => \$exe_slave_mysqld,
552             'max-save-core=i'          => \$opt_max_save_core,
553
554             # Coverage, profiling etc
555             'gcov'                     => \$opt_gcov,
556             'gprof'                    => \$opt_gprof,
557             'valgrind|valgrind-all'    => \$opt_valgrind,
558             'valgrind-mysqltest'       => \$opt_valgrind_mysqltest,
559             'valgrind-mysqld'          => \$opt_valgrind_mysqld,
560             'valgrind-options=s'       => sub {
561	       my ($opt, $value)= @_;
562	       # Deprecated option unless it's what we know pushbuild uses
563	       if ($value eq "--gen-suppressions=all --show-reachable=yes") {
564		 push(@valgrind_args, $_) for (split(' ', $value));
565		 return;
566	       }
567	       die("--valgrind-options=s is deprecated. Use ",
568		   "--valgrind-option=s, to be specified several",
569		   " times if necessary");
570	     },
571             'valgrind-option=s'        => \@valgrind_args,
572             'valgrind-path=s'          => \$opt_valgrind_path,
573	     'callgrind'                => \$opt_callgrind,
574
575             # Stress testing
576             'stress'                   => \$opt_stress,
577             'stress-suite=s'           => \$opt_stress_suite,
578             'stress-threads=i'         => \$opt_stress_threads,
579             'stress-test-file=s'       => \$opt_stress_test_file,
580             'stress-init-file=s'       => \$opt_stress_init_file,
581             'stress-mode=s'            => \$opt_stress_mode,
582             'stress-loop-count=i'      => \$opt_stress_loop_count,
583             'stress-test-count=i'      => \$opt_stress_test_count,
584             'stress-test-duration=i'   => \$opt_stress_test_duration,
585
586	     # Directories
587             'tmpdir=s'                 => \$opt_tmpdir,
588             'vardir=s'                 => \$opt_vardir,
589             'benchdir=s'               => \$glob_mysql_bench_dir,
590             'mem'                      => \$opt_mem,
591             'client-bindir=s'          => \$path_client_bindir,
592             'client-libdir=s'          => \$path_client_libdir,
593
594             # Misc
595             'report-features'          => \$opt_report_features,
596             'comment=s'                => \$opt_comment,
597             'debug'                    => \$opt_debug,
598             'fast'                     => \$opt_fast,
599             'reorder'                  => \$opt_reorder,
600             'enable-disabled'          => \$opt_enable_disabled,
601             'script-debug'             => \$opt_script_debug,
602             'verbose'                  => \$opt_verbose,
603             'sleep=i'                  => \$opt_sleep,
604             'socket=s'                 => \$opt_socket,
605             'start-dirty'              => \$opt_start_dirty,
606             'start-and-exit'           => \$opt_start_and_exit,
607             'timer!'                   => \$opt_timer,
608             'user=s'                   => \$opt_user,
609             'testcase-timeout=i'       => \$opt_testcase_timeout,
610             'suite-timeout=i'          => \$opt_suite_timeout,
611             'warnings|log-warnings'    => \$opt_warnings,
612
613             # Options which are no longer used
614             (map { $_ => \&warn_about_removed_option } @removed_options),
615
616             'help|h'                   => \$opt_usage,
617             'list-options'             => \$opt_list_options,
618            );
619
620  GetOptions(%options) or usage("Can't read options");
621
622  usage("") if $opt_usage;
623  list_options(\%options) if $opt_list_options;
624
625  $glob_scriptname=  basename($0);
626
627  if ($opt_mtr_build_thread != 0)
628  {
629    set_mtr_build_thread_ports($opt_mtr_build_thread)
630  }
631  elsif ($ENV{'MTR_BUILD_THREAD'})
632  {
633    $opt_mtr_build_thread= $ENV{'MTR_BUILD_THREAD'};
634  }
635
636  # We require that we are in the "mysql-test" directory
637  # to run mysql-test-run
638  if (! -f $glob_scriptname)
639  {
640    mtr_error("Can't find the location for the mysql-test-run script\n" .
641              "Go to the mysql-test directory and execute the script " .
642              "as follows:\n./$glob_scriptname");
643  }
644
645  if ( -d "../sql" )
646  {
647    $source_dist=  1;
648  }
649
650  # Find the absolute path to the test directory
651  $glob_mysql_test_dir=  cwd();
652  if ( $glob_cygwin_perl )
653  {
654    # Windows programs like 'mysqld' needs Windows paths
655    $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`;
656    chomp($glob_mysql_test_dir);
657  }
658  if (defined $ENV{MTR_BINDIR})
659  {
660    $default_vardir= "$ENV{MTR_BINDIR}/mysql-test/var";
661  }
662  else
663  {
664    $default_vardir= "$glob_mysql_test_dir/var";
665  }
666
667  # In most cases, the base directory we find everything relative to,
668  # is the parent directory of the "mysql-test" directory. For source
669  # distributions, TAR binary distributions and some other packages.
670  $glob_basedir= dirname($glob_mysql_test_dir);
671
672  $glob_bindir= $ENV{'MTR_BINDIR'} || $glob_basedir;
673  # In the RPM case, binaries and libraries are installed in the
674  # default system locations, instead of having our own private base
675  # directory. And we install "/usr/share/mysql-test". Moving up one
676  # more directory relative to "mysql-test" gives us a usable base
677  # directory for RPM installs.
678  if ( ! $source_dist and ! -d "$glob_basedir/bin" )
679  {
680    $glob_basedir= dirname($glob_basedir);
681  }
682
683  # Expect mysql-bench to be located adjacent to the source tree, by default
684  $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench"
685    unless defined $glob_mysql_bench_dir;
686  $glob_mysql_bench_dir= undef
687    unless -d $glob_mysql_bench_dir;
688
689
690  $glob_timers= mtr_init_timers();
691
692  # --------------------------------------------------------------------------
693  # Embedded server flag
694  # --------------------------------------------------------------------------
695  if ( $opt_embedded_server )
696  {
697    $glob_use_embedded_server= 1;
698    # Add the location for libmysqld.dll to the path.
699    if ( $glob_win32 )
700    {
701      my $lib_mysqld=
702        mtr_path_exists(vs_config_dirs('libmysqld',''));
703	  $lib_mysqld= $glob_cygwin_perl ? ":".`cygpath "$lib_mysqld"`
704                                     : ";".$lib_mysqld;
705      chomp($lib_mysqld);
706      $ENV{'PATH'}="$ENV{'PATH'}".$lib_mysqld;
707    }
708
709    push(@glob_test_mode, "embedded");
710    $opt_skip_rpl= 1;              # We never run replication with embedded
711    $opt_skip_ssl= 1;              # Turn off use of SSL
712
713    # Turn off use of bin log
714    push(@opt_extra_mysqld_opt, "--skip-log-bin");
715
716    if ( $opt_extern )
717    {
718      mtr_error("Can't use --extern with --embedded-server");
719    }
720  }
721
722  #
723  # Find the mysqld executable to be able to find the mysqld version
724  # number as early as possible
725  #
726
727  # Look for the client binaries directory
728  if ($path_client_bindir)
729  {
730    # --client-bindir=path set on command line, check that the path exists
731    $path_client_bindir= mtr_path_exists($path_client_bindir);
732  }
733  else
734  {
735    $path_client_bindir= mtr_path_exists("$glob_bindir/client_release",
736					 "$glob_bindir/client_debug",
737					 vs_config_dirs('client', ''),
738					 "$glob_bindir/client",
739					 "$glob_bindir/bin");
740  }
741
742  # Look for language files and charsetsdir, use same share
743  $path_share=      mtr_path_exists("$glob_bindir/share/mysql",
744                                    "$glob_bindir/sql/share",
745                                    "$glob_bindir/share");
746
747  $path_language=      mtr_path_exists("$path_share");
748  $path_charsetsdir =   mtr_path_exists("$glob_basedir/share/mysql/charsets",
749                                    "$glob_basedir/sql/share/charsets",
750                                    "$glob_basedir/share/charsets");
751
752  if (!$opt_extern)
753  {
754    $exe_mysqld=       mtr_exe_exists (vs_config_dirs('sql', 'mysqld'),
755                                       vs_config_dirs('sql', 'mysqld-debug'),
756				       "$glob_bindir/sql/mysqld",
757				       "$path_client_bindir/mysqld-max-nt",
758				       "$path_client_bindir/mysqld-max",
759				       "$path_client_bindir/mysqld-nt",
760				       "$path_client_bindir/mysqld",
761				       "$path_client_bindir/mysqld-debug",
762				       "$path_client_bindir/mysqld-max",
763				       "$glob_bindir/libexec/mysqld",
764				       "$glob_bindir/bin/mysqld",
765				       "$glob_bindir/sbin/mysqld");
766
767    # Use the mysqld found above to find out what features are available
768    collect_mysqld_features();
769  }
770  else
771  {
772    $mysqld_variables{'port'}= 3306;
773    $mysqld_variables{'master-port'}= 3306;
774  }
775
776  if ( $opt_comment )
777  {
778    print "\n";
779    print '#' x 78, "\n";
780    print "# $opt_comment\n";
781    print '#' x 78, "\n\n";
782  }
783
784  foreach my $arg ( @ARGV )
785  {
786    if ( $arg =~ /^--skip-/ )
787    {
788      push(@opt_extra_mysqld_opt, $arg);
789    }
790    elsif ( $arg =~ /^--$/ )
791    {
792      # It is an effect of setting 'pass_through' in option processing
793      # that the lone '--' separating options from arguments survives,
794      # simply ignore it.
795    }
796    elsif ( $arg =~ /^-/ )
797    {
798      usage("Invalid option \"$arg\"");
799    }
800    else
801    {
802      push(@opt_cases, $arg);
803    }
804  }
805
806  # --------------------------------------------------------------------------
807  # Find out type of logging that are being used
808  # --------------------------------------------------------------------------
809  if (!$opt_extern && $mysql_version_id >= 50100 )
810  {
811    foreach my $arg ( @opt_extra_mysqld_opt )
812    {
813      if ( $arg =~ /binlog[-_]format=(\S+)/ )
814      {
815      	$used_binlog_format= $1;
816      }
817    }
818    if (defined $used_binlog_format)
819    {
820      mtr_report("Using binlog format '$used_binlog_format'");
821    }
822    else
823    {
824      mtr_report("Using dynamic switching of binlog format");
825    }
826  }
827
828
829  # --------------------------------------------------------------------------
830  # Find out default storage engine being used(if any)
831  # --------------------------------------------------------------------------
832  foreach my $arg ( @opt_extra_mysqld_opt )
833  {
834    if ( $arg =~ /default-storage-engine=(\S+)/ )
835    {
836      $used_default_engine= $1;
837    }
838  }
839  mtr_report("Using default engine '$used_default_engine'")
840    if defined $used_default_engine;
841
842  if ($glob_win32 and defined $opt_mem) {
843    mtr_report("--mem not supported on Windows, ignored");
844    $opt_mem= undef;
845  }
846
847  # --------------------------------------------------------------------------
848  # Check if we should speed up tests by trying to run on tmpfs
849  # --------------------------------------------------------------------------
850  if ( defined $opt_mem )
851  {
852    mtr_error("Can't use --mem and --vardir at the same time ")
853      if $opt_vardir;
854    mtr_error("Can't use --mem and --tmpdir at the same time ")
855      if $opt_tmpdir;
856
857    # Search through list of locations that are known
858    # to be "fast disks" to list to find a suitable location
859    # Use --mem=<dir> as first location to look.
860    my @tmpfs_locations= ($opt_mem, "/dev/shm", "/tmp");
861
862    foreach my $fs (@tmpfs_locations)
863    {
864      if ( -d $fs )
865      {
866	mtr_report("Using tmpfs in $fs");
867	$opt_mem= "$fs/var";
868	$opt_mem .= $opt_mtr_build_thread if $opt_mtr_build_thread;
869	last;
870      }
871    }
872  }
873
874  # --------------------------------------------------------------------------
875  # Set the "var/" directory, as it is the base for everything else
876  # --------------------------------------------------------------------------
877  if ( ! $opt_vardir )
878  {
879    $opt_vardir= $default_vardir;
880  }
881  elsif ( $mysql_version_id < 50000 and
882	  $opt_vardir ne $default_vardir)
883  {
884    # Version 4.1 and --vardir was specified
885    # Only supported as a symlink from var/
886    # by setting up $opt_mem that symlink will be created
887    if ( ! $glob_win32 )
888    {
889      # Only platforms that have native symlinks can use the vardir trick
890      $opt_mem= $opt_vardir;
891      mtr_report("Using 4.1 vardir trick");
892    }
893
894    $opt_vardir= $default_vardir;
895  }
896
897  $path_vardir_trace= $opt_vardir;
898  # Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/...
899  $path_vardir_trace=~ s/^\w://;
900
901  # We make the path absolute, as the server will do a chdir() before usage
902  unless ( $opt_vardir =~ m,^/, or
903           ($glob_win32 and $opt_vardir =~ m,^[a-z]:/,i) )
904  {
905    # Make absolute path, relative test dir
906    $opt_vardir= "$glob_mysql_test_dir/$opt_vardir";
907  }
908
909  # --------------------------------------------------------------------------
910  # Set tmpdir
911  # --------------------------------------------------------------------------
912  $opt_tmpdir=       "$opt_vardir/tmp" unless $opt_tmpdir;
913  $opt_tmpdir =~ s,/+$,,;       # Remove ending slash if any
914
915  # --------------------------------------------------------------------------
916  # Record flag
917  # --------------------------------------------------------------------------
918  if ( $opt_record and ! @opt_cases )
919  {
920    mtr_error("Will not run in record mode without a specific test case");
921  }
922
923  if ( $opt_record )
924  {
925    $opt_skip_combination = 1;
926  }
927
928  # --------------------------------------------------------------------------
929  # ps protcol flag
930  # --------------------------------------------------------------------------
931  if ( $opt_ps_protocol )
932  {
933    push(@glob_test_mode, "ps-protocol");
934  }
935
936  # --------------------------------------------------------------------------
937  # Bench flags
938  # --------------------------------------------------------------------------
939  if ( $opt_small_bench )
940  {
941    $opt_bench=  1;
942  }
943
944  # --------------------------------------------------------------------------
945  # Big test flags
946  # --------------------------------------------------------------------------
947   if ( $opt_big_test )
948   {
949     $ENV{'BIG_TEST'}= 1;
950   }
951
952  # --------------------------------------------------------------------------
953  # Gcov flag
954  # --------------------------------------------------------------------------
955  if ( $opt_gcov and ! $source_dist )
956  {
957    mtr_error("Coverage test needs the source - please use source dist");
958  }
959
960  # --------------------------------------------------------------------------
961  # Check debug related options
962  # --------------------------------------------------------------------------
963  if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd ||
964       $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug ||
965       $opt_debugger || $opt_client_debugger )
966  {
967    # Indicate that we are using debugger
968    $glob_debugger= 1;
969    if ( $opt_extern )
970    {
971      mtr_error("Can't use --extern when using debugger");
972    }
973  }
974
975  # --------------------------------------------------------------------------
976  # Check if special exe was selected for master or slave
977  # --------------------------------------------------------------------------
978  $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld;
979  $exe_slave_mysqld=  $exe_slave_mysqld  || $exe_mysqld;
980
981  # --------------------------------------------------------------------------
982  # Check valgrind arguments
983  # --------------------------------------------------------------------------
984  if ( $opt_valgrind or $opt_valgrind_path or @valgrind_args)
985  {
986    mtr_report("Turning on valgrind for all executables");
987    $opt_valgrind= 1;
988    $opt_valgrind_mysqld= 1;
989    $opt_valgrind_mysqltest= 1;
990  }
991  elsif ( $opt_valgrind_mysqld )
992  {
993    mtr_report("Turning on valgrind for mysqld(s) only");
994    $opt_valgrind= 1;
995  }
996  elsif ( $opt_valgrind_mysqltest )
997  {
998    mtr_report("Turning on valgrind for mysqltest and mysql_client_test only");
999    $opt_valgrind= 1;
1000  }
1001
1002  if ( $opt_callgrind )
1003  {
1004    mtr_report("Turning on valgrind with callgrind for mysqld(s)");
1005    $opt_valgrind= 1;
1006    $opt_valgrind_mysqld= 1;
1007
1008    # Set special valgrind options unless options passed on command line
1009    push(@valgrind_args, "--trace-children=yes")
1010      unless @valgrind_args;
1011  }
1012
1013  if ( $opt_valgrind )
1014  {
1015    # Set valgrind_options to default unless already defined
1016    push(@valgrind_args, @default_valgrind_args)
1017      unless @valgrind_args;
1018
1019    mtr_report("Running valgrind with options \"",
1020	       join(" ", @valgrind_args), "\"");
1021  }
1022
1023  if ( ! $opt_testcase_timeout )
1024  {
1025    $opt_testcase_timeout=
1026      $ENV{MTR_TESTCASE_TIMEOUT} || $default_testcase_timeout;
1027    $opt_testcase_timeout*= 10 if $opt_valgrind;
1028    $opt_testcase_timeout*= 10 if ($opt_debug and $glob_win32);
1029  }
1030
1031  if ( ! $opt_suite_timeout )
1032  {
1033    $opt_suite_timeout=
1034      $ENV{MTR_SUITE_TIMEOUT} || $default_suite_timeout;
1035    $opt_suite_timeout*= 6 if $opt_valgrind;
1036    $opt_suite_timeout*= 6 if ($opt_debug and $glob_win32);
1037  }
1038
1039  if ( ! $opt_user )
1040  {
1041    if ( $opt_extern )
1042    {
1043      $opt_user= "test";
1044    }
1045    else
1046    {
1047      $opt_user= "root"; # We want to do FLUSH xxx commands
1048    }
1049  }
1050
1051  # On QNX, /tmp/dir/master.sock and /tmp/dir//master.sock seem to be
1052  # considered different, so avoid the extra slash (/) in the socket
1053  # paths.
1054  my $sockdir = $opt_tmpdir;
1055  $sockdir =~ s|/+$||;
1056
1057  # On some operating systems, there is a limit to the length of a
1058  # UNIX domain socket's path far below PATH_MAX, so try to avoid long
1059  # socket path names.
1060  $sockdir = tempdir(CLEANUP => 0) if ( length($sockdir) >= 70 );
1061
1062  $master->[0]=
1063  {
1064   pid           => 0,
1065   type          => "master",
1066   idx           => 0,
1067   path_myddir   => "$opt_vardir/master-data",
1068   path_myerr    => "$opt_vardir/log/master.err",
1069   path_pid    => "$opt_vardir/run/master.pid",
1070   path_sock   => "$sockdir/master.sock",
1071   port   =>  $opt_master_myport,
1072   start_timeout =>  400, # enough time create innodb tables
1073   start_opts    => [],
1074  };
1075
1076  $master->[1]=
1077  {
1078   pid           => 0,
1079   type          => "master",
1080   idx           => 1,
1081   path_myddir   => "$opt_vardir/master1-data",
1082   path_myerr    => "$opt_vardir/log/master1.err",
1083   path_pid    => "$opt_vardir/run/master1.pid",
1084   path_sock   => "$sockdir/master1.sock",
1085   port   => $opt_master_myport + 1,
1086   start_timeout => 400, # enough time create innodb tables
1087   start_opts    => [],
1088  };
1089
1090  $slave->[0]=
1091  {
1092   pid           => 0,
1093   type          => "slave",
1094   idx           => 0,
1095   path_myddir   => "$opt_vardir/slave-data",
1096   path_myerr    => "$opt_vardir/log/slave.err",
1097   path_pid    => "$opt_vardir/run/slave.pid",
1098   path_sock   => "$sockdir/slave.sock",
1099   port   => $opt_slave_myport,
1100   start_timeout => 400,
1101
1102   start_opts    => [],
1103  };
1104
1105  $slave->[1]=
1106  {
1107   pid           => 0,
1108   type          => "slave",
1109   idx           => 1,
1110   path_myddir   => "$opt_vardir/slave1-data",
1111   path_myerr    => "$opt_vardir/log/slave1.err",
1112   path_pid    => "$opt_vardir/run/slave1.pid",
1113   path_sock   => "$sockdir/slave1.sock",
1114   port   => $opt_slave_myport + 1,
1115   start_timeout => 300,
1116   start_opts    => [],
1117  };
1118
1119  $slave->[2]=
1120  {
1121   pid           => 0,
1122   type          => "slave",
1123   idx           => 2,
1124   path_myddir   => "$opt_vardir/slave2-data",
1125   path_myerr    => "$opt_vardir/log/slave2.err",
1126   path_pid    => "$opt_vardir/run/slave2.pid",
1127   path_sock   => "$sockdir/slave2.sock",
1128   port   => $opt_slave_myport + 2,
1129   start_timeout => 300,
1130   start_opts    => [],
1131  };
1132
1133  # --------------------------------------------------------------------------
1134  # extern
1135  # --------------------------------------------------------------------------
1136  if ( $opt_extern )
1137  {
1138    # Turn off features not supported when running with extern server
1139    $opt_skip_rpl= 1;
1140
1141    # Setup master->[0] with the settings for the extern server
1142    $master->[0]->{'path_sock'}=  $opt_socket ? $opt_socket : "/tmp/mysql.sock";
1143    mtr_report("Using extern server at '$master->[0]->{path_sock}'");
1144  }
1145  else
1146  {
1147    mtr_error("--socket can only be used in combination with --extern")
1148      if $opt_socket;
1149  }
1150
1151
1152
1153  $path_timefile=  "$opt_vardir/log/mysqltest-time";
1154  $path_mysqltest_log=  "$opt_vardir/log/mysqltest.log";
1155  $path_current_test_log= "$opt_vardir/log/current_test";
1156
1157  $path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/";
1158}
1159
1160#
1161# To make it easier for different devs to work on the same host,
1162# an environment variable can be used to control all ports. A small
1163# number is to be used, 0 - 16 or similar.
1164#
1165# Note the MASTER_MYPORT has to be set the same in all 4.x and 5.x
1166# versions of this script, else a 4.0 test run might conflict with a
1167# 5.1 test run, even if different MTR_BUILD_THREAD is used. This means
1168# all port numbers might not be used in this version of the script.
1169#
1170# Also note the limitation of ports we are allowed to hand out. This
1171# differs between operating systems and configuration, see
1172# http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html
1173# But a fairly safe range seems to be 5001 - 32767
1174#
1175
1176sub set_mtr_build_thread_ports($) {
1177  my $mtr_build_thread= shift;
1178
1179  if ( lc($mtr_build_thread) eq 'auto' ) {
1180    print "Requesting build thread... ";
1181    $ENV{'MTR_BUILD_THREAD'} = $mtr_build_thread = mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299);
1182    print "got ".$mtr_build_thread."\n";
1183  }
1184
1185  # Up to two masters, up to three slaves
1186  # A magic value in command_line_setup depends on these equations.
1187  $opt_master_myport=         $mtr_build_thread * 10 + 10000; # and 1
1188  $opt_slave_myport=          $opt_master_myport + 2;  # and 3 4
1189
1190  if ( $opt_master_myport < 5001 or $opt_master_myport + 10 >= 32767 )
1191  {
1192    mtr_error("MTR_BUILD_THREAD number results in a port",
1193              "outside 5001 - 32767",
1194              "($opt_master_myport - $opt_master_myport + 10)");
1195  }
1196}
1197
1198
1199sub datadir_list_setup () {
1200
1201  # Make a list of all data_dirs
1202  for (my $idx= 0; $idx < $max_master_num; $idx++)
1203  {
1204    push(@data_dir_lst, $master->[$idx]->{'path_myddir'});
1205  }
1206
1207  for (my $idx= 0; $idx < $max_slave_num; $idx++)
1208  {
1209    push(@data_dir_lst, $slave->[$idx]->{'path_myddir'});
1210  }
1211}
1212
1213
1214##############################################################################
1215#
1216#  Set paths to various executable programs
1217#
1218##############################################################################
1219
1220
1221sub collect_mysqld_features () {
1222  my $found_variable_list_start= 0;
1223  my $tmpdir;
1224  if ( $opt_tmpdir ) {
1225    # Use the requested tmpdir
1226    mkpath($opt_tmpdir) if (! -d $opt_tmpdir);
1227    $tmpdir= $opt_tmpdir;
1228  }
1229  else {
1230    $tmpdir= tempdir(CLEANUP => 0); # Directory removed by this function
1231  }
1232
1233  #
1234  # Execute "mysqld --help --verbose" to get a list
1235  # list of all features and settings
1236  #
1237  # --no-defaults and --skip-grant-tables are to avoid loading
1238  # system-wide configs and plugins
1239  #
1240  # --datadir must exist, mysqld will chdir into it
1241  #
1242  my $list= `$exe_mysqld --no-defaults --datadir=$tmpdir --lc-messages-dir=$path_language --skip-grant-tables --verbose --help`;
1243
1244  foreach my $line (split('\n', $list))
1245  {
1246    # First look for version
1247    if ( !$mysql_version_id )
1248    {
1249      # Look for version
1250      my $exe_name= basename($exe_mysqld);
1251      mtr_verbose("exe_name: $exe_name");
1252      if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ )
1253      {
1254	#print "Major: $1 Minor: $2 Build: $3\n";
1255	$mysql_version_id= $1*10000 + $2*100 + $3;
1256	#print "mysql_version_id: $mysql_version_id\n";
1257	mtr_report("MySQL Version $1.$2.$3");
1258      }
1259    }
1260    else
1261    {
1262      if (!$found_variable_list_start)
1263      {
1264	# Look for start of variables list
1265	if ( $line =~ /[\-]+\s[\-]+/ )
1266	{
1267	  $found_variable_list_start= 1;
1268	}
1269      }
1270      else
1271      {
1272	# Put variables into hash
1273	if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
1274	{
1275	  # print "$1=\"$2\"\n";
1276	  $mysqld_variables{$1}= $2;
1277	}
1278	else
1279	{
1280	  # The variable list is ended with a blank line
1281	  if ( $line =~ /^[\s]*$/ )
1282	  {
1283	    last;
1284	  }
1285	  else
1286	  {
1287	    # Send out a warning, we should fix the variables that has no
1288	    # space between variable name and it's value
1289	    # or should it be fixed width column parsing? It does not
1290	    # look like that in function my_print_variables in my_getopt.c
1291	    mtr_warning("Could not parse variable list line : $line");
1292	  }
1293	}
1294      }
1295    }
1296  }
1297  rmtree($tmpdir) if (!$opt_tmpdir);
1298  mtr_error("Could not find version of MySQL") unless $mysql_version_id;
1299  mtr_error("Could not find variabes list") unless $found_variable_list_start;
1300
1301}
1302
1303
1304sub run_query($$) {
1305  my ($mysqld, $query)= @_;
1306
1307  my $args;
1308  mtr_init_args(\$args);
1309
1310  mtr_add_arg($args, "--no-defaults");
1311  mtr_add_arg($args, "--user=%s", $opt_user);
1312  mtr_add_arg($args, "--port=%d", $mysqld->{'port'});
1313  mtr_add_arg($args, "--socket=%s", $mysqld->{'path_sock'});
1314  mtr_add_arg($args, "--silent"); # Tab separated output
1315  mtr_add_arg($args, "-e '%s'", $query);
1316
1317  my $cmd= "$exe_mysql " . join(' ', @$args);
1318  mtr_verbose("cmd: $cmd");
1319  return `$cmd`;
1320}
1321
1322
1323sub collect_mysqld_features_from_running_server ()
1324{
1325  my $list= run_query($master->[0], "use mysql; SHOW VARIABLES");
1326
1327  foreach my $line (split('\n', $list))
1328  {
1329    # Put variables into hash
1330    if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
1331    {
1332      print "$1=\"$2\"\n";
1333      $mysqld_variables{$1}= $2;
1334    }
1335  }
1336}
1337
1338sub executable_setup () {
1339
1340  #
1341  # Check if libtool is available in this distribution/clone
1342  # we need it when valgrinding or debugging non installed binary
1343  # Otherwise valgrind will valgrind the libtool wrapper or bash
1344  # and gdb will not find the real executable to debug
1345  #
1346  if ( -x "../libtool")
1347  {
1348    $exe_libtool= "../libtool";
1349    if ($opt_valgrind or $glob_debugger)
1350    {
1351      mtr_report("Using \"$exe_libtool\" when running valgrind or debugger");
1352    }
1353  }
1354
1355  # Look for my_print_defaults
1356  $exe_my_print_defaults=
1357    mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'),
1358		           "$path_client_bindir/my_print_defaults",
1359		           "$glob_bindir/extra/my_print_defaults");
1360
1361  # Look for perror
1362  $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'),
1363			                  "$glob_bindir/extra/perror",
1364			                  "$path_client_bindir/perror");
1365
1366  # Look for the client binaries
1367  $exe_mysqlcheck=     mtr_exe_exists("$path_client_bindir/mysqlcheck");
1368  $exe_mysqldump=      mtr_exe_exists("$path_client_bindir/mysqldump");
1369  $exe_mysqlimport=    mtr_exe_exists("$path_client_bindir/mysqlimport");
1370  $exe_mysqlshow=      mtr_exe_exists("$path_client_bindir/mysqlshow");
1371  $exe_mysqlbinlog=    mtr_exe_exists("$path_client_bindir/mysqlbinlog");
1372  $exe_mysqladmin=     mtr_exe_exists("$path_client_bindir/mysqladmin");
1373  $exe_mysql=          mtr_exe_exists("$path_client_bindir/mysql");
1374
1375  if (!$opt_extern)
1376  {
1377    # Look for SQL scripts directory
1378    if ( mtr_file_exists("$path_share/mysql_system_tables.sql") ne "")
1379    {
1380      # The SQL scripts are in path_share
1381      $path_sql_dir= $path_share;
1382    }
1383    else
1384    {
1385      $path_sql_dir= mtr_path_exists("$glob_basedir/share",
1386				     "$glob_basedir/scripts");
1387    }
1388
1389    if ( $mysql_version_id >= 50100 )
1390    {
1391      $exe_mysqlslap=    mtr_exe_exists("$path_client_bindir/mysqlslap");
1392    }
1393    if ( $mysql_version_id >= 50000 and !$glob_use_embedded_server )
1394    {
1395      $exe_mysql_upgrade= mtr_exe_exists("$path_client_bindir/mysql_upgrade")
1396    }
1397    else
1398    {
1399      $exe_mysql_upgrade= "";
1400    }
1401
1402    # Look for mysql_fix_privilege_tables.sql script
1403    $file_mysql_fix_privilege_tables=
1404      mtr_file_exists("$glob_basedir/scripts/mysql_fix_privilege_tables.sql",
1405  		    "$glob_basedir/share/mysql_fix_privilege_tables.sql",
1406  		    "$glob_basedir/share/mysql/mysql_fix_privilege_tables.sql");
1407
1408    # Look for the udf_example library
1409    $lib_udf_example=
1410      mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'),
1411                      "$glob_bindir/sql/.libs/udf_example.so",);
1412
1413    # Look for the ha_example library
1414    $lib_example_plugin=
1415      mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'),
1416                      "$glob_bindir/storage/example/.libs/ha_example.so",);
1417
1418  }
1419
1420  # Look for mysqltest executable
1421  if ( $glob_use_embedded_server )
1422  {
1423    $exe_mysqltest=
1424      mtr_exe_exists(vs_config_dirs('libmysqld/examples','mysqltest_embedded'),
1425                     "$glob_bindir/libmysqld/examples/mysqltest_embedded",
1426                     "$path_client_bindir/mysqltest_embedded");
1427  }
1428  else
1429  {
1430    $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
1431  }
1432
1433  # Look for mysql_client_test executable which may _not_ exist in
1434  # some versions, test using it should be skipped
1435  if ( $glob_use_embedded_server )
1436  {
1437    $exe_mysql_client_test=
1438      mtr_exe_maybe_exists(
1439        vs_config_dirs('libmysqld/examples', 'mysql_client_test_embedded'),
1440        "$glob_bindir/libmysqld/examples/mysql_client_test_embedded");
1441  }
1442  else
1443  {
1444    $exe_mysql_client_test=
1445      mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'),
1446                           "$glob_bindir/tests/mysql_client_test",
1447                           "$glob_bindir/bin/mysql_client_test");
1448  }
1449
1450  # Look for bug25714 executable which may _not_ exist in
1451  # some versions, test using it should be skipped
1452  $exe_bug25714=
1453      mtr_exe_maybe_exists(vs_config_dirs('tests', 'bug25714'),
1454                           "$glob_bindir/tests/bug25714");
1455}
1456
1457
1458sub generate_cmdline_mysqldump ($) {
1459  my($mysqld) = @_;
1460  return
1461    mtr_native_path($exe_mysqldump) .
1462      " --no-defaults -uroot --debug-check " .
1463      "--port=$mysqld->{'port'} " .
1464      "--socket=$mysqld->{'path_sock'} --password=";
1465}
1466
1467
1468##############################################################################
1469#
1470#  Set environment to be used by childs of this process for
1471#  things that are constant duting the whole lifetime of mysql-test-run.pl
1472#
1473##############################################################################
1474
1475sub mysql_client_test_arguments()
1476{
1477  my $exe= $exe_mysql_client_test;
1478
1479  my $args;
1480  mtr_init_args(\$args);
1481  if ( $opt_valgrind_mysqltest )
1482  {
1483    valgrind_arguments($args, \$exe);
1484  }
1485
1486  mtr_add_arg($args, "--no-defaults");
1487  mtr_add_arg($args, "--testcase");
1488  mtr_add_arg($args, "--user=root");
1489  mtr_add_arg($args, "--port=$master->[0]->{'port'}");
1490  mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}");
1491
1492  if ( $opt_extern || $mysql_version_id >= 50000 )
1493  {
1494    mtr_add_arg($args, "--vardir=$opt_vardir")
1495  }
1496
1497  if ( $opt_debug )
1498  {
1499    mtr_add_arg($args,
1500      "--debug=d:t:A,$path_vardir_trace/log/mysql_client_test.trace");
1501  }
1502
1503  if ( $glob_use_embedded_server )
1504  {
1505    mtr_add_arg($args,
1506      " -A --lc-messages-dir=$path_language");
1507    mtr_add_arg($args,
1508      " -A --datadir=$slave->[0]->{'path_myddir'}");
1509    mtr_add_arg($args,
1510      " -A --character-sets-dir=$path_charsetsdir");
1511  }
1512
1513  return join(" ", $exe, @$args);
1514}
1515
1516sub mysql_upgrade_arguments()
1517{
1518  my $exe= $exe_mysql_upgrade;
1519
1520  my $args;
1521  mtr_init_args(\$args);
1522#  if ( $opt_valgrind_mysql_ugrade )
1523#  {
1524#    valgrind_arguments($args, \$exe);
1525#  }
1526
1527  mtr_add_arg($args, "--no-defaults");
1528  mtr_add_arg($args, "--user=root");
1529  mtr_add_arg($args, "--port=$master->[0]->{'port'}");
1530  mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}");
1531  mtr_add_arg($args, "--datadir=$master->[0]->{'path_myddir'}");
1532  mtr_add_arg($args, "--basedir=$glob_basedir");
1533  mtr_add_arg($args, "--tmpdir=$opt_tmpdir");
1534
1535  if ( $opt_debug )
1536  {
1537    mtr_add_arg($args,
1538      "--debug=d:t:A,$path_vardir_trace/log/mysql_upgrade.trace");
1539  }
1540
1541  return join(" ", $exe, @$args);
1542}
1543
1544# Note that some env is setup in spawn/run, in "mtr_process.pl"
1545
1546sub environment_setup () {
1547
1548  umask(022);
1549
1550  my @ld_library_paths;
1551
1552  if ($path_client_libdir)
1553  {
1554    # Use the --client-libdir passed on commandline
1555    push(@ld_library_paths, "$path_client_libdir");
1556  }
1557  else
1558  {
1559    # Setup LD_LIBRARY_PATH so the libraries from this distro/clone
1560    # are used in favor of the system installed ones
1561    if ( $source_dist )
1562    {
1563      push(@ld_library_paths, "$glob_bindir/libmysql/.libs/",
1564	   "$glob_bindir/libmysql_r/.libs/",
1565	   "$glob_bindir/zlib.libs/");
1566    }
1567    else
1568    {
1569      push(@ld_library_paths, "$glob_bindir/lib");
1570    }
1571  }
1572
1573  # --------------------------------------------------------------------------
1574  # Valgrind need to be run with debug libraries otherwise it's almost
1575  # impossible to add correct supressions, that means if "/usr/lib/debug"
1576  # is available, it should be added to
1577  # LD_LIBRARY_PATH
1578  #
1579  # But pthread is broken in libc6-dbg on Debian <= 3.1 (see Debian
1580  # bug 399035, http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=399035),
1581  # so don't change LD_LIBRARY_PATH on that platform.
1582  # --------------------------------------------------------------------------
1583  my $debug_libraries_path= "/usr/lib/debug";
1584  my $deb_version;
1585  if (  $opt_valgrind and -d $debug_libraries_path and
1586        (! -e '/etc/debian_version' or
1587	 ($deb_version= mtr_grab_file('/etc/debian_version')) !~ /^[0-9]+\.[0-9]$/ or
1588         $deb_version > 3.1 ) )
1589  {
1590    push(@ld_library_paths, $debug_libraries_path);
1591  }
1592
1593  $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths,
1594				$ENV{'LD_LIBRARY_PATH'} ?
1595				split(':', $ENV{'LD_LIBRARY_PATH'}) : ());
1596  mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}");
1597
1598  $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths,
1599				  $ENV{'DYLD_LIBRARY_PATH'} ?
1600				  split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ());
1601  mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}");
1602
1603  # The environment variable used for shared libs on AIX
1604  $ENV{'SHLIB_PATH'}= join(":", @ld_library_paths,
1605                           $ENV{'SHLIB_PATH'} ?
1606                           split(':', $ENV{'SHLIB_PATH'}) : ());
1607  mtr_debug("SHLIB_PATH: $ENV{'SHLIB_PATH'}");
1608
1609  # The environment variable used for shared libs on hp-ux
1610  $ENV{'LIBPATH'}= join(":", @ld_library_paths,
1611                        $ENV{'LIBPATH'} ?
1612                        split(':', $ENV{'LIBPATH'}) : ());
1613  mtr_debug("LIBPATH: $ENV{'LIBPATH'}");
1614
1615  # --------------------------------------------------------------------------
1616  # Also command lines in .opt files may contain env vars
1617  # --------------------------------------------------------------------------
1618
1619  $ENV{'CHARSETSDIR'}=              $path_charsetsdir;
1620  $ENV{'UMASK'}=              "0660"; # The octal *string*
1621  $ENV{'UMASK_DIR'}=          "0770"; # The octal *string*
1622
1623  #
1624  # MySQL tests can produce output in various character sets
1625  # (especially, ctype_xxx.test). To avoid confusing Perl
1626  # with output which is incompatible with the current locale
1627  # settings, we reset the current values of LC_ALL and LC_CTYPE to "C".
1628  # For details, please see
1629  # Bug#27636 tests fails if LC_* variables set to *_*.UTF-8
1630  #
1631  $ENV{'LC_ALL'}=             "C";
1632  $ENV{'LC_CTYPE'}=           "C";
1633
1634  $ENV{'LC_COLLATE'}=         "C";
1635  $ENV{'USE_RUNNING_SERVER'}= $opt_extern;
1636  $ENV{'MYSQL_TEST_DIR'}=     $glob_mysql_test_dir;
1637  $ENV{'MYSQLTEST_VARDIR'}=   $opt_vardir;
1638  $ENV{'MYSQL_TMP_DIR'}=      $opt_tmpdir;
1639  $ENV{'MASTER_MYSOCK'}=      $master->[0]->{'path_sock'};
1640  $ENV{'MASTER_MYSOCK1'}=     $master->[1]->{'path_sock'};
1641  $ENV{'MASTER_MYPORT'}=      $master->[0]->{'port'};
1642  $ENV{'MASTER_MYPORT1'}=     $master->[1]->{'port'};
1643  $ENV{'SLAVE_MYSOCK'}=       $slave->[0]->{'path_sock'};
1644  $ENV{'SLAVE_MYPORT'}=       $slave->[0]->{'port'};
1645  $ENV{'SLAVE_MYPORT1'}=      $slave->[1]->{'port'};
1646  $ENV{'SLAVE_MYPORT2'}=      $slave->[2]->{'port'};
1647  $ENV{'MYSQL_TCP_PORT'}=     $mysqld_variables{'port'};
1648  $ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'master-port'};
1649
1650  $ENV{MTR_BUILD_THREAD}=      $opt_mtr_build_thread;
1651
1652  $ENV{'EXE_MYSQL'}=          $exe_mysql;
1653
1654  # ----------------------------------------------------
1655  # Setup env so childs can execute mysqlcheck
1656  # ----------------------------------------------------
1657  my $cmdline_mysqlcheck=
1658    mtr_native_path($exe_mysqlcheck) .
1659    " --no-defaults --debug-check -uroot " .
1660    "--port=$master->[0]->{'port'} " .
1661    "--socket=$master->[0]->{'path_sock'} --password=";
1662
1663  if ( $opt_debug )
1664  {
1665    $cmdline_mysqlcheck .=
1666      " --debug=d:t:A,$path_vardir_trace/log/mysqlcheck.trace";
1667  }
1668  $ENV{'MYSQL_CHECK'}=              $cmdline_mysqlcheck;
1669
1670  # ----------------------------------------------------
1671  # Setup env to childs can execute myqldump
1672  # ----------------------------------------------------
1673  my $cmdline_mysqldump= generate_cmdline_mysqldump($master->[0]);
1674  my $cmdline_mysqldumpslave= generate_cmdline_mysqldump($slave->[0]);
1675
1676  if ( $opt_debug )
1677  {
1678    $cmdline_mysqldump .=
1679      " --debug=d:t:A,$path_vardir_trace/log/mysqldump-master.trace";
1680    $cmdline_mysqldumpslave .=
1681      " --debug=d:t:A,$path_vardir_trace/log/mysqldump-slave.trace";
1682  }
1683  $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
1684  $ENV{'MYSQL_DUMP_SLAVE'}= $cmdline_mysqldumpslave;
1685
1686
1687  # ----------------------------------------------------
1688  # Setup env so childs can execute mysqlslap
1689  # ----------------------------------------------------
1690  if ( $exe_mysqlslap )
1691  {
1692    my $cmdline_mysqlslap=
1693      mtr_native_path($exe_mysqlslap) .
1694      " -uroot " .
1695      "--port=$master->[0]->{'port'} " .
1696      "--socket=$master->[0]->{'path_sock'} --password= ";
1697
1698    if ( $opt_debug )
1699   {
1700      $cmdline_mysqlslap .=
1701	" --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace";
1702    }
1703    $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap;
1704  }
1705
1706  # ----------------------------------------------------
1707  # Setup env so childs can execute mysqlimport
1708  # ----------------------------------------------------
1709  my $cmdline_mysqlimport=
1710    mtr_native_path($exe_mysqlimport) .
1711    " -uroot --debug-check " .
1712    "--port=$master->[0]->{'port'} " .
1713    "--socket=$master->[0]->{'path_sock'} --password=";
1714
1715  if ( $opt_debug )
1716  {
1717    $cmdline_mysqlimport .=
1718      " --debug=d:t:A,$path_vardir_trace/log/mysqlimport.trace";
1719  }
1720  $ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport;
1721
1722
1723  # ----------------------------------------------------
1724  # Setup env so childs can execute mysqlshow
1725  # ----------------------------------------------------
1726  my $cmdline_mysqlshow=
1727    mtr_native_path($exe_mysqlshow) .
1728    " -uroot --debug-check " .
1729    "--port=$master->[0]->{'port'} " .
1730    "--socket=$master->[0]->{'path_sock'} --password=";
1731
1732  if ( $opt_debug )
1733  {
1734    $cmdline_mysqlshow .=
1735      " --debug=d:t:A,$path_vardir_trace/log/mysqlshow.trace";
1736  }
1737  $ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow;
1738
1739  # ----------------------------------------------------
1740  # Setup env so childs can execute mysqlbinlog
1741  # ----------------------------------------------------
1742  my $cmdline_mysqlbinlog=
1743    mtr_native_path($exe_mysqlbinlog) .
1744      " --no-defaults --disable-force-if-open --debug-check";
1745  if ( !$opt_extern && $mysql_version_id >= 50000 )
1746  {
1747    $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir";
1748  }
1749  # Always use the given tmpdir for the LOAD files created
1750  # by mysqlbinlog
1751  $cmdline_mysqlbinlog .=" --local-load=$opt_tmpdir";
1752
1753  if ( $opt_debug )
1754  {
1755    $cmdline_mysqlbinlog .=
1756      " --debug=d:t:A,$path_vardir_trace/log/mysqlbinlog.trace";
1757  }
1758  $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog;
1759
1760  # ----------------------------------------------------
1761  # Setup env so childs can execute mysql
1762  # ----------------------------------------------------
1763  my $cmdline_mysql=
1764    mtr_native_path($exe_mysql) .
1765    " --no-defaults --debug-check --host=localhost  --user=root --password= " .
1766    "--port=$master->[0]->{'port'} " .
1767    "--socket=$master->[0]->{'path_sock'} ".
1768    "--character-sets-dir=$path_charsetsdir";
1769
1770  $ENV{'MYSQL'}= $cmdline_mysql;
1771
1772  # ----------------------------------------------------
1773  # Setup env so childs can execute bug25714
1774  # ----------------------------------------------------
1775  $ENV{'MYSQL_BUG25714'}=  $exe_bug25714;
1776
1777  # ----------------------------------------------------
1778  # Setup env so childs can execute mysql_client_test
1779  # ----------------------------------------------------
1780  $ENV{'MYSQL_CLIENT_TEST'}=  mysql_client_test_arguments();
1781
1782  # ----------------------------------------------------
1783  # Setup env so childs can execute mysql_upgrade
1784  # ----------------------------------------------------
1785  if ( !$opt_extern && $mysql_version_id >= 50000 )
1786  {
1787    $ENV{'MYSQL_UPGRADE'}= mysql_upgrade_arguments();
1788  }
1789
1790  if ( !$opt_extern )
1791  {
1792    $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}=  $file_mysql_fix_privilege_tables;
1793  }
1794
1795  # ----------------------------------------------------
1796  # Setup env so childs can execute my_print_defaults
1797  # ----------------------------------------------------
1798  $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= mtr_native_path($exe_my_print_defaults);
1799
1800  # ----------------------------------------------------
1801  # Setup env so childs can execute mysqladmin
1802  # ----------------------------------------------------
1803  $ENV{'MYSQLADMIN'}= mtr_native_path($exe_mysqladmin);
1804
1805  # ----------------------------------------------------
1806  # Setup env so childs can execute perror
1807  # ----------------------------------------------------
1808  $ENV{'MY_PERROR'}= mtr_native_path($exe_perror);
1809
1810  # ----------------------------------------------------
1811  # Add the path where mysqld will find udf_example.so
1812  # ----------------------------------------------------
1813  $ENV{'UDF_EXAMPLE_LIB'}=
1814    ($lib_udf_example ? basename($lib_udf_example) : "");
1815  $ENV{'UDF_EXAMPLE_LIB_OPT'}=
1816    ($lib_udf_example ? "--plugin_dir=" . dirname($lib_udf_example) : "");
1817
1818  # ----------------------------------------------------
1819  # Add the path where mysqld will find ha_example.so
1820  # ----------------------------------------------------
1821  $ENV{'EXAMPLE_PLUGIN'}=
1822    ($lib_example_plugin ? basename($lib_example_plugin) : "");
1823  $ENV{'EXAMPLE_PLUGIN_OPT'}=
1824    ($lib_example_plugin ? "--plugin_dir=" . dirname($lib_example_plugin) : "");
1825
1826  # ----------------------------------------------------
1827  # Setup env so childs can execute myisampack and myisamchk
1828  # ----------------------------------------------------
1829  $ENV{'MYISAMCHK'}= mtr_native_path(mtr_exe_exists(
1830                       vs_config_dirs('storage/myisam', 'myisamchk'),
1831                       vs_config_dirs('myisam', 'myisamchk'),
1832                       "$path_client_bindir/myisamchk",
1833                       "$glob_bindir/storage/myisam/myisamchk",
1834                       "$glob_bindir/myisam/myisamchk"));
1835  $ENV{'MYISAMPACK'}= mtr_native_path(mtr_exe_exists(
1836                        vs_config_dirs('storage/myisam', 'myisampack'),
1837                        vs_config_dirs('myisam', 'myisampack'),
1838                        "$path_client_bindir/myisampack",
1839                        "$glob_bindir/storage/myisam/myisampack",
1840                        "$glob_bindir/myisam/myisampack"));
1841
1842  # ----------------------------------------------------
1843  # Setup env so childs can execute aria_pack and aria_chk
1844  # ----------------------------------------------------
1845  $ENV{'ARIA_CHK'}= mtr_native_path(mtr_exe_maybe_exists(
1846                       vs_config_dirs('storage/maria', 'aria_chk'),
1847                       vs_config_dirs('maria', 'aria_chk'),
1848                       "$path_client_bindir/aria_chk",
1849                       "$glob_basedir/storage/maria/aria_chk",
1850                       "$glob_basedir/maria/aria_chk"));
1851  $ENV{'ARIA_PACK'}= mtr_native_path(mtr_exe_maybe_exists(
1852                        vs_config_dirs('storage/maria', 'aria_pack'),
1853                        vs_config_dirs('maria', 'aria_pack'),
1854                        "$path_client_bindir/aria_pack",
1855                        "$glob_basedir/storage/maria/aria_pack",
1856                        "$glob_basedir/maria/aria_pack"));
1857
1858  # ----------------------------------------------------
1859  # We are nice and report a bit about our settings
1860  # ----------------------------------------------------
1861  if (!$opt_extern)
1862  {
1863    print "Using MTR_BUILD_THREAD      = $ENV{MTR_BUILD_THREAD}\n";
1864    print "Using MASTER_MYPORT         = $ENV{MASTER_MYPORT}\n";
1865    print "Using MASTER_MYPORT1        = $ENV{MASTER_MYPORT1}\n";
1866    print "Using SLAVE_MYPORT          = $ENV{SLAVE_MYPORT}\n";
1867    print "Using SLAVE_MYPORT1         = $ENV{SLAVE_MYPORT1}\n";
1868    print "Using SLAVE_MYPORT2         = $ENV{SLAVE_MYPORT2}\n";
1869  }
1870
1871  # Create an environment variable to make it possible
1872  # to detect that valgrind is being used from test cases
1873  $ENV{'VALGRIND_TEST'}= $opt_valgrind;
1874
1875}
1876
1877
1878##############################################################################
1879#
1880#  If we get a ^C, we try to clean up before termination
1881#
1882##############################################################################
1883# FIXME check restrictions what to do in a signal handler
1884
1885sub signal_setup () {
1886  $SIG{INT}= \&handle_int_signal;
1887}
1888
1889
1890sub handle_int_signal () {
1891  $SIG{INT}= 'DEFAULT';         # If we get a ^C again, we die...
1892  mtr_warning("got INT signal, cleaning up.....");
1893  stop_all_servers();
1894  mtr_error("We die from ^C signal from user");
1895}
1896
1897
1898##############################################################################
1899#
1900#  Handle left overs from previous runs
1901#
1902##############################################################################
1903
1904sub kill_running_servers () {
1905
1906  if ( $opt_fast or $glob_use_embedded_server )
1907  {
1908    # FIXME is embedded server really using PID files?!
1909    unlink($master->[0]->{'path_pid'});
1910    unlink($master->[1]->{'path_pid'});
1911    unlink($slave->[0]->{'path_pid'});
1912    unlink($slave->[1]->{'path_pid'});
1913    unlink($slave->[2]->{'path_pid'});
1914  }
1915  else
1916  {
1917    # Ensure that no old mysqld test servers are running
1918    # This is different from terminating processes we have
1919    # started from this run of the script, this is terminating
1920    # leftovers from previous runs.
1921    mtr_kill_leftovers();
1922   }
1923}
1924
1925#
1926# Remove var and any directories in var/ created by previous
1927# tests
1928#
1929sub remove_stale_vardir () {
1930
1931  mtr_report("Removing Stale Files");
1932
1933  # Safety!
1934  mtr_error("No, don't remove the vardir when running with --extern")
1935    if $opt_extern;
1936
1937  mtr_verbose("opt_vardir: $opt_vardir");
1938  if ( $opt_vardir eq $default_vardir )
1939  {
1940    #
1941    # Running with "var" in mysql-test dir
1942    #
1943    if ( -l $opt_vardir)
1944    {
1945      # var is a symlink
1946
1947      if ( $opt_mem and readlink($opt_vardir) eq $opt_mem )
1948      {
1949	# Remove the directory which the link points at
1950	mtr_verbose("Removing " . readlink($opt_vardir));
1951	mtr_rmtree(readlink($opt_vardir));
1952
1953	# Remove the "var" symlink
1954	mtr_verbose("unlink($opt_vardir)");
1955	unlink($opt_vardir);
1956      }
1957      elsif ( $opt_mem )
1958      {
1959	# Just remove the "var" symlink
1960	mtr_report("WARNING: Removing '$opt_vardir' symlink it's wrong");
1961
1962	mtr_verbose("unlink($opt_vardir)");
1963	unlink($opt_vardir);
1964      }
1965      else
1966      {
1967	# Some users creates a soft link in mysql-test/var to another area
1968	# - allow it, but remove all files in it
1969
1970	mtr_report("WARNING: Using the 'mysql-test/var' symlink");
1971
1972	# Make sure the directory where it points exist
1973        if (! -d readlink($opt_vardir))
1974        {
1975          mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
1976          unlink($opt_vardir);
1977        }
1978
1979	foreach my $bin ( glob("$opt_vardir/*") )
1980	{
1981	  mtr_verbose("Removing bin $bin");
1982	  mtr_rmtree($bin);
1983	}
1984      }
1985    }
1986    else
1987    {
1988      # Remove the entire "var" dir
1989      mtr_verbose("Removing $opt_vardir/");
1990      mtr_rmtree("$opt_vardir/");
1991    }
1992
1993    if ( $opt_mem )
1994    {
1995      # A symlink from var/ to $opt_mem will be set up
1996      # remove the $opt_mem dir to assure the symlink
1997      # won't point at an old directory
1998      mtr_verbose("Removing $opt_mem");
1999      mtr_rmtree($opt_mem);
2000    }
2001
2002  }
2003  else
2004  {
2005    #
2006    # Running with "var" in some other place
2007    #
2008
2009    # Remove the var/ dir in mysql-test dir if any
2010    # this could be an old symlink that shouldn't be there
2011    # mtr_verbose("Removing $default_vardir");
2012    # mtr_rmtree($default_vardir);
2013
2014    # Remove the "var" dir
2015    mtr_verbose("Removing $opt_vardir/");
2016    mtr_rmtree("$opt_vardir/");
2017  }
2018}
2019
2020#
2021# Create var and the directories needed in var
2022#
2023sub setup_vardir() {
2024  mtr_report("Creating Directories");
2025
2026  if ( $opt_vardir eq $default_vardir )
2027  {
2028    #
2029    # Running with "var" in mysql-test dir
2030    #
2031    if ( -l $opt_vardir )
2032    {
2033      #  it's a symlink
2034
2035      # Make sure the directory where it points exist
2036      if (! -d readlink($opt_vardir))
2037      {
2038        mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
2039        unlink($opt_vardir);
2040      }
2041    }
2042    elsif ( $opt_mem )
2043    {
2044      # Runinng with "var" as a link to some "memory" location, normally tmpfs
2045      mtr_verbose("Creating $opt_mem");
2046      mkpath($opt_mem);
2047
2048      mtr_report("Symlinking 'var' to '$opt_mem'");
2049      symlink($opt_mem, $opt_vardir);
2050    }
2051  }
2052
2053  if ( ! -d $opt_vardir )
2054  {
2055    mtr_verbose("Creating $opt_vardir");
2056    mkpath($opt_vardir);
2057  }
2058
2059  # Ensure a proper error message if vardir couldn't be created
2060  unless ( -d $opt_vardir and -w $opt_vardir )
2061  {
2062    mtr_error("Writable 'var' directory is needed, use the " .
2063	      "'--vardir=<path>' option");
2064  }
2065
2066  mkpath("$opt_vardir/log");
2067  mkpath("$opt_vardir/run");
2068  mkpath("$opt_vardir/tmp");
2069  mkpath($opt_tmpdir) if $opt_tmpdir ne "$opt_vardir/tmp";
2070
2071  # Create new data dirs
2072  foreach my $data_dir (@data_dir_lst)
2073  {
2074    mkpath("$data_dir/mysql");
2075    mkpath("$data_dir/test");
2076  }
2077
2078  # Make a link std_data_ln in var/ that points to std_data
2079  if ( ! $glob_win32 )
2080  {
2081    symlink("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data_ln");
2082  }
2083  else
2084  {
2085    # on windows, copy all files from std_data into var/std_data_ln
2086    mkpath("$opt_vardir/std_data_ln");
2087    mtr_copy_dir("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data_ln");
2088  }
2089
2090  # Remove old log files
2091  foreach my $name (glob("r/*.progress r/*.log r/*.warnings"))
2092  {
2093    unlink($name);
2094  }
2095  if ( $opt_valgrind and $opt_debug )
2096  {
2097    # When both --valgrind and --debug is selected, send
2098    # all output to the trace file, making it possible to
2099    # see the exact location where valgrind complains
2100    foreach my $mysqld (@{$master}, @{$slave})
2101    {
2102      my $sidx= $mysqld->{idx} ? "$mysqld->{idx}" : "";
2103      my $trace_name= "$opt_vardir/log/" . $mysqld->{type} . "$sidx.trace";
2104      open(LOG, ">$mysqld->{path_myerr}") or die "Can't create $mysqld->{path_myerr}\n";
2105      print LOG "
2106NOTE: When running with --valgrind --debug the output from the .err file is
2107stored together with the trace file to make it easier to find the exact
2108position for valgrind errors.
2109See trace file $trace_name.\n";
2110      close(LOG);
2111      $mysqld->{path_myerr}= $trace_name;
2112    }
2113  }
2114}
2115
2116
2117sub  check_running_as_root () {
2118  # Check if running as root
2119  # i.e a file can be read regardless what mode we set it to
2120  my $test_file= "$opt_vardir/test_running_as_root.txt";
2121  mtr_tofile($test_file, "MySQL");
2122  chmod(oct("0000"), $test_file);
2123
2124  my $result="";
2125  if (open(FILE,"<",$test_file))
2126  {
2127    $result= join('', <FILE>);
2128    close FILE;
2129  }
2130
2131  # Some filesystems( for example CIFS) allows reading a file
2132  # although mode was set to 0000, but in that case a stat on
2133  # the file will not return 0000
2134  my $file_mode= (stat($test_file))[2] & 07777;
2135
2136  $ENV{'MYSQL_TEST_ROOT'}= "NO";
2137  mtr_verbose("result: $result, file_mode: $file_mode");
2138  if ($result eq "MySQL" && $file_mode == 0)
2139  {
2140    mtr_warning("running this script as _root_ will cause some " .
2141                "tests to be skipped");
2142    $ENV{'MYSQL_TEST_ROOT'}= "YES";
2143  }
2144
2145  chmod(oct("0755"), $test_file);
2146  unlink($test_file);
2147
2148}
2149
2150
2151sub check_ssl_support ($) {
2152  my $mysqld_variables= shift;
2153
2154  if ($opt_skip_ssl || $opt_extern)
2155  {
2156    if (!$opt_extern)
2157    {
2158      mtr_report("Skipping SSL");
2159    }
2160    $opt_ssl_supported= 0;
2161    $opt_ssl= 0;
2162    return;
2163  }
2164
2165  if ( ! $mysqld_variables->{'ssl'} )
2166  {
2167    if ( $opt_ssl)
2168    {
2169      mtr_error("Couldn't find support for SSL");
2170      return;
2171    }
2172    mtr_report("Skipping SSL, mysqld not compiled with SSL");
2173    $opt_ssl_supported= 0;
2174    $opt_ssl= 0;
2175    return;
2176  }
2177  mtr_report("Setting mysqld to support SSL connections");
2178  $opt_ssl_supported= 1;
2179}
2180
2181
2182sub check_debug_support ($) {
2183  my $mysqld_variables= shift;
2184
2185  if ( ! $mysqld_variables->{'debug'} )
2186  {
2187    #mtr_report("Binaries are not debug compiled");
2188    $debug_compiled_binaries= 0;
2189
2190    if ( $opt_debug )
2191    {
2192      mtr_error("Can't use --debug, binaries does not support it");
2193    }
2194    return;
2195  }
2196  mtr_report("Binaries are debug compiled");
2197  $debug_compiled_binaries= 1;
2198}
2199
2200##############################################################################
2201#
2202# Helper function to handle configuration-based subdirectories which Visual
2203# Studio uses for storing binaries.  If opt_vs_config is set, this returns
2204# a path based on that setting; if not, it returns paths for the default
2205# /release/ and /debug/ subdirectories.
2206#
2207# $exe can be undefined, if the directory itself will be used
2208#
2209###############################################################################
2210
2211sub vs_config_dirs ($$) {
2212  my ($path_part, $exe) = @_;
2213
2214  $exe = "" if not defined $exe;
2215
2216  if ($multiconfig)
2217  {
2218    return ("$glob_bindir/$path_part/$multiconfig/$exe");
2219  }
2220
2221  return ("$glob_bindir/$path_part/release/$exe",
2222          "$glob_bindir/$path_part/relwithdebinfo/$exe",
2223          "$glob_bindir/$path_part/debug/$exe");
2224}
2225
2226sub mysqld_wait_started($){
2227  my $mysqld= shift;
2228
2229  if (sleep_until_file_created($mysqld->{'path_pid'},
2230			       $mysqld->{'start_timeout'},
2231			       $mysqld->{'pid'}) == 0)
2232  {
2233    # Failed to wait for pid file
2234    return 1;
2235  }
2236
2237  # Get the "real pid" of the process, it will be used for killing
2238  # the process in ActiveState's perl on windows
2239  $mysqld->{'real_pid'}= mtr_get_pid_from_file($mysqld->{'path_pid'});
2240
2241  return 0;
2242}
2243
2244
2245##############################################################################
2246#
2247#  Run the benchmark suite
2248#
2249##############################################################################
2250
2251sub run_benchmarks ($) {
2252  my $benchmark=  shift;
2253
2254  my $args;
2255
2256  if ( ! $glob_use_embedded_server )
2257  {
2258    mysqld_start($master->[0],[],[]);
2259    if ( ! $master->[0]->{'pid'} )
2260    {
2261      mtr_error("Can't start the mysqld server");
2262    }
2263  }
2264
2265  mtr_init_args(\$args);
2266
2267  mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'});
2268  mtr_add_arg($args, "--user=%s", $opt_user);
2269
2270  if ( $opt_small_bench )
2271  {
2272    mtr_add_arg($args, "--small-test");
2273    mtr_add_arg($args, "--small-tables");
2274  }
2275
2276  chdir($glob_mysql_bench_dir)
2277    or mtr_error("Couldn't chdir to '$glob_mysql_bench_dir': $!");
2278
2279  if ( ! $benchmark )
2280  {
2281    mtr_add_arg($args, "--general-log");
2282    mtr_run("$glob_mysql_bench_dir/run-all-tests", $args, "", "", "", "");
2283    # FIXME check result code?!
2284  }
2285  elsif ( -x $benchmark )
2286  {
2287    mtr_run("$glob_mysql_bench_dir/$benchmark", $args, "", "", "", "");
2288    # FIXME check result code?!
2289  }
2290  else
2291  {
2292    mtr_error("Benchmark $benchmark not found");
2293  }
2294
2295  chdir($glob_mysql_test_dir);          # Go back
2296
2297  if ( ! $glob_use_embedded_server )
2298  {
2299    stop_masters();
2300  }
2301}
2302
2303
2304##############################################################################
2305#
2306#  Run the tests
2307#
2308##############################################################################
2309
2310sub run_tests () {
2311  my ($tests)= @_;
2312
2313  mtr_print_thick_line();
2314
2315  mtr_timer_start($glob_timers,"suite", 60 * $opt_suite_timeout);
2316
2317  mtr_report_tests_not_skipped_though_disabled($tests);
2318
2319  mtr_print_header();
2320
2321  foreach my $tinfo ( @$tests )
2322  {
2323    if (run_testcase_check_skip_test($tinfo))
2324    {
2325      next;
2326    }
2327
2328    mtr_timer_start($glob_timers,"testcase", 60 * $opt_testcase_timeout);
2329    run_testcase($tinfo);
2330    mtr_timer_stop($glob_timers,"testcase");
2331  }
2332
2333  mtr_print_line();
2334
2335  if ( ! $glob_debugger and
2336       ! $opt_extern and
2337       ! $glob_use_embedded_server )
2338  {
2339    stop_all_servers();
2340  }
2341
2342  if ( $opt_gcov )
2343  {
2344    gcov_collect(); # collect coverage information
2345  }
2346  if ( $opt_gprof )
2347  {
2348    gprof_collect(); # collect coverage information
2349  }
2350
2351  mtr_report_stats($tests);
2352
2353  mtr_timer_stop($glob_timers,"suite");
2354}
2355
2356
2357##############################################################################
2358#
2359#  Initiate the test databases
2360#
2361##############################################################################
2362
2363sub initialize_servers () {
2364
2365  datadir_list_setup();
2366
2367  if ( $opt_extern )
2368  {
2369    # Running against an already started server, if the specified
2370    # vardir does not already exist it should be created
2371    if ( ! -d $opt_vardir )
2372    {
2373      mtr_report("Creating '$opt_vardir'");
2374      setup_vardir();
2375    }
2376    else
2377    {
2378      mtr_verbose("No need to create '$opt_vardir' it already exists");
2379    }
2380  }
2381  else
2382  {
2383    kill_running_servers();
2384
2385    if ( ! $opt_start_dirty )
2386    {
2387      remove_stale_vardir();
2388      setup_vardir();
2389
2390      mysql_install_db();
2391      if ( $opt_force )
2392      {
2393	# Save a snapshot of the freshly installed db
2394	# to make it possible to restore to a known point in time
2395	save_installed_db();
2396      }
2397    }
2398  }
2399  check_running_as_root();
2400
2401  mtr_log_init("$opt_vardir/log/mysql-test-run.log");
2402
2403}
2404
2405sub mysql_install_db () {
2406
2407  install_db('master', $master->[0]->{'path_myddir'});
2408
2409  if ($max_master_num > 1)
2410  {
2411    copy_install_db('master', $master->[1]->{'path_myddir'});
2412  }
2413
2414  # Install the number of slave databses needed
2415  for (my $idx= 0; $idx < $max_slave_num; $idx++)
2416  {
2417    copy_install_db("slave".($idx+1), $slave->[$idx]->{'path_myddir'});
2418  }
2419
2420  return 0;
2421}
2422
2423
2424sub copy_install_db ($$) {
2425  my $type=      shift;
2426  my $data_dir=  shift;
2427
2428  mtr_report("Installing \u$type Database");
2429
2430  # Just copy the installed db from first master
2431  mtr_copy_dir($master->[0]->{'path_myddir'}, $data_dir);
2432
2433}
2434
2435
2436sub install_db ($$) {
2437  my $type=      shift;
2438  my $data_dir=  shift;
2439
2440  mtr_report("Installing \u$type Database");
2441
2442  my $args;
2443  my $cmd_args;
2444  mtr_init_args(\$args);
2445  mtr_add_arg($args, "--no-defaults");
2446  mtr_add_arg($args, "--bootstrap");
2447  mtr_add_arg($args, "--basedir=%s", $glob_basedir);
2448  mtr_add_arg($args, "--datadir=%s", $data_dir);
2449  mtr_add_arg($args, "--loose-skip-aria");
2450  mtr_add_arg($args, "--disable-sync-frm");
2451  mtr_add_arg($args, "--loose-disable-debug");
2452  mtr_add_arg($args, "--tmpdir=.");
2453  mtr_add_arg($args, "--core-file");
2454
2455  #
2456  # Setup args for bootstrap.test
2457  #
2458  mtr_init_args(\$cmd_args);
2459  mtr_add_arg($cmd_args, "--loose-skip-aria");
2460
2461  if ( $opt_debug )
2462  {
2463    mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap_%s.trace",
2464		$path_vardir_trace, $type);
2465  }
2466
2467  mtr_add_arg($args, "--lc-messages-dir=%s", $path_language);
2468  mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
2469
2470  # InnoDB arguments that affect file location and sizes may
2471  # need to be given to the bootstrap process as well as the
2472  # server process.
2473  foreach my $extra_opt ( @opt_extra_mysqld_opt ) {
2474    if ($extra_opt =~ /--innodb/) {
2475      mtr_add_arg($args, $extra_opt);
2476    }
2477  }
2478
2479  # If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g.,
2480  # configure --disable-grant-options), mysqld will not recognize the
2481  # --bootstrap or --skip-grant-tables options.  The user can set
2482  # MYSQLD_BOOTSTRAP to the full path to a mysqld which does accept
2483  # --bootstrap, to accommodate this.
2484  my $exe_mysqld_bootstrap = $ENV{'MYSQLD_BOOTSTRAP'} || $exe_mysqld;
2485
2486  # ----------------------------------------------------------------------
2487  # export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args>
2488  # ----------------------------------------------------------------------
2489  $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args) .
2490    " " . join(" ", @$cmd_args);
2491
2492  # ----------------------------------------------------------------------
2493  # Create the bootstrap.sql file
2494  # ----------------------------------------------------------------------
2495  my $bootstrap_sql_file= "$opt_vardir/tmp/bootstrap.sql";
2496
2497  # Use the mysql database for system tables
2498  mtr_tofile($bootstrap_sql_file, "use mysql;\n");
2499
2500  # Add the offical mysql system tables
2501  # for a production system
2502  mtr_appendfile_to_file("$path_sql_dir/mysql_system_tables.sql",
2503			 $bootstrap_sql_file);
2504  mtr_appendfile_to_file("$path_sql_dir/mysql_performance_tables.sql",
2505			 $bootstrap_sql_file);
2506
2507  # Add the mysql system tables initial data
2508  # for a production system
2509  mtr_appendfile_to_file("$path_sql_dir/mysql_system_tables_data.sql",
2510			 $bootstrap_sql_file);
2511
2512  # Add test data for timezone - this is just a subset, on a real
2513  # system these tables will be populated either by mysql_tzinfo_to_sql
2514  # or by downloading the timezone table package from our website
2515  mtr_appendfile_to_file("$path_sql_dir/mysql_test_data_timezone.sql",
2516			 $bootstrap_sql_file);
2517
2518  # Fill help tables, just an empty file when running from bk repo
2519  # but will be replaced by a real fill_help_tables.sql when
2520  # building the source dist
2521  mtr_appendfile_to_file("$path_sql_dir/fill_help_tables.sql",
2522			 $bootstrap_sql_file);
2523
2524  # Remove anonymous users
2525  mtr_tofile($bootstrap_sql_file,
2526	     "DELETE FROM mysql.user where user= '';");
2527
2528  # Log bootstrap command
2529  my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log";
2530  mtr_tofile($path_bootstrap_log,
2531	     "$exe_mysqld_bootstrap " . join(" ", @$args) . "\n");
2532
2533
2534  if ( mtr_run($exe_mysqld_bootstrap, $args, $bootstrap_sql_file,
2535               $path_bootstrap_log, $path_bootstrap_log,
2536	       "", { append_log_file => 1 }) != 0 )
2537
2538  {
2539    mtr_error("Error executing mysqld --bootstrap\n" .
2540              "Could not install system database from $bootstrap_sql_file\n" .
2541	      "see $path_bootstrap_log for errors");
2542  }
2543}
2544
2545
2546#
2547# Restore snapshot of the installed slave databases
2548# if the snapshot exists
2549#
2550sub restore_slave_databases ($) {
2551  my ($num_slaves)= @_;
2552
2553  if ( -d $path_snapshot)
2554  {
2555    for (my $idx= 0; $idx < $num_slaves; $idx++)
2556    {
2557      my $data_dir= $slave->[$idx]->{'path_myddir'};
2558      my $name= basename($data_dir);
2559      mtr_rmtree($data_dir);
2560      mtr_copy_dir("$path_snapshot/$name", $data_dir);
2561    }
2562  }
2563}
2564
2565
2566sub run_testcase_check_skip_test($)
2567{
2568  my ($tinfo)= @_;
2569
2570  # ----------------------------------------------------------------------
2571  # Skip some tests silently
2572  # ----------------------------------------------------------------------
2573
2574  if ( $::opt_start_from )
2575  {
2576    if ($tinfo->{'name'} eq $::opt_start_from )
2577    {
2578      ## Found parting test. Run this test and all tests after this one
2579      $::opt_start_from= "";
2580    }
2581    else
2582    {
2583      $tinfo->{'result'}= 'MTR_RES_SKIPPED';
2584      return 1;
2585    }
2586  }
2587
2588  # ----------------------------------------------------------------------
2589  # If marked to skip, just print out and return.
2590  # Note that a test case not marked as 'skip' can still be
2591  # skipped later, because of the test case itself in cooperation
2592  # with the mysqltest program tells us so.
2593  # ----------------------------------------------------------------------
2594
2595  if ( $tinfo->{'skip'} )
2596  {
2597    mtr_report_test_name($tinfo);
2598    mtr_report_test_skipped($tinfo);
2599    return 1;
2600  }
2601
2602  return 0;
2603}
2604
2605
2606sub do_before_run_mysqltest($)
2607{
2608  my $tinfo= shift;
2609  my $args;
2610
2611  # Remove old files produced by mysqltest
2612  my $base_file= mtr_match_extension($tinfo->{'result_file'},
2613				    "result"); # Trim extension
2614  unlink("$base_file.reject");
2615  unlink("$base_file.progress");
2616  unlink("$base_file.log");
2617  unlink("$base_file.warnings");
2618
2619  if (!$opt_extern)
2620  {
2621    if (defined $tinfo->{binlog_format} and  $mysql_version_id > 50100 )
2622    {
2623      # Dynamically switch binlog format of
2624      # master, slave is always restarted
2625      foreach my $server ( @$master )
2626      {
2627        next unless ($server->{'pid'});
2628
2629	mtr_init_args(\$args);
2630	mtr_add_arg($args, "--no-defaults");
2631	mtr_add_arg($args, "--user=root");
2632	mtr_add_arg($args, "--port=$server->{'port'}");
2633	mtr_add_arg($args, "--socket=$server->{'path_sock'}");
2634
2635	my $sql= "include/set_binlog_format_".$tinfo->{binlog_format}.".sql";
2636	mtr_verbose("Setting binlog format:", $tinfo->{binlog_format});
2637	if (mtr_run($exe_mysql, $args, $sql, "", "", "") != 0)
2638	{
2639	  mtr_error("Failed to switch binlog format");
2640	}
2641      }
2642    }
2643  }
2644}
2645
2646sub do_after_run_mysqltest($)
2647{
2648  my $tinfo= shift;
2649
2650  # Save info from this testcase run to mysqltest.log
2651  mtr_appendfile_to_file($path_current_test_log, $path_mysqltest_log)
2652    if -f $path_current_test_log;
2653  mtr_appendfile_to_file($path_timefile, $path_mysqltest_log)
2654    if -f $path_timefile;
2655}
2656
2657
2658sub run_testcase_mark_logs($$)
2659{
2660  my ($tinfo, $log_msg)= @_;
2661
2662  # Write a marker to all log files
2663
2664  # The file indicating current test name
2665  mtr_tonewfile($path_current_test_log, $log_msg);
2666
2667  # each mysqld's .err file
2668  foreach my $mysqld (@{$master}, @{$slave})
2669  {
2670    mtr_tofile($mysqld->{path_myerr}, $log_msg);
2671  }
2672}
2673
2674sub find_testcase_skipped_reason($)
2675{
2676  my ($tinfo)= @_;
2677
2678  # Set default message
2679  $tinfo->{'comment'}= "Detected by testcase(no log file)";
2680
2681  # Open mysqltest-time(the mysqltest log file)
2682  my $F= IO::File->new($path_timefile)
2683    or return;
2684  my $reason;
2685
2686  while ( my $line= <$F> )
2687  {
2688    # Look for "reason: <reason for skipping test>"
2689    if ( $line =~ /reason: (.*)/ )
2690    {
2691      $reason= $1;
2692    }
2693  }
2694
2695  if ( ! $reason )
2696  {
2697    mtr_warning("Could not find reason for skipping test in $path_timefile");
2698    $reason= "Detected by testcase(reason unknown) ";
2699  }
2700  $tinfo->{'comment'}= $reason;
2701}
2702
2703
2704##############################################################################
2705#
2706#  Run a single test case
2707#
2708##############################################################################
2709
2710# When we get here, we have already filtered out test cases that doesn't
2711# apply to the current setup, for example if we use a running server, test
2712# cases that restart the server are dropped. So this function should mostly
2713# be about doing things, not a lot of logic.
2714
2715# We don't start and kill the servers for each testcase. But some
2716# testcases needs a restart, because they specify options to start
2717# mysqld with. After that testcase, we need to restart again, to set
2718# back the normal options.
2719
2720sub run_testcase ($) {
2721  my $tinfo=  shift;
2722
2723  # -------------------------------------------------------
2724  # Init variables that can change between each test case
2725  # -------------------------------------------------------
2726
2727  $ENV{'TZ'}= $tinfo->{'timezone'};
2728  mtr_verbose("Setting timezone: $tinfo->{'timezone'}");
2729
2730  my $master_restart= run_testcase_need_master_restart($tinfo);
2731  my $slave_restart= run_testcase_need_slave_restart($tinfo);
2732
2733  if ($master_restart or $slave_restart)
2734  {
2735    # Can't restart a running server that may be in use
2736    if ( $opt_extern )
2737    {
2738      mtr_report_test_name($tinfo);
2739      $tinfo->{comment}= "Can't restart a running server";
2740      mtr_report_test_skipped($tinfo);
2741      return;
2742    }
2743
2744    run_testcase_stop_servers($tinfo, $master_restart, $slave_restart);
2745  }
2746
2747  # Write to all log files to indicate start of testcase
2748  run_testcase_mark_logs($tinfo, "CURRENT_TEST: $tinfo->{name}\n");
2749
2750  my $died= mtr_record_dead_children();
2751  if ($died or $master_restart or $slave_restart)
2752  {
2753    if (run_testcase_start_servers($tinfo))
2754    {
2755      mtr_report_test_name($tinfo);
2756      report_failure_and_restart($tinfo);
2757      return 1;
2758    }
2759  }
2760  elsif ($glob_use_embedded_server)
2761  {
2762    run_master_init_script($tinfo);
2763  }
2764
2765  # ----------------------------------------------------------------------
2766  # If --start-and-exit or --start-dirty given, stop here to let user manually
2767  # run tests
2768  # ----------------------------------------------------------------------
2769  if ( $opt_start_and_exit or $opt_start_dirty )
2770  {
2771    mtr_timer_stop_all($glob_timers);
2772    mtr_report("\nServers started, exiting");
2773    if ($glob_win32_perl)
2774    {
2775      #ActiveState perl hangs  when using normal exit, use  POSIX::_exit instead
2776      use POSIX qw[ _exit ];
2777      POSIX::_exit(0);
2778    }
2779    else
2780    {
2781      exit(0);
2782    }
2783  }
2784
2785  {
2786    do_before_run_mysqltest($tinfo);
2787
2788    my $res= run_mysqltest($tinfo);
2789    mtr_report_test_name($tinfo);
2790
2791    do_after_run_mysqltest($tinfo);
2792
2793    if ( $res == 0 )
2794    {
2795      mtr_report_test_passed($tinfo);
2796    }
2797    elsif ( $res == 62 )
2798    {
2799      # Testcase itself tell us to skip this one
2800
2801      # Try to get reason from mysqltest.log
2802      find_testcase_skipped_reason($tinfo);
2803      mtr_report_test_skipped($tinfo);
2804    }
2805    elsif ( $res == 63 )
2806    {
2807      $tinfo->{'timeout'}= 1;           # Mark as timeout
2808      report_failure_and_restart($tinfo);
2809    }
2810    elsif ( $res == 1 )
2811    {
2812      # Test case failure reported by mysqltest
2813      report_failure_and_restart($tinfo);
2814    }
2815    else
2816    {
2817      # mysqltest failed, probably crashed
2818      $tinfo->{comment}=
2819	"mysqltest returned unexpected code $res, it has probably crashed";
2820      report_failure_and_restart($tinfo);
2821    }
2822  }
2823
2824  # Remove the file that mysqltest writes info to
2825  unlink($path_timefile);
2826}
2827
2828
2829#
2830# Save a snapshot of the installed test db(s)
2831# I.e take a snapshot of the var/ dir
2832#
2833sub save_installed_db () {
2834
2835  mtr_report("Saving snapshot of installed databases");
2836  mtr_rmtree($path_snapshot);
2837
2838  foreach my $data_dir (@data_dir_lst)
2839  {
2840    my $name= basename($data_dir);
2841    mtr_copy_dir("$data_dir", "$path_snapshot/$name");
2842  }
2843}
2844
2845
2846#
2847# Save any interesting files in the data_dir
2848# before the data dir is removed.
2849#
2850sub save_files_before_restore($$) {
2851  my $test_name= shift;
2852  my $data_dir= shift;
2853  my $save_name= "$opt_vardir/log/$test_name";
2854
2855  # Look for core files
2856  foreach my $core_file ( glob("$data_dir/core*") )
2857  {
2858    last if $opt_max_save_core > 0 && $num_saved_cores >= $opt_max_save_core;
2859    my $core_name= basename($core_file);
2860    mtr_report("Saving $core_name");
2861    mkdir($save_name) if ! -d $save_name;
2862    rename("$core_file", "$save_name/$core_name");
2863    ++$num_saved_cores;
2864  }
2865}
2866
2867
2868#
2869# Restore snapshot of the installed test db(s)
2870# if the snapshot exists
2871#
2872sub restore_installed_db ($) {
2873  my $test_name= shift;
2874
2875  if ( -d $path_snapshot)
2876  {
2877    mtr_report("Restoring snapshot of databases");
2878
2879    foreach my $data_dir (@data_dir_lst)
2880    {
2881      my $name= basename($data_dir);
2882      save_files_before_restore($test_name, $data_dir);
2883      mtr_rmtree("$data_dir");
2884      mtr_copy_dir("$path_snapshot/$name", "$data_dir");
2885    }
2886  }
2887  else
2888  {
2889    # No snapshot existed
2890    mtr_error("No snapshot existed");
2891  }
2892}
2893
2894sub report_failure_and_restart ($) {
2895  my $tinfo= shift;
2896
2897  mtr_report_test_failed($tinfo);
2898  print "\n";
2899  if ( $opt_force )
2900  {
2901    # Stop all servers that are known to be running
2902    stop_all_servers();
2903
2904    # Restore the snapshot of the installed test db
2905    restore_installed_db($tinfo->{'name'});
2906    mtr_report("Resuming Tests\n");
2907    return;
2908  }
2909
2910  my $test_mode= join(" ", @::glob_test_mode) || "default";
2911  mtr_report("Aborting: $tinfo->{'name'} failed in $test_mode mode. ");
2912  mtr_report("To continue, re-run with '--force'.");
2913  if ( ! $glob_debugger and
2914       ! $opt_extern and
2915       ! $glob_use_embedded_server )
2916  {
2917    stop_all_servers();
2918  }
2919  mtr_exit(1);
2920
2921}
2922
2923
2924sub run_master_init_script ($) {
2925  my ($tinfo)= @_;
2926  my $init_script= $tinfo->{'master_sh'};
2927
2928  # Run master initialization shell script if one exists
2929  if ( $init_script )
2930  {
2931    my $ret= mtr_run("/bin/sh", [$init_script], "", "", "", "");
2932    if ( $ret != 0 )
2933    {
2934      # FIXME rewrite those scripts to return 0 if successful
2935      # mtr_warning("$init_script exited with code $ret");
2936    }
2937  }
2938}
2939
2940
2941##############################################################################
2942#
2943#  Start and stop servers
2944#
2945##############################################################################
2946
2947
2948sub do_before_start_master ($) {
2949  my ($tinfo)= @_;
2950
2951  my $tname= $tinfo->{'name'};
2952
2953  # FIXME what about second master.....
2954
2955  # Don't delete anything if starting dirty
2956  return if ($opt_start_dirty);
2957
2958  foreach my $bin ( glob("$opt_vardir/log/master*-bin*") )
2959  {
2960    unlink($bin);
2961  }
2962
2963  # FIXME only remove the ones that are tied to this master
2964  # Remove old master.info and relay-log.info files
2965  unlink("$master->[0]->{'path_myddir'}/master.info");
2966  unlink("$master->[0]->{'path_myddir'}/relay-log.info");
2967  unlink("$master->[1]->{'path_myddir'}/master.info");
2968  unlink("$master->[1]->{'path_myddir'}/relay-log.info");
2969
2970  run_master_init_script($tinfo);
2971}
2972
2973
2974sub do_before_start_slave ($) {
2975  my ($tinfo)= @_;
2976
2977  my $tname= $tinfo->{'name'};
2978  my $init_script= $tinfo->{'master_sh'};
2979
2980  # Don't delete anything if starting dirty
2981  return if ($opt_start_dirty);
2982
2983  foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") )
2984  {
2985    unlink($bin);
2986  }
2987
2988  unlink("$slave->[0]->{'path_myddir'}/master.info");
2989  unlink("$slave->[0]->{'path_myddir'}/relay-log.info");
2990
2991  # Run slave initialization shell script if one exists
2992  if ( $init_script )
2993  {
2994    my $ret= mtr_run("/bin/sh", [$init_script], "", "", "", "");
2995    if ( $ret != 0 )
2996    {
2997      # FIXME rewrite those scripts to return 0 if successful
2998      # mtr_warning("$init_script exited with code $ret");
2999    }
3000  }
3001
3002  foreach my $bin ( glob("$slave->[0]->{'path_myddir'}/log.*") )
3003  {
3004    unlink($bin);
3005  }
3006}
3007
3008
3009sub mysqld_arguments ($$$$) {
3010  my $args=              shift;
3011  my $mysqld=            shift;
3012  my $extra_opt=         shift;
3013  my $slave_master_info= shift;
3014
3015  my $idx= $mysqld->{'idx'};
3016  my $sidx= "";                 # Index as string, 0 is empty string
3017  if ( $idx> 0 )
3018  {
3019    $sidx= $idx;
3020  }
3021
3022  my $prefix= "";               # If mysqltest server arg
3023  if ( $glob_use_embedded_server )
3024  {
3025    $prefix= "--server-arg=";
3026  }
3027
3028  mtr_add_arg($args, "%s--no-defaults", $prefix);
3029
3030  mtr_add_arg($args, "%s--basedir=%s", $prefix, $glob_basedir);
3031  mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
3032
3033  if ( $mysql_version_id >= 50036)
3034  {
3035    # By default, prevent the started mysqld to access files outside of vardir
3036    mtr_add_arg($args, "%s--secure-file-priv=%s", $prefix, $opt_vardir);
3037  }
3038
3039  if ( $mysql_version_id >= 50000 )
3040  {
3041    mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
3042  }
3043
3044  mtr_add_arg($args, "%s--character-set-server=latin1", $prefix);
3045  mtr_add_arg($args, "%s--lc-messages-dir=%s", $prefix, $path_language);
3046  mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
3047
3048  # Increase default connect_timeout to avoid intermittent
3049  # disconnects when test servers are put under load
3050  # see BUG#28359
3051  mtr_add_arg($args, "%s--connect-timeout=60", $prefix);
3052
3053
3054  # When mysqld is run by a root user(euid is 0), it will fail
3055  # to start unless we specify what user to run as, see BUG#30630
3056  my $euid= $>;
3057  if (!$glob_win32 and $euid == 0 and
3058      grep(/^--user/, @$extra_opt, @opt_extra_mysqld_opt) == 0) {
3059    mtr_add_arg($args, "%s--user=root", $prefix);
3060  }
3061
3062  if ( $opt_valgrind_mysqld )
3063  {
3064    if ( $mysql_version_id < 50100 )
3065    {
3066      mtr_add_arg($args, "%s--skip-bdb", $prefix);
3067    }
3068  }
3069
3070  mtr_add_arg($args, "%s--pid-file=%s", $prefix,
3071	      $mysqld->{'path_pid'});
3072
3073  mtr_add_arg($args, "%s--port=%d", $prefix,
3074                $mysqld->{'port'});
3075
3076  mtr_add_arg($args, "%s--socket=%s", $prefix,
3077	      $mysqld->{'path_sock'});
3078
3079  mtr_add_arg($args, "%s--datadir=%s", $prefix,
3080	      $mysqld->{'path_myddir'});
3081
3082  mtr_add_arg($args, "%s--disable-sync-frm", $prefix);  # Faster test
3083
3084  if (!$opt_extern and $mysql_version_id >= 50106 )
3085  {
3086    # Turn on logging to bothe tables and file
3087    mtr_add_arg($args, "%s--log-output=table,file", $prefix);
3088  }
3089
3090  my $log_base_path= "$opt_vardir/log/$mysqld->{'type'}$sidx";
3091  mtr_add_arg($args, "%s--general-log-file=%s.log",
3092              $prefix, $log_base_path);
3093  mtr_add_arg($args, "%s--general-log", $prefix);
3094  mtr_add_arg($args,
3095	      "%s--slow-query-log-file=%s-slow.log",
3096              $prefix, $log_base_path);
3097  mtr_add_arg($args, "%s--slow-query-log", $prefix);
3098
3099  # Check if "extra_opt" contains --skip-log-bin
3100  my $skip_binlog= grep(/^--skip-log-bin/, @$extra_opt, @opt_extra_mysqld_opt);
3101  if ( $mysqld->{'type'} eq 'master' )
3102  {
3103    if (! ($opt_skip_master_binlog || $skip_binlog) )
3104    {
3105      mtr_add_arg($args, "%s--log-bin=%s/log/master-bin%s", $prefix,
3106                  $opt_vardir, $sidx);
3107    }
3108
3109    mtr_add_arg($args, "%s--server-id=%d", $prefix,
3110	       $idx > 0 ? $idx + 101 : 1);
3111
3112    mtr_add_arg($args, "%s--loose-innodb_data_file_path=ibdata1:10M:autoextend",
3113		$prefix);
3114
3115    mtr_add_arg($args, "%s--local-infile", $prefix);
3116  }
3117  else
3118  {
3119    mtr_error("unknown mysqld type")
3120      unless $mysqld->{'type'} eq 'slave';
3121
3122    mtr_add_arg($args, "%s--init-rpl-role=slave", $prefix);
3123    if (! ( $opt_skip_slave_binlog || $skip_binlog ))
3124    {
3125      mtr_add_arg($args, "%s--log-bin=%s/log/slave%s-bin", $prefix,
3126                  $opt_vardir, $sidx); # FIXME use own dir for binlogs
3127      mtr_add_arg($args, "%s--log-slave-updates", $prefix);
3128    }
3129
3130    mtr_add_arg($args, "%s--master-retry-count=10", $prefix);
3131
3132    mtr_add_arg($args, "%s--relay-log=%s/log/slave%s-relay-bin", $prefix,
3133                $opt_vardir, $sidx);
3134    mtr_add_arg($args, "%s--report-host=127.0.0.1", $prefix);
3135    mtr_add_arg($args, "%s--report-port=%d", $prefix,
3136                $mysqld->{'port'});
3137    mtr_add_arg($args, "%s--report-user=root", $prefix);
3138    mtr_add_arg($args, "%s--loose-skip-innodb", $prefix);
3139    mtr_add_arg($args, "%s--skip-slave-start", $prefix);
3140
3141    # Directory where slaves find the dumps generated by "load data"
3142    # on the server. The path need to have constant length otherwise
3143    # test results will vary, thus a relative path is used.
3144    my $slave_load_path= "../tmp";
3145    mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix,
3146                $slave_load_path);
3147    mtr_add_arg($args, "%s--slave_net_timeout=120", $prefix);
3148
3149    if ( @$slave_master_info )
3150    {
3151      foreach my $arg ( @$slave_master_info )
3152      {
3153        mtr_add_arg($args, "%s%s", $prefix, $arg);
3154      }
3155    }
3156    else
3157    {
3158#      NOTE: the backport (see BUG#48048) originally removed the
3159#            commented out lines below. However, given that they are
3160#            protected with a version check (< 50200) now, it should be
3161#            safe to keep them. The problem is that the backported patch
3162#            was into a 5.1 GA codebase - mysql-5.1-rep+2 tree - so
3163#            version is 501XX, consequently check becomes worthless. It
3164#            should be safe to uncomment them when merging up to 5.5.
3165#
3166#            RQG semisync test runs on the 5.1 GA tree and needs MTR v1.
3167#            This was causing the test to fail (slave would not start
3168#            due to unrecognized option(s)).
3169#      if ($mysql_version_id < 50200)
3170#      {
3171#        mtr_add_arg($args, "%s--master-user=root", $prefix);
3172#        mtr_add_arg($args, "%s--master-connect-retry=1", $prefix);
3173#        mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix);
3174#        mtr_add_arg($args, "%s--master-password=", $prefix);
3175#        mtr_add_arg($args, "%s--master-port=%d", $prefix,
3176#    	            $master->[0]->{'port'}); # First master
3177#      }
3178      my $slave_server_id=  2 + $idx;
3179      my $slave_rpl_rank= $slave_server_id;
3180      mtr_add_arg($args, "%s--server-id=%d", $prefix, $slave_server_id);
3181      mtr_add_arg($args, "%s--rpl-recovery-rank=%d", $prefix, $slave_rpl_rank);
3182    }
3183  } # end slave
3184
3185  if ( $debug_compiled_binaries && defined $opt_debug )
3186  {
3187    if ( $opt_debug )
3188    {
3189      mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/%s%s.trace",
3190                  $prefix, $path_vardir_trace, $mysqld->{'type'}, $sidx);
3191    }
3192    else
3193    {
3194      mtr_add_arg($args, "--disable-debug");
3195    }
3196  }
3197
3198  mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix);
3199  mtr_add_arg($args, "%s--sort_buffer_size=256K", $prefix);
3200  mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix);
3201
3202  if ( $opt_ssl_supported )
3203  {
3204    mtr_add_arg($args, "%s--ssl-ca=%s/std_data/cacert.pem", $prefix,
3205                $glob_mysql_test_dir);
3206    mtr_add_arg($args, "%s--ssl-cert=%s/std_data/server-cert.pem", $prefix,
3207                $glob_mysql_test_dir);
3208    mtr_add_arg($args, "%s--ssl-key=%s/std_data/server-key.pem", $prefix,
3209                $glob_mysql_test_dir);
3210  }
3211
3212  if ( $opt_warnings )
3213  {
3214    mtr_add_arg($args, "%s--log-warnings", $prefix);
3215  }
3216
3217  # Indicate to "mysqld" it will be debugged in debugger
3218  if ( $glob_debugger )
3219  {
3220    mtr_add_arg($args, "%s--gdb", $prefix);
3221  }
3222
3223  my $found_skip_core= 0;
3224  foreach my $arg ( @opt_extra_mysqld_opt, @$extra_opt )
3225  {
3226    # Allow --skip-core-file to be set in <testname>-[master|slave].opt file
3227    if ($arg eq "--skip-core-file")
3228    {
3229      $found_skip_core= 1;
3230    }
3231    elsif ($skip_binlog and mtr_match_prefix($arg, "--binlog-format"))
3232    {
3233      ; # Dont add --binlog-format when running without binlog
3234    }
3235    else
3236    {
3237      mtr_add_arg($args, "%s%s", $prefix, $arg);
3238    }
3239  }
3240  if ( !$found_skip_core )
3241  {
3242    mtr_add_arg($args, "%s%s", $prefix, "--core-file");
3243  }
3244
3245  if ( $opt_bench )
3246  {
3247    mtr_add_arg($args, "%s--rpl-recovery-rank=1", $prefix);
3248    mtr_add_arg($args, "%s--init-rpl-role=master", $prefix);
3249  }
3250  elsif ( $mysqld->{'type'} eq 'master' )
3251  {
3252    mtr_add_arg($args, "%s--open-files-limit=1024", $prefix);
3253  }
3254
3255  return $args;
3256}
3257
3258
3259##############################################################################
3260#
3261#  Start mysqld and return the PID
3262#
3263##############################################################################
3264
3265sub mysqld_start ($$$) {
3266  my $mysqld=            shift;
3267  my $extra_opt=         shift;
3268  my $slave_master_info= shift;
3269
3270  my $args;                             # Arg vector
3271  my $exe;
3272  my $pid= -1;
3273  my $wait_for_pid_file= 1;
3274
3275  my $type= $mysqld->{'type'};
3276  my $idx= $mysqld->{'idx'};
3277
3278  mtr_error("Internal error: mysqld should never be started for embedded")
3279    if $glob_use_embedded_server;
3280
3281  if ( $type eq 'master' )
3282  {
3283    $exe= $exe_master_mysqld;
3284  }
3285  elsif ( $type eq 'slave' )
3286  {
3287    $exe= $exe_slave_mysqld;
3288  }
3289  else
3290  {
3291    mtr_error("Unknown 'type' \"$type\" passed to mysqld_start");
3292  }
3293
3294  mtr_init_args(\$args);
3295
3296  if ( $opt_valgrind_mysqld )
3297  {
3298    valgrind_arguments($args, \$exe);
3299  }
3300
3301  mysqld_arguments($args,$mysqld,$extra_opt,$slave_master_info);
3302
3303  if ( $opt_gdb || $opt_manual_gdb)
3304  {
3305    gdb_arguments(\$args, \$exe, "$type"."_$idx");
3306  }
3307  elsif ( $opt_ddd || $opt_manual_ddd )
3308  {
3309    ddd_arguments(\$args, \$exe, "$type"."_$idx");
3310  }
3311  elsif ( $opt_debugger )
3312  {
3313    debugger_arguments(\$args, \$exe, "$type"."_$idx");
3314  }
3315  elsif ( $opt_manual_debug )
3316  {
3317     print "\nStart $type in your debugger\n" .
3318           "dir: $glob_mysql_test_dir\n" .
3319           "exe: $exe\n" .
3320	   "args:  " . join(" ", @$args)  . "\n\n" .
3321	   "Waiting ....\n";
3322
3323     # Indicate the exe should not be started
3324    $exe= undef;
3325  }
3326  else
3327  {
3328    # Default to not wait until pid file has been created
3329    $wait_for_pid_file= 0;
3330  }
3331
3332  # Remove the pidfile
3333  unlink($mysqld->{'path_pid'});
3334
3335  if ( defined $exe )
3336  {
3337    $pid= mtr_spawn($exe, $args, "",
3338		    $mysqld->{'path_myerr'},
3339		    $mysqld->{'path_myerr'},
3340		    "",
3341		    { append_log_file => 1 });
3342  }
3343
3344
3345  if ( $wait_for_pid_file && !sleep_until_file_created($mysqld->{'path_pid'},
3346						       $mysqld->{'start_timeout'},
3347						       $pid))
3348  {
3349
3350    mtr_error("Failed to start mysqld $mysqld->{'type'}");
3351  }
3352
3353
3354  # Remember pid of the started process
3355  $mysqld->{'pid'}= $pid;
3356
3357  # Remember options used when starting
3358  $mysqld->{'start_opts'}= $extra_opt;
3359  $mysqld->{'start_slave_master_info'}= $slave_master_info;
3360
3361  mtr_verbose("mysqld pid: $pid");
3362  return $pid;
3363}
3364
3365
3366sub stop_all_servers () {
3367
3368  mtr_report("Stopping All Servers");
3369
3370  my %admin_pids; # hash of admin processes that requests shutdown
3371  my @kill_pids;  # list of processes to shutdown/kill
3372  my $pid;
3373
3374  # Start shutdown of all started masters
3375  foreach my $mysqld (@{$slave}, @{$master})
3376  {
3377    if ( $mysqld->{'pid'} )
3378    {
3379      $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70);
3380      $admin_pids{$pid}= 1;
3381
3382      push(@kill_pids,{
3383		       pid      => $mysqld->{'pid'},
3384                       real_pid => $mysqld->{'real_pid'},
3385		       pidfile  => $mysqld->{'path_pid'},
3386		       sockfile => $mysqld->{'path_sock'},
3387		       port     => $mysqld->{'port'},
3388                       errfile  => $mysqld->{'path_myerr'},
3389		      });
3390
3391      $mysqld->{'pid'}= 0; # Assume we are done with it
3392    }
3393  }
3394
3395  # Wait blocking until all shutdown processes has completed
3396  mtr_wait_blocking(\%admin_pids);
3397
3398  # Make sure that process has shutdown else try to kill them
3399  mtr_check_stop_servers(\@kill_pids);
3400}
3401
3402
3403sub run_testcase_need_master_restart($)
3404{
3405  my ($tinfo)= @_;
3406
3407  # We try to find out if we are to restart the master(s)
3408  my $do_restart= 0;          # Assumes we don't have to
3409
3410  if ( $glob_use_embedded_server )
3411  {
3412    mtr_verbose("Never start or restart for embedded server");
3413    return $do_restart;
3414  }
3415  elsif ( $tinfo->{'master_sh'} )
3416  {
3417    $do_restart= 1;           # Always restart if script to run
3418    mtr_verbose("Restart master: Always restart if script to run");
3419  }
3420  if ( $tinfo->{'force_restart'} )
3421  {
3422    $do_restart= 1; # Always restart if --force-restart in -opt file
3423    mtr_verbose("Restart master: Restart forced with --force-restart");
3424  }
3425  elsif ( $master->[0]->{'running_master_options'} and
3426	  $master->[0]->{'running_master_options'}->{'timezone'} ne
3427	  $tinfo->{'timezone'})
3428  {
3429    $do_restart= 1;
3430    mtr_verbose("Restart master: Different timezone");
3431  }
3432  # Check that running master was started with same options
3433  # as the current test requires
3434  elsif (! mtr_same_opts($master->[0]->{'start_opts'},
3435                         $tinfo->{'master_opt'}) )
3436  {
3437    $do_restart= 1;
3438    mtr_verbose("Restart master: running with different options '" .
3439		join(" ", @{$tinfo->{'master_opt'}}) . "' != '" .
3440	  	join(" ", @{$master->[0]->{'start_opts'}}) . "'" );
3441  }
3442  elsif( ! $master->[0]->{'pid'} )
3443  {
3444    if ( $opt_extern )
3445    {
3446      $do_restart= 0;
3447      mtr_verbose("No restart: using extern master");
3448    }
3449    else
3450    {
3451      $do_restart= 1;
3452      mtr_verbose("Restart master: master is not started");
3453    }
3454  }
3455  return $do_restart;
3456}
3457
3458sub run_testcase_need_slave_restart($)
3459{
3460  my ($tinfo)= @_;
3461
3462  # We try to find out if we are to restart the slaves
3463  my $do_slave_restart= 0;     # Assumes we don't have to
3464
3465  if ( $glob_use_embedded_server )
3466  {
3467    mtr_verbose("Never start or restart for embedded server");
3468    return $do_slave_restart;
3469  }
3470  elsif ( $max_slave_num == 0)
3471  {
3472    mtr_verbose("Skip slave restart: No testcase use slaves");
3473  }
3474  else
3475  {
3476
3477    # Check if any slave is currently started
3478    my $any_slave_started= 0;
3479    foreach my $mysqld (@{$slave})
3480    {
3481      if ( $mysqld->{'pid'} )
3482      {
3483	$any_slave_started= 1;
3484	last;
3485      }
3486    }
3487
3488    if ($any_slave_started)
3489    {
3490      mtr_verbose("Restart slave: Slave is started, always restart");
3491      $do_slave_restart= 1;
3492    }
3493    elsif ( $tinfo->{'slave_num'} )
3494    {
3495      mtr_verbose("Restart slave: Test need slave");
3496      $do_slave_restart= 1;
3497    }
3498  }
3499
3500  return $do_slave_restart;
3501
3502}
3503
3504# ----------------------------------------------------------------------
3505# If not using a running servers we may need to stop and restart.
3506# We restart in the case we have initiation scripts, server options
3507# etc to run. But we also restart again after the test first restart
3508# and test is run, to get back to normal server settings.
3509#
3510# To make the code a bit more clean, we actually only stop servers
3511# here, and mark this to be done. Then a generic "start" part will
3512# start up the needed servers again.
3513# ----------------------------------------------------------------------
3514
3515sub run_testcase_stop_servers($$$) {
3516  my ($tinfo, $do_restart, $do_slave_restart)= @_;
3517  my $pid;
3518  my %admin_pids; # hash of admin processes that requests shutdown
3519  my @kill_pids;  # list of processes to shutdown/kill
3520
3521  # Remember if we restarted for this test case (count restarts)
3522  $tinfo->{'restarted'}= $do_restart;
3523
3524  if ( $do_restart )
3525  {
3526    delete $master->[0]->{'running_master_options'}; # Forget history
3527
3528    # Start shutdown of all started masters
3529    foreach my $mysqld (@{$master})
3530    {
3531      if ( $mysqld->{'pid'} )
3532      {
3533	$pid= mtr_mysqladmin_start($mysqld, "shutdown", 20);
3534
3535	$admin_pids{$pid}= 1;
3536
3537	push(@kill_pids,{
3538			 pid      => $mysqld->{'pid'},
3539			 real_pid => $mysqld->{'real_pid'},
3540			 pidfile  => $mysqld->{'path_pid'},
3541			 sockfile => $mysqld->{'path_sock'},
3542			 port     => $mysqld->{'port'},
3543			 errfile   => $mysqld->{'path_myerr'},
3544			});
3545
3546	$mysqld->{'pid'}= 0; # Assume we are done with it
3547      }
3548    }
3549  }
3550
3551  if ( $do_restart || $do_slave_restart )
3552  {
3553
3554    delete $slave->[0]->{'running_slave_options'}; # Forget history
3555
3556    # Start shutdown of all started slaves
3557    foreach my $mysqld (@{$slave})
3558    {
3559      if ( $mysqld->{'pid'} )
3560      {
3561	$pid= mtr_mysqladmin_start($mysqld, "shutdown", 20);
3562
3563	$admin_pids{$pid}= 1;
3564
3565	push(@kill_pids,{
3566			 pid      => $mysqld->{'pid'},
3567			 real_pid => $mysqld->{'real_pid'},
3568			 pidfile  => $mysqld->{'path_pid'},
3569			 sockfile => $mysqld->{'path_sock'},
3570			 port     => $mysqld->{'port'},
3571			 errfile   => $mysqld->{'path_myerr'},
3572			});
3573
3574
3575	$mysqld->{'pid'}= 0; # Assume we are done with it
3576      }
3577    }
3578  }
3579
3580  # ----------------------------------------------------------------------
3581  # Shutdown has now been started and lists for the shutdown processes
3582  # and the processes to be killed has been created
3583  # ----------------------------------------------------------------------
3584
3585  # Wait blocking until all shutdown processes has completed
3586  mtr_wait_blocking(\%admin_pids);
3587
3588
3589  # Make sure that process has shutdown else try to kill them
3590  mtr_check_stop_servers(\@kill_pids);
3591}
3592
3593
3594#
3595# run_testcase_start_servers
3596#
3597# Start the servers needed by this test case
3598#
3599# RETURN
3600#  0 OK
3601#  1 Start failed
3602#
3603
3604sub run_testcase_start_servers($) {
3605  my $tinfo= shift;
3606  my $tname= $tinfo->{'name'};
3607
3608  if ( $tinfo->{'component_id'} eq 'mysqld' )
3609  {
3610    if ( !$master->[0]->{'pid'} )
3611    {
3612      # Master mysqld is not started
3613      do_before_start_master($tinfo);
3614
3615      mysqld_start($master->[0],$tinfo->{'master_opt'},[]);
3616
3617    }
3618
3619    # Save this test case information, so next can examine it
3620    $master->[0]->{'running_master_options'}= $tinfo;
3621  }
3622
3623  # ----------------------------------------------------------------------
3624  # Start slaves - if needed
3625  # ----------------------------------------------------------------------
3626  if ( $tinfo->{'slave_num'} )
3627  {
3628    restore_slave_databases($tinfo->{'slave_num'});
3629
3630    do_before_start_slave($tinfo);
3631
3632    for ( my $idx= 0; $idx <  $tinfo->{'slave_num'}; $idx++ )
3633    {
3634      if ( ! $slave->[$idx]->{'pid'} )
3635      {
3636	mysqld_start($slave->[$idx],$tinfo->{'slave_opt'},
3637		     $tinfo->{'slave_mi'});
3638
3639      }
3640    }
3641
3642    # Save this test case information, so next can examine it
3643    $slave->[0]->{'running_slave_options'}= $tinfo;
3644  }
3645
3646  # Wait for mysqld's to start
3647  foreach my $mysqld (@{$master},@{$slave})
3648  {
3649
3650    next if !$mysqld->{'pid'};
3651
3652    if (mysqld_wait_started($mysqld))
3653    {
3654      # failed to start
3655      $tinfo->{'comment'}=
3656	"Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}";
3657      return 1;
3658    }
3659  }
3660  return 0;
3661}
3662
3663#
3664# Run include/check-testcase.test
3665# Before a testcase, run in record mode, save result file to var
3666# After testcase, run and compare with the recorded file, they should be equal!
3667#
3668# RETURN VALUE
3669#  0 OK
3670#  1 Check failed
3671#
3672sub run_check_testcase ($$) {
3673
3674  my $mode=     shift;
3675  my $mysqld=   shift;
3676
3677  my $name= "check-" . $mysqld->{'type'} . $mysqld->{'idx'};
3678
3679  my $args;
3680  mtr_init_args(\$args);
3681
3682  mtr_add_arg($args, "--no-defaults");
3683  mtr_add_arg($args, "--silent");
3684  mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
3685  mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
3686
3687  mtr_add_arg($args, "--socket=%s", $mysqld->{'path_sock'});
3688  mtr_add_arg($args, "--port=%d", $mysqld->{'port'});
3689  mtr_add_arg($args, "--database=test");
3690  mtr_add_arg($args, "--user=%s", $opt_user);
3691  mtr_add_arg($args, "--password=");
3692
3693  mtr_add_arg($args, "-R");
3694  mtr_add_arg($args, "$opt_vardir/tmp/$name.result");
3695
3696  if ( $mode eq "before" )
3697  {
3698    mtr_add_arg($args, "--record");
3699  }
3700
3701  my $res = mtr_run_test($exe_mysqltest,$args,
3702	        "include/check-testcase.test", "", "", "");
3703
3704  if ( $res == 1  and $mode eq "after")
3705  {
3706    mtr_run("diff",["-u",
3707		    "$opt_vardir/tmp/$name.result",
3708		    "$opt_vardir/tmp/$name.reject"],
3709	    "", "", "", "");
3710  }
3711  elsif ( $res )
3712  {
3713    mtr_error("Could not execute 'check-testcase' $mode testcase");
3714  }
3715  return $res;
3716}
3717
3718##############################################################################
3719#
3720#  Report the features that were compiled in
3721#
3722##############################################################################
3723
3724sub run_report_features () {
3725  my $args;
3726
3727  if ( ! $glob_use_embedded_server )
3728  {
3729    mysqld_start($master->[0],[],[]);
3730    if ( ! $master->[0]->{'pid'} )
3731    {
3732      mtr_error("Can't start the mysqld server");
3733    }
3734    mysqld_wait_started($master->[0]);
3735  }
3736
3737  my $tinfo = {};
3738  $tinfo->{'name'} = 'report features';
3739  $tinfo->{'result_file'} = undef;
3740  $tinfo->{'component_id'} = 'mysqld';
3741  $tinfo->{'path'} = 'include/report-features.test';
3742  $tinfo->{'timezone'}=  "GMT-3";
3743  $tinfo->{'slave_num'} = 0;
3744  $tinfo->{'master_opt'} = [];
3745  $tinfo->{'slave_opt'} = [];
3746  $tinfo->{'slave_mi'} = [];
3747  $tinfo->{'comment'} = 'report server features';
3748  run_mysqltest($tinfo);
3749
3750  if ( ! $glob_use_embedded_server )
3751  {
3752    stop_all_servers();
3753  }
3754}
3755
3756
3757sub run_mysqltest ($) {
3758  my ($tinfo)= @_;
3759  my $exe= $exe_mysqltest;
3760  my $args;
3761
3762  mtr_init_args(\$args);
3763
3764  mtr_add_arg($args, "--no-defaults");
3765  mtr_add_arg($args, "--silent");
3766  mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
3767  mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
3768  mtr_add_arg($args, "--logdir=%s/log", $opt_vardir);
3769
3770  # Log line number and time  for each line in .test file
3771  mtr_add_arg($args, "--mark-progress")
3772    if $opt_mark_progress;
3773
3774  # component_id == mysqld
3775  {
3776    mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'});
3777    mtr_add_arg($args, "--port=%d", $master->[0]->{'port'});
3778    mtr_add_arg($args, "--database=test");
3779    mtr_add_arg($args, "--user=%s", $opt_user);
3780    mtr_add_arg($args, "--password=");
3781  }
3782
3783  if ( $opt_ps_protocol )
3784  {
3785    mtr_add_arg($args, "--ps-protocol");
3786  }
3787
3788  if ( $opt_sp_protocol )
3789  {
3790    mtr_add_arg($args, "--sp-protocol");
3791  }
3792
3793  if ( $opt_view_protocol )
3794  {
3795    mtr_add_arg($args, "--view-protocol");
3796  }
3797
3798  if ( $opt_cursor_protocol )
3799  {
3800    mtr_add_arg($args, "--cursor-protocol");
3801  }
3802
3803  if ( $opt_strace_client )
3804  {
3805    $exe=  "strace";            # FIXME there are ktrace, ....
3806    mtr_add_arg($args, "-o");
3807    mtr_add_arg($args, "%s/log/mysqltest.strace", $opt_vardir);
3808    mtr_add_arg($args, "$exe_mysqltest");
3809  }
3810
3811  if ( $opt_timer )
3812  {
3813    mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir);
3814  }
3815
3816  if ( $opt_compress )
3817  {
3818    mtr_add_arg($args, "--compress");
3819  }
3820
3821  if ( $opt_sleep )
3822  {
3823    mtr_add_arg($args, "--sleep=%d", $opt_sleep);
3824  }
3825
3826  if ( $opt_debug )
3827  {
3828    mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace",
3829		$path_vardir_trace);
3830  }
3831
3832  if ( $opt_ssl_supported )
3833  {
3834    mtr_add_arg($args, "--ssl-ca=%s/std_data/cacert.pem",
3835	        $glob_mysql_test_dir);
3836    mtr_add_arg($args, "--ssl-cert=%s/std_data/client-cert.pem",
3837	        $glob_mysql_test_dir);
3838    mtr_add_arg($args, "--ssl-key=%s/std_data/client-key.pem",
3839	        $glob_mysql_test_dir);
3840  }
3841
3842  if ( $opt_ssl )
3843  {
3844    # Turn on SSL for _all_ test cases if option --ssl was used
3845    mtr_add_arg($args, "--ssl");
3846  }
3847  elsif ( $opt_ssl_supported )
3848  {
3849    mtr_add_arg($args, "--skip-ssl");
3850  }
3851
3852  foreach my $arg ( @opt_extra_mysqltest_opt )
3853  {
3854    mtr_add_arg($args, "%s", $arg);
3855  }
3856
3857  # ----------------------------------------------------------------------
3858  # If embedded server, we create server args to give mysqltest to pass on
3859  # ----------------------------------------------------------------------
3860
3861  if ( $glob_use_embedded_server )
3862  {
3863    mysqld_arguments($args,$master->[0],$tinfo->{'master_opt'},[]);
3864  }
3865
3866  # ----------------------------------------------------------------------
3867  # export MYSQL_TEST variable containing <path>/mysqltest <args>
3868  # ----------------------------------------------------------------------
3869  $ENV{'MYSQL_TEST'}=
3870    mtr_native_path($exe_mysqltest) . " " . join(" ", @$args);
3871
3872  # ----------------------------------------------------------------------
3873  # Add arguments that should not go into the MYSQL_TEST env var
3874  # ----------------------------------------------------------------------
3875
3876  if ( $opt_valgrind_mysqltest )
3877  {
3878    # Prefix the Valgrind options to the argument list.
3879    # We do this here, since we do not want to Valgrind the nested invocations
3880    # of mysqltest; that would mess up the stderr output causing test failure.
3881    my @args_saved = @$args;
3882    mtr_init_args(\$args);
3883    valgrind_arguments($args, \$exe);
3884    mtr_add_arg($args, "%s", $_) for @args_saved;
3885  }
3886
3887  mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
3888
3889  # Number of lines of resut to include in failure report
3890  mtr_add_arg($args, "--tail-lines=20");
3891
3892  if ( defined $tinfo->{'result_file'} ) {
3893    mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
3894  }
3895
3896  if ( $opt_record )
3897  {
3898    mtr_add_arg($args, "--record");
3899  }
3900
3901  if ( $opt_client_gdb )
3902  {
3903    gdb_arguments(\$args, \$exe, "client");
3904  }
3905  elsif ( $opt_client_ddd )
3906  {
3907    ddd_arguments(\$args, \$exe, "client");
3908  }
3909  elsif ( $opt_client_debugger )
3910  {
3911    debugger_arguments(\$args, \$exe, "client");
3912  }
3913
3914  if ( $opt_check_testcases )
3915  {
3916    foreach my $mysqld (@{$master}, @{$slave})
3917    {
3918      if ($mysqld->{'pid'})
3919      {
3920	run_check_testcase("before", $mysqld);
3921      }
3922    }
3923  }
3924
3925  my $res = mtr_run_test($exe,$args,"","",$path_timefile,"");
3926
3927  if ( $opt_check_testcases )
3928  {
3929    foreach my $mysqld (@{$master}, @{$slave})
3930    {
3931      if ($mysqld->{'pid'})
3932      {
3933	if (run_check_testcase("after", $mysqld))
3934	{
3935	  # Check failed, mark the test case with that info
3936	  $tinfo->{'check_testcase_failed'}= 1;
3937	}
3938      }
3939    }
3940  }
3941
3942  return $res;
3943
3944}
3945
3946
3947#
3948# Modify the exe and args so that program is run in gdb in xterm
3949#
3950sub gdb_arguments {
3951  my $args= shift;
3952  my $exe=  shift;
3953  my $type= shift;
3954
3955  # Write $args to gdb init file
3956  my $str= join(" ", @$$args);
3957  my $gdb_init_file= "$opt_tmpdir/gdbinit.$type";
3958
3959  # Remove the old gdbinit file
3960  unlink($gdb_init_file);
3961
3962  if ( $type eq "client" )
3963  {
3964    # write init file for client
3965    mtr_tofile($gdb_init_file,
3966	       "set args $str\n" .
3967	       "break main\n");
3968  }
3969  else
3970  {
3971    # write init file for mysqld
3972    mtr_tofile($gdb_init_file, <<EOGDB );
3973set args $str
3974EOGDB
3975  }
3976
3977  if ( $opt_manual_gdb )
3978  {
3979     print "\nTo start gdb for $type, type in another window:\n";
3980     print "gdb -cd $glob_mysql_test_dir -x $gdb_init_file $$exe\n";
3981
3982     # Indicate the exe should not be started
3983     $$exe= undef;
3984     return;
3985  }
3986
3987  $$args= [];
3988  mtr_add_arg($$args, "-title");
3989  mtr_add_arg($$args, "$type");
3990  mtr_add_arg($$args, "-e");
3991
3992  if ( $exe_libtool )
3993  {
3994    mtr_add_arg($$args, $exe_libtool);
3995    mtr_add_arg($$args, "--mode=execute");
3996  }
3997
3998  mtr_add_arg($$args, "gdb");
3999  mtr_add_arg($$args, "-x");
4000  mtr_add_arg($$args, "$gdb_init_file");
4001  mtr_add_arg($$args, "$$exe");
4002
4003  $$exe= "xterm";
4004}
4005
4006
4007#
4008# Modify the exe and args so that program is run in ddd
4009#
4010sub ddd_arguments {
4011  my $args= shift;
4012  my $exe=  shift;
4013  my $type= shift;
4014
4015  # Write $args to ddd init file
4016  my $str= join(" ", @$$args);
4017  my $gdb_init_file= "$opt_tmpdir/gdbinit.$type";
4018
4019  # Remove the old gdbinit file
4020  unlink($gdb_init_file);
4021
4022  if ( $type eq "client" )
4023  {
4024    # write init file for client
4025    mtr_tofile($gdb_init_file,
4026	       "set args $str\n" .
4027	       "break main\n");
4028  }
4029  else
4030  {
4031    # write init file for mysqld
4032    mtr_tofile($gdb_init_file,
4033	       "file $$exe\n" .
4034	       "set args $str\n");
4035  }
4036
4037  if ( $opt_manual_ddd )
4038  {
4039     print "\nTo start ddd for $type, type in another window:\n";
4040     print "ddd -cd $glob_mysql_test_dir -x $gdb_init_file $$exe\n";
4041
4042     # Indicate the exe should not be started
4043     $$exe= undef;
4044     return;
4045  }
4046
4047  my $save_exe= $$exe;
4048  $$args= [];
4049  if ( $exe_libtool )
4050  {
4051    $$exe= $exe_libtool;
4052    mtr_add_arg($$args, "--mode=execute");
4053    mtr_add_arg($$args, "ddd");
4054  }
4055  else
4056  {
4057    $$exe= "ddd";
4058  }
4059  mtr_add_arg($$args, "--command=$gdb_init_file");
4060  mtr_add_arg($$args, "$save_exe");
4061}
4062
4063
4064#
4065# Modify the exe and args so that program is run in the selected debugger
4066#
4067sub debugger_arguments {
4068  my $args= shift;
4069  my $exe=  shift;
4070  my $debugger= $opt_debugger || $opt_client_debugger;
4071
4072  if ( $debugger =~ /vcexpress|vc|devenv/ )
4073  {
4074    # vc[express] /debugexe exe arg1 .. argn
4075
4076    # Add /debugexe and name of the exe before args
4077    unshift(@$$args, "/debugexe");
4078    unshift(@$$args, "$$exe");
4079
4080    # Set exe to debuggername
4081    $$exe= $debugger;
4082
4083  }
4084  elsif ( $debugger =~ /windbg/ )
4085  {
4086    # windbg exe arg1 .. argn
4087
4088    # Add name of the exe before args
4089    unshift(@$$args, "$$exe");
4090
4091    # Set exe to debuggername
4092    $$exe= $debugger;
4093
4094  }
4095  elsif ( $debugger eq "dbx" )
4096  {
4097    # xterm -e dbx -r exe arg1 .. argn
4098
4099    unshift(@$$args, $$exe);
4100    unshift(@$$args, "-r");
4101    unshift(@$$args, $debugger);
4102    unshift(@$$args, "-e");
4103
4104    $$exe= "xterm";
4105
4106  }
4107  else
4108  {
4109    mtr_error("Unknown argument \"$debugger\" passed to --debugger");
4110  }
4111}
4112
4113
4114#
4115# Modify the exe and args so that program is run in valgrind
4116#
4117sub valgrind_arguments {
4118  my $args= shift;
4119  my $exe=  shift;
4120
4121  if ( $opt_callgrind)
4122  {
4123    mtr_add_arg($args, "--tool=callgrind");
4124    mtr_add_arg($args, "--base=$opt_vardir/log");
4125  }
4126  else
4127  {
4128    mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
4129    mtr_add_arg($args, "--leak-check=yes");
4130    #mtr_add_arg($args, "--db-attach=yes");
4131    mtr_add_arg($args, "--num-callers=16");
4132    mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
4133      if -f "$glob_mysql_test_dir/valgrind.supp";
4134  }
4135
4136  # Add valgrind options, can be overridden by user
4137  mtr_add_arg($args, '%s', $_) for (@valgrind_args);
4138
4139  mtr_add_arg($args, $$exe);
4140
4141  $$exe= $opt_valgrind_path || "valgrind";
4142
4143  if ($exe_libtool)
4144  {
4145    # Add "libtool --mode-execute" before the test to execute
4146    # if running in valgrind(to avoid valgrinding bash)
4147    unshift(@$args, "--mode=execute", $$exe);
4148    $$exe= $exe_libtool;
4149  }
4150}
4151
4152
4153##############################################################################
4154#
4155#  Usage
4156#
4157##############################################################################
4158
4159sub usage ($) {
4160  my $message= shift;
4161
4162  if ( $message )
4163  {
4164    print STDERR "$message\n";
4165  }
4166
4167  print <<HERE;
4168
4169$0 [ OPTIONS ] [ TESTCASE ]
4170
4171Options to control what engine/variation to run
4172
4173  embedded-server       Use the embedded server, i.e. no mysqld daemons
4174  ps-protocol           Use the binary protocol between client and server
4175  cursor-protocol       Use the cursor protocol between client and server
4176                        (implies --ps-protocol)
4177  view-protocol         Create a view to execute all non updating queries
4178  sp-protocol           Create a stored procedure to execute all queries
4179  compress              Use the compressed protocol between client and server
4180  ssl                   Use ssl protocol between client and server
4181  skip-ssl              Dont start server with support for ssl connections
4182  bench                 Run the benchmark suite
4183  small-bench           Run the benchmarks with --small-tests --small-tables
4184  vs-config             Visual Studio configuration used to create executables
4185                        (default: MTR_VS_CONFIG environment variable)
4186
4187Options to control directories to use
4188  benchdir=DIR          The directory where the benchmark suite is stored
4189                        (default: ../../mysql-bench)
4190  tmpdir=DIR            The directory where temporary files are stored
4191                        (default: ./var/tmp).
4192  vardir=DIR            The directory where files generated from the test run
4193                        is stored (default: ./var). Specifying a ramdisk or
4194                        tmpfs will speed up tests.
4195  mem                   Run testsuite in "memory" using tmpfs or ramdisk
4196                        Attempts to find a suitable location
4197                        using a builtin list of standard locations
4198                        for tmpfs (/dev/shm)
4199                        The option can also be set using environment
4200                        variable MTR_MEM=[DIR]
4201
4202Options to control what test suites or cases to run
4203
4204  force                 Continue to run the suite after failure
4205  do-test=PREFIX or REGEX
4206                        Run test cases which name are prefixed with PREFIX
4207                        or fulfills REGEX
4208  skip-test=PREFIX or REGEX
4209                        Skip test cases which name are prefixed with PREFIX
4210                        or fulfills REGEX
4211  start-from=PREFIX     Run test cases starting from test prefixed with PREFIX
4212  suite[s]=NAME1,..,NAMEN Collect tests in suites from the comma separated
4213                        list of suite names.
4214                        The default is: "$opt_suites_default"
4215  skip-rpl              Skip the replication test cases.
4216  big-test              Set the environment variable BIG_TEST, which can be
4217                        checked from test cases.
4218  combination="ARG1 .. ARG2" Specify a set of "mysqld" arguments for one
4219                        combination.
4220  skip-combination      Skip any combination options and combinations files
4221
4222Options that specify ports
4223
4224  master_port=PORT      Specify the port number used by the first master
4225  slave_port=PORT       Specify the port number used by the first slave
4226  mtr-build-thread=#    Specify unique collection of ports. Can also be set by
4227                        setting the environment variable MTR_BUILD_THREAD.
4228
4229Options for test case authoring
4230
4231  record TESTNAME       (Re)genereate the result file for TESTNAME
4232  check-testcases       Check testcases for sideeffects
4233  mark-progress         Log line number and elapsed time to <testname>.progress
4234
4235Options that pass on options
4236
4237  mysqld=ARGS           Specify additional arguments to "mysqld"
4238
4239Options to run test on running server
4240
4241  extern                Use running server for tests
4242  user=USER             User for connection to extern server
4243  socket=PATH           Socket for connection to extern server
4244
4245Options for debugging the product
4246
4247  client-ddd            Start mysqltest client in ddd
4248  client-debugger=NAME  Start mysqltest in the selected debugger
4249  client-gdb            Start mysqltest client in gdb
4250  ddd                   Start mysqld in ddd
4251  debug                 Dump trace output for all servers and client programs
4252  debugger=NAME         Start mysqld in the selected debugger
4253  gdb                   Start the mysqld(s) in gdb
4254  manual-debug          Let user manually start mysqld in debugger, before
4255                        running test(s)
4256  manual-gdb            Let user manually start mysqld in gdb, before running
4257                        test(s)
4258  manual-ddd            Let user manually start mysqld in ddd, before running
4259                        test(s)
4260  master-binary=PATH    Specify the master "mysqld" to use
4261  slave-binary=PATH     Specify the slave "mysqld" to use
4262  strace-client         Create strace output for mysqltest client
4263  max-save-core         Limit the number of core files saved (to avoid filling
4264                        up disks for heavily crashing server). Defaults to
4265                        $opt_max_save_core, set to 0 for no limit.
4266
4267Options for coverage, profiling etc
4268
4269  gcov                  FIXME
4270  gprof                 FIXME
4271  valgrind              Run the "mysqltest" and "mysqld" executables using
4272                        valgrind with default options
4273  valgrind-all          Synonym for --valgrind
4274  valgrind-mysqltest    Run the "mysqltest" and "mysql_client_test" executable
4275                        with valgrind
4276  valgrind-mysqld       Run the "mysqld" executable with valgrind
4277  valgrind-options=ARGS Deprecated, use --valgrind-option
4278  valgrind-option=ARGS  Option to give valgrind, replaces default option(s),
4279                        can be specified more then once
4280  valgrind-path=[EXE]   Path to the valgrind executable
4281  callgrind             Instruct valgrind to use callgrind
4282
4283Misc options
4284
4285  comment=STR           Write STR to the output
4286  notimer               Don't show test case execution time
4287  script-debug          Debug this script itself
4288  verbose               More verbose output
4289  start-and-exit        Only initialize and start the servers, using the
4290                        startup settings for the specified test case (if any)
4291  start-dirty           Only start the servers (without initialization) for
4292                        the specified test case (if any)
4293  fast                  Don't try to clean up from earlier runs
4294  reorder               Reorder tests to get fewer server restarts
4295  help                  Get this help text
4296
4297  testcase-timeout=MINUTES Max test case run time (default $default_testcase_timeout)
4298  suite-timeout=MINUTES Max test suite run time (default $default_suite_timeout)
4299  warnings | log-warnings Pass --log-warnings to mysqld
4300
4301  sleep=SECONDS         Passed to mysqltest, will be used as fixed sleep time
4302  client-bindir=PATH    Path to the directory where client binaries are located
4303  client-libdir=PATH    Path to the directory where client libraries are located
4304
4305Deprecated options
4306  with-openssl          Deprecated option for ssl
4307
4308
4309HERE
4310  mtr_exit(1);
4311
4312}
4313
4314sub list_options ($) {
4315  my $hash= shift;
4316
4317  for (keys %$hash) {
4318    s/(=.*|!)$//;
4319    s/\|/\n--/g;
4320    print "--$_\n";
4321  }
4322
4323  mtr_exit(1);
4324}
4325
4326