mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
252c37a639
Small amendment to original fix, as it did not work in azalea Need to handle combinations, would eventually break in 5.1 too
991 lines
25 KiB
Perl
991 lines
25 KiB
Perl
# -*- cperl -*-
|
|
# Copyright (C) 2005-2006 MySQL AB
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; version 2 of the License.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
# This is a library file used by the Perl version of mysql-test-run,
|
|
# and is part of the translation of the Bourne shell script with the
|
|
# same name.
|
|
|
|
use File::Basename;
|
|
use IO::File();
|
|
use strict;
|
|
|
|
use My::Config;
|
|
|
|
sub collect_test_cases ($);
|
|
sub collect_one_suite ($);
|
|
sub collect_one_test_case ($$$$$$$$$);
|
|
|
|
sub mtr_options_from_test_file($$);
|
|
|
|
my $do_test;
|
|
my $skip_test;
|
|
my %incompatible;
|
|
|
|
sub init_pattern {
|
|
my ($from, $what)= @_;
|
|
if ( $from =~ /^[a-z0-9]$/ ) {
|
|
# Does not contain any regex, make the pattern match
|
|
# beginning of string
|
|
$from= "^$from";
|
|
}
|
|
# Check that pattern is a valid regex
|
|
eval { "" =~/$from/; 1 } or
|
|
mtr_error("Invalid regex '$from' passed to $what\nPerl says: $@");
|
|
return $from;
|
|
}
|
|
|
|
|
|
sub collect_incomp_tests {
|
|
open (INCOMP, "lib/v1/incompatible.tests");
|
|
while (<INCOMP>)
|
|
{
|
|
next unless /^\w/;
|
|
s/\s.*\n//; # Ignore anything from first white space
|
|
$incompatible{$_}= 1;
|
|
}
|
|
}
|
|
|
|
##############################################################################
|
|
#
|
|
# Collect information about test cases we are to run
|
|
#
|
|
##############################################################################
|
|
|
|
sub collect_test_cases ($) {
|
|
$do_test= init_pattern($::opt_do_test, "--do-test");
|
|
$skip_test= init_pattern($::opt_skip_test, "--skip-test");
|
|
|
|
collect_incomp_tests();
|
|
|
|
my $suites= shift; # Semicolon separated list of test suites
|
|
my $cases = []; # Array of hash
|
|
|
|
foreach my $suite (split(",", $suites))
|
|
{
|
|
push(@$cases, collect_one_suite($suite));
|
|
}
|
|
|
|
|
|
if ( @::opt_cases )
|
|
{
|
|
# Check that the tests specified was found
|
|
# in at least one suite
|
|
foreach my $test_name_spec ( @::opt_cases )
|
|
{
|
|
my $found= 0;
|
|
my ($sname, $tname, $extension)= split_testname($test_name_spec);
|
|
foreach my $test ( @$cases )
|
|
{
|
|
# test->{name} is always in suite.name format
|
|
if ( $test->{name} =~ /.*\.$tname/ )
|
|
{
|
|
$found= 1;
|
|
}
|
|
}
|
|
if ( not $found )
|
|
{
|
|
mtr_error("Could not find $tname in any suite");
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $::opt_reorder )
|
|
{
|
|
# Reorder the test cases in an order that will make them faster to run
|
|
my %sort_criteria;
|
|
|
|
# Make a mapping of test name to a string that represents how that test
|
|
# should be sorted among the other tests. Put the most important criterion
|
|
# first, then a sub-criterion, then sub-sub-criterion, et c.
|
|
foreach my $tinfo (@$cases)
|
|
{
|
|
my @criteria = ();
|
|
|
|
# Look for tests that muct be in run in a defined order
|
|
# that is defined by test having the same name except for
|
|
# the ending digit
|
|
|
|
# Put variables into hash
|
|
my $test_name= $tinfo->{'name'};
|
|
my $depend_on_test_name;
|
|
if ( $test_name =~ /^([\D]+)([0-9]{1})$/ )
|
|
{
|
|
my $base_name= $1;
|
|
my $idx= $2;
|
|
mtr_verbose("$test_name => $base_name idx=$idx");
|
|
if ( $idx > 1 )
|
|
{
|
|
$idx-= 1;
|
|
$base_name= "$base_name$idx";
|
|
mtr_verbose("New basename $base_name");
|
|
}
|
|
|
|
foreach my $tinfo2 (@$cases)
|
|
{
|
|
if ( $tinfo2->{'name'} eq $base_name )
|
|
{
|
|
mtr_verbose("found dependent test $tinfo2->{'name'}");
|
|
$depend_on_test_name=$base_name;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( defined $depend_on_test_name )
|
|
{
|
|
mtr_verbose("Giving $test_name same critera as $depend_on_test_name");
|
|
$sort_criteria{$test_name} = $sort_criteria{$depend_on_test_name};
|
|
}
|
|
else
|
|
{
|
|
#
|
|
# Append the criteria for sorting, in order of importance.
|
|
#
|
|
push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0"));
|
|
# Group test with equal options together.
|
|
# Ending with "~" makes empty sort later than filled
|
|
push(@criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~");
|
|
|
|
$sort_criteria{$test_name} = join(" ", @criteria);
|
|
}
|
|
}
|
|
|
|
@$cases = sort {
|
|
$sort_criteria{$a->{'name'}} . $a->{'name'} cmp
|
|
$sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases;
|
|
|
|
if ( $::opt_script_debug )
|
|
{
|
|
# For debugging the sort-order
|
|
foreach my $tinfo (@$cases)
|
|
{
|
|
print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return $cases;
|
|
|
|
}
|
|
|
|
# Valid extensions and their corresonding component id
|
|
my %exts = ( 'test' => 'mysqld',
|
|
'imtest' => 'im'
|
|
);
|
|
|
|
|
|
# Returns (suitename, testname, extension)
|
|
sub split_testname {
|
|
my ($test_name)= @_;
|
|
|
|
# Get rid of directory part and split name on .'s
|
|
my @parts= split(/\./, basename($test_name));
|
|
|
|
if (@parts == 1){
|
|
# Only testname given, ex: alias
|
|
return (undef , $parts[0], undef);
|
|
} elsif (@parts == 2) {
|
|
# Either testname.test or suite.testname given
|
|
# Ex. main.alias or alias.test
|
|
|
|
if (defined $exts{$parts[1]})
|
|
{
|
|
return (undef , $parts[0], $parts[1]);
|
|
}
|
|
else
|
|
{
|
|
return ($parts[0], $parts[1], undef);
|
|
}
|
|
|
|
} elsif (@parts == 3) {
|
|
# Fully specified suitename.testname.test
|
|
# ex main.alias.test
|
|
return ( $parts[0], $parts[1], $parts[2]);
|
|
}
|
|
|
|
mtr_error("Illegal format of test name: $test_name");
|
|
}
|
|
|
|
|
|
sub collect_one_suite($)
|
|
{
|
|
my $suite= shift; # Test suite name
|
|
my @cases; # Array of hash
|
|
|
|
mtr_verbose("Collecting: $suite");
|
|
|
|
my $suitedir= "$::glob_mysql_test_dir"; # Default
|
|
if ( $suite ne "main" )
|
|
{
|
|
$suitedir= mtr_path_exists("$suitedir/suite/$suite",
|
|
"$suitedir/$suite");
|
|
mtr_verbose("suitedir: $suitedir");
|
|
}
|
|
|
|
my $testdir= "$suitedir/t";
|
|
my $resdir= "$suitedir/r";
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Build a hash of disabled testcases for this suite
|
|
# ----------------------------------------------------------------------
|
|
my %disabled;
|
|
if ( open(DISABLED, "$testdir/disabled.def" ) )
|
|
{
|
|
while ( <DISABLED> )
|
|
{
|
|
chomp;
|
|
if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
|
|
{
|
|
$disabled{$1}= $2;
|
|
}
|
|
}
|
|
close DISABLED;
|
|
}
|
|
|
|
# Read suite.opt file
|
|
my $suite_opt_file= "$testdir/suite.opt";
|
|
my $suite_opts= [];
|
|
if ( -f $suite_opt_file )
|
|
{
|
|
$suite_opts= mtr_get_opts_from_file($suite_opt_file);
|
|
}
|
|
|
|
if ( @::opt_cases )
|
|
{
|
|
# Collect in specified order
|
|
foreach my $test_name_spec ( @::opt_cases )
|
|
{
|
|
my ($sname, $tname, $extension)= split_testname($test_name_spec);
|
|
|
|
# The test name parts have now been defined
|
|
#print " suite_name: $sname\n";
|
|
#print " tname: $tname\n";
|
|
#print " extension: $extension\n";
|
|
|
|
# Check cirrect suite if suitename is defined
|
|
next if (defined $sname and $suite ne $sname);
|
|
|
|
my $component_id;
|
|
if ( defined $extension )
|
|
{
|
|
my $full_name= "$testdir/$tname.$extension";
|
|
# Extension was specified, check if the test exists
|
|
if ( ! -f $full_name)
|
|
{
|
|
# This is only an error if suite was specified, otherwise it
|
|
# could exist in another suite
|
|
mtr_error("Test '$full_name' was not found in suite '$sname'")
|
|
if $sname;
|
|
|
|
next;
|
|
}
|
|
$component_id= $exts{$extension};
|
|
}
|
|
else
|
|
{
|
|
# No extension was specified
|
|
my ($ext, $component);
|
|
while (($ext, $component)= each %exts) {
|
|
my $full_name= "$testdir/$tname.$ext";
|
|
|
|
if ( ! -f $full_name ) {
|
|
next;
|
|
}
|
|
$component_id= $component;
|
|
$extension= $ext;
|
|
}
|
|
# Test not found here, could exist in other suite
|
|
next unless $component_id;
|
|
}
|
|
|
|
collect_one_test_case($testdir,$resdir,$suite,$tname,
|
|
"$tname.$extension",\@cases,\%disabled,
|
|
$component_id,$suite_opts);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
opendir(TESTDIR, $testdir) or mtr_error("Can't open dir \"$testdir\": $!");
|
|
|
|
foreach my $elem ( sort readdir(TESTDIR) )
|
|
{
|
|
my $component_id= undef;
|
|
my $tname= undef;
|
|
|
|
if ($tname= mtr_match_extension($elem, 'test'))
|
|
{
|
|
$component_id = 'mysqld';
|
|
}
|
|
elsif ($tname= mtr_match_extension($elem, 'imtest'))
|
|
{
|
|
$component_id = 'im';
|
|
}
|
|
else
|
|
{
|
|
next;
|
|
}
|
|
|
|
# Skip tests that does not match the --do-test= filter
|
|
next if ($do_test and not $tname =~ /$do_test/o);
|
|
|
|
collect_one_test_case($testdir,$resdir,$suite,$tname,
|
|
$elem,\@cases,\%disabled,$component_id,
|
|
$suite_opts);
|
|
}
|
|
closedir TESTDIR;
|
|
}
|
|
|
|
|
|
# Return empty list if no testcases found
|
|
return if (@cases == 0);
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Read combinations for this suite and build testcases x combinations
|
|
# if any combinations exists
|
|
# ----------------------------------------------------------------------
|
|
if ( ! $::opt_skip_combination )
|
|
{
|
|
my @combinations;
|
|
my $combination_file= "$suitedir/combinations";
|
|
#print "combination_file: $combination_file\n";
|
|
if (@::opt_combinations)
|
|
{
|
|
# take the combination from command-line
|
|
mtr_verbose("Take the combination from command line");
|
|
foreach my $combination (@::opt_combinations) {
|
|
my $comb= {};
|
|
$comb->{name}= $combination;
|
|
push(@{$comb->{comb_opt}}, $combination);
|
|
push(@combinations, $comb);
|
|
}
|
|
}
|
|
elsif (-f $combination_file )
|
|
{
|
|
# Read combinations file in my.cnf format
|
|
mtr_verbose("Read combinations file");
|
|
my $config= My::Config->new($combination_file);
|
|
|
|
foreach my $group ($config->groups()) {
|
|
my $comb= {};
|
|
$comb->{name}= $group->name();
|
|
foreach my $option ( $group->options() ) {
|
|
push(@{$comb->{comb_opt}}, "--".$option->name()."=".$option->value());
|
|
}
|
|
push(@combinations, $comb);
|
|
}
|
|
}
|
|
|
|
if (@combinations)
|
|
{
|
|
print " - adding combinations\n";
|
|
#print_testcases(@cases);
|
|
|
|
my @new_cases;
|
|
foreach my $comb (@combinations)
|
|
{
|
|
foreach my $test (@cases)
|
|
{
|
|
#print $test->{name}, " ", $comb, "\n";
|
|
my $new_test= {};
|
|
|
|
while (my ($key, $value) = each(%$test)) {
|
|
if (ref $value eq "ARRAY") {
|
|
push(@{$new_test->{$key}}, @$value);
|
|
} else {
|
|
$new_test->{$key}= $value;
|
|
}
|
|
}
|
|
|
|
# Append the combination options to master_opt and slave_opt
|
|
push(@{$new_test->{master_opt}}, @{$comb->{comb_opt}});
|
|
push(@{$new_test->{slave_opt}}, @{$comb->{comb_opt}});
|
|
|
|
# Add combination name shrt name
|
|
$new_test->{combination}= $comb->{name};
|
|
|
|
# Add the new test to new test cases list
|
|
push(@new_cases, $new_test);
|
|
}
|
|
}
|
|
#print_testcases(@new_cases);
|
|
@cases= @new_cases;
|
|
#print_testcases(@cases);
|
|
}
|
|
}
|
|
|
|
optimize_cases(\@cases);
|
|
#print_testcases(@cases);
|
|
|
|
return @cases;
|
|
}
|
|
|
|
|
|
#
|
|
# Loop through all test cases
|
|
# - optimize which test to run by skipping unnecessary ones
|
|
# - update settings if necessary
|
|
#
|
|
sub optimize_cases {
|
|
my ($cases)= @_;
|
|
|
|
foreach my $tinfo ( @$cases )
|
|
{
|
|
# Skip processing if already marked as skipped
|
|
next if $tinfo->{skip};
|
|
|
|
# =======================================================
|
|
# If a special binlog format was selected with
|
|
# --mysqld=--binlog-format=x, skip all test that does not
|
|
# support it
|
|
# =======================================================
|
|
#print "used_binlog_format: $::used_binlog_format\n";
|
|
if (defined $::used_binlog_format )
|
|
{
|
|
# =======================================================
|
|
# Fixed --binlog-format=x specified on command line
|
|
# =======================================================
|
|
if ( defined $tinfo->{'binlog_formats'} )
|
|
{
|
|
#print "binlog_formats: ". join(", ", @{$tinfo->{binlog_formats}})."\n";
|
|
|
|
# The test supports different binlog formats
|
|
# check if the selected one is ok
|
|
my $supported=
|
|
grep { $_ eq $::used_binlog_format } @{$tinfo->{'binlog_formats'}};
|
|
if ( !$supported )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}=
|
|
"Doesn't support --binlog-format='$::used_binlog_format'";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# =======================================================
|
|
# Use dynamic switching of binlog format
|
|
# =======================================================
|
|
|
|
# Get binlog-format used by this test from master_opt
|
|
my $test_binlog_format;
|
|
foreach my $opt ( @{$tinfo->{master_opt}} ) {
|
|
$test_binlog_format=
|
|
mtr_match_prefix($opt, "--binlog-format=") || $test_binlog_format;
|
|
}
|
|
|
|
if (defined $test_binlog_format and
|
|
defined $tinfo->{binlog_formats} )
|
|
{
|
|
my $supported=
|
|
grep { $_ eq $test_binlog_format } @{$tinfo->{'binlog_formats'}};
|
|
if ( !$supported )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}=
|
|
"Doesn't support --binlog-format='$test_binlog_format'";
|
|
next;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
##############################################################################
|
|
#
|
|
# Collect information about a single test case
|
|
#
|
|
##############################################################################
|
|
|
|
|
|
sub collect_one_test_case($$$$$$$$$) {
|
|
my $testdir= shift;
|
|
my $resdir= shift;
|
|
my $suite= shift;
|
|
my $tname= shift;
|
|
my $elem= shift;
|
|
my $cases= shift;
|
|
my $disabled=shift;
|
|
my $component_id= shift;
|
|
my $suite_opts= shift;
|
|
|
|
my $path= "$testdir/$elem";
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Skip some tests silently
|
|
# ----------------------------------------------------------------------
|
|
|
|
if ( $::opt_start_from and $tname lt $::opt_start_from )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
my $tinfo= {};
|
|
$tinfo->{'name'}= basename($suite) . ".$tname";
|
|
$tinfo->{'result_file'}= "$resdir/$tname.result";
|
|
$tinfo->{'component_id'} = $component_id;
|
|
push(@$cases, $tinfo);
|
|
|
|
# Remove "combinations" part of test name
|
|
my $test_base_name= $tinfo->{'name'};
|
|
$test_base_name=~ s/\s.*\n//;
|
|
|
|
if (exists ($incompatible{$test_base_name}))
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Test cannot run in mtr v1";
|
|
return;
|
|
}
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Skip some tests but include in list, just mark them to skip
|
|
# ----------------------------------------------------------------------
|
|
|
|
if ( $skip_test and $tname =~ /$skip_test/o )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
return;
|
|
}
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Collect information about test case
|
|
# ----------------------------------------------------------------------
|
|
|
|
$tinfo->{'path'}= $path;
|
|
$tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work
|
|
|
|
$tinfo->{'slave_num'}= 0; # Default, no slave
|
|
$tinfo->{'master_num'}= 1; # Default, 1 master
|
|
if ( defined mtr_match_prefix($tname,"rpl") )
|
|
{
|
|
if ( $::opt_skip_rpl )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No replication tests(--skip-rpl)";
|
|
return;
|
|
}
|
|
|
|
$tinfo->{'slave_num'}= 1; # Default for rpl* tests, use one slave
|
|
|
|
}
|
|
|
|
if ( defined mtr_match_prefix($tname,"federated") )
|
|
{
|
|
# Default, federated uses the first slave as it's federated database
|
|
$tinfo->{'slave_num'}= 1;
|
|
}
|
|
|
|
my $master_opt_file= "$testdir/$tname-master.opt";
|
|
my $slave_opt_file= "$testdir/$tname-slave.opt";
|
|
my $slave_mi_file= "$testdir/$tname.slave-mi";
|
|
my $master_sh= "$testdir/$tname-master.sh";
|
|
my $slave_sh= "$testdir/$tname-slave.sh";
|
|
my $disabled_file= "$testdir/$tname.disabled";
|
|
my $im_opt_file= "$testdir/$tname-im.opt";
|
|
|
|
$tinfo->{'master_opt'}= [];
|
|
$tinfo->{'slave_opt'}= [];
|
|
$tinfo->{'slave_mi'}= [];
|
|
|
|
|
|
# Add suite opts
|
|
foreach my $opt ( @$suite_opts )
|
|
{
|
|
mtr_verbose($opt);
|
|
push(@{$tinfo->{'master_opt'}}, $opt);
|
|
push(@{$tinfo->{'slave_opt'}}, $opt);
|
|
}
|
|
|
|
# Add master opts
|
|
if ( -f $master_opt_file )
|
|
{
|
|
|
|
my $master_opt= mtr_get_opts_from_file($master_opt_file);
|
|
|
|
foreach my $opt ( @$master_opt )
|
|
{
|
|
my $value;
|
|
|
|
# The opt file is used both to send special options to the mysqld
|
|
# as well as pass special test case specific options to this
|
|
# script
|
|
|
|
$value= mtr_match_prefix($opt, "--timezone=");
|
|
if ( defined $value )
|
|
{
|
|
$tinfo->{'timezone'}= $value;
|
|
next;
|
|
}
|
|
|
|
$value= mtr_match_prefix($opt, "--slave-num=");
|
|
if ( defined $value )
|
|
{
|
|
$tinfo->{'slave_num'}= $value;
|
|
next;
|
|
}
|
|
|
|
$value= mtr_match_prefix($opt, "--result-file=");
|
|
if ( defined $value )
|
|
{
|
|
# Specifies the file mysqltest should compare
|
|
# output against
|
|
$tinfo->{'result_file'}= "r/$value.result";
|
|
next;
|
|
}
|
|
|
|
# If we set default time zone, remove the one we have
|
|
$value= mtr_match_prefix($opt, "--default-time-zone=");
|
|
if ( defined $value )
|
|
{
|
|
# Set timezone for this test case to something different
|
|
$tinfo->{'timezone'}= "GMT-8";
|
|
# Fallthrough, add the --default-time-zone option
|
|
}
|
|
|
|
# The --restart option forces a restart even if no special
|
|
# option is set. If the options are the same as next testcase
|
|
# there is no need to restart after the testcase
|
|
# has completed
|
|
if ( $opt eq "--force-restart" )
|
|
{
|
|
$tinfo->{'force_restart'}= 1;
|
|
next;
|
|
}
|
|
|
|
# Ok, this was a real option, add it
|
|
push(@{$tinfo->{'master_opt'}}, $opt);
|
|
}
|
|
}
|
|
|
|
# Add slave opts
|
|
if ( -f $slave_opt_file )
|
|
{
|
|
my $slave_opt= mtr_get_opts_from_file($slave_opt_file);
|
|
|
|
foreach my $opt ( @$slave_opt )
|
|
{
|
|
# If we set default time zone, remove the one we have
|
|
my $value= mtr_match_prefix($opt, "--default-time-zone=");
|
|
$tinfo->{'slave_opt'}= [] if defined $value;
|
|
}
|
|
push(@{$tinfo->{'slave_opt'}}, @$slave_opt);
|
|
}
|
|
|
|
if ( -f $slave_mi_file )
|
|
{
|
|
$tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file);
|
|
}
|
|
|
|
if ( -f $master_sh )
|
|
{
|
|
if ( $::glob_win32_perl )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No tests with sh scripts on Windows";
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
$tinfo->{'master_sh'}= $master_sh;
|
|
}
|
|
}
|
|
|
|
if ( -f $slave_sh )
|
|
{
|
|
if ( $::glob_win32_perl )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No tests with sh scripts on Windows";
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
$tinfo->{'slave_sh'}= $slave_sh;
|
|
}
|
|
}
|
|
|
|
if ( -f $im_opt_file )
|
|
{
|
|
$tinfo->{'im_opts'} = mtr_get_opts_from_file($im_opt_file);
|
|
}
|
|
else
|
|
{
|
|
$tinfo->{'im_opts'} = [];
|
|
}
|
|
|
|
# FIXME why this late?
|
|
my $marked_as_disabled= 0;
|
|
if ( $disabled->{$tname} )
|
|
{
|
|
$marked_as_disabled= 1;
|
|
$tinfo->{'comment'}= $disabled->{$tname};
|
|
}
|
|
|
|
if ( -f $disabled_file )
|
|
{
|
|
$marked_as_disabled= 1;
|
|
$tinfo->{'comment'}= mtr_fromfile($disabled_file);
|
|
}
|
|
|
|
# If test was marked as disabled, either opt_enable_disabled is off and then
|
|
# we skip this test, or it is on and then we run this test but warn
|
|
|
|
if ( $marked_as_disabled )
|
|
{
|
|
if ( $::opt_enable_disabled )
|
|
{
|
|
$tinfo->{'dont_skip_though_disabled'}= 1;
|
|
}
|
|
else
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'disable'}= 1; # Sub type of 'skip'
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( $component_id eq 'im' )
|
|
{
|
|
if ( $::glob_use_embedded_server )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No IM with embedded server";
|
|
return;
|
|
}
|
|
elsif ( $::opt_ps_protocol )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No IM with --ps-protocol";
|
|
return;
|
|
}
|
|
elsif ( $::opt_skip_im )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No IM tests(--skip-im)";
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mtr_options_from_test_file($tinfo,"$testdir/${tname}.test");
|
|
|
|
if ( defined $::used_default_engine )
|
|
{
|
|
# Different default engine is used
|
|
# tag test to require that engine
|
|
$tinfo->{'ndb_test'}= 1
|
|
if ( $::used_default_engine =~ /^ndb/i );
|
|
|
|
$tinfo->{'innodb_test'}= 1
|
|
if ( $::used_default_engine =~ /^innodb/i );
|
|
}
|
|
|
|
#enable federated for this test
|
|
if ($tinfo->{'federated_test'})
|
|
{
|
|
push(@{$tinfo->{'master_opt'}}, "--loose-federated");
|
|
push(@{$tinfo->{'slave_opt'}}, "--loose-federated");
|
|
}
|
|
|
|
if ( $tinfo->{'big_test'} and ! $::opt_big_test )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Test need 'big-test' option";
|
|
return;
|
|
}
|
|
|
|
if ( $tinfo->{'ndb_extra'} and ! $::opt_ndb_extra_test )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Test need 'ndb_extra' option";
|
|
return;
|
|
}
|
|
|
|
if ( $tinfo->{'require_manager'} )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Test need the _old_ manager(to be removed)";
|
|
return;
|
|
}
|
|
|
|
if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Test need debug binaries";
|
|
return;
|
|
}
|
|
|
|
if ( $tinfo->{'ndb_test'} )
|
|
{
|
|
# This is a NDB test
|
|
if ( ! $::glob_ndbcluster_supported )
|
|
{
|
|
# Ndb is not supported, skip it
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No ndbcluster support";
|
|
return;
|
|
}
|
|
elsif ( $::opt_skip_ndbcluster )
|
|
{
|
|
# All ndb test's should be skipped
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)";
|
|
return;
|
|
}
|
|
# Ndb tests run with two mysqld masters
|
|
$tinfo->{'master_num'}= 2;
|
|
}
|
|
else
|
|
{
|
|
# This is not a ndb test
|
|
if ( $::opt_with_ndbcluster_only )
|
|
{
|
|
# Only the ndb test should be run, all other should be skipped
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)";
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( $tinfo->{'innodb_test'} )
|
|
{
|
|
# This is a test that need innodb
|
|
if ( $::mysqld_variables{'innodb'} eq "OFF" )
|
|
{
|
|
# innodb is not supported, skip it
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "No innodb support";
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( $tinfo->{'need_binlog'} )
|
|
{
|
|
if (grep(/^--skip-log-bin/, @::opt_extra_mysqld_opt) )
|
|
{
|
|
$tinfo->{'skip'}= 1;
|
|
$tinfo->{'comment'}= "Test need binlog";
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( $::mysql_version_id >= 50100 )
|
|
{
|
|
# Test does not need binlog, add --skip-binlog to
|
|
# the options used when starting it
|
|
push(@{$tinfo->{'master_opt'}}, "--skip-log-bin");
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
# List of tags in the .test files that if found should set
|
|
# the specified value in "tinfo"
|
|
our @tags=
|
|
(
|
|
|
|
["include/have_binlog_format_row.inc", "binlog_formats", ["row"]],
|
|
["include/have_binlog_format_statement.inc", "binlog_formats", ["statement"]],
|
|
["include/have_binlog_format_mixed.inc", "binlog_formats", ["mixed"]],
|
|
["include/have_binlog_format_mixed_or_row.inc",
|
|
"binlog_formats", ["mixed", "row"]],
|
|
["include/have_binlog_format_mixed_or_statement.inc",
|
|
"binlog_formats", ["mixed", "statement"]],
|
|
["include/have_binlog_format_row_or_statement.inc",
|
|
"binlog_formats", ["row", "statement"]],
|
|
|
|
["include/have_innodb.inc", "innodb_test", 1],
|
|
["include/have_log_bin.inc", "need_binlog", 1],
|
|
["include/big_test.inc", "big_test", 1],
|
|
["include/have_debug.inc", "need_debug", 1],
|
|
["include/have_ndb.inc", "ndb_test", 1],
|
|
["include/have_multi_ndb.inc", "ndb_test", 1],
|
|
["include/have_ndb_extra.inc", "ndb_extra", 1],
|
|
["include/ndb_master-slave.inc", "ndb_test", 1],
|
|
["require_manager", "require_manager", 1],
|
|
["include/federated.inc", "federated_test", 1],
|
|
["include/have_federated_db.inc", "federated_test", 1],
|
|
);
|
|
|
|
sub mtr_options_from_test_file($$) {
|
|
my $tinfo= shift;
|
|
my $file= shift;
|
|
#mtr_verbose("$file");
|
|
my $F= IO::File->new($file) or mtr_error("can't open file \"$file\": $!");
|
|
|
|
while ( my $line= <$F> )
|
|
{
|
|
|
|
# Skip line if it start's with #
|
|
next if ( $line =~ /^#/ );
|
|
|
|
# Match this line against tag in "tags" array
|
|
foreach my $tag (@tags)
|
|
{
|
|
if ( index($line, $tag->[0]) >= 0 )
|
|
{
|
|
# Tag matched, assign value to "tinfo"
|
|
$tinfo->{"$tag->[1]"}= $tag->[2];
|
|
}
|
|
}
|
|
|
|
# If test sources another file, open it as well
|
|
if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ or
|
|
$line =~ /^([[:space:]]*)source(.*);$/ )
|
|
{
|
|
my $value= $2;
|
|
$value =~ s/^\s+//; # Remove leading space
|
|
$value =~ s/[[:space:]]+$//; # Remove ending space
|
|
|
|
my $sourced_file= "$::glob_mysql_test_dir/$value";
|
|
if ( -f $sourced_file )
|
|
{
|
|
# Only source the file if it exists, we may get
|
|
# false positives in the regexes above if someone
|
|
# writes "source nnnn;" in a test case(such as mysqltest.test)
|
|
mtr_options_from_test_file($tinfo, $sourced_file);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
sub print_testcases {
|
|
my (@cases)= @_;
|
|
|
|
print "=" x 60, "\n";
|
|
foreach my $test (@cases){
|
|
print "[", $test->{name}, "]", "\n";
|
|
while ((my ($key, $value)) = each(%$test)) {
|
|
print " ", $key, "=";
|
|
if (ref $value eq "ARRAY") {
|
|
print join(", ", @$value);
|
|
} else {
|
|
print $value;
|
|
}
|
|
print "\n";
|
|
}
|
|
print "\n";
|
|
}
|
|
print "=" x 60, "\n";
|
|
}
|
|
|
|
|
|
1;
|