~drizzle-trunk/drizzle/development

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