You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5605 lines
153 KiB

18 years ago
16 years ago
18 years ago
17 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
Bug #42804 --parallel option does not work for MTR under ActiveState perl The problem here was the method how MTR gets its unique thread ids. Prior to this patch, the method to do it was to maintain a global table of pid,mtr_unique_id) pairs. The table was backed by a text file. The table was cleaned up one in a while and dead processes leaking unique_ids were determined with with kill(0) or with scripting tasklist on Windows. This method is flawed specifically on native Windows Perl. fork() is implemented with starting a new thread, give it a syntetic negative PID (threadID*(-1)), until this thread creates a new process with exec() However, neither tasklist nor any other native Windows tool can cope with negative perl PIDs. This lead to incorrect determination of dead process and reusing already used mtr_unique_id. The patch introduces alternative portable method of solving unique-id problem. When a process needs a unique id in range [min...max], it just starts to open files named min, min+1,...max in a loop . After file is opened, we do non-blocking flock(). When flock() succeeds, process has allocated the ID. When process dies, file is unlocked . Checks for zombies are not necessary. Since the change would create a co-existence problems with older version of MTR, because of different way to calculate IDs, the default ID range is changed from 250-299 to 300-349. Another fix that was necessary enable --parallel option was to serialize spawn() calls on Windows. specifically, IO redirects needed to be protected. This patch also fixes hanging CRTL-C (as described in Bug #38629) for the "new" MTR. The fix was already in 6.0 and is now downported.
17 years ago
Bug #42804 --parallel option does not work for MTR under ActiveState perl The problem here was the method how MTR gets its unique thread ids. Prior to this patch, the method to do it was to maintain a global table of pid,mtr_unique_id) pairs. The table was backed by a text file. The table was cleaned up one in a while and dead processes leaking unique_ids were determined with with kill(0) or with scripting tasklist on Windows. This method is flawed specifically on native Windows Perl. fork() is implemented with starting a new thread, give it a syntetic negative PID (threadID*(-1)), until this thread creates a new process with exec() However, neither tasklist nor any other native Windows tool can cope with negative perl PIDs. This lead to incorrect determination of dead process and reusing already used mtr_unique_id. The patch introduces alternative portable method of solving unique-id problem. When a process needs a unique id in range [min...max], it just starts to open files named min, min+1,...max in a loop . After file is opened, we do non-blocking flock(). When flock() succeeds, process has allocated the ID. When process dies, file is unlocked . Checks for zombies are not necessary. Since the change would create a co-existence problems with older version of MTR, because of different way to calculate IDs, the default ID range is changed from 250-299 to 300-349. Another fix that was necessary enable --parallel option was to serialize spawn() calls on Windows. specifically, IO redirects needed to be protected. This patch also fixes hanging CRTL-C (as described in Bug #38629) for the "new" MTR. The fix was already in 6.0 and is now downported.
17 years ago
Bug #42804 --parallel option does not work for MTR under ActiveState perl The problem here was the method how MTR gets its unique thread ids. Prior to this patch, the method to do it was to maintain a global table of pid,mtr_unique_id) pairs. The table was backed by a text file. The table was cleaned up one in a while and dead processes leaking unique_ids were determined with with kill(0) or with scripting tasklist on Windows. This method is flawed specifically on native Windows Perl. fork() is implemented with starting a new thread, give it a syntetic negative PID (threadID*(-1)), until this thread creates a new process with exec() However, neither tasklist nor any other native Windows tool can cope with negative perl PIDs. This lead to incorrect determination of dead process and reusing already used mtr_unique_id. The patch introduces alternative portable method of solving unique-id problem. When a process needs a unique id in range [min...max], it just starts to open files named min, min+1,...max in a loop . After file is opened, we do non-blocking flock(). When flock() succeeds, process has allocated the ID. When process dies, file is unlocked . Checks for zombies are not necessary. Since the change would create a co-existence problems with older version of MTR, because of different way to calculate IDs, the default ID range is changed from 250-299 to 300-349. Another fix that was necessary enable --parallel option was to serialize spawn() calls on Windows. specifically, IO redirects needed to be protected. This patch also fixes hanging CRTL-C (as described in Bug #38629) for the "new" MTR. The fix was already in 6.0 and is now downported.
17 years ago
Bug #42804 --parallel option does not work for MTR under ActiveState perl The problem here was the method how MTR gets its unique thread ids. Prior to this patch, the method to do it was to maintain a global table of pid,mtr_unique_id) pairs. The table was backed by a text file. The table was cleaned up one in a while and dead processes leaking unique_ids were determined with with kill(0) or with scripting tasklist on Windows. This method is flawed specifically on native Windows Perl. fork() is implemented with starting a new thread, give it a syntetic negative PID (threadID*(-1)), until this thread creates a new process with exec() However, neither tasklist nor any other native Windows tool can cope with negative perl PIDs. This lead to incorrect determination of dead process and reusing already used mtr_unique_id. The patch introduces alternative portable method of solving unique-id problem. When a process needs a unique id in range [min...max], it just starts to open files named min, min+1,...max in a loop . After file is opened, we do non-blocking flock(). When flock() succeeds, process has allocated the ID. When process dies, file is unlocked . Checks for zombies are not necessary. Since the change would create a co-existence problems with older version of MTR, because of different way to calculate IDs, the default ID range is changed from 250-299 to 300-349. Another fix that was necessary enable --parallel option was to serialize spawn() calls on Windows. specifically, IO redirects needed to be protected. This patch also fixes hanging CRTL-C (as described in Bug #38629) for the "new" MTR. The fix was already in 6.0 and is now downported.
17 years ago
Fixed compiler warnings Fixed compile-pentium64 scripts Fixed wrong estimate of update_with_key_prefix in sql-bench Merge bk-internal.mysql.com:/home/bk/mysql-5.1 into mysql.com:/home/my/mysql-5.1 Fixed unsafe define of uint4korr() Fixed that --extern works with mysql-test-run.pl Small trivial cleanups This also fixes a bug in counting number of rows that are updated when we have many simultanous queries Move all connection handling and command exectuion main loop from sql_parse.cc to sql_connection.cc Split handle_one_connection() into reusable sub functions. Split create_new_thread() into reusable sub functions. Added thread_scheduler; Preliminary interface code for future thread_handling code. Use 'my_thread_id' for internal thread id's Make thr_alarm_kill() to depend on thread_id instead of thread Make thr_abort_locks_for_thread() depend on thread_id instead of thread In store_globals(), set my_thread_var->id to be thd->thread_id. Use my_thread_var->id as basis for my_thread_name() The above changes makes the connection we have between THD and threads more soft. Added a lot of DBUG_PRINT() and DBUG_ASSERT() functions Fixed compiler warnings Fixed core dumps when running with --debug Removed setting of signal masks (was never used) Made event code call pthread_exit() (portability fix) Fixed that event code doesn't call DBUG_xxx functions before my_thread_init() is called. Made handling of thread_id and thd->variables.pseudo_thread_id uniform. Removed one common 'not freed memory' warning from mysqltest Fixed a couple of usage of not initialized warnings (unlikely cases) Suppress compiler warnings from bdb and (for the moment) warnings from ndb
19 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
Fixed compiler warnings Fixed compile-pentium64 scripts Fixed wrong estimate of update_with_key_prefix in sql-bench Merge bk-internal.mysql.com:/home/bk/mysql-5.1 into mysql.com:/home/my/mysql-5.1 Fixed unsafe define of uint4korr() Fixed that --extern works with mysql-test-run.pl Small trivial cleanups This also fixes a bug in counting number of rows that are updated when we have many simultanous queries Move all connection handling and command exectuion main loop from sql_parse.cc to sql_connection.cc Split handle_one_connection() into reusable sub functions. Split create_new_thread() into reusable sub functions. Added thread_scheduler; Preliminary interface code for future thread_handling code. Use 'my_thread_id' for internal thread id's Make thr_alarm_kill() to depend on thread_id instead of thread Make thr_abort_locks_for_thread() depend on thread_id instead of thread In store_globals(), set my_thread_var->id to be thd->thread_id. Use my_thread_var->id as basis for my_thread_name() The above changes makes the connection we have between THD and threads more soft. Added a lot of DBUG_PRINT() and DBUG_ASSERT() functions Fixed compiler warnings Fixed core dumps when running with --debug Removed setting of signal masks (was never used) Made event code call pthread_exit() (portability fix) Fixed that event code doesn't call DBUG_xxx functions before my_thread_init() is called. Made handling of thread_id and thd->variables.pseudo_thread_id uniform. Removed one common 'not freed memory' warning from mysqltest Fixed a couple of usage of not initialized warnings (unlikely cases) Suppress compiler warnings from bdb and (for the moment) warnings from ndb
19 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
18 years ago
17 years ago
18 years ago
16 years ago
18 years ago
18 years ago
20 years ago
20 years ago
Fixed compiler warnings Fixed compile-pentium64 scripts Fixed wrong estimate of update_with_key_prefix in sql-bench Merge bk-internal.mysql.com:/home/bk/mysql-5.1 into mysql.com:/home/my/mysql-5.1 Fixed unsafe define of uint4korr() Fixed that --extern works with mysql-test-run.pl Small trivial cleanups This also fixes a bug in counting number of rows that are updated when we have many simultanous queries Move all connection handling and command exectuion main loop from sql_parse.cc to sql_connection.cc Split handle_one_connection() into reusable sub functions. Split create_new_thread() into reusable sub functions. Added thread_scheduler; Preliminary interface code for future thread_handling code. Use 'my_thread_id' for internal thread id's Make thr_alarm_kill() to depend on thread_id instead of thread Make thr_abort_locks_for_thread() depend on thread_id instead of thread In store_globals(), set my_thread_var->id to be thd->thread_id. Use my_thread_var->id as basis for my_thread_name() The above changes makes the connection we have between THD and threads more soft. Added a lot of DBUG_PRINT() and DBUG_ASSERT() functions Fixed compiler warnings Fixed core dumps when running with --debug Removed setting of signal masks (was never used) Made event code call pthread_exit() (portability fix) Fixed that event code doesn't call DBUG_xxx functions before my_thread_init() is called. Made handling of thread_id and thd->variables.pseudo_thread_id uniform. Removed one common 'not freed memory' warning from mysqltest Fixed a couple of usage of not initialized warnings (unlikely cases) Suppress compiler warnings from bdb and (for the moment) warnings from ndb
19 years ago
Fixed compiler warnings Fixed compile-pentium64 scripts Fixed wrong estimate of update_with_key_prefix in sql-bench Merge bk-internal.mysql.com:/home/bk/mysql-5.1 into mysql.com:/home/my/mysql-5.1 Fixed unsafe define of uint4korr() Fixed that --extern works with mysql-test-run.pl Small trivial cleanups This also fixes a bug in counting number of rows that are updated when we have many simultanous queries Move all connection handling and command exectuion main loop from sql_parse.cc to sql_connection.cc Split handle_one_connection() into reusable sub functions. Split create_new_thread() into reusable sub functions. Added thread_scheduler; Preliminary interface code for future thread_handling code. Use 'my_thread_id' for internal thread id's Make thr_alarm_kill() to depend on thread_id instead of thread Make thr_abort_locks_for_thread() depend on thread_id instead of thread In store_globals(), set my_thread_var->id to be thd->thread_id. Use my_thread_var->id as basis for my_thread_name() The above changes makes the connection we have between THD and threads more soft. Added a lot of DBUG_PRINT() and DBUG_ASSERT() functions Fixed compiler warnings Fixed core dumps when running with --debug Removed setting of signal masks (was never used) Made event code call pthread_exit() (portability fix) Fixed that event code doesn't call DBUG_xxx functions before my_thread_init() is called. Made handling of thread_id and thd->variables.pseudo_thread_id uniform. Removed one common 'not freed memory' warning from mysqltest Fixed a couple of usage of not initialized warnings (unlikely cases) Suppress compiler warnings from bdb and (for the moment) warnings from ndb
19 years ago
18 years ago
  1. #!/usr/bin/perl
  2. # -*- cperl -*-
  3. #
  4. ##############################################################################
  5. #
  6. # mysql-test-run.pl
  7. #
  8. # Tool used for executing a suite of .test files
  9. #
  10. # See the "MySQL Test framework manual" for more information
  11. # http://dev.mysql.com/doc/mysqltest/en/index.html
  12. #
  13. #
  14. ##############################################################################
  15. use strict;
  16. use warnings;
  17. BEGIN {
  18. # Check that mysql-test-run.pl is started from mysql-test/
  19. unless ( -f "mysql-test-run.pl" )
  20. {
  21. print "**** ERROR **** ",
  22. "You must start mysql-test-run from the mysql-test/ directory\n";
  23. exit(1);
  24. }
  25. # Check that lib exist
  26. unless ( -d "lib/" )
  27. {
  28. print "**** ERROR **** ",
  29. "Could not find the lib/ directory \n";
  30. exit(1);
  31. }
  32. }
  33. BEGIN {
  34. # Check backward compatibility support
  35. # By setting the environment variable MTR_VERSION
  36. # it's possible to use a previous version of
  37. # mysql-test-run.pl
  38. my $version= $ENV{MTR_VERSION} || 2;
  39. if ( $version == 1 )
  40. {
  41. print "=======================================================\n";
  42. print " WARNING: Using mysql-test-run.pl version 1! \n";
  43. print "=======================================================\n";
  44. # Should use exec() here on *nix but this appears not to work on Windows
  45. exit(system($^X, "lib/v1/mysql-test-run.pl", @ARGV) >> 8);
  46. }
  47. elsif ( $version == 2 )
  48. {
  49. # This is the current version, just continue
  50. ;
  51. }
  52. else
  53. {
  54. print "ERROR: Version $version of mysql-test-run does not exist!\n";
  55. exit(1);
  56. }
  57. }
  58. use lib "lib";
  59. use Cwd;
  60. use Getopt::Long;
  61. use My::File::Path; # Patched version of File::Path
  62. use File::Basename;
  63. use File::Copy;
  64. use File::Find;
  65. use File::Temp qw/tempdir/;
  66. use File::Spec::Functions qw/splitdir/;
  67. use My::Platform;
  68. use My::SafeProcess;
  69. use My::ConfigFactory;
  70. use My::Options;
  71. use My::Find;
  72. use My::SysInfo;
  73. use My::CoreDump;
  74. use mtr_cases;
  75. use mtr_report;
  76. use mtr_match;
  77. use mtr_unique;
  78. use IO::Socket::INET;
  79. use IO::Select;
  80. require "lib/mtr_process.pl";
  81. require "lib/mtr_io.pl";
  82. require "lib/mtr_gcov.pl";
  83. require "lib/mtr_gprof.pl";
  84. require "lib/mtr_misc.pl";
  85. $SIG{INT}= sub { mtr_error("Got ^C signal"); };
  86. our $mysql_version_id;
  87. our $glob_mysql_test_dir;
  88. our $basedir;
  89. our $path_charsetsdir;
  90. our $path_client_bindir;
  91. our $path_client_libdir;
  92. our $path_language;
  93. our $path_current_testlog;
  94. our $path_testlog;
  95. our $default_vardir;
  96. our $opt_vardir; # Path to use for var/ dir
  97. my $path_vardir_trace; # unix formatted opt_vardir for trace files
  98. my $opt_tmpdir; # Path to use for tmp/ dir
  99. my $opt_tmpdir_pid;
  100. my $opt_start;
  101. my $opt_start_dirty;
  102. my $opt_start_exit;
  103. my $start_only;
  104. END {
  105. if ( defined $opt_tmpdir_pid and $opt_tmpdir_pid == $$ )
  106. {
  107. if (!$opt_start_exit)
  108. {
  109. # Remove the tempdir this process has created
  110. mtr_verbose("Removing tmpdir $opt_tmpdir");
  111. rmtree($opt_tmpdir);
  112. }
  113. else
  114. {
  115. mtr_warning("tmpdir $opt_tmpdir should be removed after the server has finished");
  116. }
  117. }
  118. }
  119. sub env_or_val($$) { defined $ENV{$_[0]} ? $ENV{$_[0]} : $_[1] }
  120. my $path_config_file; # The generated config file, var/my.cnf
  121. # Visual Studio produces executables in different sub-directories based on the
  122. # configuration used to build them. To make life easier, an environment
  123. # variable or command-line option may be specified to control which set of
  124. # executables will be used by the test suite.
  125. our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
  126. my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb,innodb,innodb_plugin";
  127. my $opt_suites;
  128. our $opt_verbose= 0; # Verbose output, enable with --verbose
  129. our $exe_mysql;
  130. our $exe_mysqladmin;
  131. our $exe_mysqltest;
  132. our $exe_libtool;
  133. our $opt_big_test= 0;
  134. our @opt_combinations;
  135. our @opt_extra_mysqld_opt;
  136. my $opt_compress;
  137. my $opt_ssl;
  138. my $opt_skip_ssl;
  139. our $opt_ssl_supported;
  140. my $opt_ps_protocol;
  141. my $opt_sp_protocol;
  142. my $opt_cursor_protocol;
  143. my $opt_view_protocol;
  144. our $opt_debug;
  145. our @opt_cases; # The test cases names in argv
  146. our $opt_embedded_server;
  147. # Options used when connecting to an already running server
  148. my %opts_extern;
  149. sub using_extern { return (keys %opts_extern > 0);};
  150. our $opt_fast= 0;
  151. our $opt_force;
  152. our $opt_mem= $ENV{'MTR_MEM'};
  153. our $opt_gcov;
  154. our $opt_gcov_exe= "gcov";
  155. our $opt_gcov_err= "mysql-test-gcov.msg";
  156. our $opt_gcov_msg= "mysql-test-gcov.err";
  157. our $opt_gprof;
  158. our %gprof_dirs;
  159. our $glob_debugger= 0;
  160. our $opt_gdb;
  161. our $opt_client_gdb;
  162. our $opt_ddd;
  163. our $opt_client_ddd;
  164. our $opt_manual_gdb;
  165. our $opt_manual_ddd;
  166. our $opt_manual_debug;
  167. our $opt_debugger;
  168. our $opt_client_debugger;
  169. my $config; # The currently running config
  170. my $current_config_name; # The currently running config file template
  171. our @opt_experimentals;
  172. our $experimental_test_cases= [];
  173. my $baseport;
  174. # $opt_build_thread may later be set from $opt_port_base
  175. my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto";
  176. my $opt_port_base= $ENV{'MTR_PORT_BASE'} || "auto";
  177. my $build_thread= 0;
  178. my $opt_record;
  179. my $opt_report_features;
  180. my $opt_skip_core;
  181. our $opt_check_testcases= 1;
  182. my $opt_mark_progress;
  183. my $opt_max_connections;
  184. my $opt_sleep;
  185. my $opt_testcase_timeout= $ENV{MTR_TESTCASE_TIMEOUT} || 15; # minutes
  186. my $opt_suite_timeout = $ENV{MTR_SUITE_TIMEOUT} || 300; # minutes
  187. my $opt_shutdown_timeout= $ENV{MTR_SHUTDOWN_TIMEOUT} || 10; # seconds
  188. my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds
  189. sub suite_timeout { return $opt_suite_timeout * 60; };
  190. sub check_timeout { return $opt_testcase_timeout * 6; };
  191. my $opt_wait_all;
  192. my $opt_user_args;
  193. my $opt_repeat= 1;
  194. my $opt_retry= 3;
  195. my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2);
  196. my $opt_reorder= 1;
  197. my $opt_force_restart= 0;
  198. my $opt_strace_client;
  199. our $opt_user = "root";
  200. my $opt_valgrind= 0;
  201. my $opt_valgrind_mysqld= 0;
  202. my $opt_valgrind_mysqltest= 0;
  203. my @default_valgrind_args= ("--show-reachable=yes");
  204. my @valgrind_args;
  205. my $opt_valgrind_path;
  206. my $opt_callgrind;
  207. my %mysqld_logs;
  208. my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
  209. sub testcase_timeout ($) {
  210. my ($tinfo)= @_;
  211. if (exists $tinfo->{'case-timeout'}) {
  212. # Return test specific timeout if *longer* that the general timeout
  213. my $test_to= $tinfo->{'case-timeout'};
  214. $test_to*= 10 if $opt_valgrind;
  215. return $test_to * 60 if $test_to > $opt_testcase_timeout;
  216. }
  217. return $opt_testcase_timeout * 60;
  218. }
  219. our $opt_warnings= 1;
  220. our $opt_skip_ndbcluster= 0;
  221. my $exe_ndbd;
  222. my $exe_ndb_mgmd;
  223. my $exe_ndb_waiter;
  224. our $debug_compiled_binaries;
  225. our %mysqld_variables;
  226. my $source_dist= 0;
  227. my $opt_max_save_core= env_or_val(MTR_MAX_SAVE_CORE => 5);
  228. my $opt_max_save_datadir= env_or_val(MTR_MAX_SAVE_DATADIR => 20);
  229. my $opt_max_test_fail= env_or_val(MTR_MAX_TEST_FAIL => 10);
  230. my $opt_parallel= $ENV{MTR_PARALLEL} || 1;
  231. select(STDOUT);
  232. $| = 1; # Automatically flush STDOUT
  233. main();
  234. sub main {
  235. # Default, verbosity on
  236. report_option('verbose', 0);
  237. # This is needed for test log evaluation in "gen-build-status-page"
  238. # in all cases where the calling tool does not log the commands
  239. # directly before it executes them, like "make test-force-pl" in RPM builds.
  240. mtr_report("Logging: $0 ", join(" ", @ARGV));
  241. command_line_setup();
  242. # --help will not reach here, so now it's safe to assume we have binaries
  243. My::SafeProcess::find_bin();
  244. if ( $opt_gcov ) {
  245. gcov_prepare($basedir);
  246. }
  247. if (!$opt_suites) {
  248. $opt_suites= $DEFAULT_SUITES;
  249. # Check for any extra suites to enable based on the path name
  250. my %extra_suites=
  251. (
  252. "mysql-5.1-new-ndb" => "ndb_team",
  253. "mysql-5.1-new-ndb-merge" => "ndb_team",
  254. "mysql-5.1-telco-6.2" => "ndb_team",
  255. "mysql-5.1-telco-6.2-merge" => "ndb_team",
  256. "mysql-5.1-telco-6.3" => "ndb_team",
  257. "mysql-6.0-ndb" => "ndb_team",
  258. );
  259. foreach my $dir ( reverse splitdir($basedir) ) {
  260. my $extra_suite= $extra_suites{$dir};
  261. if (defined $extra_suite) {
  262. mtr_report("Found extra suite: $extra_suite");
  263. $opt_suites= "$extra_suite,$opt_suites";
  264. last;
  265. }
  266. }
  267. }
  268. mtr_report("Collecting tests...");
  269. my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases);
  270. if ( $opt_report_features ) {
  271. # Put "report features" as the first test to run
  272. my $tinfo = My::Test->new
  273. (
  274. name => 'report_features',
  275. # No result_file => Prints result
  276. path => 'include/report-features.test',
  277. template_path => "include/default_my.cnf",
  278. master_opt => [],
  279. slave_opt => [],
  280. );
  281. unshift(@$tests, $tinfo);
  282. }
  283. print "vardir: $opt_vardir\n";
  284. initialize_servers();
  285. #######################################################################
  286. my $num_tests= @$tests;
  287. if ( $opt_parallel eq "auto" ) {
  288. # Try to find a suitable value for number of workers
  289. my $sys_info= My::SysInfo->new();
  290. $opt_parallel= $sys_info->num_cpus();
  291. for my $limit (2000, 1500, 1000, 500){
  292. $opt_parallel-- if ($sys_info->min_bogomips() < $limit);
  293. }
  294. my $max_par= $ENV{MTR_MAX_PARALLEL} || 8;
  295. $opt_parallel= $max_par if ($opt_parallel > $max_par);
  296. $opt_parallel= $num_tests if ($opt_parallel > $num_tests);
  297. $opt_parallel= 1 if (IS_WINDOWS and $sys_info->isvm());
  298. $opt_parallel= 1 if ($opt_parallel < 1);
  299. mtr_report("Using parallel: $opt_parallel");
  300. }
  301. if ($opt_parallel > 1 && $opt_start_exit) {
  302. mtr_warning("Parallel and --start-and-exit cannot be combined\n" .
  303. "Setting parallel to 1");
  304. $opt_parallel= 1;
  305. }
  306. # Create server socket on any free port
  307. my $server = new IO::Socket::INET
  308. (
  309. LocalAddr => 'localhost',
  310. Proto => 'tcp',
  311. Listen => $opt_parallel,
  312. );
  313. mtr_error("Could not create testcase server port: $!") unless $server;
  314. my $server_port = $server->sockport();
  315. mtr_report("Using server port $server_port");
  316. # Create child processes
  317. my %children;
  318. for my $child_num (1..$opt_parallel){
  319. my $child_pid= My::SafeProcess::Base::_safe_fork();
  320. if ($child_pid == 0){
  321. $server= undef; # Close the server port in child
  322. $tests= {}; # Don't need the tests list in child
  323. # Use subdir of var and tmp unless only one worker
  324. if ($opt_parallel > 1) {
  325. set_vardir("$opt_vardir/$child_num");
  326. $opt_tmpdir= "$opt_tmpdir/$child_num";
  327. }
  328. run_worker($server_port, $child_num);
  329. exit(1);
  330. }
  331. $children{$child_pid}= 1;
  332. }
  333. #######################################################################
  334. mtr_report();
  335. mtr_print_thick_line();
  336. mtr_print_header();
  337. my $completed= run_test_server($server, $tests, $opt_parallel);
  338. exit(0) if $opt_start_exit;
  339. # Send Ctrl-C to any children still running
  340. kill("INT", keys(%children));
  341. # Wait for childs to exit
  342. foreach my $pid (keys %children)
  343. {
  344. my $ret_pid= waitpid($pid, 0);
  345. if ($ret_pid != $pid){
  346. mtr_report("Unknown process $ret_pid exited");
  347. }
  348. else {
  349. delete $children{$ret_pid};
  350. }
  351. }
  352. if ( not defined @$completed ) {
  353. mtr_error("Test suite aborted");
  354. }
  355. if ( @$completed != $num_tests){
  356. if ($opt_force){
  357. # All test should have been run, print any that are still in $tests
  358. #foreach my $test ( @$tests ){
  359. # $test->print_test();
  360. #}
  361. }
  362. # Not all tests completed, failure
  363. mtr_report();
  364. mtr_report("Only ", int(@$completed), " of $num_tests completed.");
  365. mtr_error("Not all tests completed");
  366. }
  367. mtr_print_line();
  368. if ( $opt_gcov ) {
  369. gcov_collect($basedir, $opt_gcov_exe,
  370. $opt_gcov_msg, $opt_gcov_err);
  371. }
  372. mtr_report_stats("Completed", $completed);
  373. exit(0);
  374. }
  375. sub run_test_server ($$$) {
  376. my ($server, $tests, $childs) = @_;
  377. my $num_saved_cores= 0; # Number of core files saved in vardir/log/ so far.
  378. my $num_saved_datadir= 0; # Number of datadirs saved in vardir/log/ so far.
  379. my $num_failed_test= 0; # Number of tests failed so far
  380. # Scheduler variables
  381. my $max_ndb= $childs / 2;
  382. $max_ndb = 4 if $max_ndb > 4;
  383. $max_ndb = 1 if $max_ndb < 1;
  384. my $num_ndb_tests= 0;
  385. my $completed= [];
  386. my %running;
  387. my $result;
  388. my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump
  389. my $suite_timeout= start_timer(suite_timeout());
  390. my $s= IO::Select->new();
  391. $s->add($server);
  392. while (1) {
  393. my @ready = $s->can_read(1); # Wake up once every second
  394. foreach my $sock (@ready) {
  395. if ($sock == $server) {
  396. # New client connected
  397. my $child= $sock->accept();
  398. mtr_verbose("Client connected");
  399. $s->add($child);
  400. print $child "HELLO\n";
  401. }
  402. else {
  403. my $line= <$sock>;
  404. if (!defined $line) {
  405. # Client disconnected
  406. mtr_verbose("Child closed socket");
  407. $s->remove($sock);
  408. if (--$childs == 0){
  409. return $completed;
  410. }
  411. next;
  412. }
  413. chomp($line);
  414. if ($line eq 'TESTRESULT'){
  415. $result= My::Test::read_test($sock);
  416. # $result->print_test();
  417. # Report test status
  418. mtr_report_test($result);
  419. if ( $result->is_failed() ) {
  420. # Save the workers "savedir" in var/log
  421. my $worker_savedir= $result->{savedir};
  422. my $worker_savename= basename($worker_savedir);
  423. my $savedir= "$opt_vardir/log/$worker_savename";
  424. if ($opt_max_save_datadir > 0 &&
  425. $num_saved_datadir >= $opt_max_save_datadir)
  426. {
  427. mtr_report(" - skipping '$worker_savedir/'");
  428. rmtree($worker_savedir);
  429. }
  430. else {
  431. mtr_report(" - saving '$worker_savedir/' to '$savedir/'");
  432. rename($worker_savedir, $savedir);
  433. # Move any core files from e.g. mysqltest
  434. foreach my $coref (glob("core*"), glob("*.dmp"))
  435. {
  436. mtr_report(" - found '$coref', moving it to '$savedir'");
  437. move($coref, $savedir);
  438. }
  439. if ($opt_max_save_core > 0) {
  440. # Limit number of core files saved
  441. find({ no_chdir => 1,
  442. wanted => sub {
  443. my $core_file= $File::Find::name;
  444. my $core_name= basename($core_file);
  445. if ($core_name =~ /^core/ or # Starting with core
  446. (IS_WINDOWS and $core_name =~ /\.dmp$/)){
  447. # Ending with .dmp
  448. mtr_report(" - found '$core_name'",
  449. "($num_saved_cores/$opt_max_save_core)");
  450. My::CoreDump->show($core_file, $exe_mysqld);
  451. if ($num_saved_cores >= $opt_max_save_core) {
  452. mtr_report(" - deleting it, already saved",
  453. "$opt_max_save_core");
  454. unlink("$core_file");
  455. }
  456. ++$num_saved_cores;
  457. }
  458. }
  459. },
  460. $savedir);
  461. }
  462. }
  463. $num_saved_datadir++;
  464. $num_failed_test++ unless ($result->{retries} ||
  465. $result->{exp_fail});
  466. if ( !$opt_force ) {
  467. # Test has failed, force is off
  468. push(@$completed, $result);
  469. return $completed;
  470. }
  471. elsif ($opt_max_test_fail > 0 and
  472. $num_failed_test >= $opt_max_test_fail) {
  473. push(@$completed, $result);
  474. mtr_report_stats("Too many failed", $completed, 1);
  475. mtr_report("Too many tests($num_failed_test) failed!",
  476. "Terminating...");
  477. return undef;
  478. }
  479. }
  480. # Retry test run after test failure
  481. my $retries= $result->{retries} || 2;
  482. my $test_has_failed= $result->{failures} || 0;
  483. if ($test_has_failed and $retries <= $opt_retry){
  484. # Test should be run one more time unless it has failed
  485. # too many times already
  486. my $failures= $result->{failures};
  487. if ($opt_retry > 1 and $failures >= $opt_retry_failure){
  488. mtr_report("\nTest has failed $failures times,",
  489. "no more retries!\n");
  490. }
  491. else {
  492. mtr_report("\nRetrying test, attempt($retries/$opt_retry)...\n");
  493. delete($result->{result});
  494. $result->{retries}= $retries+1;
  495. $result->write_test($sock, 'TESTCASE');
  496. next;
  497. }
  498. }
  499. # Repeat test $opt_repeat number of times
  500. my $repeat= $result->{repeat} || 1;
  501. # Don't repeat if test was skipped
  502. if ($repeat < $opt_repeat && $result->{'result'} ne 'MTR_RES_SKIPPED')
  503. {
  504. $result->{retries}= 0;
  505. $result->{rep_failures}++ if $result->{failures};
  506. $result->{failures}= 0;
  507. delete($result->{result});
  508. $result->{repeat}= $repeat+1;
  509. $result->write_test($sock, 'TESTCASE');
  510. next;
  511. }
  512. # Remove from list of running
  513. mtr_error("'", $result->{name},"' is not known to be running")
  514. unless delete $running{$result->key()};
  515. # Update scheduler variables
  516. $num_ndb_tests-- if ($result->{ndb_test});
  517. # Save result in completed list
  518. push(@$completed, $result);
  519. }
  520. elsif ($line eq 'START'){
  521. ; # Send first test
  522. }
  523. else {
  524. mtr_error("Unknown response: '$line' from client");
  525. }
  526. # Find next test to schedule
  527. # - Try to use same configuration as worker used last time
  528. # - Limit number of parallel ndb tests
  529. my $next;
  530. my $second_best;
  531. for(my $i= 0; $i <= @$tests; $i++)
  532. {
  533. my $t= $tests->[$i];
  534. last unless defined $t;
  535. if (run_testcase_check_skip_test($t)){
  536. # Move the test to completed list
  537. #mtr_report("skip - Moving test $i to completed");
  538. push(@$completed, splice(@$tests, $i, 1));
  539. # Since the test at pos $i was taken away, next
  540. # test will also be at $i -> redo
  541. redo;
  542. }
  543. # Limit number of parallell NDB tests
  544. if ($t->{ndb_test} and $num_ndb_tests >= $max_ndb){
  545. #mtr_report("Skipping, num ndb is already at max, $num_ndb_tests");
  546. next;
  547. }
  548. # Prefer same configuration, or just use next if --noreorder
  549. if (!$opt_reorder or (defined $result and
  550. $result->{template_path} eq $t->{template_path}))
  551. {
  552. #mtr_report("Test uses same config => good match");
  553. # Test uses same config => good match
  554. $next= splice(@$tests, $i, 1);
  555. last;
  556. }
  557. # Second best choice is the first that does not fulfill
  558. # any of the above conditions
  559. if (!defined $second_best){
  560. #mtr_report("Setting second_best to $i");
  561. $second_best= $i;
  562. }
  563. }
  564. # Use second best choice if no other test has been found
  565. if (!$next and defined $second_best){
  566. #mtr_report("Take second best choice $second_best");
  567. mtr_error("Internal error, second best too large($second_best)")
  568. if $second_best > $#$tests;
  569. $next= splice(@$tests, $second_best, 1);
  570. }
  571. if ($next) {
  572. #$next->print_test();
  573. $next->write_test($sock, 'TESTCASE');
  574. $running{$next->key()}= $next;
  575. $num_ndb_tests++ if ($next->{ndb_test});
  576. }
  577. else {
  578. # No more test, tell child to exit
  579. #mtr_report("Saying BYE to child");
  580. print $sock "BYE\n";
  581. }
  582. }
  583. }
  584. # ----------------------------------------------------
  585. # Check if test suite timer expired
  586. # ----------------------------------------------------
  587. if ( has_expired($suite_timeout) )
  588. {
  589. mtr_report_stats("Timeout", $completed, 1);
  590. mtr_report("Test suite timeout! Terminating...");
  591. return undef;
  592. }
  593. }
  594. }
  595. sub run_worker ($) {
  596. my ($server_port, $thread_num)= @_;
  597. $SIG{INT}= sub { exit(1); };
  598. # Connect to server
  599. my $server = new IO::Socket::INET
  600. (
  601. PeerAddr => 'localhost',
  602. PeerPort => $server_port,
  603. Proto => 'tcp'
  604. );
  605. mtr_error("Could not connect to server at port $server_port: $!")
  606. unless $server;
  607. # --------------------------------------------------------------------------
  608. # Set worker name
  609. # --------------------------------------------------------------------------
  610. report_option('name',"worker[$thread_num]");
  611. # --------------------------------------------------------------------------
  612. # Set different ports per thread
  613. # --------------------------------------------------------------------------
  614. set_build_thread_ports($thread_num);
  615. # --------------------------------------------------------------------------
  616. # Turn off verbosity in workers, unless explicitly specified
  617. # --------------------------------------------------------------------------
  618. report_option('verbose', undef) if ($opt_verbose == 0);
  619. environment_setup();
  620. # Read hello from server which it will send when shared
  621. # resources have been setup
  622. my $hello= <$server>;
  623. setup_vardir();
  624. check_running_as_root();
  625. if ( using_extern() ) {
  626. create_config_file_for_extern(%opts_extern);
  627. }
  628. # Ask server for first test
  629. print $server "START\n";
  630. while(my $line= <$server>){
  631. chomp($line);
  632. if ($line eq 'TESTCASE'){
  633. my $test= My::Test::read_test($server);
  634. #$test->print_test();
  635. # Clear comment and logfile, to avoid
  636. # reusing them from previous test
  637. delete($test->{'comment'});
  638. delete($test->{'logfile'});
  639. $test->{worker} = $thread_num if $opt_parallel > 1;
  640. run_testcase($test);
  641. #$test->{result}= 'MTR_RES_PASSED';
  642. # Send it back, now with results set
  643. #$test->print_test();
  644. $test->write_test($server, 'TESTRESULT');
  645. }
  646. elsif ($line eq 'BYE'){
  647. mtr_report("Server said BYE");
  648. stop_all_servers($opt_shutdown_timeout);
  649. if ($opt_valgrind_mysqld) {
  650. valgrind_exit_reports();
  651. }
  652. if ( $opt_gprof ) {
  653. gprof_collect (find_mysqld($basedir), keys %gprof_dirs);
  654. }
  655. exit(0);
  656. }
  657. else {
  658. mtr_error("Could not understand server, '$line'");
  659. }
  660. }
  661. stop_all_servers();
  662. exit(1);
  663. }
  664. sub ignore_option {
  665. my ($opt, $value)= @_;
  666. mtr_report("Ignoring option '$opt'");
  667. }
  668. # Setup any paths that are $opt_vardir related
  669. sub set_vardir {
  670. my ($vardir)= @_;
  671. $opt_vardir= $vardir;
  672. $path_vardir_trace= $opt_vardir;
  673. # Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/...
  674. $path_vardir_trace=~ s/^\w://;
  675. # Location of my.cnf that all clients use
  676. $path_config_file= "$opt_vardir/my.cnf";
  677. $path_testlog= "$opt_vardir/log/mysqltest.log";
  678. $path_current_testlog= "$opt_vardir/log/current_test";
  679. }
  680. sub command_line_setup {
  681. my $opt_comment;
  682. my $opt_usage;
  683. my $opt_list_options;
  684. # Read the command line options
  685. # Note: Keep list, and the order, in sync with usage at end of this file
  686. Getopt::Long::Configure("pass_through");
  687. my %options=(
  688. # Control what engine/variation to run
  689. 'embedded-server' => \$opt_embedded_server,
  690. 'ps-protocol' => \$opt_ps_protocol,
  691. 'sp-protocol' => \$opt_sp_protocol,
  692. 'view-protocol' => \$opt_view_protocol,
  693. 'cursor-protocol' => \$opt_cursor_protocol,
  694. 'ssl|with-openssl' => \$opt_ssl,
  695. 'skip-ssl' => \$opt_skip_ssl,
  696. 'compress' => \$opt_compress,
  697. 'vs-config' => \$opt_vs_config,
  698. # Max number of parallel threads to use
  699. 'parallel=s' => \$opt_parallel,
  700. # Config file to use as template for all tests
  701. 'defaults-file=s' => \&collect_option,
  702. # Extra config file to append to all generated configs
  703. 'defaults-extra-file=s' => \&collect_option,
  704. # Control what test suites or cases to run
  705. 'force' => \$opt_force,
  706. 'with-ndbcluster-only' => \&collect_option,
  707. 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster,
  708. 'suite|suites=s' => \$opt_suites,
  709. 'skip-rpl' => \&collect_option,
  710. 'skip-test=s' => \&collect_option,
  711. 'do-test=s' => \&collect_option,
  712. 'start-from=s' => \&collect_option,
  713. 'big-test' => \$opt_big_test,
  714. 'combination=s' => \@opt_combinations,
  715. 'skip-combinations' => \&collect_option,
  716. 'experimental=s' => \@opt_experimentals,
  717. 'skip-im' => \&ignore_option,
  718. # Specify ports
  719. 'build-thread|mtr-build-thread=i' => \$opt_build_thread,
  720. 'port-base|mtr-port-base=i' => \$opt_port_base,
  721. # Test case authoring
  722. 'record' => \$opt_record,
  723. 'check-testcases!' => \$opt_check_testcases,
  724. 'mark-progress' => \$opt_mark_progress,
  725. # Extra options used when starting mysqld
  726. 'mysqld=s' => \@opt_extra_mysqld_opt,
  727. # Run test on running server
  728. 'extern=s' => \%opts_extern, # Append to hash
  729. # Debugging
  730. 'debug' => \$opt_debug,
  731. 'gdb' => \$opt_gdb,
  732. 'client-gdb' => \$opt_client_gdb,
  733. 'manual-gdb' => \$opt_manual_gdb,
  734. 'manual-debug' => \$opt_manual_debug,
  735. 'ddd' => \$opt_ddd,
  736. 'client-ddd' => \$opt_client_ddd,
  737. 'manual-ddd' => \$opt_manual_ddd,
  738. 'debugger=s' => \$opt_debugger,
  739. 'client-debugger=s' => \$opt_client_debugger,
  740. 'strace-client:s' => \$opt_strace_client,
  741. 'max-save-core=i' => \$opt_max_save_core,
  742. 'max-save-datadir=i' => \$opt_max_save_datadir,
  743. 'max-test-fail=i' => \$opt_max_test_fail,
  744. # Coverage, profiling etc
  745. 'gcov' => \$opt_gcov,
  746. 'gprof' => \$opt_gprof,
  747. 'valgrind|valgrind-all' => \$opt_valgrind,
  748. 'valgrind-mysqltest' => \$opt_valgrind_mysqltest,
  749. 'valgrind-mysqld' => \$opt_valgrind_mysqld,
  750. 'valgrind-options=s' => sub {
  751. my ($opt, $value)= @_;
  752. # Deprecated option unless it's what we know pushbuild uses
  753. if ($value eq "--gen-suppressions=all --show-reachable=yes") {
  754. push(@valgrind_args, $_) for (split(' ', $value));
  755. return;
  756. }
  757. die("--valgrind-options=s is deprecated. Use ",
  758. "--valgrind-option=s, to be specified several",
  759. " times if necessary");
  760. },
  761. 'valgrind-option=s' => \@valgrind_args,
  762. 'valgrind-path=s' => \$opt_valgrind_path,
  763. 'callgrind' => \$opt_callgrind,
  764. 'debug-sync-timeout=i' => \$opt_debug_sync_timeout,
  765. # Directories
  766. 'tmpdir=s' => \$opt_tmpdir,
  767. 'vardir=s' => \$opt_vardir,
  768. 'mem' => \$opt_mem,
  769. 'client-bindir=s' => \$path_client_bindir,
  770. 'client-libdir=s' => \$path_client_libdir,
  771. # Misc
  772. 'report-features' => \$opt_report_features,
  773. 'comment=s' => \$opt_comment,
  774. 'fast' => \$opt_fast,
  775. 'force-restart' => \$opt_force_restart,
  776. 'reorder!' => \$opt_reorder,
  777. 'enable-disabled' => \&collect_option,
  778. 'verbose+' => \$opt_verbose,
  779. 'verbose-restart' => \&report_option,
  780. 'sleep=i' => \$opt_sleep,
  781. 'start-dirty' => \$opt_start_dirty,
  782. 'start-and-exit' => \$opt_start_exit,
  783. 'start' => \$opt_start,
  784. 'user-args' => \$opt_user_args,
  785. 'wait-all' => \$opt_wait_all,
  786. 'print-testcases' => \&collect_option,
  787. 'repeat=i' => \$opt_repeat,
  788. 'retry=i' => \$opt_retry,
  789. 'retry-failure=i' => \$opt_retry_failure,
  790. 'timer!' => \&report_option,
  791. 'user=s' => \$opt_user,
  792. 'testcase-timeout=i' => \$opt_testcase_timeout,
  793. 'suite-timeout=i' => \$opt_suite_timeout,
  794. 'shutdown-timeout=i' => \$opt_shutdown_timeout,
  795. 'warnings!' => \$opt_warnings,
  796. 'timestamp' => \&report_option,
  797. 'timediff' => \&report_option,
  798. 'max-connections=i' => \$opt_max_connections,
  799. 'help|h' => \$opt_usage,
  800. 'list-options' => \$opt_list_options,
  801. );
  802. GetOptions(%options) or usage("Can't read options");
  803. usage("") if $opt_usage;
  804. list_options(\%options) if $opt_list_options;
  805. # --------------------------------------------------------------------------
  806. # Setup verbosity
  807. # --------------------------------------------------------------------------
  808. if ($opt_verbose != 0){
  809. report_option('verbose', $opt_verbose);
  810. }
  811. if ( -d "../sql" )
  812. {
  813. $source_dist= 1;
  814. }
  815. # Find the absolute path to the test directory
  816. $glob_mysql_test_dir= cwd();
  817. if ($glob_mysql_test_dir =~ / /)
  818. {
  819. die("Working directory \"$glob_mysql_test_dir\" contains space\n".
  820. "Bailing out, cannot function properly with space in path");
  821. }
  822. if (IS_CYGWIN)
  823. {
  824. # Use mixed path format i.e c:/path/to/
  825. $glob_mysql_test_dir= mixed_path($glob_mysql_test_dir);
  826. }
  827. # In most cases, the base directory we find everything relative to,
  828. # is the parent directory of the "mysql-test" directory. For source
  829. # distributions, TAR binary distributions and some other packages.
  830. $basedir= dirname($glob_mysql_test_dir);
  831. # In the RPM case, binaries and libraries are installed in the
  832. # default system locations, instead of having our own private base
  833. # directory. And we install "/usr/share/mysql-test". Moving up one
  834. # more directory relative to "mysql-test" gives us a usable base
  835. # directory for RPM installs.
  836. if ( ! $source_dist and ! -d "$basedir/bin" )
  837. {
  838. $basedir= dirname($basedir);
  839. }
  840. # Look for the client binaries directory
  841. if ($path_client_bindir)
  842. {
  843. # --client-bindir=path set on command line, check that the path exists
  844. $path_client_bindir= mtr_path_exists($path_client_bindir);
  845. }
  846. else
  847. {
  848. $path_client_bindir= mtr_path_exists("$basedir/client_release",
  849. "$basedir/client_debug",
  850. vs_config_dirs('client', ''),
  851. "$basedir/client",
  852. "$basedir/bin");
  853. }
  854. # Look for language files and charsetsdir, use same share
  855. $path_language= mtr_path_exists("$basedir/share/mysql/english",
  856. "$basedir/sql/share/english",
  857. "$basedir/share/english");
  858. my $path_share= dirname($path_language);
  859. $path_charsetsdir= mtr_path_exists("$path_share/charsets");
  860. if (using_extern())
  861. {
  862. # Connect to the running mysqld and find out what it supports
  863. collect_mysqld_features_from_running_server();
  864. }
  865. else
  866. {
  867. # Run the mysqld to find out what features are available
  868. collect_mysqld_features();
  869. }
  870. if ( $opt_comment )
  871. {
  872. mtr_report();
  873. mtr_print_thick_line('#');
  874. mtr_report("# $opt_comment");
  875. mtr_print_thick_line('#');
  876. }
  877. if ( @opt_experimentals )
  878. {
  879. # $^O on Windows considered not generic enough
  880. my $plat= (IS_WINDOWS) ? 'windows' : $^O;
  881. # read the list of experimental test cases from the files specified on
  882. # the command line
  883. $experimental_test_cases = [];
  884. foreach my $exp_file (@opt_experimentals)
  885. {
  886. open(FILE, "<", $exp_file)
  887. or mtr_error("Can't read experimental file: $exp_file");
  888. mtr_report("Using experimental file: $exp_file");
  889. while(<FILE>) {
  890. chomp;
  891. # remove comments (# foo) at the beginning of the line, or after a
  892. # blank at the end of the line
  893. s/( +|^)#.*$//;
  894. # If @ platform specifier given, use this entry only if it contains
  895. # @<platform> or @!<xxx> where xxx != platform
  896. if (/\@.*/)
  897. {
  898. next if (/\@!$plat/);
  899. next unless (/\@$plat/ or /\@!/);
  900. # Then remove @ and everything after it
  901. s/\@.*$//;
  902. }
  903. # remove whitespace
  904. s/^ +//;
  905. s/ +$//;
  906. # if nothing left, don't need to remember this line
  907. if ( $_ eq "" ) {
  908. next;
  909. }
  910. # remember what is left as the name of another test case that should be
  911. # treated as experimental
  912. print " - $_\n";
  913. push @$experimental_test_cases, $_;
  914. }
  915. close FILE;
  916. }
  917. }
  918. foreach my $arg ( @ARGV )
  919. {
  920. if ( $arg =~ /^--skip-/ )
  921. {
  922. push(@opt_extra_mysqld_opt, $arg);
  923. }
  924. elsif ( $arg =~ /^--$/ )
  925. {
  926. # It is an effect of setting 'pass_through' in option processing
  927. # that the lone '--' separating options from arguments survives,
  928. # simply ignore it.
  929. }
  930. elsif ( $arg =~ /^-/ )
  931. {
  932. usage("Invalid option \"$arg\"");
  933. }
  934. else
  935. {
  936. push(@opt_cases, $arg);
  937. }
  938. }
  939. # --------------------------------------------------------------------------
  940. # Find out type of logging that are being used
  941. # --------------------------------------------------------------------------
  942. foreach my $arg ( @opt_extra_mysqld_opt )
  943. {
  944. if ( $arg =~ /binlog[-_]format=(\S+)/ )
  945. {
  946. # Save this for collect phase
  947. collect_option('binlog-format', $1);
  948. mtr_report("Using binlog format '$1'");
  949. }
  950. }
  951. # --------------------------------------------------------------------------
  952. # Find out default storage engine being used(if any)
  953. # --------------------------------------------------------------------------
  954. foreach my $arg ( @opt_extra_mysqld_opt )
  955. {
  956. if ( $arg =~ /default-storage-engine=(\S+)/ )
  957. {
  958. # Save this for collect phase
  959. collect_option('default-storage-engine', $1);
  960. mtr_report("Using default engine '$1'")
  961. }
  962. }
  963. if (IS_WINDOWS and defined $opt_mem) {
  964. mtr_report("--mem not supported on Windows, ignored");
  965. $opt_mem= undef;
  966. }
  967. if ($opt_port_base ne "auto")
  968. {
  969. if (my $rem= $opt_port_base % 10)
  970. {
  971. mtr_warning ("Port base $opt_port_base rounded down to multiple of 10");
  972. $opt_port_base-= $rem;
  973. }
  974. $opt_build_thread= $opt_port_base / 10 - 1000;
  975. }
  976. # --------------------------------------------------------------------------
  977. # Check if we should speed up tests by trying to run on tmpfs
  978. # --------------------------------------------------------------------------
  979. if ( defined $opt_mem)
  980. {
  981. mtr_error("Can't use --mem and --vardir at the same time ")
  982. if $opt_vardir;
  983. mtr_error("Can't use --mem and --tmpdir at the same time ")
  984. if $opt_tmpdir;
  985. # Search through list of locations that are known
  986. # to be "fast disks" to find a suitable location
  987. # Use --mem=<dir> as first location to look.
  988. my @tmpfs_locations= ($opt_mem, "/dev/shm", "/tmp");
  989. foreach my $fs (@tmpfs_locations)
  990. {
  991. if ( -d $fs )
  992. {
  993. my $template= "var_${opt_build_thread}_XXXX";
  994. $opt_mem= tempdir( $template, DIR => $fs, CLEANUP => 0);
  995. last;
  996. }
  997. }
  998. }
  999. # --------------------------------------------------------------------------
  1000. # Set the "var/" directory, the base for everything else
  1001. # --------------------------------------------------------------------------
  1002. $default_vardir= "$glob_mysql_test_dir/var";
  1003. if ( ! $opt_vardir )
  1004. {
  1005. $opt_vardir= $default_vardir;
  1006. }
  1007. # We make the path absolute, as the server will do a chdir() before usage
  1008. unless ( $opt_vardir =~ m,^/, or
  1009. (IS_WINDOWS and $opt_vardir =~ m,^[a-z]:/,i) )
  1010. {
  1011. # Make absolute path, relative test dir
  1012. $opt_vardir= "$glob_mysql_test_dir/$opt_vardir";
  1013. }
  1014. set_vardir($opt_vardir);
  1015. # --------------------------------------------------------------------------
  1016. # Set the "tmp" directory
  1017. # --------------------------------------------------------------------------
  1018. if ( ! $opt_tmpdir )
  1019. {
  1020. $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir;
  1021. if (check_socket_path_length("$opt_tmpdir/mysql_testsocket.sock"))
  1022. {
  1023. mtr_report("Too long tmpdir path '$opt_tmpdir'",
  1024. " creating a shorter one...");
  1025. # Create temporary directory in standard location for temporary files
  1026. $opt_tmpdir= tempdir( TMPDIR => 1, CLEANUP => 0 );
  1027. mtr_report(" - using tmpdir: '$opt_tmpdir'\n");
  1028. # Remember pid that created dir so it's removed by correct process
  1029. $opt_tmpdir_pid= $$;
  1030. }
  1031. }
  1032. $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any
  1033. # --------------------------------------------------------------------------
  1034. # fast option
  1035. # --------------------------------------------------------------------------
  1036. if ($opt_fast){
  1037. $opt_shutdown_timeout= 0; # Kill processes instead of nice shutdown
  1038. }
  1039. # --------------------------------------------------------------------------
  1040. # Check parallel value
  1041. # --------------------------------------------------------------------------
  1042. if ($opt_parallel ne "auto" && $opt_parallel < 1)
  1043. {
  1044. mtr_error("0 or negative parallel value makes no sense, use 'auto' or positive number");
  1045. }
  1046. # --------------------------------------------------------------------------
  1047. # Record flag
  1048. # --------------------------------------------------------------------------
  1049. if ( $opt_record and ! @opt_cases )
  1050. {
  1051. mtr_error("Will not run in record mode without a specific test case");
  1052. }
  1053. if ( $opt_record ) {
  1054. # Use only one worker with --record
  1055. $opt_parallel= 1;
  1056. }
  1057. # --------------------------------------------------------------------------
  1058. # Embedded server flag
  1059. # --------------------------------------------------------------------------
  1060. if ( $opt_embedded_server )
  1061. {
  1062. if ( IS_WINDOWS )
  1063. {
  1064. # Add the location for libmysqld.dll to the path.
  1065. my $separator= ";";
  1066. my $lib_mysqld=
  1067. mtr_path_exists(vs_config_dirs('libmysqld',''));
  1068. if ( IS_CYGWIN )
  1069. {
  1070. $lib_mysqld= posix_path($lib_mysqld);
  1071. $separator= ":";
  1072. }
  1073. $ENV{'PATH'}= "$ENV{'PATH'}".$separator.$lib_mysqld;
  1074. }
  1075. $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster
  1076. $opt_skip_ssl= 1; # Turn off use of SSL
  1077. # Turn off use of bin log
  1078. push(@opt_extra_mysqld_opt, "--skip-log-bin");
  1079. if ( using_extern() )
  1080. {
  1081. mtr_error("Can't use --extern with --embedded-server");
  1082. }
  1083. if ($opt_gdb)
  1084. {
  1085. mtr_warning("Silently converting --gdb to --client-gdb in embedded mode");
  1086. $opt_client_gdb= $opt_gdb;
  1087. $opt_gdb= undef;
  1088. }
  1089. if ($opt_ddd)
  1090. {
  1091. mtr_warning("Silently converting --ddd to --client-ddd in embedded mode");
  1092. $opt_client_ddd= $opt_ddd;
  1093. $opt_ddd= undef;
  1094. }
  1095. if ($opt_debugger)
  1096. {
  1097. mtr_warning("Silently converting --debugger to --client-debugger in embedded mode");
  1098. $opt_client_debugger= $opt_debugger;
  1099. $opt_debugger= undef;
  1100. }
  1101. if ( $opt_gdb || $opt_ddd || $opt_manual_gdb || $opt_manual_ddd ||
  1102. $opt_manual_debug || $opt_debugger )
  1103. {
  1104. mtr_error("You need to use the client debug options for the",
  1105. "embedded server. Ex: --client-gdb");
  1106. }
  1107. }
  1108. # --------------------------------------------------------------------------
  1109. # Big test flags
  1110. # --------------------------------------------------------------------------
  1111. if ( $opt_big_test )
  1112. {
  1113. $ENV{'BIG_TEST'}= 1;
  1114. }
  1115. # --------------------------------------------------------------------------
  1116. # Gcov flag
  1117. # --------------------------------------------------------------------------
  1118. if ( ($opt_gcov or $opt_gprof) and ! $source_dist )
  1119. {
  1120. mtr_error("Coverage test needs the source - please use source dist");
  1121. }
  1122. # --------------------------------------------------------------------------
  1123. # Check debug related options
  1124. # --------------------------------------------------------------------------
  1125. if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd ||
  1126. $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug ||
  1127. $opt_debugger || $opt_client_debugger )
  1128. {
  1129. # Indicate that we are using debugger
  1130. $glob_debugger= 1;
  1131. if ( using_extern() )
  1132. {
  1133. mtr_error("Can't use --extern when using debugger");
  1134. }
  1135. # Set one week timeout (check-testcase timeout will be 1/10th)
  1136. $opt_testcase_timeout= 7 * 24 * 60;
  1137. $opt_suite_timeout= 7 * 24 * 60;
  1138. # One day to shutdown
  1139. $opt_shutdown_timeout= 24 * 60;
  1140. # One day for PID file creation (this is given in seconds not minutes)
  1141. $opt_start_timeout= 24 * 60 * 60;
  1142. }
  1143. # --------------------------------------------------------------------------
  1144. # Modified behavior with --start options
  1145. # --------------------------------------------------------------------------
  1146. if ($opt_start or $opt_start_dirty or $opt_start_exit) {
  1147. collect_option ('quick-collect', 1);
  1148. $start_only= 1;
  1149. }
  1150. # --------------------------------------------------------------------------
  1151. # Check use of user-args
  1152. # --------------------------------------------------------------------------
  1153. if ($opt_user_args) {
  1154. mtr_error("--user-args only valid with --start options")
  1155. unless $start_only;
  1156. mtr_error("--user-args cannot be combined with named suites or tests")
  1157. if $opt_suites || @opt_cases;
  1158. }
  1159. # --------------------------------------------------------------------------
  1160. # Check use of wait-all
  1161. # --------------------------------------------------------------------------
  1162. if ($opt_wait_all && ! $start_only)
  1163. {
  1164. mtr_error("--wait-all can only be used with --start options");
  1165. }
  1166. # --------------------------------------------------------------------------
  1167. # Check timeout arguments
  1168. # --------------------------------------------------------------------------
  1169. mtr_error("Invalid value '$opt_testcase_timeout' supplied ".
  1170. "for option --testcase-timeout")
  1171. if ($opt_testcase_timeout <= 0);
  1172. mtr_error("Invalid value '$opt_suite_timeout' supplied ".
  1173. "for option --testsuite-timeout")
  1174. if ($opt_suite_timeout <= 0);
  1175. # --------------------------------------------------------------------------
  1176. # Check valgrind arguments
  1177. # --------------------------------------------------------------------------
  1178. if ( $opt_valgrind or $opt_valgrind_path or @valgrind_args)
  1179. {
  1180. mtr_report("Turning on valgrind for all executables");
  1181. $opt_valgrind= 1;
  1182. $opt_valgrind_mysqld= 1;
  1183. $opt_valgrind_mysqltest= 1;
  1184. # Increase the timeouts when running with valgrind
  1185. $opt_testcase_timeout*= 10;
  1186. $opt_suite_timeout*= 6;
  1187. $opt_start_timeout*= 10;
  1188. }
  1189. elsif ( $opt_valgrind_mysqld )
  1190. {
  1191. mtr_report("Turning on valgrind for mysqld(s) only");
  1192. $opt_valgrind= 1;
  1193. }
  1194. elsif ( $opt_valgrind_mysqltest )
  1195. {
  1196. mtr_report("Turning on valgrind for mysqltest and mysql_client_test only");
  1197. $opt_valgrind= 1;
  1198. }
  1199. if ( $opt_callgrind )
  1200. {
  1201. mtr_report("Turning on valgrind with callgrind for mysqld(s)");
  1202. $opt_valgrind= 1;
  1203. $opt_valgrind_mysqld= 1;
  1204. # Set special valgrind options unless options passed on command line
  1205. push(@valgrind_args, "--trace-children=yes")
  1206. unless @valgrind_args;
  1207. }
  1208. if ( $opt_valgrind )
  1209. {
  1210. # Set valgrind_options to default unless already defined
  1211. push(@valgrind_args, @default_valgrind_args)
  1212. unless @valgrind_args;
  1213. # Don't add --quiet; you will loose the summary reports.
  1214. mtr_report("Running valgrind with options \"",
  1215. join(" ", @valgrind_args), "\"");
  1216. }
  1217. mtr_report("Checking supported features...");
  1218. check_ndbcluster_support(\%mysqld_variables);
  1219. check_ssl_support(\%mysqld_variables);
  1220. check_debug_support(\%mysqld_variables);
  1221. executable_setup();
  1222. }
  1223. #
  1224. # To make it easier for different devs to work on the same host,
  1225. # an environment variable can be used to control all ports. A small
  1226. # number is to be used, 0 - 16 or similar.
  1227. #
  1228. # Note the MASTER_MYPORT has to be set the same in all 4.x and 5.x
  1229. # versions of this script, else a 4.0 test run might conflict with a
  1230. # 5.1 test run, even if different MTR_BUILD_THREAD is used. This means
  1231. # all port numbers might not be used in this version of the script.
  1232. #
  1233. # Also note the limitation of ports we are allowed to hand out. This
  1234. # differs between operating systems and configuration, see
  1235. # http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html
  1236. # But a fairly safe range seems to be 5001 - 32767
  1237. #
  1238. sub set_build_thread_ports($) {
  1239. my $thread= shift || 0;
  1240. if ( lc($opt_build_thread) eq 'auto' ) {
  1241. my $found_free = 0;
  1242. $build_thread = 300; # Start attempts from here
  1243. while (! $found_free)
  1244. {
  1245. $build_thread= mtr_get_unique_id($build_thread, 349);
  1246. if ( !defined $build_thread ) {
  1247. mtr_error("Could not get a unique build thread id");
  1248. }
  1249. $found_free= check_ports_free($build_thread);
  1250. # If not free, release and try from next number
  1251. if (! $found_free) {
  1252. mtr_release_unique_id();
  1253. $build_thread++;
  1254. }
  1255. }
  1256. }
  1257. else
  1258. {
  1259. $build_thread = $opt_build_thread + $thread - 1;
  1260. if (! check_ports_free($build_thread)) {
  1261. # Some port was not free(which one has already been printed)
  1262. mtr_error("Some port(s) was not free")
  1263. }
  1264. }
  1265. $ENV{MTR_BUILD_THREAD}= $build_thread;
  1266. # Calculate baseport
  1267. $baseport= $build_thread * 10 + 10000;
  1268. if ( $baseport < 5001 or $baseport + 9 >= 32767 )
  1269. {
  1270. mtr_error("MTR_BUILD_THREAD number results in a port",
  1271. "outside 5001 - 32767",
  1272. "($baseport - $baseport + 9)");
  1273. }
  1274. mtr_report("Using MTR_BUILD_THREAD $build_thread,",
  1275. "with reserved ports $baseport..".($baseport+9));
  1276. }
  1277. sub collect_mysqld_features {
  1278. my $found_variable_list_start= 0;
  1279. my $use_tmpdir;
  1280. if ( defined $opt_tmpdir and -d $opt_tmpdir){
  1281. # Create the tempdir in $opt_tmpdir
  1282. $use_tmpdir= $opt_tmpdir;
  1283. }
  1284. my $tmpdir= tempdir(CLEANUP => 0, # Directory removed by this function
  1285. DIR => $use_tmpdir);
  1286. #
  1287. # Execute "mysqld --no-defaults --help --verbose" to get a
  1288. # list of all features and settings
  1289. #
  1290. # --no-defaults and --skip-grant-tables are to avoid loading
  1291. # system-wide configs and plugins
  1292. #
  1293. # --datadir must exist, mysqld will chdir into it
  1294. #
  1295. my $args;
  1296. mtr_init_args(\$args);
  1297. mtr_add_arg($args, "--no-defaults");
  1298. mtr_add_arg($args, "--datadir=%s", mixed_path($tmpdir));
  1299. mtr_add_arg($args, "--language=%s", $path_language);
  1300. mtr_add_arg($args, "--skip-grant-tables");
  1301. mtr_add_arg($args, "--verbose");
  1302. mtr_add_arg($args, "--help");
  1303. # Need --user=root if running as *nix root user
  1304. if (!IS_WINDOWS and $> == 0)
  1305. {
  1306. mtr_add_arg($args, "--user=root");
  1307. }
  1308. my $exe_mysqld= find_mysqld($basedir);
  1309. my $cmd= join(" ", $exe_mysqld, @$args);
  1310. my $list= `$cmd`;
  1311. foreach my $line (split('\n', $list))
  1312. {
  1313. # First look for version
  1314. if ( !$mysql_version_id )
  1315. {
  1316. # Look for version
  1317. my $exe_name= basename($exe_mysqld);
  1318. mtr_verbose("exe_name: $exe_name");
  1319. if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ )
  1320. {
  1321. #print "Major: $1 Minor: $2 Build: $3\n";
  1322. $mysql_version_id= $1*10000 + $2*100 + $3;
  1323. #print "mysql_version_id: $mysql_version_id\n";
  1324. mtr_report("MySQL Version $1.$2.$3");
  1325. }
  1326. }
  1327. else
  1328. {
  1329. if (!$found_variable_list_start)
  1330. {
  1331. # Look for start of variables list
  1332. if ( $line =~ /[\-]+\s[\-]+/ )
  1333. {
  1334. $found_variable_list_start= 1;
  1335. }
  1336. }
  1337. else
  1338. {
  1339. # Put variables into hash
  1340. if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
  1341. {
  1342. # print "$1=\"$2\"\n";
  1343. $mysqld_variables{$1}= $2;
  1344. }
  1345. else
  1346. {
  1347. # The variable list is ended with a blank line
  1348. if ( $line =~ /^[\s]*$/ )
  1349. {
  1350. last;
  1351. }
  1352. else
  1353. {
  1354. # Send out a warning, we should fix the variables that has no
  1355. # space between variable name and it's value
  1356. # or should it be fixed width column parsing? It does not
  1357. # look like that in function my_print_variables in my_getopt.c
  1358. mtr_warning("Could not parse variable list line : $line");
  1359. }
  1360. }
  1361. }
  1362. }
  1363. }
  1364. rmtree($tmpdir);
  1365. mtr_error("Could not find version of MySQL") unless $mysql_version_id;
  1366. mtr_error("Could not find variabes list") unless $found_variable_list_start;
  1367. }
  1368. sub collect_mysqld_features_from_running_server ()
  1369. {
  1370. my $mysql= mtr_exe_exists("$path_client_bindir/mysql");
  1371. my $args;
  1372. mtr_init_args(\$args);
  1373. mtr_add_arg($args, "--no-defaults");
  1374. mtr_add_arg($args, "--user=%s", $opt_user);
  1375. while (my ($option, $value)= each( %opts_extern )) {
  1376. mtr_add_arg($args, "--$option=$value");
  1377. }
  1378. mtr_add_arg($args, "--silent"); # Tab separated output
  1379. mtr_add_arg($args, "-e '%s'", "use mysql; SHOW VARIABLES");
  1380. my $cmd= "$mysql " . join(' ', @$args);
  1381. mtr_verbose("cmd: $cmd");
  1382. my $list = `$cmd` or
  1383. mtr_error("Could not connect to extern server using command: '$cmd'");
  1384. foreach my $line (split('\n', $list ))
  1385. {
  1386. # Put variables into hash
  1387. if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
  1388. {
  1389. # print "$1=\"$2\"\n";
  1390. $mysqld_variables{$1}= $2;
  1391. }
  1392. }
  1393. # "Convert" innodb flag
  1394. $mysqld_variables{'innodb'}= "ON"
  1395. if ($mysqld_variables{'have_innodb'} eq "YES");
  1396. # Parse version
  1397. my $version_str= $mysqld_variables{'version'};
  1398. if ( $version_str =~ /^([0-9]*)\.([0-9]*)\.([0-9]*)/ )
  1399. {
  1400. #print "Major: $1 Minor: $2 Build: $3\n";
  1401. $mysql_version_id= $1*10000 + $2*100 + $3;
  1402. #print "mysql_version_id: $mysql_version_id\n";
  1403. mtr_report("MySQL Version $1.$2.$3");
  1404. }
  1405. mtr_error("Could not find version of MySQL") unless $mysql_version_id;
  1406. }
  1407. sub find_mysqld {
  1408. my ($mysqld_basedir)= @_;
  1409. my @mysqld_names= ("mysqld", "mysqld-max-nt", "mysqld-max",
  1410. "mysqld-nt");
  1411. if ( $opt_debug ){
  1412. # Put mysqld-debug first in the list of binaries to look for
  1413. mtr_verbose("Adding mysqld-debug first in list of binaries to look for");
  1414. unshift(@mysqld_names, "mysqld-debug");
  1415. }
  1416. return my_find_bin($mysqld_basedir,
  1417. ["sql", "libexec", "sbin", "bin"],
  1418. [@mysqld_names]);
  1419. }
  1420. sub executable_setup () {
  1421. #
  1422. # Check if libtool is available in this distribution/clone
  1423. # we need it when valgrinding or debugging non installed binary
  1424. # Otherwise valgrind will valgrind the libtool wrapper or bash
  1425. # and gdb will not find the real executable to debug
  1426. #
  1427. if ( -x "../libtool")
  1428. {
  1429. $exe_libtool= "../libtool";
  1430. if ($opt_valgrind or $glob_debugger)
  1431. {
  1432. mtr_report("Using \"$exe_libtool\" when running valgrind or debugger");
  1433. }
  1434. }
  1435. # Look for the client binaries
  1436. $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
  1437. $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
  1438. if ( ! $opt_skip_ndbcluster )
  1439. {
  1440. $exe_ndbd=
  1441. my_find_bin($basedir,
  1442. ["storage/ndb/src/kernel", "libexec", "sbin", "bin"],
  1443. "ndbd");
  1444. $exe_ndb_mgmd=
  1445. my_find_bin($basedir,
  1446. ["storage/ndb/src/mgmsrv", "libexec", "sbin", "bin"],
  1447. "ndb_mgmd");
  1448. $exe_ndb_waiter=
  1449. my_find_bin($basedir,
  1450. ["storage/ndb/tools/", "bin"],
  1451. "ndb_waiter");
  1452. }
  1453. # Look for mysqltest executable
  1454. if ( $opt_embedded_server )
  1455. {
  1456. $exe_mysqltest=
  1457. mtr_exe_exists(vs_config_dirs('libmysqld/examples','mysqltest_embedded'),
  1458. "$basedir/libmysqld/examples/mysqltest_embedded",
  1459. "$path_client_bindir/mysqltest_embedded");
  1460. }
  1461. else
  1462. {
  1463. $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
  1464. }
  1465. }
  1466. sub client_debug_arg($$) {
  1467. my ($args, $client_name)= @_;
  1468. if ( $opt_debug ) {
  1469. mtr_add_arg($args,
  1470. "--debug=d:t:A,%s/log/%s.trace",
  1471. $path_vardir_trace, $client_name)
  1472. }
  1473. }
  1474. sub mysql_fix_arguments () {
  1475. return "" if ( IS_WINDOWS );
  1476. my $exe=
  1477. mtr_script_exists("$basedir/scripts/mysql_fix_privilege_tables",
  1478. "$path_client_bindir/mysql_fix_privilege_tables");
  1479. my $args;
  1480. mtr_init_args(\$args);
  1481. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1482. mtr_add_arg($args, "--basedir=%s", $basedir);
  1483. mtr_add_arg($args, "--bindir=%s", $path_client_bindir);
  1484. mtr_add_arg($args, "--verbose");
  1485. return mtr_args2str($exe, @$args);
  1486. }
  1487. sub client_arguments ($;$) {
  1488. my $client_name= shift;
  1489. my $group_suffix= shift;
  1490. my $client_exe= mtr_exe_exists("$path_client_bindir/$client_name");
  1491. my $args;
  1492. mtr_init_args(\$args);
  1493. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1494. if (defined($group_suffix)) {
  1495. mtr_add_arg($args, "--defaults-group-suffix=%s", $group_suffix);
  1496. client_debug_arg($args, "$client_name-$group_suffix");
  1497. }
  1498. else
  1499. {
  1500. client_debug_arg($args, $client_name);
  1501. }
  1502. return mtr_args2str($client_exe, @$args);
  1503. }
  1504. sub mysqlslap_arguments () {
  1505. my $exe= mtr_exe_maybe_exists("$path_client_bindir/mysqlslap");
  1506. if ( $exe eq "" ) {
  1507. # mysqlap was not found
  1508. if (defined $mysql_version_id and $mysql_version_id >= 50100 ) {
  1509. mtr_error("Could not find the mysqlslap binary");
  1510. }
  1511. return ""; # Don't care about mysqlslap
  1512. }
  1513. my $args;
  1514. mtr_init_args(\$args);
  1515. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1516. client_debug_arg($args, "mysqlslap");
  1517. return mtr_args2str($exe, @$args);
  1518. }
  1519. sub mysqldump_arguments ($) {
  1520. my($group_suffix) = @_;
  1521. my $exe= mtr_exe_exists("$path_client_bindir/mysqldump");
  1522. my $args;
  1523. mtr_init_args(\$args);
  1524. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1525. mtr_add_arg($args, "--defaults-group-suffix=%s", $group_suffix);
  1526. client_debug_arg($args, "mysqldump-$group_suffix");
  1527. return mtr_args2str($exe, @$args);
  1528. }
  1529. sub mysql_client_test_arguments(){
  1530. my $exe;
  1531. # mysql_client_test executable may _not_ exist
  1532. if ( $opt_embedded_server ) {
  1533. $exe= mtr_exe_maybe_exists(
  1534. vs_config_dirs('libmysqld/examples','mysql_client_test_embedded'),
  1535. "$basedir/libmysqld/examples/mysql_client_test_embedded",
  1536. "$basedir/bin/mysql_client_test_embedded");
  1537. } else {
  1538. $exe= mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'),
  1539. "$basedir/tests/mysql_client_test",
  1540. "$basedir/bin/mysql_client_test");
  1541. }
  1542. my $args;
  1543. mtr_init_args(\$args);
  1544. if ( $opt_valgrind_mysqltest ) {
  1545. valgrind_arguments($args, \$exe);
  1546. }
  1547. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1548. mtr_add_arg($args, "--testcase");
  1549. mtr_add_arg($args, "--vardir=$opt_vardir");
  1550. client_debug_arg($args,"mysql_client_test");
  1551. return mtr_args2str($exe, @$args);
  1552. }
  1553. #
  1554. # Set environment to be used by childs of this process for
  1555. # things that are constant during the whole lifetime of mysql-test-run
  1556. #
  1557. sub environment_setup {
  1558. umask(022);
  1559. my @ld_library_paths;
  1560. if ($path_client_libdir)
  1561. {
  1562. # Use the --client-libdir passed on commandline
  1563. push(@ld_library_paths, "$path_client_libdir");
  1564. }
  1565. else
  1566. {
  1567. # Setup LD_LIBRARY_PATH so the libraries from this distro/clone
  1568. # are used in favor of the system installed ones
  1569. if ( $source_dist )
  1570. {
  1571. push(@ld_library_paths, "$basedir/libmysql/.libs/",
  1572. "$basedir/libmysql_r/.libs/",
  1573. "$basedir/zlib/.libs/");
  1574. }
  1575. else
  1576. {
  1577. push(@ld_library_paths, "$basedir/lib", "$basedir/lib/mysql");
  1578. }
  1579. }
  1580. # --------------------------------------------------------------------------
  1581. # Add the path where libndbclient can be found
  1582. # --------------------------------------------------------------------------
  1583. if ( !$opt_skip_ndbcluster )
  1584. {
  1585. push(@ld_library_paths, "$basedir/storage/ndb/src/.libs");
  1586. }
  1587. # --------------------------------------------------------------------------
  1588. # Add the path where mysqld will find udf_example.so
  1589. # --------------------------------------------------------------------------
  1590. my $lib_udf_example=
  1591. mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'),
  1592. "$basedir/sql/.libs/udf_example.so",);
  1593. if ( $lib_udf_example )
  1594. {
  1595. push(@ld_library_paths, dirname($lib_udf_example));
  1596. }
  1597. $ENV{'UDF_EXAMPLE_LIB'}=
  1598. ($lib_udf_example ? basename($lib_udf_example) : "");
  1599. $ENV{'UDF_EXAMPLE_LIB_OPT'}= "--plugin-dir=".
  1600. ($lib_udf_example ? dirname($lib_udf_example) : "");
  1601. # --------------------------------------------------------------------------
  1602. # Add the path where mysqld will find ha_example.so
  1603. # --------------------------------------------------------------------------
  1604. if ($mysql_version_id >= 50100) {
  1605. my $plugin_filename;
  1606. if (IS_WINDOWS)
  1607. {
  1608. $plugin_filename = "ha_example.dll";
  1609. }
  1610. else
  1611. {
  1612. $plugin_filename = "ha_example.so";
  1613. }
  1614. my $lib_example_plugin=
  1615. mtr_file_exists(vs_config_dirs('storage/example',$plugin_filename),
  1616. "$basedir/storage/example/.libs/".$plugin_filename,
  1617. "$basedir/lib/mysql/plugin/".$plugin_filename);
  1618. $ENV{'EXAMPLE_PLUGIN'}=
  1619. ($lib_example_plugin ? basename($lib_example_plugin) : "");
  1620. $ENV{'EXAMPLE_PLUGIN_OPT'}= "--plugin-dir=".
  1621. ($lib_example_plugin ? dirname($lib_example_plugin) : "");
  1622. $ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'";
  1623. $ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".$plugin_filename;
  1624. }
  1625. # ----------------------------------------------------
  1626. # Add the path where mysqld will find mypluglib.so
  1627. # ----------------------------------------------------
  1628. my $lib_simple_parser=
  1629. mtr_file_exists(vs_config_dirs('plugin/fulltext', 'mypluglib.dll'),
  1630. "$basedir/plugin/fulltext/.libs/mypluglib.so",);
  1631. $ENV{'SIMPLE_PARSER'}=
  1632. ($lib_simple_parser ? basename($lib_simple_parser) : "");
  1633. $ENV{'SIMPLE_PARSER_OPT'}= "--plugin-dir=".
  1634. ($lib_simple_parser ? dirname($lib_simple_parser) : "");
  1635. # --------------------------------------------------------------------------
  1636. # Valgrind need to be run with debug libraries otherwise it's almost
  1637. # impossible to add correct supressions, that means if "/usr/lib/debug"
  1638. # is available, it should be added to
  1639. # LD_LIBRARY_PATH
  1640. #
  1641. # But pthread is broken in libc6-dbg on Debian <= 3.1 (see Debian
  1642. # bug 399035, http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=399035),
  1643. # so don't change LD_LIBRARY_PATH on that platform.
  1644. # --------------------------------------------------------------------------
  1645. my $debug_libraries_path= "/usr/lib/debug";
  1646. my $deb_version;
  1647. if ( $opt_valgrind and -d $debug_libraries_path and
  1648. (! -e '/etc/debian_version' or
  1649. ($deb_version=
  1650. mtr_grab_file('/etc/debian_version')) !~ /^[0-9]+\.[0-9]$/ or
  1651. $deb_version > 3.1 ) )
  1652. {
  1653. push(@ld_library_paths, $debug_libraries_path);
  1654. }
  1655. $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths,
  1656. $ENV{'LD_LIBRARY_PATH'} ?
  1657. split(':', $ENV{'LD_LIBRARY_PATH'}) : ());
  1658. mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}");
  1659. $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths,
  1660. $ENV{'DYLD_LIBRARY_PATH'} ?
  1661. split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ());
  1662. mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}");
  1663. # The environment variable used for shared libs on AIX
  1664. $ENV{'SHLIB_PATH'}= join(":", @ld_library_paths,
  1665. $ENV{'SHLIB_PATH'} ?
  1666. split(':', $ENV{'SHLIB_PATH'}) : ());
  1667. mtr_debug("SHLIB_PATH: $ENV{'SHLIB_PATH'}");
  1668. # The environment variable used for shared libs on hp-ux
  1669. $ENV{'LIBPATH'}= join(":", @ld_library_paths,
  1670. $ENV{'LIBPATH'} ?
  1671. split(':', $ENV{'LIBPATH'}) : ());
  1672. mtr_debug("LIBPATH: $ENV{'LIBPATH'}");
  1673. $ENV{'CHARSETSDIR'}= $path_charsetsdir;
  1674. $ENV{'UMASK'}= "0660"; # The octal *string*
  1675. $ENV{'UMASK_DIR'}= "0770"; # The octal *string*
  1676. #
  1677. # MySQL tests can produce output in various character sets
  1678. # (especially, ctype_xxx.test). To avoid confusing Perl
  1679. # with output which is incompatible with the current locale
  1680. # settings, we reset the current values of LC_ALL and LC_CTYPE to "C".
  1681. # For details, please see
  1682. # Bug#27636 tests fails if LC_* variables set to *_*.UTF-8
  1683. #
  1684. $ENV{'LC_ALL'}= "C";
  1685. $ENV{'LC_CTYPE'}= "C";
  1686. $ENV{'LC_COLLATE'}= "C";
  1687. $ENV{'USE_RUNNING_SERVER'}= using_extern();
  1688. $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir;
  1689. $ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'master-port'} || 3306;
  1690. $ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir;
  1691. $ENV{'MYSQLTEST_VARDIR'}= $opt_vardir;
  1692. # ----------------------------------------------------
  1693. # Setup env for NDB
  1694. # ----------------------------------------------------
  1695. if ( ! $opt_skip_ndbcluster )
  1696. {
  1697. $ENV{'NDB_MGM'}=
  1698. my_find_bin($basedir,
  1699. ["storage/ndb/src/mgmclient", "bin"],
  1700. "ndb_mgm");
  1701. $ENV{'NDB_TOOLS_DIR'}=
  1702. my_find_dir($basedir,
  1703. ["storage/ndb/tools", "bin"]);
  1704. $ENV{'NDB_EXAMPLES_DIR'}=
  1705. my_find_dir($basedir,
  1706. ["storage/ndb/ndbapi-examples", "bin"]);
  1707. $ENV{'NDB_EXAMPLES_BINARY'}=
  1708. my_find_bin($basedir,
  1709. ["storage/ndb/ndbapi-examples/ndbapi_simple", "bin"],
  1710. "ndbapi_simple", NOT_REQUIRED);
  1711. my $path_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log";
  1712. $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log;
  1713. $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log;
  1714. }
  1715. # ----------------------------------------------------
  1716. # mysql clients
  1717. # ----------------------------------------------------
  1718. $ENV{'MYSQL_CHECK'}= client_arguments("mysqlcheck");
  1719. $ENV{'MYSQL_DUMP'}= mysqldump_arguments(".1");
  1720. $ENV{'MYSQL_DUMP_SLAVE'}= mysqldump_arguments(".2");
  1721. $ENV{'MYSQL_SLAP'}= mysqlslap_arguments();
  1722. $ENV{'MYSQL_IMPORT'}= client_arguments("mysqlimport");
  1723. $ENV{'MYSQL_SHOW'}= client_arguments("mysqlshow");
  1724. $ENV{'MYSQL_BINLOG'}= client_arguments("mysqlbinlog");
  1725. $ENV{'MYSQL'}= client_arguments("mysql");
  1726. $ENV{'MYSQL_SLAVE'}= client_arguments("mysql", ".2");
  1727. $ENV{'MYSQL_UPGRADE'}= client_arguments("mysql_upgrade");
  1728. $ENV{'MYSQLADMIN'}= native_path($exe_mysqladmin);
  1729. $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments();
  1730. $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= mysql_fix_arguments();
  1731. $ENV{'EXE_MYSQL'}= $exe_mysql;
  1732. # ----------------------------------------------------
  1733. # bug25714 executable may _not_ exist in
  1734. # some versions, test using it should be skipped
  1735. # ----------------------------------------------------
  1736. my $exe_bug25714=
  1737. mtr_exe_maybe_exists(vs_config_dirs('tests', 'bug25714'),
  1738. "$basedir/tests/bug25714");
  1739. $ENV{'MYSQL_BUG25714'}= native_path($exe_bug25714);
  1740. # ----------------------------------------------------
  1741. # mysql_fix_privilege_tables.sql
  1742. # ----------------------------------------------------
  1743. my $file_mysql_fix_privilege_tables=
  1744. mtr_file_exists("$basedir/scripts/mysql_fix_privilege_tables.sql",
  1745. "$basedir/share/mysql_fix_privilege_tables.sql",
  1746. "$basedir/share/mysql/mysql_fix_privilege_tables.sql");
  1747. $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables;
  1748. # ----------------------------------------------------
  1749. # my_print_defaults
  1750. # ----------------------------------------------------
  1751. my $exe_my_print_defaults=
  1752. mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'),
  1753. "$path_client_bindir/my_print_defaults",
  1754. "$basedir/extra/my_print_defaults");
  1755. $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= native_path($exe_my_print_defaults);
  1756. # ----------------------------------------------------
  1757. # Setup env so childs can execute myisampack and myisamchk
  1758. # ----------------------------------------------------
  1759. $ENV{'MYISAMCHK'}= native_path(mtr_exe_exists(
  1760. vs_config_dirs('storage/myisam', 'myisamchk'),
  1761. vs_config_dirs('myisam', 'myisamchk'),
  1762. "$path_client_bindir/myisamchk",
  1763. "$basedir/storage/myisam/myisamchk",
  1764. "$basedir/myisam/myisamchk"));
  1765. $ENV{'MYISAMPACK'}= native_path(mtr_exe_exists(
  1766. vs_config_dirs('storage/myisam', 'myisampack'),
  1767. vs_config_dirs('myisam', 'myisampack'),
  1768. "$path_client_bindir/myisampack",
  1769. "$basedir/storage/myisam/myisampack",
  1770. "$basedir/myisam/myisampack"));
  1771. # ----------------------------------------------------
  1772. # mysqlhotcopy
  1773. # ----------------------------------------------------
  1774. my $mysqlhotcopy=
  1775. mtr_pl_maybe_exists("$basedir/scripts/mysqlhotcopy");
  1776. # Since mysqltest interprets the real path as "false" in an if,
  1777. # use 1 ("true") to indicate "not exists" so it can be tested for
  1778. $ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy || 1;
  1779. # ----------------------------------------------------
  1780. # perror
  1781. # ----------------------------------------------------
  1782. my $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'),
  1783. "$basedir/extra/perror",
  1784. "$path_client_bindir/perror");
  1785. $ENV{'MY_PERROR'}= native_path($exe_perror);
  1786. # Create an environment variable to make it possible
  1787. # to detect that valgrind is being used from test cases
  1788. $ENV{'VALGRIND_TEST'}= $opt_valgrind;
  1789. }
  1790. #
  1791. # Remove var and any directories in var/ created by previous
  1792. # tests
  1793. #
  1794. sub remove_stale_vardir () {
  1795. mtr_report("Removing old var directory...");
  1796. # Safety!
  1797. mtr_error("No, don't remove the vardir when running with --extern")
  1798. if using_extern();
  1799. mtr_verbose("opt_vardir: $opt_vardir");
  1800. if ( $opt_vardir eq $default_vardir )
  1801. {
  1802. #
  1803. # Running with "var" in mysql-test dir
  1804. #
  1805. if ( -l $opt_vardir)
  1806. {
  1807. # var is a symlink
  1808. if ( $opt_mem )
  1809. {
  1810. # Remove the directory which the link points at
  1811. mtr_verbose("Removing " . readlink($opt_vardir));
  1812. rmtree(readlink($opt_vardir));
  1813. # Remove the "var" symlink
  1814. mtr_verbose("unlink($opt_vardir)");
  1815. unlink($opt_vardir);
  1816. }
  1817. else
  1818. {
  1819. # Some users creates a soft link in mysql-test/var to another area
  1820. # - allow it, but remove all files in it
  1821. mtr_report(" - WARNING: Using the 'mysql-test/var' symlink");
  1822. # Make sure the directory where it points exist
  1823. mtr_error("The destination for symlink $opt_vardir does not exist")
  1824. if ! -d readlink($opt_vardir);
  1825. foreach my $bin ( glob("$opt_vardir/*") )
  1826. {
  1827. mtr_verbose("Removing bin $bin");
  1828. rmtree($bin);
  1829. }
  1830. }
  1831. }
  1832. else
  1833. {
  1834. # Remove the entire "var" dir
  1835. mtr_verbose("Removing $opt_vardir/");
  1836. rmtree("$opt_vardir/");
  1837. }
  1838. if ( $opt_mem )
  1839. {
  1840. # A symlink from var/ to $opt_mem will be set up
  1841. # remove the $opt_mem dir to assure the symlink
  1842. # won't point at an old directory
  1843. mtr_verbose("Removing $opt_mem");
  1844. rmtree($opt_mem);
  1845. }
  1846. }
  1847. else
  1848. {
  1849. #
  1850. # Running with "var" in some other place
  1851. #
  1852. # Remove the var/ dir in mysql-test dir if any
  1853. # this could be an old symlink that shouldn't be there
  1854. mtr_verbose("Removing $default_vardir");
  1855. rmtree($default_vardir);
  1856. # Remove the "var" dir
  1857. mtr_verbose("Removing $opt_vardir/");
  1858. rmtree("$opt_vardir/");
  1859. }
  1860. # Remove the "tmp" dir
  1861. mtr_verbose("Removing $opt_tmpdir/");
  1862. rmtree("$opt_tmpdir/");
  1863. }
  1864. #
  1865. # Create var and the directories needed in var
  1866. #
  1867. sub setup_vardir() {
  1868. mtr_report("Creating var directory '$opt_vardir'...");
  1869. if ( $opt_vardir eq $default_vardir )
  1870. {
  1871. #
  1872. # Running with "var" in mysql-test dir
  1873. #
  1874. if ( -l $opt_vardir )
  1875. {
  1876. # it's a symlink
  1877. # Make sure the directory where it points exist
  1878. mtr_error("The destination for symlink $opt_vardir does not exist")
  1879. if ! -d readlink($opt_vardir);
  1880. }
  1881. elsif ( $opt_mem )
  1882. {
  1883. # Runinng with "var" as a link to some "memory" location, normally tmpfs
  1884. mtr_verbose("Creating $opt_mem");
  1885. mkpath($opt_mem);
  1886. mtr_report(" - symlinking 'var' to '$opt_mem'");
  1887. symlink($opt_mem, $opt_vardir);
  1888. }
  1889. }
  1890. if ( ! -d $opt_vardir )
  1891. {
  1892. mtr_verbose("Creating $opt_vardir");
  1893. mkpath($opt_vardir);
  1894. }
  1895. # Ensure a proper error message if vardir couldn't be created
  1896. unless ( -d $opt_vardir and -w $opt_vardir )
  1897. {
  1898. mtr_error("Writable 'var' directory is needed, use the " .
  1899. "'--vardir=<path>' option");
  1900. }
  1901. mkpath("$opt_vardir/log");
  1902. mkpath("$opt_vardir/run");
  1903. # Create var/tmp and tmp - they might be different
  1904. mkpath("$opt_vardir/tmp");
  1905. mkpath($opt_tmpdir) if ($opt_tmpdir ne "$opt_vardir/tmp");
  1906. # On some operating systems, there is a limit to the length of a
  1907. # UNIX domain socket's path far below PATH_MAX.
  1908. # Don't allow that to happen
  1909. if (check_socket_path_length("$opt_tmpdir/testsocket.sock")){
  1910. mtr_error("Socket path '$opt_tmpdir' too long, it would be ",
  1911. "truncated and thus not possible to use for connection to ",
  1912. "MySQL Server. Set a shorter with --tmpdir=<path> option");
  1913. }
  1914. # copy all files from std_data into var/std_data
  1915. # and make them world readable
  1916. copytree("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data", "0022");
  1917. # Remove old log files
  1918. foreach my $name (glob("r/*.progress r/*.log r/*.warnings"))
  1919. {
  1920. unlink($name);
  1921. }
  1922. }
  1923. #
  1924. # Check if running as root
  1925. # i.e a file can be read regardless what mode we set it to
  1926. #
  1927. sub check_running_as_root () {
  1928. my $test_file= "$opt_vardir/test_running_as_root.txt";
  1929. mtr_tofile($test_file, "MySQL");
  1930. chmod(oct("0000"), $test_file);
  1931. my $result="";
  1932. if (open(FILE,"<",$test_file))
  1933. {
  1934. $result= join('', <FILE>);
  1935. close FILE;
  1936. }
  1937. # Some filesystems( for example CIFS) allows reading a file
  1938. # although mode was set to 0000, but in that case a stat on
  1939. # the file will not return 0000
  1940. my $file_mode= (stat($test_file))[2] & 07777;
  1941. mtr_verbose("result: $result, file_mode: $file_mode");
  1942. if ($result eq "MySQL" && $file_mode == 0)
  1943. {
  1944. mtr_warning("running this script as _root_ will cause some " .
  1945. "tests to be skipped");
  1946. $ENV{'MYSQL_TEST_ROOT'}= "YES";
  1947. }
  1948. chmod(oct("0755"), $test_file);
  1949. unlink($test_file);
  1950. }
  1951. sub check_ssl_support ($) {
  1952. my $mysqld_variables= shift;
  1953. if ($opt_skip_ssl)
  1954. {
  1955. mtr_report(" - skipping SSL");
  1956. $opt_ssl_supported= 0;
  1957. $opt_ssl= 0;
  1958. return;
  1959. }
  1960. if ( ! $mysqld_variables->{'ssl'} )
  1961. {
  1962. if ( $opt_ssl)
  1963. {
  1964. mtr_error("Couldn't find support for SSL");
  1965. return;
  1966. }
  1967. mtr_report(" - skipping SSL, mysqld not compiled with SSL");
  1968. $opt_ssl_supported= 0;
  1969. $opt_ssl= 0;
  1970. return;
  1971. }
  1972. mtr_report(" - SSL connections supported");
  1973. $opt_ssl_supported= 1;
  1974. }
  1975. sub check_debug_support ($) {
  1976. my $mysqld_variables= shift;
  1977. if ( ! $mysqld_variables->{'debug'} )
  1978. {
  1979. #mtr_report(" - binaries are not debug compiled");
  1980. $debug_compiled_binaries= 0;
  1981. if ( $opt_debug )
  1982. {
  1983. mtr_error("Can't use --debug, binaries does not support it");
  1984. }
  1985. return;
  1986. }
  1987. mtr_report(" - binaries are debug compiled");
  1988. $debug_compiled_binaries= 1;
  1989. }
  1990. #
  1991. # Helper function to handle configuration-based subdirectories which Visual
  1992. # Studio uses for storing binaries. If opt_vs_config is set, this returns
  1993. # a path based on that setting; if not, it returns paths for the default
  1994. # /release/ and /debug/ subdirectories.
  1995. #
  1996. # $exe can be undefined, if the directory itself will be used
  1997. #
  1998. sub vs_config_dirs ($$) {
  1999. my ($path_part, $exe) = @_;
  2000. $exe = "" if not defined $exe;
  2001. # Don't look in these dirs when not on windows
  2002. return () unless IS_WINDOWS;
  2003. if ($opt_vs_config)
  2004. {
  2005. return ("$basedir/$path_part/$opt_vs_config/$exe");
  2006. }
  2007. return ("$basedir/$path_part/release/$exe",
  2008. "$basedir/$path_part/relwithdebinfo/$exe",
  2009. "$basedir/$path_part/debug/$exe");
  2010. }
  2011. sub check_ndbcluster_support ($) {
  2012. my $mysqld_variables= shift;
  2013. if ($opt_skip_ndbcluster)
  2014. {
  2015. mtr_report(" - skipping ndbcluster");
  2016. return;
  2017. }
  2018. if ( ! $mysqld_variables{'ndb-connectstring'} )
  2019. {
  2020. mtr_report(" - skipping ndbcluster, mysqld not compiled with ndbcluster");
  2021. $opt_skip_ndbcluster= 2;
  2022. return;
  2023. }
  2024. mtr_report(" - using ndbcluster when necessary, mysqld supports it");
  2025. return;
  2026. }
  2027. sub ndbcluster_wait_started($$){
  2028. my $cluster= shift;
  2029. my $ndb_waiter_extra_opt= shift;
  2030. my $path_waitlog= join('/', $opt_vardir, $cluster->name(), "ndb_waiter.log");
  2031. my $args;
  2032. mtr_init_args(\$args);
  2033. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2034. mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix());
  2035. mtr_add_arg($args, "--timeout=%d", $opt_start_timeout);
  2036. if ($ndb_waiter_extra_opt)
  2037. {
  2038. mtr_add_arg($args, "$ndb_waiter_extra_opt");
  2039. }
  2040. # Start the ndb_waiter which will connect to the ndb_mgmd
  2041. # and poll it for state of the ndbd's, will return when
  2042. # all nodes in the cluster is started
  2043. my $res= My::SafeProcess->run
  2044. (
  2045. name => "ndb_waiter ".$cluster->name(),
  2046. path => $exe_ndb_waiter,
  2047. args => \$args,
  2048. output => $path_waitlog,
  2049. error => $path_waitlog,
  2050. append => 1,
  2051. );
  2052. # Check that ndb_mgmd(s) are still alive
  2053. foreach my $ndb_mgmd ( in_cluster($cluster, ndb_mgmds()) )
  2054. {
  2055. my $proc= $ndb_mgmd->{proc};
  2056. if ( ! $proc->wait_one(0) )
  2057. {
  2058. mtr_warning("$proc died");
  2059. return 2;
  2060. }
  2061. }
  2062. # Check that all started ndbd(s) are still alive
  2063. foreach my $ndbd ( in_cluster($cluster, ndbds()) )
  2064. {
  2065. my $proc= $ndbd->{proc};
  2066. next unless defined $proc;
  2067. if ( ! $proc->wait_one(0) )
  2068. {
  2069. mtr_warning("$proc died");
  2070. return 3;
  2071. }
  2072. }
  2073. if ($res)
  2074. {
  2075. mtr_verbose("ndbcluster_wait_started failed");
  2076. return 1;
  2077. }
  2078. return 0;
  2079. }
  2080. sub ndb_mgmd_wait_started($) {
  2081. my ($cluster)= @_;
  2082. my $retries= 100;
  2083. while ($retries)
  2084. {
  2085. my $result= ndbcluster_wait_started($cluster, "--no-contact");
  2086. if ($result == 0)
  2087. {
  2088. # ndb_mgmd is started
  2089. mtr_verbose("ndb_mgmd is started");
  2090. return 0;
  2091. }
  2092. elsif ($result > 1)
  2093. {
  2094. mtr_warning("Cluster process failed while waiting for start");
  2095. return $result;
  2096. }
  2097. mtr_milli_sleep(100);
  2098. $retries--;
  2099. }
  2100. return 1;
  2101. }
  2102. sub ndb_mgmd_start ($$) {
  2103. my ($cluster, $ndb_mgmd)= @_;
  2104. mtr_verbose("ndb_mgmd_start");
  2105. my $dir= $ndb_mgmd->value("DataDir");
  2106. mkpath($dir) unless -d $dir;
  2107. my $args;
  2108. mtr_init_args(\$args);
  2109. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2110. mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix());
  2111. mtr_add_arg($args, "--mycnf");
  2112. mtr_add_arg($args, "--nodaemon");
  2113. my $path_ndb_mgmd_log= "$dir/ndb_mgmd.log";
  2114. $ndb_mgmd->{'proc'}= My::SafeProcess->new
  2115. (
  2116. name => $ndb_mgmd->after('cluster_config.'),
  2117. path => $exe_ndb_mgmd,
  2118. args => \$args,
  2119. output => $path_ndb_mgmd_log,
  2120. error => $path_ndb_mgmd_log,
  2121. append => 1,
  2122. verbose => $opt_verbose,
  2123. );
  2124. mtr_verbose("Started $ndb_mgmd->{proc}");
  2125. # FIXME Should not be needed
  2126. # Unfortunately the cluster nodes will fail to start
  2127. # if ndb_mgmd has not started properly
  2128. if (ndb_mgmd_wait_started($cluster))
  2129. {
  2130. mtr_warning("Failed to wait for start of ndb_mgmd");
  2131. return 1;
  2132. }
  2133. return 0;
  2134. }
  2135. sub ndbd_start {
  2136. my ($cluster, $ndbd)= @_;
  2137. mtr_verbose("ndbd_start");
  2138. my $dir= $ndbd->value("DataDir");
  2139. mkpath($dir) unless -d $dir;
  2140. my $args;
  2141. mtr_init_args(\$args);
  2142. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2143. mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix());
  2144. mtr_add_arg($args, "--nodaemon");
  2145. # > 5.0 { 'character-sets-dir' => \&fix_charset_dir },
  2146. my $path_ndbd_log= "$dir/ndbd.log";
  2147. my $proc= My::SafeProcess->new
  2148. (
  2149. name => $ndbd->after('cluster_config.'),
  2150. path => $exe_ndbd,
  2151. args => \$args,
  2152. output => $path_ndbd_log,
  2153. error => $path_ndbd_log,
  2154. append => 1,
  2155. verbose => $opt_verbose,
  2156. );
  2157. mtr_verbose("Started $proc");
  2158. $ndbd->{proc}= $proc;
  2159. return;
  2160. }
  2161. sub ndbcluster_start ($) {
  2162. my $cluster= shift;
  2163. mtr_verbose("ndbcluster_start '".$cluster->name()."'");
  2164. foreach my $ndb_mgmd ( in_cluster($cluster, ndb_mgmds()) )
  2165. {
  2166. next if started($ndb_mgmd);
  2167. ndb_mgmd_start($cluster, $ndb_mgmd);
  2168. }
  2169. foreach my $ndbd ( in_cluster($cluster, ndbds()) )
  2170. {
  2171. next if started($ndbd);
  2172. ndbd_start($cluster, $ndbd);
  2173. }
  2174. return 0;
  2175. }
  2176. sub create_config_file_for_extern {
  2177. my %opts=
  2178. (
  2179. socket => '/tmp/mysqld.sock',
  2180. port => 3306,
  2181. user => $opt_user,
  2182. password => '',
  2183. @_
  2184. );
  2185. mtr_report("Creating my.cnf file for extern server...");
  2186. my $F= IO::File->new($path_config_file, "w")
  2187. or mtr_error("Can't write to $path_config_file: $!");
  2188. print $F "[client]\n";
  2189. while (my ($option, $value)= each( %opts )) {
  2190. print $F "$option= $value\n";
  2191. mtr_report(" $option= $value");
  2192. }
  2193. print $F <<EOF
  2194. # binlog reads from [client] and [mysqlbinlog]
  2195. [mysqlbinlog]
  2196. character-sets-dir= $path_charsetsdir
  2197. local-load= $opt_tmpdir
  2198. # mysql_fix_privilege_tables.sh don't read from [client]
  2199. [mysql_fix_privilege_tables]
  2200. socket = $opts{'socket'}
  2201. port = $opts{'port'}
  2202. user = $opts{'user'}
  2203. password = $opts{'password'}
  2204. EOF
  2205. ;
  2206. $F= undef; # Close file
  2207. }
  2208. #
  2209. # Kill processes left from previous runs, normally
  2210. # there should be none so make sure to warn
  2211. # if there is one
  2212. #
  2213. sub kill_leftovers ($) {
  2214. my $rundir= shift;
  2215. return unless ( -d $rundir );
  2216. mtr_report("Checking leftover processes...");
  2217. # Scan the "run" directory for process id's to kill
  2218. opendir(RUNDIR, $rundir)
  2219. or mtr_error("kill_leftovers, can't open dir \"$rundir\": $!");
  2220. while ( my $elem= readdir(RUNDIR) )
  2221. {
  2222. # Only read pid from files that end with .pid
  2223. if ( $elem =~ /.*[.]pid$/ )
  2224. {
  2225. my $pidfile= "$rundir/$elem";
  2226. next unless -f $pidfile;
  2227. my $pid= mtr_fromfile($pidfile);
  2228. unlink($pidfile);
  2229. unless ($pid=~ /^(\d+)/){
  2230. # The pid was not a valid number
  2231. mtr_warning("Got invalid pid '$pid' from '$elem'");
  2232. next;
  2233. }
  2234. mtr_report(" - found old pid $pid in '$elem', killing it...");
  2235. my $ret= kill("KILL", $pid);
  2236. if ($ret == 0) {
  2237. mtr_report(" process did not exist!");
  2238. next;
  2239. }
  2240. my $check_counter= 100;
  2241. while ($ret > 0 and $check_counter--) {
  2242. mtr_milli_sleep(100);
  2243. $ret= kill(0, $pid);
  2244. }
  2245. mtr_report($check_counter ? " ok!" : " failed!");
  2246. }
  2247. else
  2248. {
  2249. mtr_warning("Found non pid file '$elem' in '$rundir'")
  2250. if -f "$rundir/$elem";
  2251. }
  2252. }
  2253. closedir(RUNDIR);
  2254. }
  2255. #
  2256. # Check that all the ports that are going to
  2257. # be used are free
  2258. #
  2259. sub check_ports_free ($)
  2260. {
  2261. my $bthread= shift;
  2262. my $portbase = $bthread * 10 + 10000;
  2263. for ($portbase..$portbase+9){
  2264. if (mtr_ping_port($_)){
  2265. mtr_report(" - 'localhost:$_' was not free");
  2266. return 0; # One port was not free
  2267. }
  2268. }
  2269. return 1; # All ports free
  2270. }
  2271. sub initialize_servers {
  2272. if ( using_extern() )
  2273. {
  2274. # Running against an already started server, if the specified
  2275. # vardir does not already exist it should be created
  2276. if ( ! -d $opt_vardir )
  2277. {
  2278. setup_vardir();
  2279. }
  2280. else
  2281. {
  2282. mtr_verbose("No need to create '$opt_vardir' it already exists");
  2283. }
  2284. }
  2285. else
  2286. {
  2287. # Kill leftovers from previous run
  2288. # using any pidfiles found in var/run
  2289. kill_leftovers("$opt_vardir/run");
  2290. if ( ! $opt_start_dirty )
  2291. {
  2292. remove_stale_vardir();
  2293. setup_vardir();
  2294. mysql_install_db(default_mysqld(), "$opt_vardir/install.db");
  2295. }
  2296. }
  2297. }
  2298. #
  2299. # Remove all newline characters expect after semicolon
  2300. #
  2301. sub sql_to_bootstrap {
  2302. my ($sql) = @_;
  2303. my @lines= split(/\n/, $sql);
  2304. my $result= "\n";
  2305. my $delimiter= ';';
  2306. foreach my $line (@lines) {
  2307. # Change current delimiter if line starts with "delimiter"
  2308. if ( $line =~ /^delimiter (.*)/ ) {
  2309. my $new= $1;
  2310. # Remove old delimiter from end of new
  2311. $new=~ s/\Q$delimiter\E$//;
  2312. $delimiter = $new;
  2313. mtr_debug("changed delimiter to $delimiter");
  2314. # No need to add the delimiter to result
  2315. next;
  2316. }
  2317. # Add newline if line ends with $delimiter
  2318. # and convert the current delimiter to semicolon
  2319. if ( $line =~ /\Q$delimiter\E$/ ){
  2320. $line =~ s/\Q$delimiter\E$/;/;
  2321. $result.= "$line\n";
  2322. mtr_debug("Added default delimiter");
  2323. next;
  2324. }
  2325. # Remove comments starting with --
  2326. if ( $line =~ /^\s*--/ ) {
  2327. mtr_debug("Discarded $line");
  2328. next;
  2329. }
  2330. # Replace @HOSTNAME with localhost
  2331. $line=~ s/\'\@HOSTNAME\@\'/localhost/;
  2332. # Default, just add the line without newline
  2333. # but with a space as separator
  2334. $result.= "$line ";
  2335. }
  2336. return $result;
  2337. }
  2338. sub default_mysqld {
  2339. # Generate new config file from template
  2340. my $config= My::ConfigFactory->new_config
  2341. ( {
  2342. basedir => $basedir,
  2343. testdir => $glob_mysql_test_dir,
  2344. template_path => "include/default_my.cnf",
  2345. vardir => $opt_vardir,
  2346. tmpdir => $opt_tmpdir,
  2347. baseport => 0,
  2348. user => $opt_user,
  2349. password => '',
  2350. }
  2351. );
  2352. my $mysqld= $config->group('mysqld.1')
  2353. or mtr_error("Couldn't find mysqld.1 in default config");
  2354. return $mysqld;
  2355. }
  2356. sub mysql_install_db {
  2357. my ($mysqld, $datadir)= @_;
  2358. my $install_datadir= $datadir || $mysqld->value('datadir');
  2359. my $install_basedir= $mysqld->value('basedir');
  2360. my $install_lang= $mysqld->value('language');
  2361. my $install_chsdir= $mysqld->value('character-sets-dir');
  2362. mtr_report("Installing system database...");
  2363. my $args;
  2364. mtr_init_args(\$args);
  2365. mtr_add_arg($args, "--no-defaults");
  2366. mtr_add_arg($args, "--bootstrap");
  2367. mtr_add_arg($args, "--basedir=%s", $install_basedir);
  2368. mtr_add_arg($args, "--datadir=%s", $install_datadir);
  2369. mtr_add_arg($args, "--loose-skip-innodb");
  2370. mtr_add_arg($args, "--loose-skip-falcon");
  2371. mtr_add_arg($args, "--loose-skip-ndbcluster");
  2372. mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/");
  2373. mtr_add_arg($args, "--core-file");
  2374. if ( $opt_debug )
  2375. {
  2376. mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap.trace",
  2377. $path_vardir_trace);
  2378. }
  2379. mtr_add_arg($args, "--language=%s", $install_lang);
  2380. mtr_add_arg($args, "--character-sets-dir=%s", $install_chsdir);
  2381. # If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g.,
  2382. # configure --disable-grant-options), mysqld will not recognize the
  2383. # --bootstrap or --skip-grant-tables options. The user can set
  2384. # MYSQLD_BOOTSTRAP to the full path to a mysqld which does accept
  2385. # --bootstrap, to accommodate this.
  2386. my $exe_mysqld_bootstrap =
  2387. $ENV{'MYSQLD_BOOTSTRAP'} || find_mysqld($install_basedir);
  2388. # ----------------------------------------------------------------------
  2389. # export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args>
  2390. # ----------------------------------------------------------------------
  2391. $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args);
  2392. # ----------------------------------------------------------------------
  2393. # Create the bootstrap.sql file
  2394. # ----------------------------------------------------------------------
  2395. my $bootstrap_sql_file= "$opt_vardir/tmp/bootstrap.sql";
  2396. my $path_sql= my_find_file($install_basedir,
  2397. ["mysql", "sql/share", "share/mysql",
  2398. "share", "scripts"],
  2399. "mysql_system_tables.sql",
  2400. NOT_REQUIRED);
  2401. if (-f $path_sql )
  2402. {
  2403. my $sql_dir= dirname($path_sql);
  2404. # Use the mysql database for system tables
  2405. mtr_tofile($bootstrap_sql_file, "use mysql\n");
  2406. # Add the offical mysql system tables
  2407. # for a production system
  2408. mtr_appendfile_to_file("$sql_dir/mysql_system_tables.sql",
  2409. $bootstrap_sql_file);
  2410. # Add the mysql system tables initial data
  2411. # for a production system
  2412. mtr_appendfile_to_file("$sql_dir/mysql_system_tables_data.sql",
  2413. $bootstrap_sql_file);
  2414. # Add test data for timezone - this is just a subset, on a real
  2415. # system these tables will be populated either by mysql_tzinfo_to_sql
  2416. # or by downloading the timezone table package from our website
  2417. mtr_appendfile_to_file("$sql_dir/mysql_test_data_timezone.sql",
  2418. $bootstrap_sql_file);
  2419. # Fill help tables, just an empty file when running from bk repo
  2420. # but will be replaced by a real fill_help_tables.sql when
  2421. # building the source dist
  2422. mtr_appendfile_to_file("$sql_dir/fill_help_tables.sql",
  2423. $bootstrap_sql_file);
  2424. }
  2425. else
  2426. {
  2427. # Install db from init_db.sql that exist in early 5.1 and 5.0
  2428. # versions of MySQL
  2429. my $init_file= "$install_basedir/mysql-test/lib/init_db.sql";
  2430. mtr_report(" - from '$init_file'");
  2431. my $text= mtr_grab_file($init_file) or
  2432. mtr_error("Can't open '$init_file': $!");
  2433. mtr_tofile($bootstrap_sql_file,
  2434. sql_to_bootstrap($text));
  2435. }
  2436. # Remove anonymous users
  2437. mtr_tofile($bootstrap_sql_file,
  2438. "DELETE FROM mysql.user where user= '';\n");
  2439. # Create mtr database
  2440. mtr_tofile($bootstrap_sql_file,
  2441. "CREATE DATABASE mtr;\n");
  2442. # Add help tables and data for warning detection and supression
  2443. mtr_tofile($bootstrap_sql_file,
  2444. sql_to_bootstrap(mtr_grab_file("include/mtr_warnings.sql")));
  2445. # Add procedures for checking server is restored after testcase
  2446. mtr_tofile($bootstrap_sql_file,
  2447. sql_to_bootstrap(mtr_grab_file("include/mtr_check.sql")));
  2448. # Log bootstrap command
  2449. my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log";
  2450. mtr_tofile($path_bootstrap_log,
  2451. "$exe_mysqld_bootstrap " . join(" ", @$args) . "\n");
  2452. # Create directories mysql and test
  2453. mkpath("$install_datadir/mysql");
  2454. mkpath("$install_datadir/test");
  2455. if ( My::SafeProcess->run
  2456. (
  2457. name => "bootstrap",
  2458. path => $exe_mysqld_bootstrap,
  2459. args => \$args,
  2460. input => $bootstrap_sql_file,
  2461. output => $path_bootstrap_log,
  2462. error => $path_bootstrap_log,
  2463. append => 1,
  2464. verbose => $opt_verbose,
  2465. ) != 0)
  2466. {
  2467. mtr_error("Error executing mysqld --bootstrap\n" .
  2468. "Could not install system database from $bootstrap_sql_file\n" .
  2469. "see $path_bootstrap_log for errors");
  2470. }
  2471. }
  2472. sub run_testcase_check_skip_test($)
  2473. {
  2474. my ($tinfo)= @_;
  2475. # ----------------------------------------------------------------------
  2476. # If marked to skip, just print out and return.
  2477. # Note that a test case not marked as 'skip' can still be
  2478. # skipped later, because of the test case itself in cooperation
  2479. # with the mysqltest program tells us so.
  2480. # ----------------------------------------------------------------------
  2481. if ( $tinfo->{'skip'} )
  2482. {
  2483. mtr_report_test_skipped($tinfo) unless $start_only;
  2484. return 1;
  2485. }
  2486. return 0;
  2487. }
  2488. sub run_query {
  2489. my ($tinfo, $mysqld, $query)= @_;
  2490. my $args;
  2491. mtr_init_args(\$args);
  2492. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2493. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  2494. mtr_add_arg($args, "-e %s", $query);
  2495. my $res= My::SafeProcess->run
  2496. (
  2497. name => "run_query -> ".$mysqld->name(),
  2498. path => $exe_mysql,
  2499. args => \$args,
  2500. output => '/dev/null',
  2501. error => '/dev/null'
  2502. );
  2503. return $res
  2504. }
  2505. sub do_before_run_mysqltest($)
  2506. {
  2507. my $tinfo= shift;
  2508. # Remove old files produced by mysqltest
  2509. my $base_file= mtr_match_extension($tinfo->{result_file},
  2510. "result"); # Trim extension
  2511. if (defined $base_file ){
  2512. unlink("$base_file.reject");
  2513. unlink("$base_file.progress");
  2514. unlink("$base_file.log");
  2515. unlink("$base_file.warnings");
  2516. }
  2517. if ( $mysql_version_id < 50000 ) {
  2518. # Set environment variable NDB_STATUS_OK to 1
  2519. # if script decided to run mysqltest cluster _is_ installed ok
  2520. $ENV{'NDB_STATUS_OK'} = "1";
  2521. } elsif ( $mysql_version_id < 50100 ) {
  2522. # Set environment variable NDB_STATUS_OK to YES
  2523. # if script decided to run mysqltest cluster _is_ installed ok
  2524. $ENV{'NDB_STATUS_OK'} = "YES";
  2525. }
  2526. }
  2527. #
  2528. # Check all server for sideffects
  2529. #
  2530. # RETURN VALUE
  2531. # 0 ok
  2532. # 1 Check failed
  2533. # >1 Fatal errro
  2534. sub check_testcase($$)
  2535. {
  2536. my ($tinfo, $mode)= @_;
  2537. my $tname= $tinfo->{name};
  2538. # Start the mysqltest processes in parallel to save time
  2539. # also makes it possible to wait for any process to exit during the check
  2540. my %started;
  2541. foreach my $mysqld ( mysqlds() )
  2542. {
  2543. # Skip if server has been restarted with additional options
  2544. if ( defined $mysqld->{'proc'} && ! exists $mysqld->{'restart_opts'} )
  2545. {
  2546. my $proc= start_check_testcase($tinfo, $mode, $mysqld);
  2547. $started{$proc->pid()}= $proc;
  2548. }
  2549. }
  2550. # Return immediately if no check proceess was started
  2551. return 0 unless ( keys %started );
  2552. my $timeout= start_timer(check_timeout());
  2553. while (1){
  2554. my $result;
  2555. my $proc= My::SafeProcess->wait_any_timeout($timeout);
  2556. mtr_report("Got $proc");
  2557. if ( delete $started{$proc->pid()} ) {
  2558. my $err_file= $proc->user_data();
  2559. my $base_file= mtr_match_extension($err_file, "err"); # Trim extension
  2560. # One check testcase process returned
  2561. my $res= $proc->exit_status();
  2562. if ( $res == 0){
  2563. # Check completed without problem
  2564. # Remove the .err file the check generated
  2565. unlink($err_file);
  2566. # Remove the .result file the check generated
  2567. if ( $mode eq 'after' ){
  2568. unlink("$base_file.result");
  2569. }
  2570. if ( keys(%started) == 0){
  2571. # All checks completed
  2572. return 0;
  2573. }
  2574. # Wait for next process to exit
  2575. next;
  2576. }
  2577. else
  2578. {
  2579. if ( $mode eq "after" and $res == 1 )
  2580. {
  2581. # Test failed, grab the report mysqltest has created
  2582. my $report= mtr_grab_file($err_file);
  2583. $tinfo->{check}.=
  2584. "\nMTR's internal check of the test case '$tname' failed.
  2585. This means that the test case does not preserve the state that existed
  2586. before the test case was executed. Most likely the test case did not
  2587. do a proper clean-up.
  2588. This is the diff of the states of the servers before and after the
  2589. test case was executed:\n";
  2590. $tinfo->{check}.= $report;
  2591. # Check failed, mark the test case with that info
  2592. $tinfo->{'check_testcase_failed'}= 1;
  2593. $result= 1;
  2594. }
  2595. elsif ( $res )
  2596. {
  2597. my $report= mtr_grab_file($err_file);
  2598. $tinfo->{comment}.=
  2599. "Could not execute 'check-testcase' $mode ".
  2600. "testcase '$tname' (res: $res):\n";
  2601. $tinfo->{comment}.= $report;
  2602. $result= 2;
  2603. }
  2604. # Remove the .result file the check generated
  2605. unlink("$base_file.result");
  2606. }
  2607. }
  2608. elsif ( $proc->{timeout} ) {
  2609. $tinfo->{comment}.= "Timeout for 'check-testcase' expired after "
  2610. .check_timeout()." seconds";
  2611. $result= 4;
  2612. }
  2613. else {
  2614. # Unknown process returned, most likley a crash, abort everything
  2615. $tinfo->{comment}=
  2616. "The server $proc crashed while running ".
  2617. "'check testcase $mode test'".
  2618. get_log_from_proc($proc, $tinfo->{name});
  2619. $result= 3;
  2620. }
  2621. # Kill any check processes still running
  2622. map($_->kill(), values(%started));
  2623. return $result;
  2624. }
  2625. mtr_error("INTERNAL_ERROR: check_testcase");
  2626. }
  2627. # Start run mysqltest on one server
  2628. #
  2629. # RETURN VALUE
  2630. # 0 OK
  2631. # 1 Check failed
  2632. #
  2633. sub start_run_one ($$) {
  2634. my ($mysqld, $run)= @_;
  2635. my $name= "$run-".$mysqld->name();
  2636. my $args;
  2637. mtr_init_args(\$args);
  2638. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2639. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  2640. mtr_add_arg($args, "--silent");
  2641. mtr_add_arg($args, "--skip-safemalloc");
  2642. mtr_add_arg($args, "--test-file=%s", "include/$run.test");
  2643. my $errfile= "$opt_vardir/tmp/$name.err";
  2644. my $proc= My::SafeProcess->new
  2645. (
  2646. name => $name,
  2647. path => $exe_mysqltest,
  2648. error => $errfile,
  2649. output => $errfile,
  2650. args => \$args,
  2651. user_data => $errfile,
  2652. verbose => $opt_verbose,
  2653. );
  2654. mtr_verbose("Started $proc");
  2655. return $proc;
  2656. }
  2657. #
  2658. # Run script on all servers, collect results
  2659. #
  2660. # RETURN VALUE
  2661. # 0 ok
  2662. # 1 Failure
  2663. sub run_on_all($$)
  2664. {
  2665. my ($tinfo, $run)= @_;
  2666. # Start the mysqltest processes in parallel to save time
  2667. # also makes it possible to wait for any process to exit during the check
  2668. # and to have a timeout process
  2669. my %started;
  2670. foreach my $mysqld ( mysqlds() )
  2671. {
  2672. if ( defined $mysqld->{'proc'} )
  2673. {
  2674. my $proc= start_run_one($mysqld, $run);
  2675. $started{$proc->pid()}= $proc;
  2676. }
  2677. }
  2678. # Return immediately if no check proceess was started
  2679. return 0 unless ( keys %started );
  2680. my $timeout= start_timer(check_timeout());
  2681. while (1){
  2682. my $result;
  2683. my $proc= My::SafeProcess->wait_any_timeout($timeout);
  2684. mtr_report("Got $proc");
  2685. if ( delete $started{$proc->pid()} ) {
  2686. # One mysqltest process returned
  2687. my $err_file= $proc->user_data();
  2688. my $res= $proc->exit_status();
  2689. # Append the report from .err file
  2690. $tinfo->{comment}.= " == $err_file ==\n";
  2691. $tinfo->{comment}.= mtr_grab_file($err_file);
  2692. $tinfo->{comment}.= "\n";
  2693. # Remove the .err file
  2694. unlink($err_file);
  2695. if ( keys(%started) == 0){
  2696. # All completed
  2697. return 0;
  2698. }
  2699. # Wait for next process to exit
  2700. next;
  2701. }
  2702. elsif ($proc->{timeout}) {
  2703. $tinfo->{comment}.= "Timeout for '$run' expired after "
  2704. .check_timeout()." seconds";
  2705. }
  2706. else {
  2707. # Unknown process returned, most likley a crash, abort everything
  2708. $tinfo->{comment}.=
  2709. "The server $proc crashed while running '$run'".
  2710. get_log_from_proc($proc, $tinfo->{name});
  2711. }
  2712. # Kill any check processes still running
  2713. map($_->kill(), values(%started));
  2714. return 1;
  2715. }
  2716. mtr_error("INTERNAL_ERROR: run_on_all");
  2717. }
  2718. sub mark_log {
  2719. my ($log, $tinfo)= @_;
  2720. my $log_msg= "CURRENT_TEST: $tinfo->{name}\n";
  2721. mtr_tofile($log, $log_msg);
  2722. }
  2723. sub find_testcase_skipped_reason($)
  2724. {
  2725. my ($tinfo)= @_;
  2726. # Set default message
  2727. $tinfo->{'comment'}= "Detected by testcase(no log file)";
  2728. # Open the test log file
  2729. my $F= IO::File->new($path_current_testlog)
  2730. or return;
  2731. my $reason;
  2732. while ( my $line= <$F> )
  2733. {
  2734. # Look for "reason: <reason for skipping test>"
  2735. if ( $line =~ /reason: (.*)/ )
  2736. {
  2737. $reason= $1;
  2738. }
  2739. }
  2740. if ( ! $reason )
  2741. {
  2742. mtr_warning("Could not find reason for skipping test in $path_current_testlog");
  2743. $reason= "Detected by testcase(reason unknown) ";
  2744. }
  2745. $tinfo->{'comment'}= $reason;
  2746. }
  2747. sub find_analyze_request
  2748. {
  2749. # Open the test log file
  2750. my $F= IO::File->new($path_current_testlog)
  2751. or return;
  2752. my $analyze;
  2753. while ( my $line= <$F> )
  2754. {
  2755. # Look for "reason: <reason for skipping test>"
  2756. if ( $line =~ /analyze: (.*)/ )
  2757. {
  2758. $analyze= $1;
  2759. }
  2760. }
  2761. return $analyze;
  2762. }
  2763. # The test can leave a file in var/tmp/ to signal
  2764. # that all servers should be restarted
  2765. sub restart_forced_by_test
  2766. {
  2767. my $restart = 0;
  2768. foreach my $mysqld ( mysqlds() )
  2769. {
  2770. my $datadir = $mysqld->value('datadir');
  2771. my $force_restart_file = "$datadir/mtr/force_restart";
  2772. if ( -f $force_restart_file )
  2773. {
  2774. mtr_verbose("Restart of servers forced by test");
  2775. $restart = 1;
  2776. last;
  2777. }
  2778. }
  2779. return $restart;
  2780. }
  2781. # Return timezone value of tinfo or default value
  2782. sub timezone {
  2783. my ($tinfo)= @_;
  2784. return $tinfo->{timezone} || "GMT-3";
  2785. }
  2786. # Storage for changed environment variables
  2787. my %old_env;
  2788. #
  2789. # Run a single test case
  2790. #
  2791. # RETURN VALUE
  2792. # 0 OK
  2793. # > 0 failure
  2794. #
  2795. sub run_testcase ($) {
  2796. my $tinfo= shift;
  2797. mtr_verbose("Running test:", $tinfo->{name});
  2798. # Allow only alpanumerics pluss _ - + . in combination names,
  2799. # or anything beginning with -- (the latter comes from --combination)
  2800. my $combination= $tinfo->{combination};
  2801. if ($combination && $combination !~ /^\w[-\w\.\+]+$/
  2802. && $combination !~ /^--/)
  2803. {
  2804. mtr_error("Combination '$combination' contains illegal characters");
  2805. }
  2806. # -------------------------------------------------------
  2807. # Init variables that can change between each test case
  2808. # -------------------------------------------------------
  2809. my $timezone= timezone($tinfo);
  2810. $ENV{'TZ'}= $timezone;
  2811. mtr_verbose("Setting timezone: $timezone");
  2812. if ( ! using_extern() )
  2813. {
  2814. my @restart= servers_need_restart($tinfo);
  2815. if ( @restart != 0) {
  2816. stop_servers($tinfo, @restart );
  2817. }
  2818. if ( started(all_servers()) == 0 )
  2819. {
  2820. # Remove old datadirs
  2821. clean_datadir() unless $opt_start_dirty;
  2822. # Restore old ENV
  2823. while (my ($option, $value)= each( %old_env )) {
  2824. if (defined $value){
  2825. mtr_verbose("Restoring $option to $value");
  2826. $ENV{$option}= $value;
  2827. } else {
  2828. mtr_verbose("Removing $option");
  2829. delete($ENV{$option});
  2830. }
  2831. }
  2832. %old_env= ();
  2833. mtr_verbose("Generating my.cnf from '$tinfo->{template_path}'");
  2834. # Generate new config file from template
  2835. $config= My::ConfigFactory->new_config
  2836. ( {
  2837. basedir => $basedir,
  2838. testdir => $glob_mysql_test_dir,
  2839. template_path => $tinfo->{template_path},
  2840. extra_template_path => $tinfo->{extra_template_path},
  2841. vardir => $opt_vardir,
  2842. tmpdir => $opt_tmpdir,
  2843. baseport => $baseport,
  2844. #hosts => [ 'host1', 'host2' ],
  2845. user => $opt_user,
  2846. password => '',
  2847. ssl => $opt_ssl_supported,
  2848. embedded => $opt_embedded_server,
  2849. }
  2850. );
  2851. # Write the new my.cnf
  2852. $config->save($path_config_file);
  2853. # Remember current config so a restart can occur when a test need
  2854. # to use a different one
  2855. $current_config_name= $tinfo->{template_path};
  2856. #
  2857. # Set variables in the ENV section
  2858. #
  2859. foreach my $option ($config->options_in_group("ENV"))
  2860. {
  2861. # Save old value to restore it before next time
  2862. $old_env{$option->name()}= $ENV{$option->name()};
  2863. mtr_verbose($option->name(), "=",$option->value());
  2864. $ENV{$option->name()}= $option->value();
  2865. }
  2866. }
  2867. # Write start of testcase to log
  2868. mark_log($path_current_testlog, $tinfo);
  2869. if (start_servers($tinfo))
  2870. {
  2871. report_failure_and_restart($tinfo);
  2872. return 1;
  2873. }
  2874. }
  2875. # --------------------------------------------------------------------
  2876. # If --start or --start-dirty given, stop here to let user manually
  2877. # run tests
  2878. # If --wait-all is also given, do the same, but don't die if one
  2879. # server exits
  2880. # ----------------------------------------------------------------------
  2881. if ( $start_only )
  2882. {
  2883. mtr_print("\nStarted", started(all_servers()));
  2884. mtr_print("Using config for test", $tinfo->{name});
  2885. mtr_print("Port and socket path for server(s):");
  2886. foreach my $mysqld ( mysqlds() )
  2887. {
  2888. mtr_print ($mysqld->name() . " " . $mysqld->value('port') .
  2889. " " . $mysqld->value('socket'));
  2890. }
  2891. if ( $opt_start_exit )
  2892. {
  2893. mtr_print("Server(s) started, not waiting for them to finish");
  2894. if (IS_WINDOWS)
  2895. {
  2896. POSIX::_exit(0); # exit hangs here in ActiveState Perl
  2897. }
  2898. else
  2899. {
  2900. exit(0);
  2901. }
  2902. }
  2903. mtr_print("Waiting for server(s) to exit...");
  2904. if ( $opt_wait_all ) {
  2905. My::SafeProcess->wait_all();
  2906. mtr_print( "All servers exited" );
  2907. exit(1);
  2908. }
  2909. else {
  2910. my $proc= My::SafeProcess->wait_any();
  2911. if ( grep($proc eq $_, started(all_servers())) )
  2912. {
  2913. mtr_print("Server $proc died");
  2914. exit(1);
  2915. }
  2916. mtr_print("Unknown process $proc died");
  2917. exit(1);
  2918. }
  2919. }
  2920. my $test_timeout= start_timer(testcase_timeout($tinfo));
  2921. do_before_run_mysqltest($tinfo);
  2922. if ( $opt_check_testcases and check_testcase($tinfo, "before") ){
  2923. # Failed to record state of server or server crashed
  2924. report_failure_and_restart($tinfo);
  2925. return 1;
  2926. }
  2927. my $test= start_mysqltest($tinfo);
  2928. # Set only when we have to keep waiting after expectedly died server
  2929. my $keep_waiting_proc = 0;
  2930. while (1)
  2931. {
  2932. my $proc;
  2933. if ($keep_waiting_proc)
  2934. {
  2935. # Any other process exited?
  2936. $proc = My::SafeProcess->check_any();
  2937. if ($proc)
  2938. {
  2939. mtr_verbose ("Found exited process $proc");
  2940. }
  2941. else
  2942. {
  2943. $proc = $keep_waiting_proc;
  2944. # Also check if timer has expired, if so cancel waiting
  2945. if ( has_expired($test_timeout) )
  2946. {
  2947. $keep_waiting_proc = 0;
  2948. }
  2949. }
  2950. }
  2951. if (! $keep_waiting_proc)
  2952. {
  2953. $proc= My::SafeProcess->wait_any_timeout($test_timeout);
  2954. }
  2955. # Will be restored if we need to keep waiting
  2956. $keep_waiting_proc = 0;
  2957. unless ( defined $proc )
  2958. {
  2959. mtr_error("wait_any failed");
  2960. }
  2961. mtr_verbose("Got $proc");
  2962. # ----------------------------------------------------
  2963. # Was it the test program that exited
  2964. # ----------------------------------------------------
  2965. if ($proc eq $test)
  2966. {
  2967. my $res= $test->exit_status();
  2968. if ($res == 0 and $opt_warnings and check_warnings($tinfo) )
  2969. {
  2970. # Test case suceeded, but it has produced unexpected
  2971. # warnings, continue in $res == 1
  2972. $res= 1;
  2973. }
  2974. if ( $res == 0 )
  2975. {
  2976. my $check_res;
  2977. if ( restart_forced_by_test() )
  2978. {
  2979. stop_all_servers($opt_shutdown_timeout);
  2980. }
  2981. elsif ( $opt_check_testcases and
  2982. $check_res= check_testcase($tinfo, "after"))
  2983. {
  2984. if ($check_res == 1) {
  2985. # Test case had sideeffects, not fatal error, just continue
  2986. stop_all_servers($opt_shutdown_timeout);
  2987. mtr_report("Resuming tests...\n");
  2988. }
  2989. else {
  2990. # Test case check failed fatally, probably a server crashed
  2991. report_failure_and_restart($tinfo);
  2992. return 1;
  2993. }
  2994. }
  2995. mtr_report_test_passed($tinfo);
  2996. }
  2997. elsif ( $res == 62 )
  2998. {
  2999. # Testcase itself tell us to skip this one
  3000. $tinfo->{skip_detected_by_test}= 1;
  3001. # Try to get reason from test log file
  3002. find_testcase_skipped_reason($tinfo);
  3003. mtr_report_test_skipped($tinfo);
  3004. }
  3005. elsif ( $res == 65 )
  3006. {
  3007. # Testprogram killed by signal
  3008. $tinfo->{comment}=
  3009. "testprogram crashed(returned code $res)";
  3010. report_failure_and_restart($tinfo);
  3011. }
  3012. elsif ( $res == 1 )
  3013. {
  3014. # Check if the test tool requests that
  3015. # an analyze script should be run
  3016. my $analyze= find_analyze_request();
  3017. if ($analyze){
  3018. run_on_all($tinfo, "analyze-$analyze");
  3019. }
  3020. # Wait a bit and see if a server died, if so report that instead
  3021. mtr_milli_sleep(100);
  3022. my $srvproc= My::SafeProcess::check_any();
  3023. if ($srvproc && grep($srvproc eq $_, started(all_servers()))) {
  3024. $proc= $srvproc;
  3025. goto SRVDIED;
  3026. }
  3027. # Test case failure reported by mysqltest
  3028. report_failure_and_restart($tinfo);
  3029. }
  3030. else
  3031. {
  3032. # mysqltest failed, probably crashed
  3033. $tinfo->{comment}=
  3034. "mysqltest failed with unexpected return code $res\n";
  3035. report_failure_and_restart($tinfo);
  3036. }
  3037. # Save info from this testcase run to mysqltest.log
  3038. if( -f $path_current_testlog)
  3039. {
  3040. mtr_appendfile_to_file($path_current_testlog, $path_testlog);
  3041. unlink($path_current_testlog);
  3042. }
  3043. return ($res == 62) ? 0 : $res;
  3044. }
  3045. # ----------------------------------------------------
  3046. # Check if it was an expected crash
  3047. # ----------------------------------------------------
  3048. SRVDIED:
  3049. my $check_crash = check_expected_crash_and_restart($proc);
  3050. if ($check_crash)
  3051. {
  3052. # Keep waiting if it returned 2, if 1 don't wait or stop waiting.
  3053. $keep_waiting_proc = 0 if $check_crash == 1;
  3054. $keep_waiting_proc = $proc if $check_crash == 2;
  3055. next;
  3056. }
  3057. # ----------------------------------------------------
  3058. # Stop the test case timer
  3059. # ----------------------------------------------------
  3060. $test_timeout= 0;
  3061. # ----------------------------------------------------
  3062. # Check if it was a server that died
  3063. # ----------------------------------------------------
  3064. if ( grep($proc eq $_, started(all_servers())) )
  3065. {
  3066. # Server failed, probably crashed
  3067. $tinfo->{comment}=
  3068. "Server $proc failed during test run" .
  3069. get_log_from_proc($proc, $tinfo->{name});
  3070. # ----------------------------------------------------
  3071. # It's not mysqltest that has exited, kill it
  3072. # ----------------------------------------------------
  3073. $test->kill();
  3074. report_failure_and_restart($tinfo);
  3075. return 1;
  3076. }
  3077. # Try to dump core for mysqltest and all servers
  3078. foreach my $proc ($test, started(all_servers()))
  3079. {
  3080. mtr_print("Trying to dump core for $proc");
  3081. if ($proc->dump_core())
  3082. {
  3083. $proc->wait_one(20);
  3084. }
  3085. }
  3086. # ----------------------------------------------------
  3087. # It's not mysqltest that has exited, kill it
  3088. # ----------------------------------------------------
  3089. $test->kill();
  3090. # ----------------------------------------------------
  3091. # Check if testcase timer expired
  3092. # ----------------------------------------------------
  3093. if ( $proc->{timeout} )
  3094. {
  3095. my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log";
  3096. $tinfo->{comment}=
  3097. "Test case timeout after ".testcase_timeout($tinfo).
  3098. " seconds\n\n";
  3099. # Add 20 last executed commands from test case log file
  3100. if (-e $log_file_name)
  3101. {
  3102. $tinfo->{comment}.=
  3103. "== $log_file_name == \n".
  3104. mtr_lastlinesfromfile($log_file_name, 20)."\n";
  3105. }
  3106. $tinfo->{'timeout'}= testcase_timeout($tinfo); # Mark as timeout
  3107. run_on_all($tinfo, 'analyze-timeout');
  3108. report_failure_and_restart($tinfo);
  3109. return 1;
  3110. }
  3111. mtr_error("Unhandled process $proc exited");
  3112. }
  3113. mtr_error("Should never come here");
  3114. }
  3115. # Extract server log from after the last occurrence of named test
  3116. # Return as an array of lines
  3117. #
  3118. sub extract_server_log ($$) {
  3119. my ($error_log, $tname) = @_;
  3120. # Open the servers .err log file and read all lines
  3121. # belonging to current tets into @lines
  3122. my $Ferr = IO::File->new($error_log)
  3123. or mtr_error("Could not open file '$error_log' for reading: $!");
  3124. my @lines;
  3125. my $found_test= 0; # Set once we've found the log of this test
  3126. while ( my $line = <$Ferr> )
  3127. {
  3128. if ($found_test)
  3129. {
  3130. # If test wasn't last after all, discard what we found, test again.
  3131. if ( $line =~ /^CURRENT_TEST:/)
  3132. {
  3133. @lines= ();
  3134. $found_test= $line =~ /^CURRENT_TEST: $tname/;
  3135. }
  3136. else
  3137. {
  3138. push(@lines, $line);
  3139. }
  3140. }
  3141. else
  3142. {
  3143. # Search for beginning of test, until found
  3144. $found_test= 1 if ($line =~ /^CURRENT_TEST: $tname/);
  3145. }
  3146. }
  3147. $Ferr = undef; # Close error log file
  3148. # mysql_client_test.test sends a COM_DEBUG packet to the server
  3149. # to provoke a SAFEMALLOC leak report, ignore any warnings
  3150. # between "Begin/end safemalloc memory dump"
  3151. if ( grep(/Begin safemalloc memory dump:/, @lines) > 0)
  3152. {
  3153. my $discard_lines= 1;
  3154. foreach my $line ( @lines )
  3155. {
  3156. if ($line =~ /Begin safemalloc memory dump:/){
  3157. $discard_lines = 1;
  3158. } elsif ($line =~ /End safemalloc memory dump./){
  3159. $discard_lines = 0;
  3160. }
  3161. if ($discard_lines){
  3162. $line = "ignored";
  3163. }
  3164. }
  3165. }
  3166. return @lines;
  3167. }
  3168. # Get log from server identified from its $proc object, from named test
  3169. # Return as a single string
  3170. #
  3171. sub get_log_from_proc ($$) {
  3172. my ($proc, $name)= @_;
  3173. my $srv_log= "";
  3174. foreach my $mysqld (mysqlds()) {
  3175. if ($mysqld->{proc} eq $proc) {
  3176. my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name);
  3177. $srv_log= "\nServer log from this test:\n" . join ("", @srv_lines);
  3178. last;
  3179. }
  3180. }
  3181. return $srv_log;
  3182. }
  3183. # Perform a rough examination of the servers
  3184. # error log and write all lines that look
  3185. # suspicious into $error_log.warnings
  3186. #
  3187. sub extract_warning_lines ($$) {
  3188. my ($error_log, $tname) = @_;
  3189. my @lines= extract_server_log($error_log, $tname);
  3190. # Write all suspicious lines to $error_log.warnings file
  3191. my $warning_log = "$error_log.warnings";
  3192. my $Fwarn = IO::File->new($warning_log, "w")
  3193. or die("Could not open file '$warning_log' for writing: $!");
  3194. print $Fwarn "Suspicious lines from $error_log\n";
  3195. my @patterns =
  3196. (
  3197. qr/^Warning:|mysqld: Warning|\[Warning\]/,
  3198. qr/^Error:|\[ERROR\]/,
  3199. qr/^==\d+==\s+\S/, # valgrind errors
  3200. qr/InnoDB: Warning|InnoDB: Error/,
  3201. qr/^safe_mutex:|allocated at line/,
  3202. qr/missing DBUG_RETURN/,
  3203. qr/Attempting backtrace/,
  3204. qr/Assertion .* failed/,
  3205. );
  3206. my $skip_valgrind= 0;
  3207. foreach my $line ( @lines )
  3208. {
  3209. if ($opt_valgrind_mysqld) {
  3210. # Skip valgrind summary from tests where server has been restarted
  3211. # Should this contain memory leaks, the final report will find it
  3212. # Use a generic pattern for summaries
  3213. $skip_valgrind= 1 if $line =~ /^==\d+== [A-Z ]+ SUMMARY:/;
  3214. $skip_valgrind= 0 unless $line =~ /^==\d+==/;
  3215. next if $skip_valgrind;
  3216. }
  3217. foreach my $pat ( @patterns )
  3218. {
  3219. if ( $line =~ /$pat/ )
  3220. {
  3221. print $Fwarn $line;
  3222. last;
  3223. }
  3224. }
  3225. }
  3226. $Fwarn = undef; # Close file
  3227. }
  3228. # Run include/check-warnings.test
  3229. #
  3230. # RETURN VALUE
  3231. # 0 OK
  3232. # 1 Check failed
  3233. #
  3234. sub start_check_warnings ($$) {
  3235. my $tinfo= shift;
  3236. my $mysqld= shift;
  3237. my $name= "warnings-".$mysqld->name();
  3238. my $log_error= $mysqld->value('#log-error');
  3239. # To be communicated to the test
  3240. $ENV{MTR_LOG_ERROR}= $log_error;
  3241. extract_warning_lines($log_error, $tinfo->{name});
  3242. my $args;
  3243. mtr_init_args(\$args);
  3244. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  3245. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  3246. mtr_add_arg($args, "--skip-safemalloc");
  3247. mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test");
  3248. if ( $opt_embedded_server )
  3249. {
  3250. # Get the args needed for the embedded server
  3251. # and append them to args prefixed
  3252. # with --sever-arg=
  3253. my $mysqld= $config->group('embedded')
  3254. or mtr_error("Could not get [embedded] section");
  3255. my $mysqld_args;
  3256. mtr_init_args(\$mysqld_args);
  3257. my $extra_opts= get_extra_opts($mysqld, $tinfo);
  3258. mysqld_arguments($mysqld_args, $mysqld, $extra_opts);
  3259. mtr_add_arg($args, "--server-arg=%s", $_) for @$mysqld_args;
  3260. }
  3261. my $errfile= "$opt_vardir/tmp/$name.err";
  3262. my $proc= My::SafeProcess->new
  3263. (
  3264. name => $name,
  3265. path => $exe_mysqltest,
  3266. error => $errfile,
  3267. output => $errfile,
  3268. args => \$args,
  3269. user_data => $errfile,
  3270. verbose => $opt_verbose,
  3271. );
  3272. mtr_verbose("Started $proc");
  3273. return $proc;
  3274. }
  3275. #
  3276. # Loop through our list of processes and check the error log
  3277. # for unexepcted errors and warnings
  3278. #
  3279. sub check_warnings ($) {
  3280. my ($tinfo)= @_;
  3281. my $res= 0;
  3282. my $tname= $tinfo->{name};
  3283. # Clear previous warnings
  3284. delete($tinfo->{warnings});
  3285. # Start the mysqltest processes in parallel to save time
  3286. # also makes it possible to wait for any process to exit during the check
  3287. my %started;
  3288. foreach my $mysqld ( mysqlds() )
  3289. {
  3290. if ( defined $mysqld->{'proc'} )
  3291. {
  3292. my $proc= start_check_warnings($tinfo, $mysqld);
  3293. $started{$proc->pid()}= $proc;
  3294. }
  3295. }
  3296. # Return immediately if no check proceess was started
  3297. return 0 unless ( keys %started );
  3298. my $timeout= start_timer(check_timeout());
  3299. while (1){
  3300. my $result= 0;
  3301. my $proc= My::SafeProcess->wait_any_timeout($timeout);
  3302. mtr_report("Got $proc");
  3303. if ( delete $started{$proc->pid()} ) {
  3304. # One check warning process returned
  3305. my $res= $proc->exit_status();
  3306. my $err_file= $proc->user_data();
  3307. if ( $res == 0 or $res == 62 ){
  3308. if ( $res == 0 ) {
  3309. # Check completed with problem
  3310. my $report= mtr_grab_file($err_file);
  3311. # Log to var/log/warnings file
  3312. mtr_tofile("$opt_vardir/log/warnings",
  3313. $tname."\n".$report);
  3314. $tinfo->{'warnings'}.= $report;
  3315. $result= 1;
  3316. }
  3317. if ( $res == 62 ) {
  3318. # Test case was ok and called "skip"
  3319. # Remove the .err file the check generated
  3320. unlink($err_file);
  3321. }
  3322. if ( keys(%started) == 0){
  3323. # All checks completed
  3324. return $result;
  3325. }
  3326. # Wait for next process to exit
  3327. next;
  3328. }
  3329. else
  3330. {
  3331. my $report= mtr_grab_file($err_file);
  3332. $tinfo->{comment}.=
  3333. "Could not execute 'check-warnings' for ".
  3334. "testcase '$tname' (res: $res):\n";
  3335. $tinfo->{comment}.= $report;
  3336. $result= 2;
  3337. }
  3338. }
  3339. elsif ( $proc->{timeout} ) {
  3340. $tinfo->{comment}.= "Timeout for 'check warnings' expired after "
  3341. .check_timeout()." seconds";
  3342. $result= 4;
  3343. }
  3344. else {
  3345. # Unknown process returned, most likley a crash, abort everything
  3346. $tinfo->{comment}=
  3347. "The server $proc crashed while running 'check warnings'".
  3348. get_log_from_proc($proc, $tinfo->{name});
  3349. $result= 3;
  3350. }
  3351. # Kill any check processes still running
  3352. map($_->kill(), values(%started));
  3353. return $result;
  3354. }
  3355. mtr_error("INTERNAL_ERROR: check_warnings");
  3356. }
  3357. #
  3358. # Loop through our list of processes and look for and entry
  3359. # with the provided pid, if found check for the file indicating
  3360. # expected crash and restart it.
  3361. #
  3362. sub check_expected_crash_and_restart {
  3363. my ($proc)= @_;
  3364. foreach my $mysqld ( mysqlds() )
  3365. {
  3366. next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc );
  3367. # Check if crash expected by looking at the .expect file
  3368. # in var/tmp
  3369. my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
  3370. if ( -f $expect_file )
  3371. {
  3372. mtr_verbose("Crash was expected, file '$expect_file' exists");
  3373. for (my $waits = 0; $waits < 50; $waits++)
  3374. {
  3375. # If last line in expect file starts with "wait"
  3376. # sleep a little and try again, thus allowing the
  3377. # test script to control when the server should start
  3378. # up again. Keep trying for up to 5s at a time.
  3379. my $last_line= mtr_lastlinesfromfile($expect_file, 1);
  3380. if ($last_line =~ /^wait/ )
  3381. {
  3382. mtr_verbose("Test says wait before restart") if $waits == 0;
  3383. mtr_milli_sleep(100);
  3384. next;
  3385. }
  3386. # If last line begins "restart:", the rest of the line is read as
  3387. # extra command line options to add to the restarted mysqld.
  3388. # Anything other than 'wait' or 'restart:' (with a colon) will
  3389. # result in a restart with original mysqld options.
  3390. if ($last_line =~ /restart:(.+)/) {
  3391. my @rest_opt= split(' ', $1);
  3392. $mysqld->{'restart_opts'}= \@rest_opt;
  3393. } else {
  3394. delete $mysqld->{'restart_opts'};
  3395. }
  3396. unlink($expect_file);
  3397. # Start server with same settings as last time
  3398. mysqld_start($mysqld, $mysqld->{'started_opts'});
  3399. return 1;
  3400. }
  3401. # Loop ran through: we should keep waiting after a re-check
  3402. return 2;
  3403. }
  3404. }
  3405. # Not an expected crash
  3406. return 0;
  3407. }
  3408. # Remove all files and subdirectories of a directory
  3409. sub clean_dir {
  3410. my ($dir)= @_;
  3411. mtr_verbose("clean_dir: $dir");
  3412. finddepth(
  3413. { no_chdir => 1,
  3414. wanted => sub {
  3415. if (-d $_){
  3416. # A dir
  3417. if ($_ eq $dir){
  3418. # The dir to clean
  3419. return;
  3420. } else {
  3421. mtr_verbose("rmdir: '$_'");
  3422. rmdir($_) or mtr_warning("rmdir($_) failed: $!");
  3423. }
  3424. } else {
  3425. # Hopefully a file
  3426. mtr_verbose("unlink: '$_'");
  3427. unlink($_) or mtr_warning("unlink($_) failed: $!");
  3428. }
  3429. }
  3430. },
  3431. $dir);
  3432. }
  3433. sub clean_datadir {
  3434. mtr_verbose("Cleaning datadirs...");
  3435. if (started(all_servers()) != 0){
  3436. mtr_error("Trying to clean datadir before all servers stopped");
  3437. }
  3438. foreach my $cluster ( clusters() )
  3439. {
  3440. my $cluster_dir= "$opt_vardir/".$cluster->{name};
  3441. mtr_verbose(" - removing '$cluster_dir'");
  3442. rmtree($cluster_dir);
  3443. }
  3444. foreach my $mysqld ( mysqlds() )
  3445. {
  3446. my $mysqld_dir= dirname($mysqld->value('datadir'));
  3447. if (-d $mysqld_dir ) {
  3448. mtr_verbose(" - removing '$mysqld_dir'");
  3449. rmtree($mysqld_dir);
  3450. }
  3451. }
  3452. # Remove all files in tmp and var/tmp
  3453. clean_dir("$opt_vardir/tmp");
  3454. if ($opt_tmpdir ne "$opt_vardir/tmp"){
  3455. clean_dir($opt_tmpdir);
  3456. }
  3457. }
  3458. #
  3459. # Save datadir before it's removed
  3460. #
  3461. sub save_datadir_after_failure($$) {
  3462. my ($dir, $savedir)= @_;
  3463. mtr_report(" - saving '$dir'");
  3464. my $dir_name= basename($dir);
  3465. rename("$dir", "$savedir/$dir_name");
  3466. }
  3467. sub remove_ndbfs_from_ndbd_datadir {
  3468. my ($ndbd_datadir)= @_;
  3469. # Remove the ndb_*_fs directory from ndbd.X/ dir
  3470. foreach my $ndbfs_dir ( glob("$ndbd_datadir/ndb_*_fs") )
  3471. {
  3472. next unless -d $ndbfs_dir; # Skip if not a directory
  3473. rmtree($ndbfs_dir);
  3474. }
  3475. }
  3476. sub after_failure ($) {
  3477. my ($tinfo)= @_;
  3478. mtr_report("Saving datadirs...");
  3479. my $save_dir= "$opt_vardir/log/";
  3480. $save_dir.= $tinfo->{name};
  3481. # Add combination name if any
  3482. $save_dir.= "-$tinfo->{combination}"
  3483. if defined $tinfo->{combination};
  3484. # Save savedir path for server
  3485. $tinfo->{savedir}= $save_dir;
  3486. mkpath($save_dir) if ! -d $save_dir;
  3487. # Save the used my.cnf file
  3488. copy($path_config_file, $save_dir);
  3489. # Copy the tmp dir
  3490. copytree("$opt_vardir/tmp/", "$save_dir/tmp/");
  3491. if ( clusters() ) {
  3492. foreach my $cluster ( clusters() ) {
  3493. my $cluster_dir= "$opt_vardir/".$cluster->{name};
  3494. # Remove the fileystem of each ndbd
  3495. foreach my $ndbd ( in_cluster($cluster, ndbds()) )
  3496. {
  3497. my $ndbd_datadir= $ndbd->value("DataDir");
  3498. remove_ndbfs_from_ndbd_datadir($ndbd_datadir);
  3499. }
  3500. save_datadir_after_failure($cluster_dir, $save_dir);
  3501. }
  3502. }
  3503. else {
  3504. foreach my $mysqld ( mysqlds() ) {
  3505. my $data_dir= $mysqld->value('datadir');
  3506. save_datadir_after_failure(dirname($data_dir), $save_dir);
  3507. }
  3508. }
  3509. }
  3510. sub report_failure_and_restart ($) {
  3511. my $tinfo= shift;
  3512. stop_all_servers();
  3513. $tinfo->{'result'}= 'MTR_RES_FAILED';
  3514. my $test_failures= $tinfo->{'failures'} || 0;
  3515. $tinfo->{'failures'}= $test_failures + 1;
  3516. if ( $tinfo->{comment} )
  3517. {
  3518. # The test failure has been detected by mysql-test-run.pl
  3519. # when starting the servers or due to other error, the reason for
  3520. # failing the test is saved in "comment"
  3521. ;
  3522. }
  3523. if ( !defined $tinfo->{logfile} )
  3524. {
  3525. my $logfile= $path_current_testlog;
  3526. if ( defined $logfile )
  3527. {
  3528. if ( -f $logfile )
  3529. {
  3530. # Test failure was detected by test tool and its report
  3531. # about what failed has been saved to file. Save the report
  3532. # in tinfo
  3533. $tinfo->{logfile}= mtr_fromfile($logfile);
  3534. # If no newlines in the test log:
  3535. # (it will contain the CURRENT_TEST written by mtr, so is not empty)
  3536. if ($tinfo->{logfile} !~ /\n/)
  3537. {
  3538. # Show how far it got before suddenly failing
  3539. $tinfo->{comment}.= "mysqltest failed but provided no output\n";
  3540. my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log";
  3541. if (-e $log_file_name) {
  3542. $tinfo->{comment}.=
  3543. "The result from queries just before the failure was:".
  3544. "\n< snip >\n".
  3545. mtr_lastlinesfromfile($log_file_name, 20)."\n";
  3546. }
  3547. }
  3548. }
  3549. else
  3550. {
  3551. # The test tool report didn't exist, display an
  3552. # error message
  3553. $tinfo->{logfile}= "Could not open test tool report '$logfile'";
  3554. }
  3555. }
  3556. }
  3557. after_failure($tinfo);
  3558. mtr_report_test($tinfo);
  3559. }
  3560. sub run_sh_script {
  3561. my ($script)= @_;
  3562. return 0 unless defined $script;
  3563. mtr_verbose("Running '$script'");
  3564. my $ret= system("/bin/sh $script") >> 8;
  3565. return $ret;
  3566. }
  3567. sub mysqld_stop {
  3568. my $mysqld= shift or die "usage: mysqld_stop(<mysqld>)";
  3569. my $args;
  3570. mtr_init_args(\$args);
  3571. mtr_add_arg($args, "--no-defaults");
  3572. mtr_add_arg($args, "--character-sets-dir=%s", $mysqld->value('character-sets-dir'));
  3573. mtr_add_arg($args, "--user=%s", $opt_user);
  3574. mtr_add_arg($args, "--password=");
  3575. mtr_add_arg($args, "--port=%d", $mysqld->value('port'));
  3576. mtr_add_arg($args, "--host=%s", $mysqld->value('#host'));
  3577. mtr_add_arg($args, "--connect_timeout=20");
  3578. mtr_add_arg($args, "--protocol=tcp");
  3579. mtr_add_arg($args, "shutdown");
  3580. My::SafeProcess->run
  3581. (
  3582. name => "mysqladmin shutdown ".$mysqld->name(),
  3583. path => $exe_mysqladmin,
  3584. args => \$args,
  3585. error => "/dev/null",
  3586. );
  3587. }
  3588. sub mysqld_arguments ($$$) {
  3589. my $args= shift;
  3590. my $mysqld= shift;
  3591. my $extra_opts= shift;
  3592. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  3593. # When mysqld is run by a root user(euid is 0), it will fail
  3594. # to start unless we specify what user to run as, see BUG#30630
  3595. my $euid= $>;
  3596. if (!IS_WINDOWS and $euid == 0 and
  3597. (grep(/^--user/, @$extra_opts)) == 0) {
  3598. mtr_add_arg($args, "--user=root");
  3599. }
  3600. if ( $opt_valgrind_mysqld )
  3601. {
  3602. mtr_add_arg($args, "--skip-safemalloc");
  3603. if ( $mysql_version_id < 50100 )
  3604. {
  3605. mtr_add_arg($args, "--skip-bdb");
  3606. }
  3607. }
  3608. if ( $mysql_version_id >= 50106 && !$opt_user_args)
  3609. {
  3610. # Turn on logging to file
  3611. mtr_add_arg($args, "--log-output=file");
  3612. }
  3613. # Check if "extra_opt" contains skip-log-bin
  3614. my $skip_binlog= grep(/^(--|--loose-)skip-log-bin/, @$extra_opts);
  3615. # Indicate to mysqld it will be debugged in debugger
  3616. if ( $glob_debugger )
  3617. {
  3618. mtr_add_arg($args, "--gdb");
  3619. }
  3620. my $found_skip_core= 0;
  3621. foreach my $arg ( @$extra_opts )
  3622. {
  3623. # Allow --skip-core-file to be set in <testname>-[master|slave].opt file
  3624. if ($arg eq "--skip-core-file")
  3625. {
  3626. $found_skip_core= 1;
  3627. }
  3628. elsif ($skip_binlog and mtr_match_prefix($arg, "--binlog-format"))
  3629. {
  3630. ; # Dont add --binlog-format when running without binlog
  3631. }
  3632. elsif ($arg eq "--loose-skip-log-bin" and
  3633. $mysqld->option("log-slave-updates"))
  3634. {
  3635. ; # Dont add --skip-log-bin when mysqld have --log-slave-updates in config
  3636. }
  3637. else
  3638. {
  3639. mtr_add_arg($args, "%s", $arg);
  3640. }
  3641. }
  3642. $opt_skip_core = $found_skip_core;
  3643. if ( !$found_skip_core && !$opt_user_args )
  3644. {
  3645. mtr_add_arg($args, "%s", "--core-file");
  3646. }
  3647. # Enable the debug sync facility, set default wait timeout.
  3648. # Facility stays disabled if timeout value is zero.
  3649. mtr_add_arg($args, "--loose-debug-sync-timeout=%s",
  3650. $opt_debug_sync_timeout) unless $opt_user_args;
  3651. return $args;
  3652. }
  3653. sub mysqld_start ($$) {
  3654. my $mysqld= shift;
  3655. my $extra_opts= shift;
  3656. mtr_verbose(My::Options::toStr("mysqld_start", @$extra_opts));
  3657. my $exe= find_mysqld($mysqld->value('basedir'));
  3658. my $wait_for_pid_file= 1;
  3659. mtr_error("Internal error: mysqld should never be started for embedded")
  3660. if $opt_embedded_server;
  3661. my $args;
  3662. mtr_init_args(\$args);
  3663. if ( $opt_valgrind_mysqld )
  3664. {
  3665. valgrind_arguments($args, \$exe);
  3666. }
  3667. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  3668. # Add any additional options from an in-test restart
  3669. my @all_opts= @$extra_opts;
  3670. if (exists $mysqld->{'restart_opts'}) {
  3671. push (@all_opts, @{$mysqld->{'restart_opts'}});
  3672. }
  3673. mysqld_arguments($args,$mysqld,\@all_opts);
  3674. if ( $opt_debug )
  3675. {
  3676. mtr_add_arg($args, "--debug=d:t:i:A,%s/log/%s.trace",
  3677. $path_vardir_trace, $mysqld->name());
  3678. }
  3679. if (IS_WINDOWS)
  3680. {
  3681. # Trick the server to send output to stderr, with --console
  3682. mtr_add_arg($args, "--console");
  3683. }
  3684. if ( $opt_gdb || $opt_manual_gdb )
  3685. {
  3686. gdb_arguments(\$args, \$exe, $mysqld->name());
  3687. }
  3688. elsif ( $opt_ddd || $opt_manual_ddd )
  3689. {
  3690. ddd_arguments(\$args, \$exe, $mysqld->name());
  3691. }
  3692. elsif ( $opt_debugger )
  3693. {
  3694. debugger_arguments(\$args, \$exe, $mysqld->name());
  3695. }
  3696. elsif ( $opt_manual_debug )
  3697. {
  3698. print "\nStart " .$mysqld->name()." in your debugger\n" .
  3699. "dir: $glob_mysql_test_dir\n" .
  3700. "exe: $exe\n" .
  3701. "args: " . join(" ", @$args) . "\n\n" .
  3702. "Waiting ....\n";
  3703. # Indicate the exe should not be started
  3704. $exe= undef;
  3705. }
  3706. else
  3707. {
  3708. # Default to not wait until pid file has been created
  3709. $wait_for_pid_file= 0;
  3710. }
  3711. # Remove the old pidfile if any
  3712. unlink($mysqld->value('pid-file'));
  3713. my $output= $mysqld->value('#log-error');
  3714. if ( $opt_valgrind and $opt_debug )
  3715. {
  3716. # When both --valgrind and --debug is selected, send
  3717. # all output to the trace file, making it possible to
  3718. # see the exact location where valgrind complains
  3719. $output= "$opt_vardir/log/".$mysqld->name().".trace";
  3720. }
  3721. # Remember this log file for valgrind error report search
  3722. $mysqld_logs{$output}= 1 if $opt_valgrind;
  3723. # Remember data dir for gmon.out files if using gprof
  3724. $gprof_dirs{$mysqld->value('datadir')}= 1 if $opt_gprof;
  3725. if ( defined $exe )
  3726. {
  3727. $mysqld->{'proc'}= My::SafeProcess->new
  3728. (
  3729. name => $mysqld->name(),
  3730. path => $exe,
  3731. args => \$args,
  3732. output => $output,
  3733. error => $output,
  3734. append => 1,
  3735. verbose => $opt_verbose,
  3736. nocore => $opt_skip_core,
  3737. host => undef,
  3738. shutdown => sub { mysqld_stop($mysqld) },
  3739. );
  3740. mtr_verbose("Started $mysqld->{proc}");
  3741. }
  3742. if ( $wait_for_pid_file &&
  3743. !sleep_until_file_created($mysqld->value('pid-file'),
  3744. $opt_start_timeout,
  3745. $mysqld->{'proc'}))
  3746. {
  3747. my $mname= $mysqld->name();
  3748. mtr_error("Failed to start mysqld $mname with command $exe");
  3749. }
  3750. # Remember options used when starting
  3751. $mysqld->{'started_opts'}= $extra_opts;
  3752. return;
  3753. }
  3754. sub stop_all_servers () {
  3755. my $shutdown_timeout = $_[0] or 0;
  3756. mtr_verbose("Stopping all servers...");
  3757. # Kill all started servers
  3758. My::SafeProcess::shutdown($shutdown_timeout,
  3759. started(all_servers()));
  3760. # Remove pidfiles
  3761. foreach my $server ( all_servers() )
  3762. {
  3763. my $pid_file= $server->if_exist('pid-file');
  3764. unlink($pid_file) if defined $pid_file;
  3765. }
  3766. # Mark servers as stopped
  3767. map($_->{proc}= undef, all_servers());
  3768. }
  3769. # Find out if server should be restarted for this test
  3770. sub server_need_restart {
  3771. my ($tinfo, $server)= @_;
  3772. if ( using_extern() )
  3773. {
  3774. mtr_verbose_restart($server, "no restart for --extern server");
  3775. return 0;
  3776. }
  3777. if ( $tinfo->{'force_restart'} ) {
  3778. mtr_verbose_restart($server, "forced in .opt file");
  3779. return 1;
  3780. }
  3781. if ( $opt_force_restart ) {
  3782. mtr_verbose_restart($server, "forced restart turned on");
  3783. return 1;
  3784. }
  3785. if ( $tinfo->{template_path} ne $current_config_name)
  3786. {
  3787. mtr_verbose_restart($server, "using different config file");
  3788. return 1;
  3789. }
  3790. if ( $tinfo->{'master_sh'} || $tinfo->{'slave_sh'} )
  3791. {
  3792. mtr_verbose_restart($server, "sh script to run");
  3793. return 1;
  3794. }
  3795. if ( ! started($server) )
  3796. {
  3797. mtr_verbose_restart($server, "not started");
  3798. return 1;
  3799. }
  3800. my $started_tinfo= $server->{'started_tinfo'};
  3801. if ( defined $started_tinfo )
  3802. {
  3803. # Check if timezone of test that server was started
  3804. # with differs from timezone of next test
  3805. if ( timezone($started_tinfo) ne timezone($tinfo) )
  3806. {
  3807. mtr_verbose_restart($server, "different timezone");
  3808. return 1;
  3809. }
  3810. }
  3811. # Temporary re-enable the "always restart slave" hack
  3812. # this should be removed asap, but will require that each rpl
  3813. # testcase cleanup better after itself - ie. stop and reset
  3814. # replication
  3815. # Use the "#!use-slave-opt" marker to detect that this is a "slave"
  3816. # server
  3817. if ( $server->option("#!use-slave-opt") ){
  3818. mtr_verbose_restart($server, "Always restart slave(s)");
  3819. return 1;
  3820. }
  3821. my $is_mysqld= grep ($server eq $_, mysqlds());
  3822. if ($is_mysqld)
  3823. {
  3824. # Check that running process was started with same options
  3825. # as the current test requires
  3826. my $extra_opts= get_extra_opts($server, $tinfo);
  3827. my $started_opts= $server->{'started_opts'};
  3828. # Also, always restart if server had been restarted with additional
  3829. # options within test.
  3830. if (!My::Options::same($started_opts, $extra_opts) ||
  3831. exists $server->{'restart_opts'})
  3832. {
  3833. my $use_dynamic_option_switch= 0;
  3834. if (!$use_dynamic_option_switch)
  3835. {
  3836. mtr_verbose_restart($server, "running with different options '" .
  3837. join(" ", @{$extra_opts}) . "' != '" .
  3838. join(" ", @{$started_opts}) . "'" );
  3839. return 1;
  3840. }
  3841. mtr_verbose(My::Options::toStr("started_opts", @$started_opts));
  3842. mtr_verbose(My::Options::toStr("extra_opts", @$extra_opts));
  3843. # Get diff and check if dynamic switch is possible
  3844. my @diff_opts= My::Options::diff($started_opts, $extra_opts);
  3845. mtr_verbose(My::Options::toStr("diff_opts", @diff_opts));
  3846. my $query= My::Options::toSQL(@diff_opts);
  3847. mtr_verbose("Attempting dynamic switch '$query'");
  3848. if (run_query($tinfo, $server, $query)){
  3849. mtr_verbose("Restart: running with different options '" .
  3850. join(" ", @{$extra_opts}) . "' != '" .
  3851. join(" ", @{$started_opts}) . "'" );
  3852. return 1;
  3853. }
  3854. # Remember the dynamically set options
  3855. $server->{'started_opts'}= $extra_opts;
  3856. }
  3857. }
  3858. # Default, no restart
  3859. return 0;
  3860. }
  3861. sub servers_need_restart($) {
  3862. my ($tinfo)= @_;
  3863. return grep { server_need_restart($tinfo, $_); } all_servers();
  3864. }
  3865. #
  3866. # Return list of specific servers
  3867. # - there is no servers in an empty config
  3868. #
  3869. sub _like { return $config ? $config->like($_[0]) : (); }
  3870. sub mysqlds { return _like('mysqld.'); }
  3871. sub ndbds { return _like('cluster_config.ndbd.');}
  3872. sub ndb_mgmds { return _like('cluster_config.ndb_mgmd.'); }
  3873. sub clusters { return _like('mysql_cluster.'); }
  3874. sub all_servers { return ( mysqlds(), ndb_mgmds(), ndbds() ); }
  3875. #
  3876. # Filter a list of servers and return only those that are part
  3877. # of the specified cluster
  3878. #
  3879. sub in_cluster {
  3880. my ($cluster)= shift;
  3881. # Return only processes for a specific cluster
  3882. return grep { $_->suffix() eq $cluster->suffix() } @_;
  3883. }
  3884. #
  3885. # Filter a list of servers and return the SafeProcess
  3886. # for only those that are started or stopped
  3887. #
  3888. sub started { return grep(defined $_, map($_->{proc}, @_)); }
  3889. sub stopped { return grep(!defined $_, map($_->{proc}, @_)); }
  3890. sub envsubst {
  3891. my $string= shift;
  3892. if ( ! defined $ENV{$string} )
  3893. {
  3894. mtr_error(".opt file references '$string' which is not set");
  3895. }
  3896. return $ENV{$string};
  3897. }
  3898. sub get_extra_opts {
  3899. # No extra options if --user-args
  3900. return \@opt_extra_mysqld_opt if $opt_user_args;
  3901. my ($mysqld, $tinfo)= @_;
  3902. my $opts=
  3903. $mysqld->option("#!use-slave-opt") ?
  3904. $tinfo->{slave_opt} : $tinfo->{master_opt};
  3905. # Expand environment variables
  3906. foreach my $opt ( @$opts )
  3907. {
  3908. $opt =~ s/\$\{(\w+)\}/envsubst($1)/ge;
  3909. $opt =~ s/\$(\w+)/envsubst($1)/ge;
  3910. }
  3911. return $opts;
  3912. }
  3913. sub stop_servers($$) {
  3914. my ($tinfo, @servers)= @_;
  3915. # Remember if we restarted for this test case (count restarts)
  3916. $tinfo->{'restarted'}= 1;
  3917. if ( join('|', @servers) eq join('|', all_servers()) )
  3918. {
  3919. # All servers are going down, use some kind of order to
  3920. # avoid too many warnings in the log files
  3921. mtr_report("Restarting all servers");
  3922. # mysqld processes
  3923. My::SafeProcess::shutdown( $opt_shutdown_timeout, started(mysqlds()) );
  3924. # cluster processes
  3925. My::SafeProcess::shutdown( $opt_shutdown_timeout,
  3926. started(ndbds(), ndb_mgmds()) );
  3927. }
  3928. else
  3929. {
  3930. mtr_report("Restarting ", started(@servers));
  3931. # Stop only some servers
  3932. My::SafeProcess::shutdown( $opt_shutdown_timeout,
  3933. started(@servers) );
  3934. }
  3935. foreach my $server (@servers)
  3936. {
  3937. # Mark server as stopped
  3938. $server->{proc}= undef;
  3939. # Forget history
  3940. delete $server->{'started_tinfo'};
  3941. delete $server->{'started_opts'};
  3942. delete $server->{'started_cnf'};
  3943. }
  3944. }
  3945. #
  3946. # start_servers
  3947. #
  3948. # Start servers not already started
  3949. #
  3950. # RETURN
  3951. # 0 OK
  3952. # 1 Start failed
  3953. #
  3954. sub start_servers($) {
  3955. my ($tinfo)= @_;
  3956. # Make sure the safe_process also exits from now on
  3957. # Could not be done before, as we don't want this for the bootstrap
  3958. if ($opt_start_exit) {
  3959. My::SafeProcess->start_exit();
  3960. }
  3961. # Start clusters
  3962. foreach my $cluster ( clusters() )
  3963. {
  3964. ndbcluster_start($cluster);
  3965. }
  3966. # Start mysqlds
  3967. foreach my $mysqld ( mysqlds() )
  3968. {
  3969. if ( $mysqld->{proc} )
  3970. {
  3971. # Already started
  3972. # Write start of testcase to log file
  3973. mark_log($mysqld->value('#log-error'), $tinfo);
  3974. next;
  3975. }
  3976. my $datadir= $mysqld->value('datadir');
  3977. if ($opt_start_dirty)
  3978. {
  3979. # Don't delete anything if starting dirty
  3980. ;
  3981. }
  3982. else
  3983. {
  3984. my @options= ('log-bin', 'relay-log');
  3985. foreach my $option_name ( @options ) {
  3986. next unless $mysqld->option($option_name);
  3987. my $file_name= $mysqld->value($option_name);
  3988. next unless
  3989. defined $file_name and
  3990. -e $file_name;
  3991. mtr_debug(" -removing '$file_name'");
  3992. unlink($file_name) or die ("unable to remove file '$file_name'");
  3993. }
  3994. if (-d $datadir ) {
  3995. mtr_verbose(" - removing '$datadir'");
  3996. rmtree($datadir);
  3997. }
  3998. }
  3999. my $mysqld_basedir= $mysqld->value('basedir');
  4000. if ( $basedir eq $mysqld_basedir )
  4001. {
  4002. if (! $opt_start_dirty) # If dirty, keep possibly grown system db
  4003. {
  4004. # Copy datadir from installed system db
  4005. for my $path ( "$opt_vardir", "$opt_vardir/..") {
  4006. my $install_db= "$path/install.db";
  4007. copytree($install_db, $datadir)
  4008. if -d $install_db;
  4009. }
  4010. mtr_error("Failed to copy system db to '$datadir'")
  4011. unless -d $datadir;
  4012. }
  4013. }
  4014. else
  4015. {
  4016. mysql_install_db($mysqld); # For versional testing
  4017. mtr_error("Failed to install system db to '$datadir'")
  4018. unless -d $datadir;
  4019. }
  4020. # Create the servers tmpdir
  4021. my $tmpdir= $mysqld->value('tmpdir');
  4022. mkpath($tmpdir) unless -d $tmpdir;
  4023. # Write start of testcase to log file
  4024. mark_log($mysqld->value('#log-error'), $tinfo);
  4025. # Run <tname>-master.sh
  4026. if ($mysqld->option('#!run-master-sh') and
  4027. run_sh_script($tinfo->{master_sh}) )
  4028. {
  4029. $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'";
  4030. return 1;
  4031. }
  4032. # Run <tname>-slave.sh
  4033. if ($mysqld->option('#!run-slave-sh') and
  4034. run_sh_script($tinfo->{slave_sh}))
  4035. {
  4036. $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'";
  4037. return 1;
  4038. }
  4039. if (!$opt_embedded_server)
  4040. {
  4041. my $extra_opts= get_extra_opts($mysqld, $tinfo);
  4042. mysqld_start($mysqld,$extra_opts);
  4043. # Save this test case information, so next can examine it
  4044. $mysqld->{'started_tinfo'}= $tinfo;
  4045. }
  4046. }
  4047. # Wait for clusters to start
  4048. foreach my $cluster ( clusters() )
  4049. {
  4050. if (ndbcluster_wait_started($cluster, ""))
  4051. {
  4052. # failed to start
  4053. $tinfo->{'comment'}= "Start of '".$cluster->name()."' cluster failed";
  4054. return 1;
  4055. }
  4056. }
  4057. # Wait for mysqlds to start
  4058. foreach my $mysqld ( mysqlds() )
  4059. {
  4060. next if !started($mysqld);
  4061. if (sleep_until_file_created($mysqld->value('pid-file'),
  4062. $opt_start_timeout,
  4063. $mysqld->{'proc'}) == 0) {
  4064. $tinfo->{comment}=
  4065. "Failed to start ".$mysqld->name();
  4066. my $logfile= $mysqld->value('#log-error');
  4067. if ( defined $logfile and -f $logfile )
  4068. {
  4069. my @srv_lines= extract_server_log($logfile, $tinfo->{name});
  4070. $tinfo->{logfile}= "Server log is:\n" . join ("", @srv_lines);
  4071. }
  4072. else
  4073. {
  4074. $tinfo->{logfile}= "Could not open server logfile: '$logfile'";
  4075. }
  4076. return 1;
  4077. }
  4078. }
  4079. return 0;
  4080. }
  4081. #
  4082. # Run include/check-testcase.test
  4083. # Before a testcase, run in record mode and save result file to var/tmp
  4084. # After testcase, run and compare with the recorded file, they should be equal!
  4085. #
  4086. # RETURN VALUE
  4087. # The newly started process
  4088. #
  4089. sub start_check_testcase ($$$) {
  4090. my $tinfo= shift;
  4091. my $mode= shift;
  4092. my $mysqld= shift;
  4093. my $name= "check-".$mysqld->name();
  4094. # Replace dots in name with underscore to avoid that mysqltest
  4095. # misinterpret's what the filename extension is :(
  4096. $name=~ s/\./_/g;
  4097. my $args;
  4098. mtr_init_args(\$args);
  4099. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  4100. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  4101. mtr_add_arg($args, "--skip-safemalloc");
  4102. mtr_add_arg($args, "--result-file=%s", "$opt_vardir/tmp/$name.result");
  4103. mtr_add_arg($args, "--test-file=%s", "include/check-testcase.test");
  4104. mtr_add_arg($args, "--verbose");
  4105. if ( $mode eq "before" )
  4106. {
  4107. mtr_add_arg($args, "--record");
  4108. }
  4109. my $errfile= "$opt_vardir/tmp/$name.err";
  4110. my $proc= My::SafeProcess->new
  4111. (
  4112. name => $name,
  4113. path => $exe_mysqltest,
  4114. error => $errfile,
  4115. output => $errfile,
  4116. args => \$args,
  4117. user_data => $errfile,
  4118. verbose => $opt_verbose,
  4119. );
  4120. mtr_report("Started $proc");
  4121. return $proc;
  4122. }
  4123. sub run_mysqltest ($) {
  4124. my $proc= start_mysqltest(@_);
  4125. $proc->wait();
  4126. }
  4127. sub start_mysqltest ($) {
  4128. my ($tinfo)= @_;
  4129. my $exe= $exe_mysqltest;
  4130. my $args;
  4131. mtr_init_args(\$args);
  4132. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  4133. mtr_add_arg($args, "--silent");
  4134. mtr_add_arg($args, "--skip-safemalloc");
  4135. mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
  4136. mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
  4137. mtr_add_arg($args, "--logdir=%s/log", $opt_vardir);
  4138. # Log line number and time for each line in .test file
  4139. mtr_add_arg($args, "--mark-progress")
  4140. if $opt_mark_progress;
  4141. mtr_add_arg($args, "--database=test");
  4142. if ( $opt_ps_protocol )
  4143. {
  4144. mtr_add_arg($args, "--ps-protocol");
  4145. }
  4146. if ( $opt_sp_protocol )
  4147. {
  4148. mtr_add_arg($args, "--sp-protocol");
  4149. }
  4150. if ( $opt_view_protocol )
  4151. {
  4152. mtr_add_arg($args, "--view-protocol");
  4153. }
  4154. if ( $opt_cursor_protocol )
  4155. {
  4156. mtr_add_arg($args, "--cursor-protocol");
  4157. }
  4158. if ( $opt_strace_client )
  4159. {
  4160. $exe= $opt_strace_client || "strace";
  4161. mtr_add_arg($args, "-o");
  4162. mtr_add_arg($args, "%s/log/mysqltest.strace", $opt_vardir);
  4163. mtr_add_arg($args, "$exe_mysqltest");
  4164. }
  4165. mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir);
  4166. if ( $opt_compress )
  4167. {
  4168. mtr_add_arg($args, "--compress");
  4169. }
  4170. if ( $opt_sleep )
  4171. {
  4172. mtr_add_arg($args, "--sleep=%d", $opt_sleep);
  4173. }
  4174. if ( $opt_ssl )
  4175. {
  4176. # Turn on SSL for _all_ test cases if option --ssl was used
  4177. mtr_add_arg($args, "--ssl");
  4178. }
  4179. if ( $opt_max_connections ) {
  4180. mtr_add_arg($args, "--max-connections=%d", $opt_max_connections);
  4181. }
  4182. if ( $opt_embedded_server )
  4183. {
  4184. # Get the args needed for the embedded server
  4185. # and append them to args prefixed
  4186. # with --sever-arg=
  4187. my $mysqld= $config->group('embedded')
  4188. or mtr_error("Could not get [embedded] section");
  4189. my $mysqld_args;
  4190. mtr_init_args(\$mysqld_args);
  4191. my $extra_opts= get_extra_opts($mysqld, $tinfo);
  4192. mysqld_arguments($mysqld_args, $mysqld, $extra_opts);
  4193. mtr_add_arg($args, "--server-arg=%s", $_) for @$mysqld_args;
  4194. if (IS_WINDOWS)
  4195. {
  4196. # Trick the server to send output to stderr, with --console
  4197. mtr_add_arg($args, "--server-arg=--console");
  4198. }
  4199. }
  4200. # ----------------------------------------------------------------------
  4201. # export MYSQL_TEST variable containing <path>/mysqltest <args>
  4202. # ----------------------------------------------------------------------
  4203. $ENV{'MYSQL_TEST'}= mtr_args2str($exe_mysqltest, @$args);
  4204. # ----------------------------------------------------------------------
  4205. # Add arguments that should not go into the MYSQL_TEST env var
  4206. # ----------------------------------------------------------------------
  4207. if ( $opt_valgrind_mysqltest )
  4208. {
  4209. # Prefix the Valgrind options to the argument list.
  4210. # We do this here, since we do not want to Valgrind the nested invocations
  4211. # of mysqltest; that would mess up the stderr output causing test failure.
  4212. my @args_saved = @$args;
  4213. mtr_init_args(\$args);
  4214. valgrind_arguments($args, \$exe);
  4215. mtr_add_arg($args, "%s", $_) for @args_saved;
  4216. }
  4217. mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
  4218. # Number of lines of resut to include in failure report
  4219. mtr_add_arg($args, "--tail-lines=20");
  4220. if ( defined $tinfo->{'result_file'} ) {
  4221. mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
  4222. }
  4223. client_debug_arg($args, "mysqltest");
  4224. if ( $opt_record )
  4225. {
  4226. mtr_add_arg($args, "--record");
  4227. # When recording to a non existing result file
  4228. # the name of that file is in "record_file"
  4229. if ( defined $tinfo->{'record_file'} ) {
  4230. mtr_add_arg($args, "--result-file=%s", $tinfo->{record_file});
  4231. }
  4232. }
  4233. if ( $opt_client_gdb )
  4234. {
  4235. gdb_arguments(\$args, \$exe, "client");
  4236. }
  4237. elsif ( $opt_client_ddd )
  4238. {
  4239. ddd_arguments(\$args, \$exe, "client");
  4240. }
  4241. elsif ( $opt_client_debugger )
  4242. {
  4243. debugger_arguments(\$args, \$exe, "client");
  4244. }
  4245. my $proc= My::SafeProcess->new
  4246. (
  4247. name => "mysqltest",
  4248. path => $exe,
  4249. args => \$args,
  4250. append => 1,
  4251. error => $path_current_testlog,
  4252. verbose => $opt_verbose,
  4253. );
  4254. mtr_verbose("Started $proc");
  4255. return $proc;
  4256. }
  4257. #
  4258. # Modify the exe and args so that program is run in gdb in xterm
  4259. #
  4260. sub gdb_arguments {
  4261. my $args= shift;
  4262. my $exe= shift;
  4263. my $type= shift;
  4264. # Write $args to gdb init file
  4265. my $str= join " ", map { s/"/\\"/g; "\"$_\""; } @$$args;
  4266. my $gdb_init_file= "$opt_vardir/tmp/gdbinit.$type";
  4267. # Remove the old gdbinit file
  4268. unlink($gdb_init_file);
  4269. if ( $type eq "client" )
  4270. {
  4271. # write init file for client
  4272. mtr_tofile($gdb_init_file,
  4273. "set args $str\n" .
  4274. "break main\n");
  4275. }
  4276. else
  4277. {
  4278. # write init file for mysqld
  4279. mtr_tofile($gdb_init_file,
  4280. "set args $str\n" .
  4281. "break mysql_parse\n" .
  4282. "commands 1\n" .
  4283. "disable 1\n" .
  4284. "end\n" .
  4285. "run");
  4286. }
  4287. if ( $opt_manual_gdb )
  4288. {
  4289. print "\nTo start gdb for $type, type in another window:\n";
  4290. print "gdb -cd $glob_mysql_test_dir -x $gdb_init_file $$exe\n";
  4291. # Indicate the exe should not be started
  4292. $$exe= undef;
  4293. return;
  4294. }
  4295. $$args= [];
  4296. mtr_add_arg($$args, "-title");
  4297. mtr_add_arg($$args, "$type");
  4298. mtr_add_arg($$args, "-e");
  4299. if ( $exe_libtool )
  4300. {
  4301. mtr_add_arg($$args, $exe_libtool);
  4302. mtr_add_arg($$args, "--mode=execute");
  4303. }
  4304. mtr_add_arg($$args, "gdb");
  4305. mtr_add_arg($$args, "-x");
  4306. mtr_add_arg($$args, "$gdb_init_file");
  4307. mtr_add_arg($$args, "$$exe");
  4308. $$exe= "xterm";
  4309. }
  4310. #
  4311. # Modify the exe and args so that program is run in ddd
  4312. #
  4313. sub ddd_arguments {
  4314. my $args= shift;
  4315. my $exe= shift;
  4316. my $type= shift;
  4317. # Write $args to ddd init file
  4318. my $str= join " ", map { s/"/\\"/g; "\"$_\""; } @$$args;
  4319. my $gdb_init_file= "$opt_vardir/tmp/gdbinit.$type";
  4320. # Remove the old gdbinit file
  4321. unlink($gdb_init_file);
  4322. if ( $type eq "client" )
  4323. {
  4324. # write init file for client
  4325. mtr_tofile($gdb_init_file,
  4326. "set args $str\n" .
  4327. "break main\n");
  4328. }
  4329. else
  4330. {
  4331. # write init file for mysqld
  4332. mtr_tofile($gdb_init_file,
  4333. "file $$exe\n" .
  4334. "set args $str\n" .
  4335. "break mysql_parse\n" .
  4336. "commands 1\n" .
  4337. "disable 1\n" .
  4338. "end");
  4339. }
  4340. if ( $opt_manual_ddd )
  4341. {
  4342. print "\nTo start ddd for $type, type in another window:\n";
  4343. print "ddd -cd $glob_mysql_test_dir -x $gdb_init_file $$exe\n";
  4344. # Indicate the exe should not be started
  4345. $$exe= undef;
  4346. return;
  4347. }
  4348. my $save_exe= $$exe;
  4349. $$args= [];
  4350. if ( $exe_libtool )
  4351. {
  4352. $$exe= $exe_libtool;
  4353. mtr_add_arg($$args, "--mode=execute");
  4354. mtr_add_arg($$args, "ddd");
  4355. }
  4356. else
  4357. {
  4358. $$exe= "ddd";
  4359. }
  4360. mtr_add_arg($$args, "--command=$gdb_init_file");
  4361. mtr_add_arg($$args, "$save_exe");
  4362. }
  4363. #
  4364. # Modify the exe and args so that program is run in the selected debugger
  4365. #
  4366. sub debugger_arguments {
  4367. my $args= shift;
  4368. my $exe= shift;
  4369. my $debugger= $opt_debugger || $opt_client_debugger;
  4370. if ( $debugger =~ /vcexpress|vc|devenv/ )
  4371. {
  4372. # vc[express] /debugexe exe arg1 .. argn
  4373. # Add name of the exe and /debugexe before args
  4374. unshift(@$$args, "$$exe");
  4375. unshift(@$$args, "/debugexe");
  4376. # Set exe to debuggername
  4377. $$exe= $debugger;
  4378. }
  4379. elsif ( $debugger =~ /windbg/ )
  4380. {
  4381. # windbg exe arg1 .. argn
  4382. # Add name of the exe before args
  4383. unshift(@$$args, "$$exe");
  4384. # Set exe to debuggername
  4385. $$exe= $debugger;
  4386. }
  4387. elsif ( $debugger eq "dbx" )
  4388. {
  4389. # xterm -e dbx -r exe arg1 .. argn
  4390. unshift(@$$args, $$exe);
  4391. unshift(@$$args, "-r");
  4392. unshift(@$$args, $debugger);
  4393. unshift(@$$args, "-e");
  4394. $$exe= "xterm";
  4395. }
  4396. else
  4397. {
  4398. mtr_error("Unknown argument \"$debugger\" passed to --debugger");
  4399. }
  4400. }
  4401. #
  4402. # Modify the exe and args so that program is run in valgrind
  4403. #
  4404. sub valgrind_arguments {
  4405. my $args= shift;
  4406. my $exe= shift;
  4407. if ( $opt_callgrind)
  4408. {
  4409. mtr_add_arg($args, "--tool=callgrind");
  4410. mtr_add_arg($args, "--base=$opt_vardir/log");
  4411. }
  4412. else
  4413. {
  4414. mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
  4415. mtr_add_arg($args, "--leak-check=yes");
  4416. mtr_add_arg($args, "--num-callers=16");
  4417. mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
  4418. if -f "$glob_mysql_test_dir/valgrind.supp";
  4419. }
  4420. # Add valgrind options, can be overriden by user
  4421. mtr_add_arg($args, '%s', $_) for (@valgrind_args);
  4422. mtr_add_arg($args, $$exe);
  4423. $$exe= $opt_valgrind_path || "valgrind";
  4424. if ($exe_libtool)
  4425. {
  4426. # Add "libtool --mode-execute" before the test to execute
  4427. # if running in valgrind(to avoid valgrinding bash)
  4428. unshift(@$args, "--mode=execute", $$exe);
  4429. $$exe= $exe_libtool;
  4430. }
  4431. }
  4432. #
  4433. # Search server logs for valgrind reports printed at mysqld termination
  4434. #
  4435. sub valgrind_exit_reports() {
  4436. foreach my $log_file (keys %mysqld_logs)
  4437. {
  4438. my @culprits= ();
  4439. my $valgrind_rep= "";
  4440. my $found_report= 0;
  4441. my $err_in_report= 0;
  4442. my $LOGF = IO::File->new($log_file)
  4443. or mtr_error("Could not open file '$log_file' for reading: $!");
  4444. while ( my $line = <$LOGF> )
  4445. {
  4446. if ($line =~ /^CURRENT_TEST: (.+)$/)
  4447. {
  4448. my $testname= $1;
  4449. # If we have a report, report it if needed and start new list of tests
  4450. if ($found_report)
  4451. {
  4452. if ($err_in_report)
  4453. {
  4454. mtr_print ("Valgrind report from $log_file after tests:\n",
  4455. @culprits);
  4456. mtr_print_line();
  4457. print ("$valgrind_rep\n");
  4458. $err_in_report= 0;
  4459. }
  4460. # Make ready to collect new report
  4461. @culprits= ();
  4462. $found_report= 0;
  4463. $valgrind_rep= "";
  4464. }
  4465. push (@culprits, $testname);
  4466. next;
  4467. }
  4468. # This line marks the start of a valgrind report
  4469. $found_report= 1 if $line =~ /ERROR SUMMARY:/;
  4470. if ($found_report) {
  4471. $line=~ s/^==\d+== //;
  4472. $valgrind_rep .= $line;
  4473. $err_in_report= 1 if $line =~ /ERROR SUMMARY: [1-9]/;
  4474. $err_in_report= 1 if $line =~ /definitely lost: [1-9]/;
  4475. $err_in_report= 1 if $line =~ /possibly lost: [1-9]/;
  4476. }
  4477. }
  4478. $LOGF= undef;
  4479. if ($err_in_report) {
  4480. mtr_print ("Valgrind report from $log_file after tests:\n", @culprits);
  4481. mtr_print_line();
  4482. print ("$valgrind_rep\n");
  4483. }
  4484. }
  4485. }
  4486. #
  4487. # Usage
  4488. #
  4489. sub usage ($) {
  4490. my ($message)= @_;
  4491. if ( $message )
  4492. {
  4493. print STDERR "$message\n";
  4494. }
  4495. print <<HERE;
  4496. $0 [ OPTIONS ] [ TESTCASE ]
  4497. Options to control what engine/variation to run
  4498. embedded-server Use the embedded server, i.e. no mysqld daemons
  4499. ps-protocol Use the binary protocol between client and server
  4500. cursor-protocol Use the cursor protocol between client and server
  4501. (implies --ps-protocol)
  4502. view-protocol Create a view to execute all non updating queries
  4503. sp-protocol Create a stored procedure to execute all queries
  4504. compress Use the compressed protocol between client and server
  4505. ssl Use ssl protocol between client and server
  4506. skip-ssl Dont start server with support for ssl connections
  4507. vs-config Visual Studio configuration used to create executables
  4508. (default: MTR_VS_CONFIG environment variable)
  4509. defaults-file=<config template> Use fixed config template for all
  4510. tests
  4511. defaults_extra_file=<config template> Extra config template to add to
  4512. all generated configs
  4513. combination=<opt> Use at least twice to run tests with specified
  4514. options to mysqld
  4515. skip-combinations Ignore combination file (or options)
  4516. Options to control directories to use
  4517. tmpdir=DIR The directory where temporary files are stored
  4518. (default: ./var/tmp).
  4519. vardir=DIR The directory where files generated from the test run
  4520. is stored (default: ./var). Specifying a ramdisk or
  4521. tmpfs will speed up tests.
  4522. mem Run testsuite in "memory" using tmpfs or ramdisk
  4523. Attempts to find a suitable location
  4524. using a builtin list of standard locations
  4525. for tmpfs (/dev/shm)
  4526. The option can also be set using environment
  4527. variable MTR_MEM=[DIR]
  4528. client-bindir=PATH Path to the directory where client binaries are located
  4529. client-libdir=PATH Path to the directory where client libraries are located
  4530. Options to control what test suites or cases to run
  4531. force Continue to run the suite after failure
  4532. with-ndbcluster-only Run only tests that include "ndb" in the filename
  4533. skip-ndb[cluster] Skip all tests that need cluster
  4534. do-test=PREFIX or REGEX
  4535. Run test cases which name are prefixed with PREFIX
  4536. or fulfills REGEX
  4537. skip-test=PREFIX or REGEX
  4538. Skip test cases which name are prefixed with PREFIX
  4539. or fulfills REGEX
  4540. start-from=PREFIX Run test cases starting test prefixed with PREFIX where
  4541. prefix may be suite.testname or just testname
  4542. suite[s]=NAME1,..,NAMEN
  4543. Collect tests in suites from the comma separated
  4544. list of suite names.
  4545. The default is: "$DEFAULT_SUITES"
  4546. skip-rpl Skip the replication test cases.
  4547. big-test Also run tests marked as "big"
  4548. enable-disabled Run also tests marked as disabled
  4549. print-testcases Don't run the tests but print details about all the
  4550. selected tests, in the order they would be run.
  4551. Options that specify ports
  4552. mtr-port-base=# Base for port numbers, ports from this number to
  4553. port-base=# number+9 are reserved. Should be divisible by 10;
  4554. if not it will be rounded down. May be set with
  4555. environment variable MTR_PORT_BASE. If this value is
  4556. set and is not "auto", it overrides build-thread.
  4557. mtr-build-thread=# Specify unique number to calculate port number(s) from.
  4558. build-thread=# Can be set in environment variable MTR_BUILD_THREAD.
  4559. Set MTR_BUILD_THREAD="auto" to automatically aquire
  4560. a build thread id that is unique to current host
  4561. Options for test case authoring
  4562. record TESTNAME (Re)genereate the result file for TESTNAME
  4563. check-testcases Check testcases for sideeffects
  4564. mark-progress Log line number and elapsed time to <testname>.progress
  4565. Options that pass on options
  4566. mysqld=ARGS Specify additional arguments to "mysqld"
  4567. Options to run test on running server
  4568. extern option=value Run only the tests against an already started server
  4569. the options to use for connection to the extern server
  4570. must be specified using name-value pair notation
  4571. For example:
  4572. ./$0 --extern socket=/tmp/mysqld.sock
  4573. Options for debugging the product
  4574. client-ddd Start mysqltest client in ddd
  4575. client-debugger=NAME Start mysqltest in the selected debugger
  4576. client-gdb Start mysqltest client in gdb
  4577. ddd Start mysqld in ddd
  4578. debug Dump trace output for all servers and client programs
  4579. debugger=NAME Start mysqld in the selected debugger
  4580. gdb Start the mysqld(s) in gdb
  4581. manual-debug Let user manually start mysqld in debugger, before
  4582. running test(s)
  4583. manual-gdb Let user manually start mysqld in gdb, before running
  4584. test(s)
  4585. manual-ddd Let user manually start mysqld in ddd, before running
  4586. test(s)
  4587. strace-client=[path] Create strace output for mysqltest client, optionally
  4588. specifying name and path to the trace program to use.
  4589. Example: $0 --strace-client=ktrace
  4590. max-save-core Limit the number of core files saved (to avoid filling
  4591. up disks for heavily crashing server). Defaults to
  4592. $opt_max_save_core, set to 0 for no limit. Set
  4593. it's default with MTR_MAX_SAVE_CORE
  4594. max-save-datadir Limit the number of datadir saved (to avoid filling
  4595. up disks for heavily crashing server). Defaults to
  4596. $opt_max_save_datadir, set to 0 for no limit. Set
  4597. it's default with MTR_MAX_SAVE_DATDIR
  4598. max-test-fail Limit the number of test failurs before aborting
  4599. the current test run. Defaults to
  4600. $opt_max_test_fail, set to 0 for no limit. Set
  4601. it's default with MTR_MAX_TEST_FAIL
  4602. Options for valgrind
  4603. valgrind Run the "mysqltest" and "mysqld" executables using
  4604. valgrind with default options
  4605. valgrind-all Synonym for --valgrind
  4606. valgrind-mysqltest Run the "mysqltest" and "mysql_client_test" executable
  4607. with valgrind
  4608. valgrind-mysqld Run the "mysqld" executable with valgrind
  4609. valgrind-options=ARGS Deprecated, use --valgrind-option
  4610. valgrind-option=ARGS Option to give valgrind, replaces default option(s),
  4611. can be specified more then once
  4612. valgrind-path=<EXE> Path to the valgrind executable
  4613. callgrind Instruct valgrind to use callgrind
  4614. Misc options
  4615. user=USER User for connecting to mysqld(default: $opt_user)
  4616. comment=STR Write STR to the output
  4617. notimer Don't show test case execution time
  4618. verbose More verbose output(use multiple times for even more)
  4619. verbose-restart Write when and why servers are restarted
  4620. start Only initialize and start the servers, using the
  4621. startup settings for the first specified test case
  4622. Example:
  4623. $0 --start alias &
  4624. start-and-exit Same as --start, but mysql-test-run terminates and
  4625. leaves just the server running
  4626. start-dirty Only start the servers (without initialization) for
  4627. the first specified test case
  4628. user-args In combination with start* and no test name, drops
  4629. arguments to mysqld except those speficied with
  4630. --mysqld (if any)
  4631. wait-all If --start or --start-dirty option is used, wait for all
  4632. servers to exit before finishing the process
  4633. fast Run as fast as possible, dont't wait for servers
  4634. to shutdown etc.
  4635. force-restart Always restart servers between tests
  4636. parallel=N Run tests in N parallel threads (default=1)
  4637. Use parallel=auto for auto-setting of N
  4638. repeat=N Run each test N number of times
  4639. retry=N Retry tests that fail N times, limit number of failures
  4640. to $opt_retry_failure
  4641. retry-failure=N Limit number of retries for a failed test
  4642. reorder Reorder tests to get fewer server restarts
  4643. help Get this help text
  4644. testcase-timeout=MINUTES Max test case run time (default $opt_testcase_timeout)
  4645. suite-timeout=MINUTES Max test suite run time (default $opt_suite_timeout)
  4646. shutdown-timeout=SECONDS Max number of seconds to wait for server shutdown
  4647. before killing servers (default $opt_shutdown_timeout)
  4648. warnings Scan the log files for warnings. Use --nowarnings
  4649. to turn off.
  4650. sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time
  4651. debug-sync-timeout=NUM Set default timeout for WAIT_FOR debug sync
  4652. actions. Disable facility with NUM=0.
  4653. gcov Collect coverage information after the test.
  4654. The result is a gcov file per source and header file.
  4655. experimental=<file> Refer to list of tests considered experimental;
  4656. failures will be marked exp-fail instead of fail.
  4657. report-features First run a "test" that reports mysql features
  4658. timestamp Print timestamp before each test report line
  4659. timediff With --timestamp, also print time passed since
  4660. *previous* test started
  4661. max-connections=N Max number of open connection to server in mysqltest
  4662. HERE
  4663. exit(1);
  4664. }
  4665. sub list_options ($) {
  4666. my $hash= shift;
  4667. for (keys %$hash) {
  4668. s/([:=].*|[+!])$//;
  4669. s/\|/\n--/g;
  4670. print "--$_\n" unless /list-options/;
  4671. }
  4672. exit(1);
  4673. }