~drizzle-trunk/drizzle/development

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