diff options
Diffstat (limited to 'mysql-test/lib/mtr_cases.pl')
-rw-r--r-- | mysql-test/lib/mtr_cases.pl | 449 |
1 files changed, 305 insertions, 144 deletions
diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 009269f382e..d270d72d526 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -5,11 +5,14 @@ # same name. use File::Basename; +use IO::File(); use strict; sub collect_test_cases ($); sub collect_one_test_case ($$$$$$$); +sub mtr_options_from_test_file($$); + ############################################################################## # # Collect information about test cases we are to run @@ -37,12 +40,31 @@ sub collect_test_cases ($) { opendir(TESTDIR, $testdir) or mtr_error("Can't open dir \"$testdir\": $!"); + # ---------------------------------------------------------------------- + # Disable some tests listed in disabled.def + # ---------------------------------------------------------------------- + my %disabled; + if ( open(DISABLED, "$testdir/disabled.def" ) ) + { + while ( <DISABLED> ) + { + chomp; + if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ ) + { + $disabled{$1}= $2; + } + } + close DISABLED; + } + if ( @::opt_cases ) { - foreach my $tname ( @::opt_cases ) { # Run in specified order, no sort + foreach my $tname ( @::opt_cases ) + { + # Run in specified order, no sort my $elem= undef; my $component_id= undef; - + # Get rid of directory part (path). Leave the extension since it is used # to understand type of the test. @@ -65,7 +87,7 @@ sub collect_test_cases ($) { # If target component is known, check that the specified test case # exists. - # + # # Otherwise, try to guess the target component. if ( $component_id ) @@ -100,31 +122,15 @@ sub collect_test_cases ($) { } } - collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,{}, + collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, $component_id); } closedir TESTDIR; } else { - # ---------------------------------------------------------------------- - # Disable some tests listed in disabled.def - # ---------------------------------------------------------------------- - my %disabled; - if ( ! $::opt_ignore_disabled_def and open(DISABLED, "$testdir/disabled.def" ) ) + foreach my $elem ( sort readdir(TESTDIR) ) { - while ( <DISABLED> ) - { - chomp; - if ( /^\s*([^\s:]+)\s*:\s*(.*?)\s*$/ ) - { - $disabled{$1}= $2; - } - } - close DISABLED; - } - - foreach my $elem ( sort readdir(TESTDIR) ) { my $component_id= undef; my $tname= undef; @@ -140,8 +146,10 @@ sub collect_test_cases ($) { { next; } - - next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test); + + # Skip tests that does not match the --do-test= filter + next if $::opt_do_test and + ! defined mtr_match_prefix($elem,$::opt_do_test); collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, $component_id); @@ -149,43 +157,79 @@ sub collect_test_cases ($) { closedir TESTDIR; } - # To speed things up, we sort first in if the test require a restart - # or not, second in alphanumeric order. - + # Reorder the test cases in an order that will make them faster to run if ( $::opt_reorder ) { my %sort_criteria; - my $tinfo; # 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 $tinfo (@$cases) + foreach my $tinfo (@$cases) { - my @this_criteria = (); - - # Append the criteria for sorting, in order of importance. - push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); # Ending with "~" makes empty sort later than filled - push(@this_criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); - push(@this_criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); - push(@this_criteria, "big_test=" . ($tinfo->{'big_test'} ? "1" : "0")); - push(@this_criteria, join("|", sort keys %{$tinfo})); # Group similar things together. The values may differ substantially. FIXME? - push(@this_criteria, $tinfo->{'name'}); # Finally, order by the name - - $sort_criteria{$tinfo->{"name"}} = join(" ", @this_criteria); + 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"}} cmp $sort_criteria{$b->{"name"}}; } @$cases; + @$cases = sort { + $sort_criteria{$a->{'name'}} . $a->{'name'} cmp + $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases; -### For debugging the sort-order -# foreach $tinfo (@$cases) -# { -# print $sort_criteria{$tinfo->{"name"}}; -# print " -> \t"; -# print $tinfo->{"name"}; -# print "\n"; -# } + if ( $::opt_script_debug ) + { + # For debugging the sort-order + foreach my $tinfo (@$cases) + { + print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n"); + } + } } return $cases; @@ -219,9 +263,6 @@ sub collect_one_test_case($$$$$$$) { return; } - # ---------------------------------------------------------------------- - # Skip some tests but include in list, just mark them to skip - # ---------------------------------------------------------------------- my $tinfo= {}; $tinfo->{'name'}= $tname; @@ -229,6 +270,10 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'component_id'} = $component_id; push(@$cases, $tinfo); + # ---------------------------------------------------------------------- + # Skip some tests but include in list, just mark them to skip + # ---------------------------------------------------------------------- + if ( $::opt_skip_test and defined mtr_match_prefix($tname,$::opt_skip_test) ) { $tinfo->{'skip'}= 1; @@ -242,57 +287,31 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'path'}= $path; $tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work + $tinfo->{'slave_num'}= 0; # Default, no slave 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, use one slave - # FIXME currently we always restart slaves - $tinfo->{'slave_restart'}= 1; + $tinfo->{'slave_num'}= 1; # Default for rpl* tests, use one slave if ( $tname eq 'rpl_failsafe' or $tname eq 'rpl_chain_temp_table' ) { -# $tinfo->{'slave_num'}= 3; # Not 3 ? Check old code, strange + # $tinfo->{'slave_num'}= 3; # Not 3 ? Check old code, strange } } if ( defined mtr_match_prefix($tname,"federated") ) { - $tinfo->{'slave_num'}= 1; # Default, use one slave - - # FIXME currently we always restart slaves - $tinfo->{'slave_restart'}= 1; - } - - # Cluster is needed by test case if testname contains ndb - if ( defined mtr_match_substring($tname,"ndb") ) - { - $tinfo->{'ndb_test'}= 1; - if ( $::opt_skip_ndbcluster ) - { - # Skip all ndb tests - $tinfo->{'skip'}= 1; - return; - } - if ( ! $::opt_with_ndbcluster ) - { - # Ndb is not supported, skip them - $tinfo->{'skip'}= 1; - return; - } - } - else - { - $tinfo->{'ndb_test'}= 0; + # Default, federated uses the first slave as it's federated database + $tinfo->{'slave_num'}= 1; } - # FIXME what about embedded_server + ndbcluster, skip ?! - my $master_opt_file= "$testdir/$tname-master.opt"; my $slave_opt_file= "$testdir/$tname-slave.opt"; my $slave_mi_file= "$testdir/$tname.slave-mi"; @@ -307,57 +326,59 @@ sub collect_one_test_case($$$$$$$) { if ( -f $master_opt_file ) { - $tinfo->{'master_restart'}= 1; # We think so for now - MASTER_OPT: - { - my $master_opt= mtr_get_opts_from_file($master_opt_file); + my $master_opt= mtr_get_opts_from_file($master_opt_file); - foreach my $opt ( @$master_opt ) - { - my $value; + foreach my $opt ( @$master_opt ) + { + my $value; - # This is a dirty hack from old mysql-test-run, we use the opt - # file to flag other things as well, it is not a opt list at - # all + # 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; - last MASTER_OPT; - } + $value= mtr_match_prefix($opt, "--timezone="); + if ( defined $value ) + { + $tinfo->{'timezone'}= $value; + next; + } - $value= mtr_match_prefix($opt, "--result-file="); - if ( defined $value ) - { - $tinfo->{'result_file'}= "r/$value.result"; - if ( $::opt_result_ext and $::opt_record or - -f "$tinfo->{'result_file'}$::opt_result_ext") - { - $tinfo->{'result_file'}.= $::opt_result_ext; - } - $tinfo->{'master_restart'}= 0; - last MASTER_OPT; - } + $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 ) - { - $tinfo->{'master_opt'}= []; - } + # 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 list, add it - push(@{$tinfo->{'master_opt'}}, @$master_opt); + # Ok, this was a real option, add it + push(@{$tinfo->{'master_opt'}}, $opt); } } if ( -f $slave_opt_file ) { - $tinfo->{'slave_restart'}= 1; my $slave_opt= mtr_get_opts_from_file($slave_opt_file); foreach my $opt ( @$slave_opt ) @@ -372,7 +393,6 @@ sub collect_one_test_case($$$$$$$) { if ( -f $slave_mi_file ) { $tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file); - $tinfo->{'slave_restart'}= 1; } if ( -f $master_sh ) @@ -380,11 +400,12 @@ sub collect_one_test_case($$$$$$$) { if ( $::glob_win32_perl ) { $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No tests with sh scripts on Windows"; + return; } else { $tinfo->{'master_sh'}= $master_sh; - $tinfo->{'master_restart'}= 1; } } @@ -393,11 +414,12 @@ sub collect_one_test_case($$$$$$$) { if ( $::glob_win32_perl ) { $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No tests with sh scripts on Windows"; + return; } else { $tinfo->{'slave_sh'}= $slave_sh; - $tinfo->{'slave_restart'}= 1; } } @@ -411,56 +433,195 @@ sub collect_one_test_case($$$$$$$) { } # FIXME why this late? + my $marked_as_disabled= 0; if ( $disabled->{$tname} ) { - $tinfo->{'skip'}= 1; - $tinfo->{'disable'}= 1; # Sub type of 'skip' - $tinfo->{'comment'}= $disabled->{$tname} if $disabled->{$tname}; + $marked_as_disabled= 1; + $tinfo->{'comment'}= $disabled->{$tname}; } if ( -f $disabled_file ) { - $tinfo->{'skip'}= 1; - $tinfo->{'disable'}= 1; # Sub type of 'skip' + $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; - - mtr_report( - "Instance Manager tests are not available in embedded mode. " . - "Test case '$tname' is skipped."); + $tinfo->{'comment'}= "No IM with embedded server"; + return; } elsif ( $::opt_ps_protocol ) { $tinfo->{'skip'}= 1; - - mtr_report( - "Instance Manager tests are not run with --ps-protocol. " . - "Test case '$tname' is skipped."); + $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 ( $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 ( defined $tinfo->{'binlog_format'} and + ! ( $tinfo->{'binlog_format'} eq $::used_binlog_format ) ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Not running with binlog format '$tinfo->{'binlog_format'}'"; + return; + } + + if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test need debug binaries"; + return; + } - mtr_report( - "Instance Manager executable is unavailable." . - "Test case '$tname' is skipped."); + 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; + } + } + 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 inndob + if ( $::mysqld_variables{'innodb'} eq "FALSE" ) + { + # innodb is not supported, skip it + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No innodb support"; + return; + } + } + } +} - # We can't restart a running server that may be in use - if ( $::glob_use_running_server and - ( $tinfo->{'master_restart'} or $tinfo->{'slave_restart'} ) ) +# List of tags in the .test files that if found should set +# the specified value in "tinfo" +our @tags= +( + ["include/have_innodb.inc", "innodb_test", 1], + ["include/have_binlog_format_row.inc", "binlog_format", "row"], + ["include/have_binlog_format_statement.inc", "binlog_format", "stmt"], + ["include/have_binlog_format_mixed.inc", "binlog_format", "mixed"], + ["include/big_test.inc", "big_test", 1], + ["include/have_debug.inc", "need_debug", 1], + ["include/have_ndb.inc", "ndb_test", 1], + ["include/have_ndb_extra.inc", "ndb_extra", 1], + ["require_manager", "require_manager", 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> ) { - $tinfo->{'skip'}= 1; + # 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); + } + } + } } - 1; |