~mathiaz/ubuntu/lucid/mysql-dfsg-5.1/zap-bug-552053

« back to all changes in this revision

Viewing changes to mysql-test/lib/v1/mtr_cases.pl

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2009-06-25 12:55:45 UTC
  • mfrom: (1.1.2 upstream) (0.1.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20090625125545-m8ogs96zzsri74xe
Tags: 5.1.34-1ubuntu1
* Merge from debian experimental (and 5.0 from main), remaining changes:
  - debian/mysql-server-5.1.config:
    + ask for MySQL root password at priority high instead of medium so
      that the password prompt is seen on a default install. (LP: #319843)
    + don't ask for root password when upgrading from a 5.0 install.
  - debian/control:
    + Make libmysqlclient16-dev a transitional package depending on
      libmysqlclient-dev.
    + Make libmysqlclient-dev conflict with libmysqlclient15-dev.
    + Don't build mysql-server, mysql-client, mysql-common and
      libmysqlclient15-dev binary packages since they're still provided
      by mysql-dfsg-5.0.
    + Make mysql-{client,server}-5.1 packages conflict and
      replace mysql-{client,server}-5.0, but not provide
      mysql-{client,server}.
    + Depend on a specific version of mysql-common rather than the src
      version of mysql-dfsg-5.1 since mysql-common is currently part of
      mysql-dfsg-5.0.
    + Lower mailx from a Recommends to a Suggests to avoid pulling in
      a full MTA on all installs of mysql-server. (LP: #259477)
  - debian/rules:
    + added -fno-strict-aliasing to CFLAGS to get around mysql testsuite
      build failures.
    + install mysql-test and sql-bench to /usr/share/mysql/ rather than
      /usr/.
  - debian/additions/debian-start.inc.sh: support ANSI mode (LP: #310211)
  - Add AppArmor profile:
    - debian/apparmor-profile: apparmor profile.
    - debian/rules, debian/mysql-server-5.0.files: install apparmor profile.
    - debian/mysql-server-5.0.dirs: add etc/apparmor.d/force-complain
    - debian/mysql-server-5.0.postrm: remove symlink in force-complain/ on
      purge.
    - debian/mysql-server-5.1.README.Debian: add apparmor documentation.
    - debian/additions/my.cnf: Add warning about apparmor. (LP: #201799)
    - debian/mysql-server-5.1.postinst: reload apparmor profiles.
  - debian/additions/my.cnf: remove language option. Error message files are
    located in a different directory in MySQL 5.0. Setting the language
    option to use /usr/share/mysql/english breaks 5.0. Both 5.0 and 5.1
    use a default value that works. (LP: #316974)
  - debian/mysql-server-5.1.mysql.init:
    + Clearly indicate that we do not support running multiple instances
      of mysqld by duplicating the init script.
      (closes: #314785, #324834, #435165, #444216)
    + Properly parameterize all existing references to the mysql config
      file (/etc/mysql/my.cnf).
  - debian/mysql-server-5.0.postinst: Clear out the second password
    when setting up mysql. (LP: #344816)
  - mysql-server-core-5.1 package for files needed by Akonadi:
    + debian/control: create mysql-server-core-5.1 package.
    + debian/mysql-server-core-5.1.files, debian/mysql-server-5.1.files:
      move core mysqld files to mysql-server-core-5.1 package.
  - Don't package sql-bench and mysql-test file.
* Dropped changes:
  - debian/patches/92_ssl_test_cert.dpatch: certificate expiration in
    test suite (LP: #323755). Included upstream.
* Dropped from 5.0:
  - apparmor profile:
    - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6. All version
      of apparmor-profile (>hardy) are higher than this version.
    - debian/mysql-server-5.0.preinst: create symlink for force-complain/
      on pre-feisty upgrades, upgrades where apparmor-profiles profile is
      unchanged (ie non-enforcing) and upgrades where the profile
      doesn't exist. Support for pre-hardy upgrades is no longer needed.
* debian/mysql-server-5.1.postinst: fix debian-sys-maint user creation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- cperl -*-
 
2
# Copyright (C) 2005-2006 MySQL AB
 
3
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; version 2 of the License.
 
7
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
16
 
 
17
# This is a library file used by the Perl version of mysql-test-run,
 
18
# and is part of the translation of the Bourne shell script with the
 
19
# same name.
 
20
 
 
21
use File::Basename;
 
22
use IO::File();
 
23
use strict;
 
24
 
 
25
use My::Config;
 
26
 
 
27
sub collect_test_cases ($);
 
28
sub collect_one_suite ($);
 
29
sub collect_one_test_case ($$$$$$$$$);
 
30
 
 
31
sub mtr_options_from_test_file($$);
 
32
 
 
33
my $do_test;
 
34
my $skip_test;
 
35
 
 
36
sub init_pattern {
 
37
  my ($from, $what)= @_;
 
38
  if ( $from =~ /^[a-z0-9]$/ ) {
 
39
    # Does not contain any regex, make the pattern match
 
40
    # beginning of string
 
41
    $from= "^$from";
 
42
  }
 
43
  # Check that pattern is a valid regex
 
44
  eval { "" =~/$from/; 1 } or
 
45
    mtr_error("Invalid regex '$from' passed to $what\nPerl says: $@");
 
46
  return $from;
 
47
}
 
48
 
 
49
 
 
50
 
 
51
##############################################################################
 
52
#
 
53
#  Collect information about test cases we are to run
 
54
#
 
55
##############################################################################
 
56
 
 
57
sub collect_test_cases ($) {
 
58
  $do_test= init_pattern($::opt_do_test, "--do-test");
 
59
  $skip_test= init_pattern($::opt_skip_test, "--skip-test");
 
60
 
 
61
  my $suites= shift; # Semicolon separated list of test suites
 
62
  my $cases = [];    # Array of hash
 
63
 
 
64
  foreach my $suite (split(",", $suites))
 
65
  {
 
66
    push(@$cases, collect_one_suite($suite));
 
67
  }
 
68
 
 
69
 
 
70
  if ( @::opt_cases )
 
71
  {
 
72
    # Check that the tests specified was found
 
73
    # in at least one suite
 
74
    foreach my $test_name_spec ( @::opt_cases )
 
75
    {
 
76
      my $found= 0;
 
77
      my ($sname, $tname, $extension)= split_testname($test_name_spec);
 
78
      foreach my $test ( @$cases )
 
79
      {
 
80
        # test->{name} is always in suite.name format
 
81
        if ( $test->{name} =~ /.*\.$tname/ )
 
82
        {
 
83
          $found= 1;
 
84
        }
 
85
      }
 
86
      if ( not $found )
 
87
      {
 
88
        mtr_error("Could not find $tname in any suite");
 
89
      }
 
90
    }
 
91
  }
 
92
 
 
93
  if ( $::opt_reorder )
 
94
  {
 
95
    # Reorder the test cases in an order that will make them faster to run
 
96
    my %sort_criteria;
 
97
 
 
98
    # Make a mapping of test name to a string that represents how that test
 
99
    # should be sorted among the other tests.  Put the most important criterion
 
100
    # first, then a sub-criterion, then sub-sub-criterion, et c.
 
101
    foreach my $tinfo (@$cases)
 
102
    {
 
103
      my @criteria = ();
 
104
 
 
105
      # Look for tests that muct be in run in a defined order
 
106
      # that is defined by test having the same name except for
 
107
      # the ending digit
 
108
 
 
109
      # Put variables into hash
 
110
      my $test_name= $tinfo->{'name'};
 
111
      my $depend_on_test_name;
 
112
      if ( $test_name =~ /^([\D]+)([0-9]{1})$/ )
 
113
      {
 
114
        my $base_name= $1;
 
115
        my $idx= $2;
 
116
        mtr_verbose("$test_name =>  $base_name idx=$idx");
 
117
        if ( $idx > 1 )
 
118
        {
 
119
          $idx-= 1;
 
120
          $base_name= "$base_name$idx";
 
121
          mtr_verbose("New basename $base_name");
 
122
        }
 
123
 
 
124
        foreach my $tinfo2 (@$cases)
 
125
        {
 
126
          if ( $tinfo2->{'name'} eq $base_name )
 
127
          {
 
128
            mtr_verbose("found dependent test $tinfo2->{'name'}");
 
129
            $depend_on_test_name=$base_name;
 
130
          }
 
131
        }
 
132
      }
 
133
 
 
134
      if ( defined $depend_on_test_name )
 
135
      {
 
136
        mtr_verbose("Giving $test_name same critera as $depend_on_test_name");
 
137
        $sort_criteria{$test_name} = $sort_criteria{$depend_on_test_name};
 
138
      }
 
139
      else
 
140
      {
 
141
        #
 
142
        # Append the criteria for sorting, in order of importance.
 
143
        #
 
144
        push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0"));
 
145
        # Group test with equal options together.
 
146
        # Ending with "~" makes empty sort later than filled
 
147
        push(@criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~");
 
148
 
 
149
        $sort_criteria{$test_name} = join(" ", @criteria);
 
150
      }
 
151
    }
 
152
 
 
153
    @$cases = sort {
 
154
      $sort_criteria{$a->{'name'}} . $a->{'name'} cmp
 
155
        $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases;
 
156
 
 
157
    if ( $::opt_script_debug )
 
158
    {
 
159
      # For debugging the sort-order
 
160
      foreach my $tinfo (@$cases)
 
161
      {
 
162
        print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n");
 
163
      }
 
164
    }
 
165
  }
 
166
 
 
167
  return $cases;
 
168
 
 
169
}
 
170
 
 
171
# Valid extensions and their corresonding component id
 
172
my %exts = ( 'test' => 'mysqld',
 
173
             'imtest' => 'im'
 
174
           );
 
175
 
 
176
 
 
177
# Returns (suitename, testname, extension)
 
178
sub split_testname {
 
179
  my ($test_name)= @_;
 
180
 
 
181
  # Get rid of directory part and split name on .'s
 
182
  my @parts= split(/\./, basename($test_name));
 
183
 
 
184
  if (@parts == 1){
 
185
    # Only testname given, ex: alias
 
186
    return (undef , $parts[0], undef);
 
187
  } elsif (@parts == 2) {
 
188
    # Either testname.test or suite.testname given
 
189
    # Ex. main.alias or alias.test
 
190
 
 
191
    if (defined $exts{$parts[1]})
 
192
    {
 
193
      return (undef , $parts[0], $parts[1]);
 
194
    }
 
195
    else
 
196
    {
 
197
      return ($parts[0], $parts[1], undef);
 
198
    }
 
199
 
 
200
  } elsif (@parts == 3) {
 
201
    # Fully specified suitename.testname.test
 
202
    # ex main.alias.test
 
203
    return ( $parts[0], $parts[1], $parts[2]);
 
204
  }
 
205
 
 
206
  mtr_error("Illegal format of test name: $test_name");
 
207
}
 
208
 
 
209
 
 
210
sub collect_one_suite($)
 
211
{
 
212
  my $suite= shift;  # Test suite name
 
213
  my @cases;  # Array of hash
 
214
 
 
215
  mtr_verbose("Collecting: $suite");
 
216
 
 
217
  my $suitedir= "$::glob_mysql_test_dir"; # Default
 
218
  if ( $suite ne "main" )
 
219
  {
 
220
    $suitedir= mtr_path_exists("$suitedir/suite/$suite",
 
221
                               "$suitedir/$suite");
 
222
    mtr_verbose("suitedir: $suitedir");
 
223
  }
 
224
 
 
225
  my $testdir= "$suitedir/t";
 
226
  my $resdir=  "$suitedir/r";
 
227
 
 
228
  # ----------------------------------------------------------------------
 
229
  # Build a hash of disabled testcases for this suite
 
230
  # ----------------------------------------------------------------------
 
231
  my %disabled;
 
232
  if ( open(DISABLED, "$testdir/disabled.def" ) )
 
233
  {
 
234
    while ( <DISABLED> )
 
235
      {
 
236
        chomp;
 
237
        if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
 
238
          {
 
239
            $disabled{$1}= $2;
 
240
          }
 
241
      }
 
242
    close DISABLED;
 
243
  }
 
244
 
 
245
  # Read suite.opt file
 
246
  my $suite_opt_file=  "$testdir/suite.opt";
 
247
  my $suite_opts= [];
 
248
  if ( -f $suite_opt_file )
 
249
  {
 
250
    $suite_opts= mtr_get_opts_from_file($suite_opt_file);
 
251
  }
 
252
 
 
253
  if ( @::opt_cases )
 
254
  {
 
255
    # Collect in specified order
 
256
    foreach my $test_name_spec ( @::opt_cases )
 
257
    {
 
258
      my ($sname, $tname, $extension)= split_testname($test_name_spec);
 
259
 
 
260
      # The test name parts have now been defined
 
261
      #print "  suite_name: $sname\n";
 
262
      #print "  tname:      $tname\n";
 
263
      #print "  extension:  $extension\n";
 
264
 
 
265
      # Check cirrect suite if suitename is defined
 
266
      next if (defined $sname and $suite ne $sname);
 
267
 
 
268
      my $component_id;
 
269
      if ( defined $extension )
 
270
      {
 
271
        my $full_name= "$testdir/$tname.$extension";
 
272
        # Extension was specified, check if the test exists
 
273
        if ( ! -f $full_name)
 
274
        {
 
275
          # This is only an error if suite was specified, otherwise it
 
276
          # could exist in another suite
 
277
          mtr_error("Test '$full_name' was not found in suite '$sname'")
 
278
            if $sname;
 
279
 
 
280
          next;
 
281
        }
 
282
        $component_id= $exts{$extension};
 
283
      }
 
284
      else
 
285
      {
 
286
        # No extension was specified
 
287
        my ($ext, $component);
 
288
        while (($ext, $component)= each %exts) {
 
289
          my $full_name= "$testdir/$tname.$ext";
 
290
 
 
291
          if ( ! -f $full_name ) {
 
292
            next;
 
293
          }
 
294
          $component_id= $component;
 
295
          $extension= $ext;
 
296
        }
 
297
        # Test not found here, could exist in other suite
 
298
        next unless $component_id;
 
299
      }
 
300
 
 
301
      collect_one_test_case($testdir,$resdir,$suite,$tname,
 
302
                            "$tname.$extension",\@cases,\%disabled,
 
303
                            $component_id,$suite_opts);
 
304
    }
 
305
  }
 
306
  else
 
307
  {
 
308
    opendir(TESTDIR, $testdir) or mtr_error("Can't open dir \"$testdir\": $!");
 
309
 
 
310
    foreach my $elem ( sort readdir(TESTDIR) )
 
311
    {
 
312
      my $component_id= undef;
 
313
      my $tname= undef;
 
314
 
 
315
      if ($tname= mtr_match_extension($elem, 'test'))
 
316
      {
 
317
        $component_id = 'mysqld';
 
318
      }
 
319
      elsif ($tname= mtr_match_extension($elem, 'imtest'))
 
320
      {
 
321
        $component_id = 'im';
 
322
      }
 
323
      else
 
324
      {
 
325
        next;
 
326
      }
 
327
 
 
328
      # Skip tests that does not match the --do-test= filter
 
329
      next if ($do_test and not $tname =~ /$do_test/o);
 
330
 
 
331
      collect_one_test_case($testdir,$resdir,$suite,$tname,
 
332
                            $elem,\@cases,\%disabled,$component_id,
 
333
                            $suite_opts);
 
334
    }
 
335
    closedir TESTDIR;
 
336
  }
 
337
 
 
338
 
 
339
  #  Return empty list if no testcases found
 
340
  return if (@cases == 0);
 
341
 
 
342
  # ----------------------------------------------------------------------
 
343
  # Read combinations for this suite and build testcases x combinations
 
344
  # if any combinations exists
 
345
  # ----------------------------------------------------------------------
 
346
  if ( ! $::opt_skip_combination )
 
347
  {
 
348
    my @combinations;
 
349
    my $combination_file= "$suitedir/combinations";
 
350
    #print "combination_file: $combination_file\n";
 
351
    if (@::opt_combinations)
 
352
    {
 
353
      # take the combination from command-line
 
354
      mtr_verbose("Take the combination from command line");
 
355
      foreach my $combination (@::opt_combinations) {
 
356
        my $comb= {};
 
357
        $comb->{name}= $combination;
 
358
        push(@{$comb->{comb_opt}}, $combination);
 
359
        push(@combinations, $comb);
 
360
      }
 
361
    }
 
362
    elsif (-f $combination_file )
 
363
    {
 
364
      # Read combinations file in my.cnf format
 
365
      mtr_verbose("Read combinations file");
 
366
      my $config= My::Config->new($combination_file);
 
367
 
 
368
      foreach my $group ($config->groups()) {
 
369
        my $comb= {};
 
370
        $comb->{name}= $group->name();
 
371
        foreach my $option ( $group->options() ) {
 
372
          push(@{$comb->{comb_opt}}, "--".$option->name()."=".$option->value());
 
373
        }
 
374
        push(@combinations, $comb);
 
375
      }
 
376
    }
 
377
 
 
378
    if (@combinations)
 
379
    {
 
380
      print " - adding combinations\n";
 
381
      #print_testcases(@cases);
 
382
 
 
383
      my @new_cases;
 
384
      foreach my $comb (@combinations)
 
385
      {
 
386
        foreach my $test (@cases)
 
387
        {
 
388
          #print $test->{name}, " ", $comb, "\n";
 
389
          my $new_test= {};
 
390
 
 
391
          while (my ($key, $value) = each(%$test)) {
 
392
            if (ref $value eq "ARRAY") {
 
393
              push(@{$new_test->{$key}}, @$value);
 
394
            } else {
 
395
              $new_test->{$key}= $value;
 
396
            }
 
397
          }
 
398
 
 
399
          # Append the combination options to master_opt and slave_opt
 
400
          push(@{$new_test->{master_opt}}, @{$comb->{comb_opt}});
 
401
          push(@{$new_test->{slave_opt}}, @{$comb->{comb_opt}});
 
402
 
 
403
          # Add combination name shrt name
 
404
          $new_test->{combination}= $comb->{name};
 
405
 
 
406
          # Add the new test to new test cases list
 
407
          push(@new_cases, $new_test);
 
408
        }
 
409
      }
 
410
      #print_testcases(@new_cases);
 
411
      @cases= @new_cases;
 
412
      #print_testcases(@cases);
 
413
    }
 
414
  }
 
415
 
 
416
  optimize_cases(\@cases);
 
417
  #print_testcases(@cases);
 
418
 
 
419
  return @cases;
 
420
}
 
421
 
 
422
 
 
423
#
 
424
# Loop through all test cases
 
425
# - optimize which test to run by skipping unnecessary ones
 
426
# - update settings if necessary
 
427
#
 
428
sub optimize_cases {
 
429
  my ($cases)= @_;
 
430
 
 
431
  foreach my $tinfo ( @$cases )
 
432
  {
 
433
    # Skip processing if already marked as skipped
 
434
    next if $tinfo->{skip};
 
435
 
 
436
    # =======================================================
 
437
    # If a special binlog format was selected with
 
438
    # --mysqld=--binlog-format=x, skip all test that does not
 
439
    # support it
 
440
    # =======================================================
 
441
    #print "used_binlog_format: $::used_binlog_format\n";
 
442
    if (defined $::used_binlog_format )
 
443
    {
 
444
      # =======================================================
 
445
      # Fixed --binlog-format=x specified on command line
 
446
      # =======================================================
 
447
      if ( defined $tinfo->{'binlog_formats'} )
 
448
      {
 
449
        #print "binlog_formats: ". join(", ", @{$tinfo->{binlog_formats}})."\n";
 
450
 
 
451
        # The test supports different binlog formats
 
452
        # check if the selected one is ok
 
453
        my $supported=
 
454
          grep { $_ eq $::used_binlog_format } @{$tinfo->{'binlog_formats'}};
 
455
        if ( !$supported )
 
456
        {
 
457
          $tinfo->{'skip'}= 1;
 
458
          $tinfo->{'comment'}=
 
459
            "Doesn't support --binlog-format='$::used_binlog_format'";
 
460
        }
 
461
      }
 
462
    }
 
463
    else
 
464
    {
 
465
      # =======================================================
 
466
      # Use dynamic switching of binlog format
 
467
      # =======================================================
 
468
 
 
469
      # Get binlog-format used by this test from master_opt
 
470
      my $test_binlog_format;
 
471
      foreach my $opt ( @{$tinfo->{master_opt}} ) {
 
472
        $test_binlog_format=
 
473
          mtr_match_prefix($opt, "--binlog-format=") || $test_binlog_format;
 
474
      }
 
475
 
 
476
      if (defined $test_binlog_format and
 
477
          defined $tinfo->{binlog_formats} )
 
478
      {
 
479
        my $supported=
 
480
          grep { $_ eq $test_binlog_format } @{$tinfo->{'binlog_formats'}};
 
481
        if ( !$supported )
 
482
        {
 
483
          $tinfo->{'skip'}= 1;
 
484
          $tinfo->{'comment'}=
 
485
            "Doesn't support --binlog-format='$test_binlog_format'";
 
486
          next;
 
487
        }
 
488
      }
 
489
    }
 
490
 
 
491
  }
 
492
}
 
493
 
 
494
 
 
495
##############################################################################
 
496
#
 
497
#  Collect information about a single test case
 
498
#
 
499
##############################################################################
 
500
 
 
501
 
 
502
sub collect_one_test_case($$$$$$$$$) {
 
503
  my $testdir= shift;
 
504
  my $resdir=  shift;
 
505
  my $suite=   shift;
 
506
  my $tname=   shift;
 
507
  my $elem=    shift;
 
508
  my $cases=   shift;
 
509
  my $disabled=shift;
 
510
  my $component_id= shift;
 
511
  my $suite_opts= shift;
 
512
 
 
513
  my $path= "$testdir/$elem";
 
514
 
 
515
  # ----------------------------------------------------------------------
 
516
  # Skip some tests silently
 
517
  # ----------------------------------------------------------------------
 
518
 
 
519
  if ( $::opt_start_from and $tname lt $::opt_start_from )
 
520
  {
 
521
    return;
 
522
  }
 
523
 
 
524
 
 
525
  my $tinfo= {};
 
526
  $tinfo->{'name'}= basename($suite) . ".$tname";
 
527
  $tinfo->{'result_file'}= "$resdir/$tname.result";
 
528
  $tinfo->{'component_id'} = $component_id;
 
529
  push(@$cases, $tinfo);
 
530
 
 
531
  # ----------------------------------------------------------------------
 
532
  # Skip some tests but include in list, just mark them to skip
 
533
  # ----------------------------------------------------------------------
 
534
 
 
535
  if ( $skip_test and $tname =~ /$skip_test/o )
 
536
  {
 
537
    $tinfo->{'skip'}= 1;
 
538
    return;
 
539
  }
 
540
 
 
541
  # ----------------------------------------------------------------------
 
542
  # Collect information about test case
 
543
  # ----------------------------------------------------------------------
 
544
 
 
545
  $tinfo->{'path'}= $path;
 
546
  $tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work
 
547
 
 
548
  $tinfo->{'slave_num'}= 0; # Default, no slave
 
549
  $tinfo->{'master_num'}= 1; # Default, 1 master
 
550
  if ( defined mtr_match_prefix($tname,"rpl") )
 
551
  {
 
552
    if ( $::opt_skip_rpl )
 
553
    {
 
554
      $tinfo->{'skip'}= 1;
 
555
      $tinfo->{'comment'}= "No replication tests(--skip-rpl)";
 
556
      return;
 
557
    }
 
558
 
 
559
    $tinfo->{'slave_num'}= 1; # Default for rpl* tests, use one slave
 
560
 
 
561
  }
 
562
 
 
563
  if ( defined mtr_match_prefix($tname,"federated") )
 
564
  {
 
565
    # Default, federated uses the first slave as it's federated database
 
566
    $tinfo->{'slave_num'}= 1;
 
567
  }
 
568
 
 
569
  my $master_opt_file= "$testdir/$tname-master.opt";
 
570
  my $slave_opt_file=  "$testdir/$tname-slave.opt";
 
571
  my $slave_mi_file=   "$testdir/$tname.slave-mi";
 
572
  my $master_sh=       "$testdir/$tname-master.sh";
 
573
  my $slave_sh=        "$testdir/$tname-slave.sh";
 
574
  my $disabled_file=   "$testdir/$tname.disabled";
 
575
  my $im_opt_file=     "$testdir/$tname-im.opt";
 
576
 
 
577
  $tinfo->{'master_opt'}= [];
 
578
  $tinfo->{'slave_opt'}=  [];
 
579
  $tinfo->{'slave_mi'}=   [];
 
580
 
 
581
 
 
582
  # Add suite opts
 
583
  foreach my $opt ( @$suite_opts )
 
584
  {
 
585
    mtr_verbose($opt);
 
586
    push(@{$tinfo->{'master_opt'}}, $opt);
 
587
    push(@{$tinfo->{'slave_opt'}}, $opt);
 
588
  }
 
589
 
 
590
  # Add master opts
 
591
  if ( -f $master_opt_file )
 
592
  {
 
593
 
 
594
    my $master_opt= mtr_get_opts_from_file($master_opt_file);
 
595
 
 
596
    foreach my $opt ( @$master_opt )
 
597
    {
 
598
      my $value;
 
599
 
 
600
      # The opt file is used both to send special options to the mysqld
 
601
      # as well as pass special test case specific options to this
 
602
      # script
 
603
 
 
604
      $value= mtr_match_prefix($opt, "--timezone=");
 
605
      if ( defined $value )
 
606
      {
 
607
        $tinfo->{'timezone'}= $value;
 
608
        next;
 
609
      }
 
610
 
 
611
      $value= mtr_match_prefix($opt, "--slave-num=");
 
612
      if ( defined $value )
 
613
      {
 
614
        $tinfo->{'slave_num'}= $value;
 
615
        next;
 
616
      }
 
617
 
 
618
      $value= mtr_match_prefix($opt, "--result-file=");
 
619
      if ( defined $value )
 
620
      {
 
621
        # Specifies the file mysqltest should compare
 
622
        # output against
 
623
        $tinfo->{'result_file'}= "r/$value.result";
 
624
        next;
 
625
      }
 
626
 
 
627
      # If we set default time zone, remove the one we have
 
628
      $value= mtr_match_prefix($opt, "--default-time-zone=");
 
629
      if ( defined $value )
 
630
      {
 
631
        # Set timezone for this test case to something different
 
632
        $tinfo->{'timezone'}= "GMT-8";
 
633
        # Fallthrough, add the --default-time-zone option
 
634
      }
 
635
 
 
636
      # The --restart option forces a restart even if no special
 
637
      # option is set. If the options are the same as next testcase
 
638
      # there is no need to restart after the testcase
 
639
      # has completed
 
640
      if ( $opt eq "--force-restart" )
 
641
      {
 
642
        $tinfo->{'force_restart'}= 1;
 
643
        next;
 
644
      }
 
645
 
 
646
      # Ok, this was a real option, add it
 
647
      push(@{$tinfo->{'master_opt'}}, $opt);
 
648
    }
 
649
  }
 
650
 
 
651
  # Add slave opts
 
652
  if ( -f $slave_opt_file )
 
653
  {
 
654
    my $slave_opt= mtr_get_opts_from_file($slave_opt_file);
 
655
 
 
656
    foreach my $opt ( @$slave_opt )
 
657
    {
 
658
      # If we set default time zone, remove the one we have
 
659
      my $value= mtr_match_prefix($opt, "--default-time-zone=");
 
660
      $tinfo->{'slave_opt'}= [] if defined $value;
 
661
    }
 
662
    push(@{$tinfo->{'slave_opt'}}, @$slave_opt);
 
663
  }
 
664
 
 
665
  if ( -f $slave_mi_file )
 
666
  {
 
667
    $tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file);
 
668
  }
 
669
 
 
670
  if ( -f $master_sh )
 
671
  {
 
672
    if ( $::glob_win32_perl )
 
673
    {
 
674
      $tinfo->{'skip'}= 1;
 
675
      $tinfo->{'comment'}= "No tests with sh scripts on Windows";
 
676
      return;
 
677
    }
 
678
    else
 
679
    {
 
680
      $tinfo->{'master_sh'}= $master_sh;
 
681
    }
 
682
  }
 
683
 
 
684
  if ( -f $slave_sh )
 
685
  {
 
686
    if ( $::glob_win32_perl )
 
687
    {
 
688
      $tinfo->{'skip'}= 1;
 
689
      $tinfo->{'comment'}= "No tests with sh scripts on Windows";
 
690
      return;
 
691
    }
 
692
    else
 
693
    {
 
694
      $tinfo->{'slave_sh'}= $slave_sh;
 
695
    }
 
696
  }
 
697
 
 
698
  if ( -f $im_opt_file )
 
699
  {
 
700
    $tinfo->{'im_opts'} = mtr_get_opts_from_file($im_opt_file);
 
701
  }
 
702
  else
 
703
  {
 
704
    $tinfo->{'im_opts'} = [];
 
705
  }
 
706
 
 
707
  # FIXME why this late?
 
708
  my $marked_as_disabled= 0;
 
709
  if ( $disabled->{$tname} )
 
710
  {
 
711
    $marked_as_disabled= 1;
 
712
    $tinfo->{'comment'}= $disabled->{$tname};
 
713
  }
 
714
 
 
715
  if ( -f $disabled_file )
 
716
  {
 
717
    $marked_as_disabled= 1;
 
718
    $tinfo->{'comment'}= mtr_fromfile($disabled_file);
 
719
  }
 
720
 
 
721
  # If test was marked as disabled, either opt_enable_disabled is off and then
 
722
  # we skip this test, or it is on and then we run this test but warn
 
723
 
 
724
  if ( $marked_as_disabled )
 
725
  {
 
726
    if ( $::opt_enable_disabled )
 
727
    {
 
728
      $tinfo->{'dont_skip_though_disabled'}= 1;
 
729
    }
 
730
    else
 
731
    {
 
732
      $tinfo->{'skip'}= 1;
 
733
      $tinfo->{'disable'}= 1;   # Sub type of 'skip'
 
734
      return;
 
735
    }
 
736
  }
 
737
 
 
738
  if ( $component_id eq 'im' )
 
739
  {
 
740
    if ( $::glob_use_embedded_server )
 
741
    {
 
742
      $tinfo->{'skip'}= 1;
 
743
      $tinfo->{'comment'}= "No IM with embedded server";
 
744
      return;
 
745
    }
 
746
    elsif ( $::opt_ps_protocol )
 
747
    {
 
748
      $tinfo->{'skip'}= 1;
 
749
      $tinfo->{'comment'}= "No IM with --ps-protocol";
 
750
      return;
 
751
    }
 
752
    elsif ( $::opt_skip_im )
 
753
    {
 
754
      $tinfo->{'skip'}= 1;
 
755
      $tinfo->{'comment'}= "No IM tests(--skip-im)";
 
756
      return;
 
757
    }
 
758
  }
 
759
  else
 
760
  {
 
761
    mtr_options_from_test_file($tinfo,"$testdir/${tname}.test");
 
762
 
 
763
    if ( defined $::used_default_engine )
 
764
    {
 
765
      # Different default engine is used
 
766
      # tag test to require that engine
 
767
      $tinfo->{'ndb_test'}= 1
 
768
        if ( $::used_default_engine =~ /^ndb/i );
 
769
 
 
770
      $tinfo->{'innodb_test'}= 1
 
771
        if ( $::used_default_engine =~ /^innodb/i );
 
772
    }
 
773
 
 
774
    #enable federated for this test
 
775
    if ($tinfo->{'federated_test'})
 
776
    {
 
777
      push(@{$tinfo->{'master_opt'}}, "--loose-federated");
 
778
      push(@{$tinfo->{'slave_opt'}}, "--loose-federated");
 
779
    }
 
780
 
 
781
    if ( $tinfo->{'big_test'} and ! $::opt_big_test )
 
782
    {
 
783
      $tinfo->{'skip'}= 1;
 
784
      $tinfo->{'comment'}= "Test need 'big-test' option";
 
785
      return;
 
786
    }
 
787
 
 
788
    if ( $tinfo->{'ndb_extra'} and ! $::opt_ndb_extra_test )
 
789
    {
 
790
      $tinfo->{'skip'}= 1;
 
791
      $tinfo->{'comment'}= "Test need 'ndb_extra' option";
 
792
      return;
 
793
    }
 
794
 
 
795
    if ( $tinfo->{'require_manager'} )
 
796
    {
 
797
      $tinfo->{'skip'}= 1;
 
798
      $tinfo->{'comment'}= "Test need the _old_ manager(to be removed)";
 
799
      return;
 
800
    }
 
801
 
 
802
    if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries )
 
803
    {
 
804
      $tinfo->{'skip'}= 1;
 
805
      $tinfo->{'comment'}= "Test need debug binaries";
 
806
      return;
 
807
    }
 
808
 
 
809
    if ( $tinfo->{'ndb_test'} )
 
810
    {
 
811
      # This is a NDB test
 
812
      if ( ! $::glob_ndbcluster_supported )
 
813
      {
 
814
        # Ndb is not supported, skip it
 
815
        $tinfo->{'skip'}= 1;
 
816
        $tinfo->{'comment'}= "No ndbcluster support";
 
817
        return;
 
818
      }
 
819
      elsif ( $::opt_skip_ndbcluster )
 
820
      {
 
821
        # All ndb test's should be skipped
 
822
        $tinfo->{'skip'}= 1;
 
823
        $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)";
 
824
        return;
 
825
      }
 
826
      # Ndb tests run with two mysqld masters
 
827
      $tinfo->{'master_num'}= 2;
 
828
    }
 
829
    else
 
830
    {
 
831
      # This is not a ndb test
 
832
      if ( $::opt_with_ndbcluster_only )
 
833
      {
 
834
        # Only the ndb test should be run, all other should be skipped
 
835
        $tinfo->{'skip'}= 1;
 
836
        $tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)";
 
837
        return;
 
838
      }
 
839
    }
 
840
 
 
841
    if ( $tinfo->{'innodb_test'} )
 
842
    {
 
843
      # This is a test that need innodb
 
844
      if ( $::mysqld_variables{'innodb'} ne "TRUE" )
 
845
      {
 
846
        # innodb is not supported, skip it
 
847
        $tinfo->{'skip'}= 1;
 
848
        $tinfo->{'comment'}= "No innodb support";
 
849
        return;
 
850
      }
 
851
    }
 
852
 
 
853
    if ( $tinfo->{'need_binlog'} )
 
854
    {
 
855
      if (grep(/^--skip-log-bin/,  @::opt_extra_mysqld_opt) )
 
856
      {
 
857
        $tinfo->{'skip'}= 1;
 
858
        $tinfo->{'comment'}= "Test need binlog";
 
859
        return;
 
860
      }
 
861
    }
 
862
    else
 
863
    {
 
864
      if ( $::mysql_version_id >= 50100 )
 
865
      {
 
866
        # Test does not need binlog, add --skip-binlog to
 
867
        # the options used when starting it
 
868
        push(@{$tinfo->{'master_opt'}}, "--skip-log-bin");
 
869
      }
 
870
    }
 
871
 
 
872
  }
 
873
}
 
874
 
 
875
 
 
876
# List of tags in the .test files that if found should set
 
877
# the specified value in "tinfo"
 
878
our @tags=
 
879
(
 
880
 
 
881
 ["include/have_binlog_format_row.inc", "binlog_formats", ["row"]],
 
882
 ["include/have_binlog_format_statement.inc", "binlog_formats", ["statement"]],
 
883
 ["include/have_binlog_format_mixed.inc", "binlog_formats", ["mixed"]],
 
884
 ["include/have_binlog_format_mixed_or_row.inc",
 
885
  "binlog_formats", ["mixed", "row"]],
 
886
 ["include/have_binlog_format_mixed_or_statement.inc",
 
887
  "binlog_formats", ["mixed", "statement"]],
 
888
 ["include/have_binlog_format_row_or_statement.inc",
 
889
  "binlog_formats", ["row", "statement"]],
 
890
 
 
891
 ["include/have_innodb.inc", "innodb_test", 1],
 
892
 ["include/have_log_bin.inc", "need_binlog", 1],
 
893
 ["include/big_test.inc", "big_test", 1],
 
894
 ["include/have_debug.inc", "need_debug", 1],
 
895
 ["include/have_ndb.inc", "ndb_test", 1],
 
896
 ["include/have_multi_ndb.inc", "ndb_test", 1],
 
897
 ["include/have_ndb_extra.inc", "ndb_extra", 1],
 
898
 ["include/ndb_master-slave.inc", "ndb_test", 1],
 
899
 ["require_manager", "require_manager", 1],
 
900
 ["include/federated.inc", "federated_test", 1],
 
901
 ["include/have_federated_db.inc", "federated_test", 1],
 
902
);
 
903
 
 
904
sub mtr_options_from_test_file($$) {
 
905
  my $tinfo= shift;
 
906
  my $file= shift;
 
907
  #mtr_verbose("$file");
 
908
  my $F= IO::File->new($file) or mtr_error("can't open file \"$file\": $!");
 
909
 
 
910
  while ( my $line= <$F> )
 
911
  {
 
912
 
 
913
    # Skip line if it start's with #
 
914
    next if ( $line =~ /^#/ );
 
915
 
 
916
    # Match this line against tag in "tags" array
 
917
    foreach my $tag (@tags)
 
918
    {
 
919
      if ( index($line, $tag->[0]) >= 0 )
 
920
      {
 
921
          # Tag matched, assign value to "tinfo"
 
922
        $tinfo->{"$tag->[1]"}= $tag->[2];
 
923
      }
 
924
    }
 
925
 
 
926
    # If test sources another file, open it as well
 
927
    if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ or
 
928
         $line =~ /^([[:space:]]*)source(.*);$/ )
 
929
    {
 
930
      my $value= $2;
 
931
      $value =~ s/^\s+//;  # Remove leading space
 
932
      $value =~ s/[[:space:]]+$//;  # Remove ending space
 
933
 
 
934
      my $sourced_file= "$::glob_mysql_test_dir/$value";
 
935
      if ( -f $sourced_file )
 
936
      {
 
937
        # Only source the file if it exists, we may get
 
938
        # false positives in the regexes above if someone
 
939
        # writes "source nnnn;" in a test case(such as mysqltest.test)
 
940
        mtr_options_from_test_file($tinfo, $sourced_file);
 
941
      }
 
942
    }
 
943
  }
 
944
}
 
945
 
 
946
 
 
947
sub print_testcases {
 
948
  my (@cases)= @_;
 
949
 
 
950
  print "=" x 60, "\n";
 
951
  foreach my $test (@cases){
 
952
    print "[", $test->{name}, "]", "\n";
 
953
    while ((my ($key, $value)) = each(%$test)) {
 
954
      print " ", $key, "=";
 
955
      if (ref $value eq "ARRAY") {
 
956
        print join(", ", @$value);
 
957
      } else {
 
958
        print $value;
 
959
      }
 
960
      print "\n";
 
961
    }
 
962
    print "\n";
 
963
  }
 
964
  print "=" x 60, "\n";
 
965
}
 
966
 
 
967
 
 
968
1;