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