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