~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to mysql-test/mysql-test-run

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

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