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