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.

4473 lines
119 KiB

18 years ago
18 years ago
20 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
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
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
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
20 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
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. use lib "lib";
  34. use Cwd;
  35. use Getopt::Long;
  36. use My::File::Path; # Patched version of File::Path
  37. use File::Basename;
  38. use File::Copy;
  39. use File::Find;
  40. use File::Temp qw / tempdir /;
  41. use File::Spec::Functions qw / splitdir /;
  42. use My::Platform;
  43. use My::SafeProcess;
  44. use My::ConfigFactory;
  45. use My::Options;
  46. use My::Find;
  47. use My::SysInfo;
  48. use mtr_cases;
  49. use mtr_report;
  50. use mtr_match;
  51. use IO::Socket::INET;
  52. use IO::Select;
  53. require "lib/mtr_process.pl";
  54. require "lib/mtr_io.pl";
  55. require "lib/mtr_gcov.pl";
  56. require "lib/mtr_misc.pl";
  57. require "lib/mtr_unique.pl";
  58. $SIG{INT}= sub { mtr_error("Got ^C signal"); };
  59. our $mysql_version_id;
  60. our $glob_mysql_test_dir;
  61. our $basedir;
  62. our $path_charsetsdir;
  63. our $path_client_bindir;
  64. our $path_client_libdir;
  65. our $path_language;
  66. our $path_current_testlog;
  67. our $path_testlog;
  68. our $default_vardir;
  69. our $opt_vardir; # Path to use for var/ dir
  70. my $path_vardir_trace; # unix formatted opt_vardir for trace files
  71. my $opt_tmpdir; # Path to use for tmp/ dir
  72. my $path_config_file; # The generated config file, var/my.cnf
  73. # Visual Studio produces executables in different sub-directories based on the
  74. # configuration used to build them. To make life easier, an environment
  75. # variable or command-line option may be specified to control which set of
  76. # executables will be used by the test suite.
  77. our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
  78. my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb";
  79. my $opt_suites;
  80. our $opt_verbose= 0; # Verbose output, enable with --verbose
  81. our $exe_mysql;
  82. our $exe_mysqladmin;
  83. our $exe_mysqltest;
  84. our $exe_libtool;
  85. my $opt_big_test= 0;
  86. our @opt_combinations;
  87. our @opt_extra_mysqld_opt;
  88. our $opt_compress;
  89. our $opt_ssl;
  90. our $opt_skip_ssl;
  91. our $opt_ssl_supported;
  92. our $opt_ps_protocol;
  93. our $opt_sp_protocol;
  94. our $opt_cursor_protocol;
  95. our $opt_view_protocol;
  96. our $opt_debug;
  97. our @opt_cases; # The test cases names in argv
  98. our $opt_embedded_server;
  99. # Options used when connecting to an already running server
  100. my %opts_extern;
  101. sub using_extern { return (keys %opts_extern > 0);};
  102. our $opt_fast= 0;
  103. our $opt_force;
  104. our $opt_mem= $ENV{'MTR_MEM'};
  105. our $opt_gcov;
  106. our $opt_gcov_err;
  107. our $opt_gcov_msg;
  108. our $glob_debugger= 0;
  109. our $opt_gdb;
  110. our $opt_client_gdb;
  111. our $opt_ddd;
  112. our $opt_client_ddd;
  113. our $opt_manual_gdb;
  114. our $opt_manual_ddd;
  115. our $opt_manual_debug;
  116. our $opt_debugger;
  117. our $opt_client_debugger;
  118. my $config; # The currently running config
  119. my $current_config_name; # The currently running config file template
  120. my $opt_baseport;
  121. my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto";
  122. my $opt_record;
  123. my $opt_report_features;
  124. our $opt_check_testcases= 1;
  125. my $opt_mark_progress;
  126. my $opt_sleep;
  127. my $opt_testcase_timeout= 15; # minutes
  128. my $opt_suite_timeout = 180; # minutes
  129. my $opt_shutdown_timeout= 10; # seconds
  130. my $opt_start_timeout = 30; # seconds
  131. my $opt_start;
  132. my $opt_start_dirty;
  133. my $opt_repeat= 1;
  134. my $opt_retry= 3;
  135. my $opt_retry_failure= 2;
  136. my $opt_parallel;
  137. my $opt_strace_client;
  138. our $opt_user;
  139. my $opt_valgrind= 0;
  140. my $opt_valgrind_mysqld= 0;
  141. my $opt_valgrind_mysqltest= 0;
  142. my @default_valgrind_args= ("--show-reachable=yes");
  143. my @valgrind_args;
  144. my $opt_valgrind_path;
  145. my $opt_callgrind;
  146. our $opt_warnings= 1;
  147. our $opt_skip_ndbcluster= 0;
  148. our $opt_skip_ndbcluster_slave= 0;
  149. our $opt_with_ndbcluster;
  150. my $exe_ndbd;
  151. my $exe_ndb_mgmd;
  152. my $exe_ndb_waiter;
  153. our $path_sql_dir;
  154. our $debug_compiled_binaries;
  155. our %mysqld_variables;
  156. my $source_dist= 0;
  157. my $opt_max_save_core= $ENV{MTR_MAX_SAVE_CORE} || 5;
  158. my $opt_max_save_datadir= $ENV{MTR_MAX_SAVE_DATADIR} || 20;
  159. my $opt_max_test_fail= $ENV{MTR_MAX_TEST_FAIL} || 10;
  160. select(STDOUT);
  161. $| = 1; # Automatically flush STDOUT
  162. main();
  163. sub main {
  164. report_option('verbose', 0);
  165. # This is needed for test log evaluation in "gen-build-status-page"
  166. # in all cases where the calling tool does not log the commands
  167. # directly before it executes them, like "make test-force-pl" in RPM builds.
  168. mtr_report("Logging: $0 ", join(" ", @ARGV));
  169. Getopt::Long::Configure("pass_through");
  170. GetOptions('parallel=i' => \$opt_parallel) or usage("Can't read options");
  171. if ( not defined $opt_parallel ) {
  172. # Try to find a suitable value for number of workers
  173. my $sys_info= My::SysInfo->new();
  174. $sys_info->print_info();
  175. $opt_parallel= $sys_info->num_cpus();
  176. for my $limit (2000, 1500, 1000, 500){
  177. $opt_parallel-- if ($sys_info->min_bogomips() < $limit);
  178. }
  179. $opt_parallel= 1 if ($opt_parallel < 1);
  180. mtr_report("Using parallel: $opt_parallel");
  181. }
  182. # Create server socket on any free port
  183. my $server = new IO::Socket::INET
  184. (
  185. LocalAddr => 'localhost',
  186. Proto => 'tcp',
  187. Listen => $opt_parallel,
  188. );
  189. mtr_error("Could not create testcase server port: $!") unless $server;
  190. my $server_port = $server->sockport();
  191. mtr_report("Using server port $server_port");
  192. # Create child processes
  193. my %children;
  194. for my $child_num (1..$opt_parallel){
  195. my $child_pid= My::SafeProcess::Base::_safe_fork();
  196. if ($child_pid == 0){
  197. $server= undef; # Close the server port in child
  198. run_worker($server_port, $child_num);
  199. exit(1);
  200. }
  201. $children{$child_pid}= 1;
  202. }
  203. command_line_setup(0);
  204. if ( $opt_gcov ) {
  205. gcov_prepare();
  206. }
  207. if (!$opt_suites) {
  208. $opt_suites= $DEFAULT_SUITES;
  209. # Check for any extra suites to enable based on the path name
  210. my %extra_suites=
  211. (
  212. "mysql-5.1-new-ndb" => "ndb_team",
  213. "mysql-5.1-new-ndb-merge" => "ndb_team",
  214. "mysql-5.1-telco-6.2" => "ndb_team",
  215. "mysql-5.1-telco-6.2-merge" => "ndb_team",
  216. "mysql-5.1-telco-6.3" => "ndb_team",
  217. "mysql-6.0-ndb" => "ndb_team",
  218. );
  219. foreach my $dir ( reverse splitdir($basedir) ) {
  220. my $extra_suite= $extra_suites{$dir};
  221. if (defined $extra_suite) {
  222. mtr_report("Found extra suite: $extra_suite");
  223. $opt_suites= "$extra_suite,$opt_suites";
  224. last;
  225. }
  226. }
  227. }
  228. mtr_report("Collecting tests...");
  229. my $tests= collect_test_cases($opt_suites, \@opt_cases);
  230. if ( $opt_report_features ) {
  231. # Put "report features" as the first test to run
  232. my $tinfo = My::Test->new
  233. (
  234. name => 'report_features',
  235. result_file => undef, # Prints result
  236. path => 'include/report-features.test'.
  237. master_opt => [],
  238. slave_opt => [],
  239. );
  240. unshift(@$tests, $tinfo);
  241. }
  242. initialize_servers();
  243. mtr_report();
  244. mtr_print_thick_line();
  245. mtr_print_header();
  246. my $num_tests= @$tests;
  247. my $completed= run_test_server($server, $tests, $opt_parallel);
  248. # Send Ctrl-C to any children still running
  249. kill("INT", keys(%children));
  250. # Wait for childs to exit
  251. foreach my $pid (keys %children)
  252. {
  253. my $ret_pid= waitpid($pid, 0);
  254. if ($ret_pid != $pid){
  255. mtr_report("Unknown process $ret_pid exited");
  256. }
  257. else {
  258. delete $children{$ret_pid};
  259. }
  260. }
  261. if ( not defined @$completed ) {
  262. mtr_error("Test suite aborted");
  263. }
  264. if ( @$completed != $num_tests){
  265. if ($opt_force){
  266. # All test should have been run, print any that are still in $tests
  267. foreach my $test ( @$tests ){
  268. $test->print_test();
  269. }
  270. }
  271. # Not all tests completed, failure
  272. mtr_report();
  273. mtr_report("Only ", int(@$completed), " of $num_tests completed.");
  274. mtr_error("Not all tests completed");
  275. }
  276. mtr_print_line();
  277. mtr_report_stats($completed);
  278. exit(0);
  279. }
  280. sub run_test_server {
  281. my ($server, $tests, $childs) = @_;
  282. my $num_saved_cores= 0; # Number of core files saved in vardir/log/ so far.
  283. my $num_saved_datadir= 0; # Number of datadirs saved in vardir/log/ so far.
  284. my $num_failed_test= 0; # Number of tests failed so far
  285. # Scheduler variables
  286. my $max_ndb= $opt_parallel / 2;
  287. $max_ndb = 4 if $max_ndb > 4;
  288. $max_ndb = 1 if $max_ndb < 1;
  289. my $num_ndb_tests= 0;
  290. my $completed= [];
  291. my %running;
  292. my $result;
  293. my $suite_timeout_proc= My::SafeProcess->timer($opt_suite_timeout * 60);
  294. my $s= IO::Select->new();
  295. $s->add($server);
  296. while (1) {
  297. my @ready = $s->can_read(1); # Wake up once every second
  298. foreach my $sock (@ready) {
  299. if ($sock == $server) {
  300. # New client connected
  301. my $child= $sock->accept();
  302. mtr_verbose("Client connected");
  303. $s->add($child);
  304. print $child "HELLO\n";
  305. }
  306. else {
  307. my $line= <$sock>;
  308. if (!defined $line) {
  309. # Client disconnected
  310. mtr_verbose("Child closed socket");
  311. $s->remove($sock);
  312. if (--$childs == 0){
  313. $suite_timeout_proc->kill();
  314. return $completed;
  315. }
  316. next;
  317. }
  318. chomp($line);
  319. if ($line eq 'TESTRESULT'){
  320. $result= My::Test::read_test($sock);
  321. # $result->print_test();
  322. # Report test status
  323. mtr_report_test($result);
  324. if ( $result->is_failed() ) {
  325. # Save the workers "savedir" in var/log
  326. my $worker_savedir= $result->{savedir};
  327. my $worker_savename= basename($worker_savedir);
  328. my $savedir= "$opt_vardir/log/$worker_savename";
  329. if ($opt_max_save_datadir > 0 &&
  330. $num_saved_datadir >= $opt_max_save_datadir)
  331. {
  332. mtr_report(" - skipping '$worker_savedir/'");
  333. rmtree($worker_savedir);
  334. }
  335. else {
  336. mtr_report(" - saving '$worker_savedir/' to '$savedir/'");
  337. rename($worker_savedir, $savedir);
  338. if ($opt_max_save_core > 0) {
  339. # Limit number of core files saved
  340. find({ no_chdir => 1,
  341. wanted => sub {
  342. my $core_file= $File::Find::name;
  343. my $core_name= basename($core_file);
  344. if ($core_name =~ "core*"){
  345. if ($num_saved_cores >= $opt_max_save_core) {
  346. mtr_report(" - deleting '$core_name'",
  347. "($num_saved_cores/$opt_max_save_core)");
  348. unlink("$core_file");
  349. }
  350. else {
  351. mtr_report(" - found '$core_name'",
  352. "($num_saved_cores/$opt_max_save_core)");
  353. }
  354. ++$num_saved_cores;
  355. }
  356. }
  357. },
  358. $savedir);
  359. }
  360. }
  361. $num_saved_datadir++;
  362. if ( !$opt_force ) {
  363. # Test has failed, force is off
  364. $suite_timeout_proc->kill();
  365. push(@$completed, $result);
  366. return $completed;
  367. }
  368. elsif ($num_failed_test > 0 and
  369. $num_failed_test >= $opt_max_test_fail) {
  370. $suite_timeout_proc->kill();
  371. mtr_report("Too many tests($num_failed_test) failed!",
  372. "Terminating...");
  373. return undef;
  374. }
  375. $num_failed_test++;
  376. }
  377. # Retry test run after test failure
  378. my $retries= $result->{retries} || 2;
  379. my $test_has_failed= $result->{failures} || 0;
  380. if ($test_has_failed and $retries <= $opt_retry){
  381. # Test should be run one more time unless it has failed
  382. # too many times already
  383. my $failures= $result->{failures};
  384. if ($opt_retry > 1 and $failures >= $opt_retry_failure){
  385. mtr_report("\nTest has failed $failures times,",
  386. "no more retries!\n");
  387. }
  388. else {
  389. mtr_report("\nRetrying test, attempt($retries/$opt_retry)...\n");
  390. delete($result->{result});
  391. $result->{retries}= $retries+1;
  392. $result->write_test($sock, 'TESTCASE');
  393. next;
  394. }
  395. }
  396. # Repeat test $opt_repeat number of times
  397. my $repeat= $result->{repeat} || 1;
  398. if ($repeat < $opt_repeat)
  399. {
  400. $result->{retries}= 0;
  401. $result->{failures}= 0;
  402. delete($result->{result});
  403. $result->{repeat}= $repeat+1;
  404. $result->write_test($sock, 'TESTCASE');
  405. next;
  406. }
  407. # Remove from list of running
  408. mtr_error("'", $result->{name},"' is not known to be running")
  409. unless delete $running{$result->key()};
  410. # Update scheduler variables
  411. $num_ndb_tests-- if ($result->{ndb_test});
  412. # Save result in completed list
  413. push(@$completed, $result);
  414. }
  415. elsif ($line eq 'START'){
  416. ; # Send first test
  417. }
  418. else {
  419. mtr_error("Unknown response: '$line' from client");
  420. }
  421. # Find next test to schedule
  422. # - Try to use same configuration as worker used last time
  423. # - Limit number of parallel ndb tests
  424. my $next;
  425. my $second_best;
  426. for(my $i= 0; $i <= $#$tests; $i++)
  427. {
  428. my $t= $tests->[$i];
  429. if (run_testcase_check_skip_test($t)){
  430. # Move the test to completed list
  431. #mtr_report("skip - Moving test $i to completed");
  432. push(@$completed, splice(@$tests, $i, 1));
  433. redo; # Start over again
  434. }
  435. # Limit number of parallell NDB tests
  436. if ($t->{ndb_test} and $num_ndb_tests >= $max_ndb){
  437. #mtr_report("Skipping, num ndb is already at max, $num_ndb_tests");
  438. next;
  439. }
  440. # Prefer same configuration
  441. if (defined $result and
  442. $result->{template_path} eq $t->{template_path})
  443. {
  444. #mtr_report("Test uses same config => good match");
  445. # Test uses same config => good match
  446. $next= splice(@$tests, $i, 1);
  447. last;
  448. }
  449. # Second best choice is the first that does not fulfill
  450. # any of the above conditions
  451. if (!defined $second_best){
  452. #mtr_report("Setting second_best to $i");
  453. $second_best= $i;
  454. }
  455. }
  456. # Use second best choice if no other test has been found
  457. if (!$next and defined $second_best){
  458. #mtr_report("Take second best choice $second_best");
  459. mtr_error("Internal error, second best too large")
  460. if $second_best > $#$tests;
  461. $next= splice(@$tests, $second_best, 1);
  462. }
  463. if ($next) {
  464. #$next->print_test();
  465. $next->write_test($sock, 'TESTCASE');
  466. $running{$next->key()}= $next;
  467. $num_ndb_tests++ if ($next->{ndb_test});
  468. }
  469. else {
  470. # No more test, tell child to exit
  471. #mtr_report("Saying BYE to child");
  472. print $sock "BYE\n";
  473. }
  474. }
  475. }
  476. # ----------------------------------------------------
  477. # Check if test suite timer expired
  478. # ----------------------------------------------------
  479. if ( ! $suite_timeout_proc->wait_one(0) )
  480. {
  481. mtr_report("Test suite timeout! Terminating...");
  482. return undef;
  483. }
  484. }
  485. }
  486. sub run_worker ($) {
  487. my ($server_port, $thread_num)= @_;
  488. $SIG{INT}= sub { exit(1); };
  489. report_option('name',"worker[$thread_num]");
  490. # Connect to server
  491. my $server = new IO::Socket::INET
  492. (
  493. PeerAddr => 'localhost',
  494. PeerPort => $server_port,
  495. Proto => 'tcp'
  496. );
  497. mtr_error("Could not connect to server at port $server_port: $!")
  498. unless $server;
  499. # Read hello from server which it will send when shared
  500. # resources have been setup
  501. my $hello= <$server>;
  502. command_line_setup($thread_num);
  503. if ( $opt_gcov )
  504. {
  505. gcov_prepare();
  506. }
  507. setup_vardir();
  508. mysql_install_db($thread_num);
  509. if ( using_extern() ) {
  510. create_config_file_for_extern(%opts_extern);
  511. }
  512. # Ask server for first test
  513. print $server "START\n";
  514. while(my $line= <$server>){
  515. chomp($line);
  516. if ($line eq 'TESTCASE'){
  517. my $test= My::Test::read_test($server);
  518. #$test->print_test();
  519. run_testcase($test);
  520. #$test->{result}= 'MTR_RES_PASSED';
  521. # Send it back, now with results set
  522. #$test->print_test();
  523. $test->write_test($server, 'TESTRESULT');
  524. }
  525. elsif ($line eq 'BYE'){
  526. mtr_report("Server said BYE");
  527. exit(0);
  528. }
  529. else {
  530. mtr_error("Could not understand server, '$line'");
  531. }
  532. }
  533. stop_all_servers();
  534. if ( $opt_gcov )
  535. {
  536. gcov_collect(); # collect coverage information
  537. }
  538. if ( $opt_gcov )
  539. {
  540. gcov_collect(); # collect coverage information
  541. }
  542. exit(1);
  543. }
  544. sub ignore_option {
  545. my ($opt, $value)= @_;
  546. print "Ignoring option '$opt'\n";
  547. }
  548. sub command_line_setup {
  549. my ($thread_num)= @_;
  550. my $opt_comment;
  551. my $opt_usage;
  552. # Read the command line options
  553. # Note: Keep list, and the order, in sync with usage at end of this file
  554. Getopt::Long::Configure("pass_through");
  555. GetOptions(
  556. # Control what engine/variation to run
  557. 'embedded-server' => \$opt_embedded_server,
  558. 'ps-protocol' => \$opt_ps_protocol,
  559. 'sp-protocol' => \$opt_sp_protocol,
  560. 'view-protocol' => \$opt_view_protocol,
  561. 'cursor-protocol' => \$opt_cursor_protocol,
  562. 'ssl|with-openssl' => \$opt_ssl,
  563. 'skip-ssl' => \$opt_skip_ssl,
  564. 'compress' => \$opt_compress,
  565. 'with-ndbcluster|ndb' => \$opt_with_ndbcluster,
  566. 'vs-config' => \$opt_vs_config,
  567. # Config file to use as template for all tests
  568. 'defaults-file=s' => \&collect_option,
  569. # Extra config file to append to all generated configs
  570. 'defaults-extra-file=s' => \&collect_option,
  571. # Control what test suites or cases to run
  572. 'force' => \$opt_force,
  573. 'with-ndbcluster-only' => \&collect_option,
  574. 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster,
  575. 'skip-ndbcluster-slave|skip-ndb-slave'
  576. => \$opt_skip_ndbcluster_slave,
  577. 'suite|suites=s' => \$opt_suites,
  578. 'skip-rpl' => \&collect_option,
  579. 'skip-test=s' => \&collect_option,
  580. 'do-test=s' => \&collect_option,
  581. 'start-from=s' => \&collect_option,
  582. 'big-test' => \$opt_big_test,
  583. 'combination=s' => \@opt_combinations,
  584. 'skip-combinations' => \&collect_option,
  585. 'skip-im' => \&ignore_option,
  586. # Specify ports
  587. 'build-thread|mtr-build-thread=i' => \$opt_build_thread,
  588. # Test case authoring
  589. 'record' => \$opt_record,
  590. 'check-testcases!' => \$opt_check_testcases,
  591. 'mark-progress' => \$opt_mark_progress,
  592. # Extra options used when starting mysqld
  593. 'mysqld=s' => \@opt_extra_mysqld_opt,
  594. # Run test on running server
  595. 'extern=s' => \%opts_extern, # Append to hash
  596. # Debugging
  597. 'debug' => \$opt_debug,
  598. 'gdb' => \$opt_gdb,
  599. 'client-gdb' => \$opt_client_gdb,
  600. 'manual-gdb' => \$opt_manual_gdb,
  601. 'manual-debug' => \$opt_manual_debug,
  602. 'ddd' => \$opt_ddd,
  603. 'client-ddd' => \$opt_client_ddd,
  604. 'manual-ddd' => \$opt_manual_ddd,
  605. 'debugger=s' => \$opt_debugger,
  606. 'client-debugger=s' => \$opt_client_debugger,
  607. 'strace-client:s' => \$opt_strace_client,
  608. 'max-save-core=i' => \$opt_max_save_core,
  609. 'max-save-datadir=i' => \$opt_max_save_datadir,
  610. 'max-test-fail=i' => \$opt_max_test_fail,
  611. # Coverage, profiling etc
  612. 'gcov' => \$opt_gcov,
  613. 'valgrind|valgrind-all' => \$opt_valgrind,
  614. 'valgrind-mysqltest' => \$opt_valgrind_mysqltest,
  615. 'valgrind-mysqld' => \$opt_valgrind_mysqld,
  616. 'valgrind-options=s' => sub {
  617. my ($opt, $value)= @_;
  618. # Deprecated option unless it's what we know pushbuild uses
  619. if ($value eq "--gen-suppressions=all --show-reachable=yes") {
  620. push(@valgrind_args, $_) for (split(' ', $value));
  621. return;
  622. }
  623. die("--valgrind-options=s is deprecated. Use ",
  624. "--valgrind-option=s, to be specified several",
  625. " times if necessary");
  626. },
  627. 'valgrind-option=s' => \@valgrind_args,
  628. 'valgrind-path=s' => \$opt_valgrind_path,
  629. 'callgrind' => \$opt_callgrind,
  630. # Directories
  631. 'tmpdir=s' => \$opt_tmpdir,
  632. 'vardir=s' => \$opt_vardir,
  633. 'mem' => \$opt_mem,
  634. 'client-bindir=s' => \$path_client_bindir,
  635. 'client-libdir=s' => \$path_client_libdir,
  636. # Misc
  637. 'report-features' => \$opt_report_features,
  638. 'comment=s' => \$opt_comment,
  639. 'fast' => \$opt_fast,
  640. 'reorder!' => \&collect_option,
  641. 'enable-disabled' => \&collect_option,
  642. 'verbose+' => \$opt_verbose,
  643. 'verbose-restart' => \&report_option,
  644. 'sleep=i' => \$opt_sleep,
  645. 'start-dirty' => \$opt_start_dirty,
  646. 'start' => \$opt_start,
  647. 'print-testcases' => \&collect_option,
  648. 'repeat=i' => \$opt_repeat,
  649. 'retry=i' => \$opt_retry,
  650. 'retry-failure=i' => \$opt_retry_failure,
  651. 'timer!' => \&report_option,
  652. 'user=s' => \$opt_user,
  653. 'testcase-timeout=i' => \$opt_testcase_timeout,
  654. 'suite-timeout=i' => \$opt_suite_timeout,
  655. 'shutdown-timeout=i' => \$opt_shutdown_timeout,
  656. 'warnings!' => \$opt_warnings,
  657. 'timestamp' => \&report_option,
  658. 'timediff' => \&report_option,
  659. 'help|h' => \$opt_usage,
  660. ) or usage("Can't read options");
  661. usage("") if $opt_usage;
  662. # --------------------------------------------------------------------------
  663. # Setup verbosity
  664. # --------------------------------------------------------------------------
  665. if ($thread_num == 0){
  666. # The server should by default have verbose on
  667. report_option('verbose', $opt_verbose ? $opt_verbose : 0);
  668. } else {
  669. # Worker should by default have verbose off
  670. report_option('verbose', $opt_verbose ? $opt_verbose : undef);
  671. }
  672. # --------------------------------------------------------------------------
  673. # Check build_thread and calculate baseport
  674. # Use auto build thread in all but first worker
  675. # --------------------------------------------------------------------------
  676. set_build_thread_ports($thread_num > 1 ? 'auto' : $opt_build_thread);
  677. if ( -d "../sql" )
  678. {
  679. $source_dist= 1;
  680. }
  681. # Find the absolute path to the test directory
  682. $glob_mysql_test_dir= cwd();
  683. if (IS_CYGWIN)
  684. {
  685. # Use mixed path format i.e c:/path/to/
  686. $glob_mysql_test_dir= mixed_path($glob_mysql_test_dir);
  687. }
  688. # In most cases, the base directory we find everything relative to,
  689. # is the parent directory of the "mysql-test" directory. For source
  690. # distributions, TAR binary distributions and some other packages.
  691. $basedir= dirname($glob_mysql_test_dir);
  692. # In the RPM case, binaries and libraries are installed in the
  693. # default system locations, instead of having our own private base
  694. # directory. And we install "/usr/share/mysql-test". Moving up one
  695. # more directory relative to "mysql-test" gives us a usable base
  696. # directory for RPM installs.
  697. if ( ! $source_dist and ! -d "$basedir/bin" )
  698. {
  699. $basedir= dirname($basedir);
  700. }
  701. # Look for the client binaries directory
  702. if ($path_client_bindir)
  703. {
  704. # --client-bindir=path set on command line, check that the path exists
  705. $path_client_bindir= mtr_path_exists($path_client_bindir);
  706. }
  707. else
  708. {
  709. $path_client_bindir= mtr_path_exists("$basedir/client_release",
  710. "$basedir/client_debug",
  711. vs_config_dirs('client', ''),
  712. "$basedir/client",
  713. "$basedir/bin");
  714. }
  715. # Look for language files and charsetsdir, use same share
  716. my $path_share= mtr_path_exists("$basedir/share/mysql",
  717. "$basedir/sql/share",
  718. "$basedir/share");
  719. $path_language= mtr_path_exists("$path_share/english");
  720. $path_charsetsdir= mtr_path_exists("$path_share/charsets");
  721. # Look for SQL scripts directory
  722. if ( mtr_file_exists("$path_share/mysql_system_tables.sql") ne "")
  723. {
  724. # The SQL scripts are in path_share
  725. $path_sql_dir= $path_share;
  726. }
  727. else
  728. {
  729. $path_sql_dir= mtr_path_exists("$basedir/share",
  730. "$basedir/scripts");
  731. }
  732. # Run the mysqld to find out what features are available
  733. collect_mysqld_features();
  734. if ( $opt_comment )
  735. {
  736. mtr_report();
  737. mtr_print_thick_line('#');
  738. mtr_report("# $opt_comment");
  739. mtr_print_thick_line('#');
  740. }
  741. foreach my $arg ( @ARGV )
  742. {
  743. if ( $arg =~ /^--skip-/ )
  744. {
  745. push(@opt_extra_mysqld_opt, $arg);
  746. }
  747. elsif ( $arg =~ /^--$/ )
  748. {
  749. # It is an effect of setting 'pass_through' in option processing
  750. # that the lone '--' separating options from arguments survives,
  751. # simply ignore it.
  752. }
  753. elsif ( $arg =~ /^-/ )
  754. {
  755. usage("Invalid option \"$arg\"");
  756. }
  757. else
  758. {
  759. push(@opt_cases, $arg);
  760. }
  761. }
  762. # --------------------------------------------------------------------------
  763. # Find out type of logging that are being used
  764. # --------------------------------------------------------------------------
  765. foreach my $arg ( @opt_extra_mysqld_opt )
  766. {
  767. if ( $arg =~ /binlog[-_]format=(\S+)/ )
  768. {
  769. # Save this for collect phase
  770. collect_option('binlog-format', $1);
  771. mtr_report("Using binlog format '$1'");
  772. }
  773. }
  774. # --------------------------------------------------------------------------
  775. # Find out default storage engine being used(if any)
  776. # --------------------------------------------------------------------------
  777. foreach my $arg ( @opt_extra_mysqld_opt )
  778. {
  779. if ( $arg =~ /default-storage-engine=(\S+)/ )
  780. {
  781. # Save this for collect phase
  782. collect_option('default-storage-engine', $1);
  783. mtr_report("Using default engine '$1'")
  784. }
  785. }
  786. # --------------------------------------------------------------------------
  787. # Check if we should speed up tests by trying to run on tmpfs
  788. # - Dont check in workers
  789. # --------------------------------------------------------------------------
  790. if ( defined $opt_mem and $thread_num == 0)
  791. {
  792. mtr_error("Can't use --mem and --vardir at the same time ")
  793. if $opt_vardir;
  794. mtr_error("Can't use --mem and --tmpdir at the same time ")
  795. if $opt_tmpdir;
  796. # Search through list of locations that are known
  797. # to be "fast disks" to find a suitable location
  798. # Use --mem=<dir> as first location to look.
  799. my @tmpfs_locations= ($opt_mem, "/dev/shm", "/tmp");
  800. foreach my $fs (@tmpfs_locations)
  801. {
  802. if ( -d $fs )
  803. {
  804. my $template= "var_${opt_build_thread}_XXXX";
  805. $opt_mem= tempdir( $template, DIR => $fs, CLEANUP => 0);
  806. last;
  807. }
  808. }
  809. }
  810. # --------------------------------------------------------------------------
  811. # Set the "var/" directory, as it is the base for everything else
  812. # --------------------------------------------------------------------------
  813. $default_vardir= "$glob_mysql_test_dir/var";
  814. if ( ! $opt_vardir )
  815. {
  816. $opt_vardir= $default_vardir;
  817. }
  818. # If more than one parallel run, use a subdir of the selected var
  819. if ($thread_num && $opt_parallel > 1) {
  820. $opt_vardir.= "/".$thread_num;
  821. }
  822. $path_vardir_trace= $opt_vardir;
  823. # Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/...
  824. $path_vardir_trace=~ s/^\w://;
  825. # We make the path absolute, as the server will do a chdir() before usage
  826. unless ( $opt_vardir =~ m,^/, or
  827. (IS_WINDOWS and $opt_vardir =~ m,^[a-z]:/,i) )
  828. {
  829. # Make absolute path, relative test dir
  830. $opt_vardir= "$glob_mysql_test_dir/$opt_vardir";
  831. }
  832. # Location of my.cnf that all clients use
  833. $path_config_file= "$opt_vardir/my.cnf";
  834. # --------------------------------------------------------------------------
  835. # Set tmpdir
  836. # --------------------------------------------------------------------------
  837. $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir;
  838. $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any
  839. # If more than one parallel run, use a subdir of the selected tmpdir
  840. if ($thread_num && $opt_parallel > 1 and $opt_tmpdir ne "$opt_vardir/tmp") {
  841. $opt_tmpdir.= "/".$thread_num;
  842. }
  843. # --------------------------------------------------------------------------
  844. # fast option
  845. # --------------------------------------------------------------------------
  846. if ($opt_fast){
  847. $opt_shutdown_timeout= 0; # Kill processes instead of nice shutdown
  848. }
  849. # --------------------------------------------------------------------------
  850. # Record flag
  851. # --------------------------------------------------------------------------
  852. if ( $opt_record and ! @opt_cases )
  853. {
  854. mtr_error("Will not run in record mode without a specific test case");
  855. }
  856. # --------------------------------------------------------------------------
  857. # Embedded server flag
  858. # --------------------------------------------------------------------------
  859. if ( $opt_embedded_server )
  860. {
  861. if ( IS_WINDOWS )
  862. {
  863. # Add the location for libmysqld.dll to the path.
  864. my $separator= ";";
  865. my $lib_mysqld=
  866. mtr_path_exists(vs_config_dirs('libmysqld',''));
  867. if ( IS_CYGWIN )
  868. {
  869. $lib_mysqld= posix_path($lib_mysqld);
  870. $separator= ":";
  871. }
  872. $ENV{'PATH'}= "$ENV{'PATH'}".$separator.$lib_mysqld;
  873. }
  874. $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster
  875. $opt_skip_ssl= 1; # Turn off use of SSL
  876. # Turn off use of bin log
  877. push(@opt_extra_mysqld_opt, "--skip-log-bin");
  878. if ( using_extern() )
  879. {
  880. mtr_error("Can't use --extern with --embedded-server");
  881. }
  882. }
  883. # --------------------------------------------------------------------------
  884. # Big test flags
  885. # --------------------------------------------------------------------------
  886. if ( $opt_big_test )
  887. {
  888. $ENV{'BIG_TEST'}= 1;
  889. }
  890. # --------------------------------------------------------------------------
  891. # Gcov flag
  892. # --------------------------------------------------------------------------
  893. if ( $opt_gcov and ! $source_dist )
  894. {
  895. mtr_error("Coverage test needs the source - please use source dist");
  896. }
  897. # --------------------------------------------------------------------------
  898. # Check debug related options
  899. # --------------------------------------------------------------------------
  900. if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd ||
  901. $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug ||
  902. $opt_debugger || $opt_client_debugger )
  903. {
  904. # Indicate that we are using debugger
  905. $glob_debugger= 1;
  906. if ( using_extern() )
  907. {
  908. mtr_error("Can't use --extern when using debugger");
  909. }
  910. }
  911. # --------------------------------------------------------------------------
  912. # Set timeout values
  913. # --------------------------------------------------------------------------
  914. $opt_start_timeout*= $opt_parallel;
  915. #
  916. # Check valgrind arguments
  917. # --------------------------------------------------------------------------
  918. if ( $opt_valgrind or $opt_valgrind_path or @valgrind_args)
  919. {
  920. mtr_report("Turning on valgrind for all executables");
  921. $opt_valgrind= 1;
  922. $opt_valgrind_mysqld= 1;
  923. $opt_valgrind_mysqltest= 1;
  924. # Increase the timeouts when running with valgrind
  925. $opt_testcase_timeout*= 10;
  926. $opt_suite_timeout*= 6;
  927. $opt_start_timeout*= 10;
  928. }
  929. elsif ( $opt_valgrind_mysqld )
  930. {
  931. mtr_report("Turning on valgrind for mysqld(s) only");
  932. $opt_valgrind= 1;
  933. }
  934. elsif ( $opt_valgrind_mysqltest )
  935. {
  936. mtr_report("Turning on valgrind for mysqltest and mysql_client_test only");
  937. $opt_valgrind= 1;
  938. }
  939. if ( $opt_callgrind )
  940. {
  941. mtr_report("Turning on valgrind with callgrind for mysqld(s)");
  942. $opt_valgrind= 1;
  943. $opt_valgrind_mysqld= 1;
  944. # Set special valgrind options unless options passed on command line
  945. push(@valgrind_args, "--trace-children=yes")
  946. unless @valgrind_args;
  947. }
  948. if ( $opt_valgrind )
  949. {
  950. # Set valgrind_options to default unless already defined
  951. push(@valgrind_args, @default_valgrind_args)
  952. unless @valgrind_args;
  953. mtr_report("Running valgrind with options \"",
  954. join(" ", @valgrind_args), "\"");
  955. }
  956. if ( ! $opt_user )
  957. {
  958. $opt_user= "root"; # We want to do FLUSH xxx commands
  959. }
  960. $path_testlog= "$opt_vardir/log/mysqltest.log";
  961. $path_current_testlog= "$opt_vardir/log/current_test";
  962. mtr_report("Checking supported features...");
  963. check_ndbcluster_support(\%mysqld_variables);
  964. check_ssl_support(\%mysqld_variables);
  965. check_debug_support(\%mysqld_variables);
  966. executable_setup();
  967. environment_setup();
  968. }
  969. #
  970. # To make it easier for different devs to work on the same host,
  971. # an environment variable can be used to control all ports. A small
  972. # number is to be used, 0 - 16 or similar.
  973. #
  974. # Note the MASTER_MYPORT has to be set the same in all 4.x and 5.x
  975. # versions of this script, else a 4.0 test run might conflict with a
  976. # 5.1 test run, even if different MTR_BUILD_THREAD is used. This means
  977. # all port numbers might not be used in this version of the script.
  978. #
  979. # Also note the limitation of ports we are allowed to hand out. This
  980. # differs between operating systems and configuration, see
  981. # http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html
  982. # But a fairly safe range seems to be 5001 - 32767
  983. #
  984. sub set_build_thread_ports($) {
  985. my $build_thread= shift || 0;
  986. if ( lc($build_thread) eq 'auto' ) {
  987. mtr_report("Requesting build thread... ");
  988. $build_thread=
  989. mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299);
  990. mtr_report(" - got $build_thread");
  991. }
  992. $ENV{MTR_BUILD_THREAD}= $build_thread;
  993. $opt_build_thread= $build_thread;
  994. # Calculate baseport
  995. $opt_baseport= $build_thread * 10 + 10000;
  996. if ( $opt_baseport < 5001 or $opt_baseport + 9 >= 32767 )
  997. {
  998. mtr_error("MTR_BUILD_THREAD number results in a port",
  999. "outside 5001 - 32767",
  1000. "($opt_baseport - $opt_baseport + 9)");
  1001. }
  1002. mtr_report("Using MTR_BUILD_THREAD $build_thread,",
  1003. "with reserved ports $opt_baseport..".($opt_baseport+9));
  1004. }
  1005. sub collect_mysqld_features {
  1006. my $found_variable_list_start= 0;
  1007. my $tmpdir= tempdir(CLEANUP => 0); # Directory removed by this function
  1008. #
  1009. # Execute "mysqld --no-defaults --help --verbose" to get a
  1010. # list of all features and settings
  1011. #
  1012. # --no-defaults and --skip-grant-tables are to avoid loading
  1013. # system-wide configs and plugins
  1014. #
  1015. # --datadir must exist, mysqld will chdir into it
  1016. #
  1017. my $args;
  1018. mtr_init_args(\$args);
  1019. mtr_add_arg($args, "--no-defaults");
  1020. mtr_add_arg($args, "--datadir=%s", mixed_path($tmpdir));
  1021. mtr_add_arg($args, "--language=%s", $path_language);
  1022. mtr_add_arg($args, "--skip-grant-tables");
  1023. mtr_add_arg($args, "--verbose");
  1024. mtr_add_arg($args, "--help");
  1025. my $exe_mysqld= find_mysqld($basedir);
  1026. my $cmd= join(" ", $exe_mysqld, @$args);
  1027. my $list= `$cmd`;
  1028. foreach my $line (split('\n', $list))
  1029. {
  1030. # First look for version
  1031. if ( !$mysql_version_id )
  1032. {
  1033. # Look for version
  1034. my $exe_name= basename($exe_mysqld);
  1035. mtr_verbose("exe_name: $exe_name");
  1036. if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ )
  1037. {
  1038. #print "Major: $1 Minor: $2 Build: $3\n";
  1039. $mysql_version_id= $1*10000 + $2*100 + $3;
  1040. #print "mysql_version_id: $mysql_version_id\n";
  1041. mtr_report("MySQL Version $1.$2.$3");
  1042. }
  1043. }
  1044. else
  1045. {
  1046. if (!$found_variable_list_start)
  1047. {
  1048. # Look for start of variables list
  1049. if ( $line =~ /[\-]+\s[\-]+/ )
  1050. {
  1051. $found_variable_list_start= 1;
  1052. }
  1053. }
  1054. else
  1055. {
  1056. # Put variables into hash
  1057. if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
  1058. {
  1059. # print "$1=\"$2\"\n";
  1060. $mysqld_variables{$1}= $2;
  1061. }
  1062. else
  1063. {
  1064. # The variable list is ended with a blank line
  1065. if ( $line =~ /^[\s]*$/ )
  1066. {
  1067. last;
  1068. }
  1069. else
  1070. {
  1071. # Send out a warning, we should fix the variables that has no
  1072. # space between variable name and it's value
  1073. # or should it be fixed width column parsing? It does not
  1074. # look like that in function my_print_variables in my_getopt.c
  1075. mtr_warning("Could not parse variable list line : $line");
  1076. }
  1077. }
  1078. }
  1079. }
  1080. }
  1081. rmtree($tmpdir);
  1082. mtr_error("Could not find version of MySQL") unless $mysql_version_id;
  1083. mtr_error("Could not find variabes list") unless $found_variable_list_start;
  1084. }
  1085. sub find_mysqld {
  1086. my ($mysqld_basedir)= @_;
  1087. my @mysqld_names= ("mysqld", "mysqld-max-nt", "mysqld-max",
  1088. "mysqld-nt");
  1089. if ( $opt_debug ){
  1090. # Put mysqld-debug first in the list of binaries to look for
  1091. mtr_verbose("Adding mysqld-debug first in list of binaries to look for");
  1092. unshift(@mysqld_names, "mysqld-debug");
  1093. }
  1094. return my_find_bin($mysqld_basedir,
  1095. ["sql", "libexec", "sbin"],
  1096. [@mysqld_names]);
  1097. }
  1098. sub executable_setup () {
  1099. #
  1100. # Check if libtool is available in this distribution/clone
  1101. # we need it when valgrinding or debugging non installed binary
  1102. # Otherwise valgrind will valgrind the libtool wrapper or bash
  1103. # and gdb will not find the real executable to debug
  1104. #
  1105. if ( -x "../libtool")
  1106. {
  1107. $exe_libtool= "../libtool";
  1108. if ($opt_valgrind or $glob_debugger)
  1109. {
  1110. mtr_report("Using \"$exe_libtool\" when running valgrind or debugger");
  1111. }
  1112. }
  1113. # Look for the client binaries
  1114. $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
  1115. $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
  1116. if ( ! $opt_skip_ndbcluster )
  1117. {
  1118. $exe_ndbd=
  1119. my_find_bin($basedir,
  1120. ["storage/ndb/src/kernel", "libexec"],
  1121. "ndbd");
  1122. $exe_ndb_mgmd=
  1123. my_find_bin($basedir,
  1124. ["storage/ndb/src/mgmsrv", "libexec"],
  1125. "ndb_mgmd");
  1126. $exe_ndb_waiter=
  1127. my_find_bin($basedir,
  1128. ["storage/ndb/tools/", "bin"],
  1129. "ndb_waiter");
  1130. }
  1131. # Look for mysqltest executable
  1132. if ( $opt_embedded_server )
  1133. {
  1134. $exe_mysqltest=
  1135. mtr_exe_exists(vs_config_dirs('libmysqld/examples','mysqltest_embedded'),
  1136. "$basedir/libmysqld/examples/mysqltest_embedded",
  1137. "$path_client_bindir/mysqltest_embedded");
  1138. }
  1139. else
  1140. {
  1141. $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
  1142. }
  1143. }
  1144. sub client_debug_arg($$) {
  1145. my ($args, $client_name)= @_;
  1146. if ( $opt_debug ) {
  1147. mtr_add_arg($args,
  1148. "--debug=d:t:A,%s/log/%s.trace",
  1149. $path_vardir_trace, $client_name)
  1150. }
  1151. }
  1152. sub mysql_fix_arguments () {
  1153. return "" if ( IS_WINDOWS );
  1154. my $exe=
  1155. mtr_script_exists("$basedir/scripts/mysql_fix_privilege_tables",
  1156. "$path_client_bindir/mysql_fix_privilege_tables");
  1157. my $args;
  1158. mtr_init_args(\$args);
  1159. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1160. mtr_add_arg($args, "--basedir=", $basedir);
  1161. mtr_add_arg($args, "--bindir=", $path_client_bindir);
  1162. mtr_add_arg($args, "--verbose");
  1163. return mtr_args2str($exe, @$args);
  1164. }
  1165. sub client_arguments ($) {
  1166. my $client_name= shift;
  1167. my $client_exe= mtr_exe_exists("$path_client_bindir/$client_name");
  1168. my $args;
  1169. mtr_init_args(\$args);
  1170. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1171. client_debug_arg($args, $client_name);
  1172. return mtr_args2str($client_exe, @$args);
  1173. }
  1174. sub mysqlslap_arguments () {
  1175. my $exe= mtr_exe_maybe_exists("$path_client_bindir/mysqlslap");
  1176. if ( $exe eq "" ) {
  1177. # mysqlap was not found
  1178. if (defined $mysql_version_id and $mysql_version_id >= 50100 ) {
  1179. mtr_error("Could not find the mysqlslap binary");
  1180. }
  1181. return ""; # Don't care about mysqlslap
  1182. }
  1183. my $args;
  1184. mtr_init_args(\$args);
  1185. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1186. client_debug_arg($args, "mysqlslap");
  1187. return mtr_args2str($exe, @$args);
  1188. }
  1189. sub mysqldump_arguments ($) {
  1190. my($group_suffix) = @_;
  1191. my $exe= mtr_exe_exists("$path_client_bindir/mysqldump");
  1192. my $args;
  1193. mtr_init_args(\$args);
  1194. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1195. mtr_add_arg($args, "--defaults-group-suffix=%s", $group_suffix);
  1196. client_debug_arg($args, "mysqldump-$group_suffix");
  1197. return mtr_args2str($exe, @$args);
  1198. }
  1199. sub mysql_client_test_arguments(){
  1200. my $exe;
  1201. # mysql_client_test executable may _not_ exist
  1202. if ( $opt_embedded_server ) {
  1203. $exe= mtr_exe_maybe_exists(
  1204. vs_config_dirs('libmysqld/examples','mysql_client_test_embedded'),
  1205. "$basedir/libmysqld/examples/mysql_client_test_embedded");
  1206. } else {
  1207. $exe= mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'),
  1208. "$basedir/tests/mysql_client_test",
  1209. "$basedir/bin/mysql_client_test");
  1210. }
  1211. my $args;
  1212. mtr_init_args(\$args);
  1213. if ( $opt_valgrind_mysqltest ) {
  1214. valgrind_arguments($args, \$exe);
  1215. }
  1216. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1217. mtr_add_arg($args, "--testcase");
  1218. mtr_add_arg($args, "--vardir=$opt_vardir");
  1219. client_debug_arg($args,"mysql_client_test");
  1220. return mtr_args2str($exe, @$args);
  1221. }
  1222. #
  1223. # Set environment to be used by childs of this process for
  1224. # things that are constant during the whole lifetime of mysql-test-run
  1225. #
  1226. sub environment_setup {
  1227. umask(022);
  1228. my @ld_library_paths;
  1229. if ($path_client_libdir)
  1230. {
  1231. # Use the --client-libdir passed on commandline
  1232. push(@ld_library_paths, "$path_client_libdir");
  1233. }
  1234. else
  1235. {
  1236. # Setup LD_LIBRARY_PATH so the libraries from this distro/clone
  1237. # are used in favor of the system installed ones
  1238. if ( $source_dist )
  1239. {
  1240. push(@ld_library_paths, "$basedir/libmysql/.libs/",
  1241. "$basedir/libmysql_r/.libs/",
  1242. "$basedir/zlib.libs/");
  1243. }
  1244. else
  1245. {
  1246. push(@ld_library_paths, "$basedir/lib");
  1247. }
  1248. }
  1249. # --------------------------------------------------------------------------
  1250. # Add the path where libndbclient can be found
  1251. # --------------------------------------------------------------------------
  1252. if ( !$opt_skip_ndbcluster )
  1253. {
  1254. push(@ld_library_paths, "$basedir/storage/ndb/src/.libs");
  1255. }
  1256. # --------------------------------------------------------------------------
  1257. # Add the path where mysqld will find udf_example.so
  1258. # --------------------------------------------------------------------------
  1259. my $lib_udf_example=
  1260. mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'),
  1261. "$basedir/sql/.libs/udf_example.so",);
  1262. if ( $lib_udf_example )
  1263. {
  1264. push(@ld_library_paths, dirname($lib_udf_example));
  1265. }
  1266. $ENV{'UDF_EXAMPLE_LIB'}=
  1267. ($lib_udf_example ? basename($lib_udf_example) : "");
  1268. $ENV{'UDF_EXAMPLE_LIB_OPT'}= "--plugin-dir=".
  1269. ($lib_udf_example ? dirname($lib_udf_example) : "");
  1270. # --------------------------------------------------------------------------
  1271. # Add the path where mysqld will find ha_example.so
  1272. # --------------------------------------------------------------------------
  1273. if ($mysql_version_id >= 50100) {
  1274. my $lib_example_plugin=
  1275. mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'),
  1276. "$basedir/storage/example/.libs/ha_example.so",);
  1277. $ENV{'EXAMPLE_PLUGIN'}=
  1278. ($lib_example_plugin ? basename($lib_example_plugin) : "");
  1279. $ENV{'EXAMPLE_PLUGIN_OPT'}= "--plugin-dir=".
  1280. ($lib_example_plugin ? dirname($lib_example_plugin) : "");
  1281. }
  1282. # --------------------------------------------------------------------------
  1283. # Valgrind need to be run with debug libraries otherwise it's almost
  1284. # impossible to add correct supressions, that means if "/usr/lib/debug"
  1285. # is available, it should be added to
  1286. # LD_LIBRARY_PATH
  1287. #
  1288. # But pthread is broken in libc6-dbg on Debian <= 3.1 (see Debian
  1289. # bug 399035, http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=399035),
  1290. # so don't change LD_LIBRARY_PATH on that platform.
  1291. # --------------------------------------------------------------------------
  1292. my $debug_libraries_path= "/usr/lib/debug";
  1293. my $deb_version;
  1294. if ( $opt_valgrind and -d $debug_libraries_path and
  1295. (! -e '/etc/debian_version' or
  1296. ($deb_version=
  1297. mtr_grab_file('/etc/debian_version')) !~ /^[0-9]+\.[0-9]$/ or
  1298. $deb_version > 3.1 ) )
  1299. {
  1300. push(@ld_library_paths, $debug_libraries_path);
  1301. }
  1302. $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths,
  1303. $ENV{'LD_LIBRARY_PATH'} ?
  1304. split(':', $ENV{'LD_LIBRARY_PATH'}) : ());
  1305. mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}");
  1306. $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths,
  1307. $ENV{'DYLD_LIBRARY_PATH'} ?
  1308. split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ());
  1309. mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}");
  1310. # The environment variable used for shared libs on AIX
  1311. $ENV{'SHLIB_PATH'}= join(":", @ld_library_paths,
  1312. $ENV{'SHLIB_PATH'} ?
  1313. split(':', $ENV{'SHLIB_PATH'}) : ());
  1314. mtr_debug("SHLIB_PATH: $ENV{'SHLIB_PATH'}");
  1315. # The environment variable used for shared libs on hp-ux
  1316. $ENV{'LIBPATH'}= join(":", @ld_library_paths,
  1317. $ENV{'LIBPATH'} ?
  1318. split(':', $ENV{'LIBPATH'}) : ());
  1319. mtr_debug("LIBPATH: $ENV{'LIBPATH'}");
  1320. $ENV{'CHARSETSDIR'}= $path_charsetsdir;
  1321. $ENV{'UMASK'}= "0660"; # The octal *string*
  1322. $ENV{'UMASK_DIR'}= "0770"; # The octal *string*
  1323. #
  1324. # MySQL tests can produce output in various character sets
  1325. # (especially, ctype_xxx.test). To avoid confusing Perl
  1326. # with output which is incompatible with the current locale
  1327. # settings, we reset the current values of LC_ALL and LC_CTYPE to "C".
  1328. # For details, please see
  1329. # Bug#27636 tests fails if LC_* variables set to *_*.UTF-8
  1330. #
  1331. $ENV{'LC_ALL'}= "C";
  1332. $ENV{'LC_CTYPE'}= "C";
  1333. $ENV{'LC_COLLATE'}= "C";
  1334. $ENV{'USE_RUNNING_SERVER'}= using_extern();
  1335. $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir;
  1336. $ENV{'MYSQLTEST_VARDIR'}= $opt_vardir;
  1337. $ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'master-port'} || 3306;
  1338. $ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir;
  1339. # ----------------------------------------------------
  1340. # Setup env for NDB
  1341. # ----------------------------------------------------
  1342. if ( ! $opt_skip_ndbcluster )
  1343. {
  1344. $ENV{'NDB_MGM'}=
  1345. my_find_bin($basedir,
  1346. ["storage/ndb/src/mgmclient", "bin"],
  1347. "ndb_mgm");
  1348. $ENV{'NDB_TOOLS_DIR'}=
  1349. my_find_dir($basedir,
  1350. ["storage/ndb/tools", "bin"]);
  1351. $ENV{'NDB_EXAMPLES_DIR'}=
  1352. my_find_dir($basedir,
  1353. ["storage/ndb/ndbapi-examples", "bin"]);
  1354. $ENV{'NDB_EXAMPLES_BINARY'}=
  1355. my_find_bin($basedir,
  1356. ["storage/ndb/ndbapi-examples/ndbapi_simple", "bin"],
  1357. "ndbapi_simple", NOT_REQUIRED);
  1358. my $path_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log";
  1359. $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log;
  1360. $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log;
  1361. }
  1362. # ----------------------------------------------------
  1363. # mysql clients
  1364. # ----------------------------------------------------
  1365. $ENV{'MYSQL_CHECK'}= client_arguments("mysqlcheck");
  1366. $ENV{'MYSQL_DUMP'}= mysqldump_arguments(".1");
  1367. $ENV{'MYSQL_DUMP_SLAVE'}= mysqldump_arguments(".2");
  1368. $ENV{'MYSQL_SLAP'}= mysqlslap_arguments();
  1369. $ENV{'MYSQL_IMPORT'}= client_arguments("mysqlimport");
  1370. $ENV{'MYSQL_SHOW'}= client_arguments("mysqlshow");
  1371. $ENV{'MYSQL_BINLOG'}= client_arguments("mysqlbinlog");
  1372. $ENV{'MYSQL'}= client_arguments("mysql");
  1373. $ENV{'MYSQL_UPGRADE'}= client_arguments("mysql_upgrade");
  1374. $ENV{'MYSQLADMIN'}= native_path($exe_mysqladmin);
  1375. $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments();
  1376. $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= mysql_fix_arguments();
  1377. $ENV{'EXE_MYSQL'}= $exe_mysql;
  1378. # ----------------------------------------------------
  1379. # bug25714 executable may _not_ exist in
  1380. # some versions, test using it should be skipped
  1381. # ----------------------------------------------------
  1382. my $exe_bug25714=
  1383. mtr_exe_maybe_exists(vs_config_dirs('tests', 'bug25714'),
  1384. "$basedir/tests/bug25714");
  1385. $ENV{'MYSQL_BUG25714'}= native_path($exe_bug25714);
  1386. # ----------------------------------------------------
  1387. # mysql_fix_privilege_tables.sql
  1388. # ----------------------------------------------------
  1389. my $file_mysql_fix_privilege_tables=
  1390. mtr_file_exists("$basedir/scripts/mysql_fix_privilege_tables.sql",
  1391. "$basedir/share/mysql_fix_privilege_tables.sql");
  1392. $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables;
  1393. # ----------------------------------------------------
  1394. # my_print_defaults
  1395. # ----------------------------------------------------
  1396. my $exe_my_print_defaults=
  1397. mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'),
  1398. "$path_client_bindir/my_print_defaults",
  1399. "$basedir/extra/my_print_defaults");
  1400. $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= native_path($exe_my_print_defaults);
  1401. # ----------------------------------------------------
  1402. # Setup env so childs can execute myisampack and myisamchk
  1403. # ----------------------------------------------------
  1404. $ENV{'MYISAMCHK'}= native_path(mtr_exe_exists(
  1405. vs_config_dirs('storage/myisam', 'myisamchk'),
  1406. vs_config_dirs('myisam', 'myisamchk'),
  1407. "$path_client_bindir/myisamchk",
  1408. "$basedir/storage/myisam/myisamchk",
  1409. "$basedir/myisam/myisamchk"));
  1410. $ENV{'MYISAMPACK'}= native_path(mtr_exe_exists(
  1411. vs_config_dirs('storage/myisam', 'myisampack'),
  1412. vs_config_dirs('myisam', 'myisampack'),
  1413. "$path_client_bindir/myisampack",
  1414. "$basedir/storage/myisam/myisampack",
  1415. "$basedir/myisam/myisampack"));
  1416. # ----------------------------------------------------
  1417. # perror
  1418. # ----------------------------------------------------
  1419. my $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'),
  1420. "$basedir/extra/perror",
  1421. "$path_client_bindir/perror");
  1422. $ENV{'MY_PERROR'}= native_path($exe_perror);
  1423. # Create an environment variable to make it possible
  1424. # to detect that valgrind is being used from test cases
  1425. $ENV{'VALGRIND_TEST'}= $opt_valgrind;
  1426. }
  1427. #
  1428. # Remove var and any directories in var/ created by previous
  1429. # tests
  1430. #
  1431. sub remove_stale_vardir () {
  1432. mtr_report("Removing old var directory...");
  1433. # Safety!
  1434. mtr_error("No, don't remove the vardir when running with --extern")
  1435. if using_extern();
  1436. mtr_verbose("opt_vardir: $opt_vardir");
  1437. if ( $opt_vardir eq $default_vardir )
  1438. {
  1439. #
  1440. # Running with "var" in mysql-test dir
  1441. #
  1442. if ( -l $opt_vardir)
  1443. {
  1444. # var is a symlink
  1445. if ( $opt_mem )
  1446. {
  1447. # Remove the directory which the link points at
  1448. mtr_verbose("Removing " . readlink($opt_vardir));
  1449. rmtree(readlink($opt_vardir));
  1450. # Remove the "var" symlink
  1451. mtr_verbose("unlink($opt_vardir)");
  1452. unlink($opt_vardir);
  1453. }
  1454. else
  1455. {
  1456. # Some users creates a soft link in mysql-test/var to another area
  1457. # - allow it, but remove all files in it
  1458. mtr_report(" - WARNING: Using the 'mysql-test/var' symlink");
  1459. # Make sure the directory where it points exist
  1460. mtr_error("The destination for symlink $opt_vardir does not exist")
  1461. if ! -d readlink($opt_vardir);
  1462. foreach my $bin ( glob("$opt_vardir/*") )
  1463. {
  1464. mtr_verbose("Removing bin $bin");
  1465. rmtree($bin);
  1466. }
  1467. }
  1468. }
  1469. else
  1470. {
  1471. # Remove the entire "var" dir
  1472. mtr_verbose("Removing $opt_vardir/");
  1473. rmtree("$opt_vardir/");
  1474. }
  1475. if ( $opt_mem )
  1476. {
  1477. # A symlink from var/ to $opt_mem will be set up
  1478. # remove the $opt_mem dir to assure the symlink
  1479. # won't point at an old directory
  1480. mtr_verbose("Removing $opt_mem");
  1481. rmtree($opt_mem);
  1482. }
  1483. }
  1484. else
  1485. {
  1486. #
  1487. # Running with "var" in some other place
  1488. #
  1489. # Remove the var/ dir in mysql-test dir if any
  1490. # this could be an old symlink that shouldn't be there
  1491. mtr_verbose("Removing $default_vardir");
  1492. rmtree($default_vardir);
  1493. # Remove the "var" dir
  1494. mtr_verbose("Removing $opt_vardir/");
  1495. rmtree("$opt_vardir/");
  1496. }
  1497. }
  1498. #
  1499. # Create var and the directories needed in var
  1500. #
  1501. sub setup_vardir() {
  1502. mtr_report("Creating var directory '$opt_vardir'...");
  1503. if ( $opt_vardir eq $default_vardir )
  1504. {
  1505. #
  1506. # Running with "var" in mysql-test dir
  1507. #
  1508. if ( -l $opt_vardir )
  1509. {
  1510. # it's a symlink
  1511. # Make sure the directory where it points exist
  1512. mtr_error("The destination for symlink $opt_vardir does not exist")
  1513. if ! -d readlink($opt_vardir);
  1514. }
  1515. elsif ( $opt_mem )
  1516. {
  1517. # Runinng with "var" as a link to some "memory" location, normally tmpfs
  1518. mtr_verbose("Creating $opt_mem");
  1519. mkpath($opt_mem);
  1520. mtr_report(" - symlinking 'var' to '$opt_mem'");
  1521. symlink($opt_mem, $opt_vardir);
  1522. }
  1523. }
  1524. if ( ! -d $opt_vardir )
  1525. {
  1526. mtr_verbose("Creating $opt_vardir");
  1527. mkpath($opt_vardir);
  1528. }
  1529. # Ensure a proper error message if vardir couldn't be created
  1530. unless ( -d $opt_vardir and -w $opt_vardir )
  1531. {
  1532. mtr_error("Writable 'var' directory is needed, use the " .
  1533. "'--vardir=<path>' option");
  1534. }
  1535. mkpath("$opt_vardir/log");
  1536. mkpath("$opt_vardir/run");
  1537. # Create var/tmp and tmp - they might be different
  1538. mkpath("$opt_vardir/tmp");
  1539. mkpath($opt_tmpdir) if ($opt_tmpdir ne "$opt_vardir/tmp");
  1540. # On some operating systems, there is a limit to the length of a
  1541. # UNIX domain socket's path far below PATH_MAX.
  1542. # Don't allow that to happen
  1543. if (check_socket_path_length("$opt_tmpdir/testsocket.sock")){
  1544. mtr_error("Socket path '$opt_tmpdir' too long, it would be ",
  1545. "truncated and thus not possible to use for connection to ",
  1546. "MySQL Server. Set a shorter with --tmpdir=<path> option");
  1547. }
  1548. # copy all files from std_data into var/std_data
  1549. # and make them writable
  1550. copytree("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data");
  1551. # Remove old log files
  1552. foreach my $name (glob("r/*.progress r/*.log r/*.warnings"))
  1553. {
  1554. unlink($name);
  1555. }
  1556. }
  1557. #
  1558. # Check if running as root
  1559. # i.e a file can be read regardless what mode we set it to
  1560. #
  1561. sub check_running_as_root () {
  1562. my $test_file= "$opt_vardir/test_running_as_root.txt";
  1563. mtr_tofile($test_file, "MySQL");
  1564. chmod(oct("0000"), $test_file);
  1565. my $result="";
  1566. if (open(FILE,"<",$test_file))
  1567. {
  1568. $result= join('', <FILE>);
  1569. close FILE;
  1570. }
  1571. # Some filesystems( for example CIFS) allows reading a file
  1572. # although mode was set to 0000, but in that case a stat on
  1573. # the file will not return 0000
  1574. my $file_mode= (stat($test_file))[2] & 07777;
  1575. $ENV{'MYSQL_TEST_ROOT'}= "NO";
  1576. mtr_verbose("result: $result, file_mode: $file_mode");
  1577. if ($result eq "MySQL" && $file_mode == 0)
  1578. {
  1579. mtr_warning("running this script as _root_ will cause some " .
  1580. "tests to be skipped");
  1581. $ENV{'MYSQL_TEST_ROOT'}= "YES";
  1582. }
  1583. chmod(oct("0755"), $test_file);
  1584. unlink($test_file);
  1585. }
  1586. sub check_ssl_support ($) {
  1587. my $mysqld_variables= shift;
  1588. if ($opt_skip_ssl)
  1589. {
  1590. mtr_report(" - skipping SSL");
  1591. $opt_ssl_supported= 0;
  1592. $opt_ssl= 0;
  1593. return;
  1594. }
  1595. if ( ! $mysqld_variables->{'ssl'} )
  1596. {
  1597. if ( $opt_ssl)
  1598. {
  1599. mtr_error("Couldn't find support for SSL");
  1600. return;
  1601. }
  1602. mtr_report(" - skipping SSL, mysqld not compiled with SSL");
  1603. $opt_ssl_supported= 0;
  1604. $opt_ssl= 0;
  1605. return;
  1606. }
  1607. mtr_report(" - SSL connections supported");
  1608. $opt_ssl_supported= 1;
  1609. }
  1610. sub check_debug_support ($) {
  1611. my $mysqld_variables= shift;
  1612. if ( ! $mysqld_variables->{'debug'} )
  1613. {
  1614. #mtr_report(" - binaries are not debug compiled");
  1615. $debug_compiled_binaries= 0;
  1616. if ( $opt_debug )
  1617. {
  1618. mtr_error("Can't use --debug, binaries does not support it");
  1619. }
  1620. return;
  1621. }
  1622. mtr_report(" - binaries are debug compiled");
  1623. $debug_compiled_binaries= 1;
  1624. }
  1625. #
  1626. # Helper function to handle configuration-based subdirectories which Visual
  1627. # Studio uses for storing binaries. If opt_vs_config is set, this returns
  1628. # a path based on that setting; if not, it returns paths for the default
  1629. # /release/ and /debug/ subdirectories.
  1630. #
  1631. # $exe can be undefined, if the directory itself will be used
  1632. #
  1633. sub vs_config_dirs ($$) {
  1634. my ($path_part, $exe) = @_;
  1635. $exe = "" if not defined $exe;
  1636. # Don't look in these dirs when not on windows
  1637. return () unless IS_WINDOWS;
  1638. if ($opt_vs_config)
  1639. {
  1640. return ("$basedir/$path_part/$opt_vs_config/$exe");
  1641. }
  1642. return ("$basedir/$path_part/release/$exe",
  1643. "$basedir/$path_part/relwithdebinfo/$exe",
  1644. "$basedir/$path_part/debug/$exe");
  1645. }
  1646. sub check_ndbcluster_support ($) {
  1647. my $mysqld_variables= shift;
  1648. if ($opt_skip_ndbcluster)
  1649. {
  1650. mtr_report(" - skipping ndbcluster");
  1651. $opt_skip_ndbcluster_slave= $opt_skip_ndbcluster;
  1652. return;
  1653. }
  1654. if ( ! $mysqld_variables{'ndb-connectstring'} )
  1655. {
  1656. mtr_report(" - skipping ndbcluster, mysqld not compiled with ndbcluster");
  1657. $opt_skip_ndbcluster= 2;
  1658. $opt_skip_ndbcluster_slave= 2;
  1659. return;
  1660. }
  1661. mtr_report(" - using ndbcluster when necessary, mysqld supports it");
  1662. return;
  1663. }
  1664. sub ndbcluster_wait_started($$){
  1665. my $cluster= shift;
  1666. my $ndb_waiter_extra_opt= shift;
  1667. my $path_waitlog= join('/', $opt_vardir, $cluster->name(), "ndb_waiter.log");
  1668. my $args;
  1669. mtr_init_args(\$args);
  1670. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1671. mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix());
  1672. mtr_add_arg($args, "--timeout=%d", $opt_start_timeout);
  1673. if ($ndb_waiter_extra_opt)
  1674. {
  1675. mtr_add_arg($args, "$ndb_waiter_extra_opt");
  1676. }
  1677. # Start the ndb_waiter which will connect to the ndb_mgmd
  1678. # and poll it for state of the ndbd's, will return when
  1679. # all nodes in the cluster is started
  1680. my $res= My::SafeProcess->run
  1681. (
  1682. name => "ndb_waiter ".$cluster->name(),
  1683. path => $exe_ndb_waiter,
  1684. args => \$args,
  1685. output => $path_waitlog,
  1686. error => $path_waitlog,
  1687. append => 1,
  1688. );
  1689. # Check that ndb_mgmd(s) are still alive
  1690. foreach my $ndb_mgmd ( in_cluster($cluster, ndb_mgmds()) )
  1691. {
  1692. my $proc= $ndb_mgmd->{proc};
  1693. if ( ! $proc->wait_one(0) )
  1694. {
  1695. mtr_warning("$proc died");
  1696. return 2;
  1697. }
  1698. }
  1699. # Check that all started ndbd(s) are still alive
  1700. foreach my $ndbd ( in_cluster($cluster, ndbds()) )
  1701. {
  1702. my $proc= $ndbd->{proc};
  1703. next unless defined $proc;
  1704. if ( ! $proc->wait_one(0) )
  1705. {
  1706. mtr_warning("$proc died");
  1707. return 3;
  1708. }
  1709. }
  1710. if ($res)
  1711. {
  1712. mtr_verbose("ndbcluster_wait_started failed");
  1713. return 1;
  1714. }
  1715. return 0;
  1716. }
  1717. sub ndb_mgmd_wait_started($) {
  1718. my ($cluster)= @_;
  1719. my $retries= 100;
  1720. while ($retries)
  1721. {
  1722. my $result= ndbcluster_wait_started($cluster, "--no-contact");
  1723. if ($result == 0)
  1724. {
  1725. # ndb_mgmd is started
  1726. mtr_verbose("ndb_mgmd is started");
  1727. return 0;
  1728. }
  1729. elsif ($result > 1)
  1730. {
  1731. mtr_warning("Cluster process failed while waiting for start");
  1732. return $result;
  1733. }
  1734. mtr_milli_sleep(100);
  1735. $retries--;
  1736. }
  1737. return 1;
  1738. }
  1739. sub ndb_mgmd_start ($$) {
  1740. my ($cluster, $ndb_mgmd)= @_;
  1741. mtr_verbose("ndb_mgmd_start");
  1742. my $dir= $ndb_mgmd->value("DataDir");
  1743. mkpath($dir) unless -d $dir;
  1744. my $args;
  1745. mtr_init_args(\$args);
  1746. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1747. mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix());
  1748. mtr_add_arg($args, "--mycnf");
  1749. mtr_add_arg($args, "--nodaemon");
  1750. my $path_ndb_mgmd_log= "$dir/ndb_mgmd.log";
  1751. $ndb_mgmd->{'proc'}= My::SafeProcess->new
  1752. (
  1753. name => $ndb_mgmd->after('cluster_config.'),
  1754. path => $exe_ndb_mgmd,
  1755. args => \$args,
  1756. output => $path_ndb_mgmd_log,
  1757. error => $path_ndb_mgmd_log,
  1758. append => 1,
  1759. verbose => $opt_verbose,
  1760. );
  1761. mtr_verbose("Started $ndb_mgmd->{proc}");
  1762. # FIXME Should not be needed
  1763. # Unfortunately the cluster nodes will fail to start
  1764. # if ndb_mgmd has not started properly
  1765. if (ndb_mgmd_wait_started($cluster))
  1766. {
  1767. mtr_warning("Failed to wait for start of ndb_mgmd");
  1768. return 1;
  1769. }
  1770. return 0;
  1771. }
  1772. sub ndbd_start {
  1773. my ($cluster, $ndbd)= @_;
  1774. mtr_verbose("ndbd_start");
  1775. my $dir= $ndbd->value("DataDir");
  1776. mkpath($dir) unless -d $dir;
  1777. my $args;
  1778. mtr_init_args(\$args);
  1779. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  1780. mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix());
  1781. mtr_add_arg($args, "--nodaemon");
  1782. # > 5.0 { 'character-sets-dir' => \&fix_charset_dir },
  1783. my $path_ndbd_log= "$dir/ndbd.log";
  1784. my $proc= My::SafeProcess->new
  1785. (
  1786. name => $ndbd->after('cluster_config.'),
  1787. path => $exe_ndbd,
  1788. args => \$args,
  1789. output => $path_ndbd_log,
  1790. error => $path_ndbd_log,
  1791. append => 1,
  1792. verbose => $opt_verbose,
  1793. );
  1794. mtr_verbose("Started $proc");
  1795. $ndbd->{proc}= $proc;
  1796. return;
  1797. }
  1798. sub ndbcluster_start ($) {
  1799. my $cluster= shift;
  1800. mtr_verbose("ndbcluster_start '".$cluster->name()."'");
  1801. foreach my $ndb_mgmd ( in_cluster($cluster, ndb_mgmds()) )
  1802. {
  1803. next if started($ndb_mgmd);
  1804. ndb_mgmd_start($cluster, $ndb_mgmd);
  1805. }
  1806. foreach my $ndbd ( in_cluster($cluster, ndbds()) )
  1807. {
  1808. next if started($ndbd);
  1809. ndbd_start($cluster, $ndbd);
  1810. }
  1811. return 0;
  1812. }
  1813. sub create_config_file_for_extern {
  1814. my %opts=
  1815. (
  1816. socket => '/tmp/mysqld.sock',
  1817. port => 3306,
  1818. user => 'test',
  1819. password => '',
  1820. @_
  1821. );
  1822. mtr_report("Creating my.cnf file for extern server...");
  1823. my $F= IO::File->new($path_config_file, "w")
  1824. or mtr_error("Can't write to $path_config_file: $!");
  1825. print $F "[client]\n";
  1826. while (my ($option, $value)= each( %opts )) {
  1827. print $F "$option= $value\n";
  1828. mtr_report(" $option= $value");
  1829. }
  1830. print $F <<EOF
  1831. # binlog reads from [client] and [mysqlbinlog]
  1832. [mysqlbinlog]
  1833. character-sets-dir= $path_charsetsdir
  1834. # mysql_fix_privilege_tables.sh don't read from [client]
  1835. [mysql_fix_privilege_tables]
  1836. socket = $opts{'socket'}
  1837. port = $opts{'port'}
  1838. user = $opts{'user'}
  1839. password = $opts{'password'}
  1840. EOF
  1841. ;
  1842. $F= undef; # Close file
  1843. }
  1844. #
  1845. # Kill processes left from previous runs, normally
  1846. # there should be none so make sure to warn
  1847. # if there is one
  1848. #
  1849. sub kill_leftovers ($) {
  1850. my $rundir= shift;
  1851. return unless ( -d $rundir );
  1852. mtr_report("Checking leftover processes...");
  1853. # Scan the "run" directory for process id's to kill
  1854. opendir(RUNDIR, $rundir)
  1855. or mtr_error("kill_leftovers, can't open dir \"$rundir\": $!");
  1856. while ( my $elem= readdir(RUNDIR) )
  1857. {
  1858. # Only read pid from files that end with .pid
  1859. if ( $elem =~ /.*[.]pid$/ )
  1860. {
  1861. my $pidfile= "$rundir/$elem";
  1862. next unless -f $pidfile;
  1863. my $pid= mtr_fromfile($pidfile);
  1864. unlink($pidfile);
  1865. unless ($pid=~ /^(\d+)/){
  1866. # The pid was not a valid number
  1867. mtr_warning("Got invalid pid '$pid' from '$elem'");
  1868. next;
  1869. }
  1870. mtr_report(" - found old pid $pid in '$elem', killing it...");
  1871. my $ret= kill(9, $pid);
  1872. if ($ret == 0) {
  1873. mtr_report(" process did not exist!");
  1874. next;
  1875. }
  1876. my $check_counter= 100;
  1877. while ($ret > 0 and $check_counter--) {
  1878. mtr_milli_sleep(100);
  1879. $ret= kill(0, $pid);
  1880. }
  1881. mtr_report($check_counter ? " ok!" : " failed!");
  1882. }
  1883. else
  1884. {
  1885. mtr_warning("Found non pid file '$elem' in '$rundir'")
  1886. if -f "$rundir/$elem";
  1887. }
  1888. }
  1889. closedir(RUNDIR);
  1890. }
  1891. #
  1892. # Check that all the ports that are going to
  1893. # be used are free
  1894. #
  1895. sub check_ports_free
  1896. {
  1897. my @ports_to_check;
  1898. for ($opt_baseport..$opt_baseport+9){
  1899. push(@ports_to_check, $_);
  1900. }
  1901. mtr_report("Checking ports...");
  1902. # print "@ports_to_check\n";
  1903. foreach my $port (@ports_to_check){
  1904. if (mtr_ping_port($port)){
  1905. mtr_report(" - 'localhost:$port' was not free");
  1906. return 1; # One port was not free
  1907. }
  1908. }
  1909. return 0; # All ports free
  1910. }
  1911. sub initialize_servers {
  1912. if ( using_extern() )
  1913. {
  1914. # Running against an already started server, if the specified
  1915. # vardir does not already exist it should be created
  1916. if ( ! -d $opt_vardir )
  1917. {
  1918. setup_vardir();
  1919. }
  1920. else
  1921. {
  1922. mtr_verbose("No need to create '$opt_vardir' it already exists");
  1923. }
  1924. }
  1925. else
  1926. {
  1927. # Kill leftovers from previous run
  1928. # using any pidfiles found in var/run
  1929. kill_leftovers("$opt_vardir/run");
  1930. if (check_ports_free()){
  1931. # Some port was not free(which one has already been printed)
  1932. mtr_error("Some port(s) was not free")
  1933. }
  1934. if ( ! $opt_start_dirty )
  1935. {
  1936. remove_stale_vardir();
  1937. setup_vardir();
  1938. mysql_install_db(0);
  1939. }
  1940. }
  1941. check_running_as_root();
  1942. }
  1943. #
  1944. # Remove all newline characters expect after semicolon
  1945. #
  1946. sub sql_to_bootstrap {
  1947. my ($sql) = @_;
  1948. my @lines= split(/\n/, $sql);
  1949. my $result= "\n";
  1950. my $delimiter= ';';
  1951. foreach my $line (@lines) {
  1952. # Change current delimiter if line starts with "delimiter"
  1953. if ( $line =~ /^delimiter (.*)/ ) {
  1954. my $new= $1;
  1955. # Remove old delimiter from end of new
  1956. $new=~ s/\Q$delimiter\E$//;
  1957. $delimiter = $new;
  1958. mtr_debug("changed delimiter to $delimiter");
  1959. # No need to add the delimiter to result
  1960. next;
  1961. }
  1962. # Add newline if line ends with $delimiter
  1963. # and convert the current delimiter to semicolon
  1964. if ( $line =~ /\Q$delimiter\E$/ ){
  1965. $line =~ s/\Q$delimiter\E$/;/;
  1966. $result.= "$line\n";
  1967. mtr_debug("Added default delimiter");
  1968. next;
  1969. }
  1970. # Remove comments starting with --
  1971. if ( $line =~ /^\s*--/ ) {
  1972. mtr_debug("Discarded $line");
  1973. next;
  1974. }
  1975. # Replace @HOSTNAME with localhost
  1976. $line=~ s/\'\@HOSTNAME\@\'/localhost/;
  1977. # Default, just add the line without newline
  1978. # but with a space as separator
  1979. $result.= "$line ";
  1980. }
  1981. return $result;
  1982. }
  1983. sub mysql_install_db {
  1984. my ($thread_num)= @_;
  1985. my $data_dir= "$opt_vardir/install.db";
  1986. mtr_report("Installing system database...");
  1987. my $args;
  1988. mtr_init_args(\$args);
  1989. mtr_add_arg($args, "--no-defaults");
  1990. mtr_add_arg($args, "--bootstrap");
  1991. mtr_add_arg($args, "--basedir=%s", $basedir);
  1992. mtr_add_arg($args, "--datadir=%s", $data_dir);
  1993. mtr_add_arg($args, "--loose-skip-innodb");
  1994. mtr_add_arg($args, "--loose-skip-ndbcluster");
  1995. mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/");
  1996. mtr_add_arg($args, "--core-file");
  1997. if ( $opt_debug )
  1998. {
  1999. mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap.trace",
  2000. $path_vardir_trace);
  2001. }
  2002. mtr_add_arg($args, "--language=%s", $path_language);
  2003. mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
  2004. # If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g.,
  2005. # configure --disable-grant-options), mysqld will not recognize the
  2006. # --bootstrap or --skip-grant-tables options. The user can set
  2007. # MYSQLD_BOOTSTRAP to the full path to a mysqld which does accept
  2008. # --bootstrap, to accommodate this.
  2009. my $exe_mysqld_bootstrap = $ENV{'MYSQLD_BOOTSTRAP'} || find_mysqld($basedir);
  2010. # ----------------------------------------------------------------------
  2011. # export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args>
  2012. # ----------------------------------------------------------------------
  2013. $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args);
  2014. return if $thread_num > 0; # Only generate MYSQLD_BOOTSTRAP_CMD in workers
  2015. # ----------------------------------------------------------------------
  2016. # Create the bootstrap.sql file
  2017. # ----------------------------------------------------------------------
  2018. my $bootstrap_sql_file= "$opt_vardir/tmp/bootstrap.sql";
  2019. if (-f "$path_sql_dir/mysql_system_tables.sql")
  2020. {
  2021. # Use the mysql database for system tables
  2022. mtr_tofile($bootstrap_sql_file, "use mysql\n");
  2023. # Add the offical mysql system tables
  2024. # for a production system
  2025. mtr_appendfile_to_file("$path_sql_dir/mysql_system_tables.sql",
  2026. $bootstrap_sql_file);
  2027. # Add the mysql system tables initial data
  2028. # for a production system
  2029. mtr_appendfile_to_file("$path_sql_dir/mysql_system_tables_data.sql",
  2030. $bootstrap_sql_file);
  2031. # Add test data for timezone - this is just a subset, on a real
  2032. # system these tables will be populated either by mysql_tzinfo_to_sql
  2033. # or by downloading the timezone table package from our website
  2034. mtr_appendfile_to_file("$path_sql_dir/mysql_test_data_timezone.sql",
  2035. $bootstrap_sql_file);
  2036. }
  2037. else
  2038. {
  2039. # Install db from init_db.sql that exist in early 5.1 and 5.0
  2040. # versions of MySQL
  2041. my $init_file= "$basedir/mysql-test/lib/init_db.sql";
  2042. mtr_report(" - from '$init_file'");
  2043. my $text= mtr_grab_file($init_file) or
  2044. mtr_error("Can't open '$init_file': $!");
  2045. mtr_tofile($bootstrap_sql_file,
  2046. sql_to_bootstrap($text));
  2047. }
  2048. # Fill help tables, just an empty file when running from bk repo
  2049. # but will be replaced by a real fill_help_tables.sql when
  2050. # building the source dist
  2051. mtr_appendfile_to_file("$path_sql_dir/fill_help_tables.sql",
  2052. $bootstrap_sql_file);
  2053. # Remove anonymous users
  2054. mtr_tofile($bootstrap_sql_file,
  2055. "DELETE FROM mysql.user where user= '';\n");
  2056. # Create mtr database
  2057. mtr_tofile($bootstrap_sql_file,
  2058. "CREATE DATABASE mtr;\n");
  2059. # Add help tables and data for warning detection and supression
  2060. mtr_tofile($bootstrap_sql_file,
  2061. sql_to_bootstrap(mtr_grab_file("include/mtr_warnings.sql")));
  2062. # Add procedures for checking server is restored after testcase
  2063. mtr_tofile($bootstrap_sql_file,
  2064. sql_to_bootstrap(mtr_grab_file("include/mtr_check.sql")));
  2065. # Log bootstrap command
  2066. my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log";
  2067. mtr_tofile($path_bootstrap_log,
  2068. "$exe_mysqld_bootstrap " . join(" ", @$args) . "\n");
  2069. # Create directories mysql and test
  2070. mkpath("$data_dir/mysql");
  2071. mkpath("$data_dir/test");
  2072. if ( My::SafeProcess->run
  2073. (
  2074. name => "bootstrap",
  2075. path => $exe_mysqld_bootstrap,
  2076. args => \$args,
  2077. input => $bootstrap_sql_file,
  2078. output => $path_bootstrap_log,
  2079. error => $path_bootstrap_log,
  2080. append => 1,
  2081. verbose => $opt_verbose,
  2082. ) != 0)
  2083. {
  2084. mtr_error("Error executing mysqld --bootstrap\n" .
  2085. "Could not install system database from $bootstrap_sql_file\n" .
  2086. "see $path_bootstrap_log for errors");
  2087. }
  2088. }
  2089. sub run_testcase_check_skip_test($)
  2090. {
  2091. my ($tinfo)= @_;
  2092. # ----------------------------------------------------------------------
  2093. # If marked to skip, just print out and return.
  2094. # Note that a test case not marked as 'skip' can still be
  2095. # skipped later, because of the test case itself in cooperation
  2096. # with the mysqltest program tells us so.
  2097. # ----------------------------------------------------------------------
  2098. if ( $tinfo->{'skip'} )
  2099. {
  2100. mtr_report_test_skipped($tinfo);
  2101. return 1;
  2102. }
  2103. return 0;
  2104. }
  2105. sub run_query {
  2106. my ($tinfo, $mysqld, $query)= @_;
  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", $mysqld->after('mysqld'));
  2111. mtr_add_arg($args, "-e %s", $query);
  2112. my $res= My::SafeProcess->run
  2113. (
  2114. name => "run_query -> ".$mysqld->name(),
  2115. path => $exe_mysql,
  2116. args => \$args,
  2117. output => '/dev/null',
  2118. error => '/dev/null'
  2119. );
  2120. return $res
  2121. }
  2122. sub do_before_run_mysqltest($)
  2123. {
  2124. my $tinfo= shift;
  2125. # Remove old files produced by mysqltest
  2126. my $base_file= mtr_match_extension($tinfo->{'result_file'},
  2127. "result"); # Trim extension
  2128. unlink("$base_file.reject");
  2129. unlink("$base_file.progress");
  2130. unlink("$base_file.log");
  2131. unlink("$base_file.warnings");
  2132. if ( $mysql_version_id < 50000 ) {
  2133. # Set environment variable NDB_STATUS_OK to 1
  2134. # if script decided to run mysqltest cluster _is_ installed ok
  2135. $ENV{'NDB_STATUS_OK'} = "1";
  2136. } elsif ( $mysql_version_id < 50100 ) {
  2137. # Set environment variable NDB_STATUS_OK to YES
  2138. # if script decided to run mysqltest cluster _is_ installed ok
  2139. $ENV{'NDB_STATUS_OK'} = "YES";
  2140. }
  2141. }
  2142. #
  2143. # Check all server for sideffects
  2144. #
  2145. # RETURN VALUE
  2146. # 0 ok
  2147. # 1 Check failed
  2148. # >1 Fatal errro
  2149. sub check_testcase($$)
  2150. {
  2151. my ($tinfo, $mode)= @_;
  2152. my $tname= $tinfo->{name};
  2153. # Start the mysqltest processes in parallel to save time
  2154. # also makes it possible to wait for any process to exit during the check
  2155. my %started;
  2156. foreach my $mysqld ( mysqlds() )
  2157. {
  2158. if ( defined $mysqld->{'proc'} )
  2159. {
  2160. my $proc= start_check_testcase($tinfo, $mode, $mysqld);
  2161. $started{$proc->pid()}= $proc;
  2162. }
  2163. }
  2164. # Return immediately if no check proceess was started
  2165. return 0 unless ( keys %started );
  2166. while (1){
  2167. my $result;
  2168. my $proc= My::SafeProcess->wait_any();
  2169. mtr_report("Got $proc");
  2170. if ( delete $started{$proc->pid()} ) {
  2171. my $err_file= $proc->user_data();
  2172. my $base_file= mtr_match_extension($err_file, "err"); # Trim extension
  2173. # One check testcase process returned
  2174. my $res= $proc->exit_status();
  2175. if ( $res == 0){
  2176. # Check completed without problem
  2177. # Remove the .err file the check generated
  2178. unlink($err_file);
  2179. # Remove the .result file the check generated
  2180. if ( $mode eq 'after' ){
  2181. unlink("$base_file.result");
  2182. }
  2183. if ( keys(%started) == 0){
  2184. # All checks completed
  2185. return 0;
  2186. }
  2187. # Wait for next process to exit
  2188. next;
  2189. }
  2190. else
  2191. {
  2192. if ( $mode eq "after" and $res == 1 )
  2193. {
  2194. # Test failed, grab the report mysqltest has created
  2195. my $report= mtr_grab_file($err_file);
  2196. $tinfo->{check}.=
  2197. "\nThe check of testcase '$tname' failed, this is the\n".
  2198. "diff between before and after:\n";
  2199. $tinfo->{check}.= $report;
  2200. # Check failed, mark the test case with that info
  2201. $tinfo->{'check_testcase_failed'}= 1;
  2202. $result= 1;
  2203. }
  2204. elsif ( $res )
  2205. {
  2206. my $report= mtr_grab_file($err_file);
  2207. $tinfo->{comment}.=
  2208. "Could not execute 'check-testcase' $mode testcase '$tname':\n";
  2209. $tinfo->{comment}.= $report;
  2210. $result= 2;
  2211. }
  2212. # Remove the .err file the check generated
  2213. unlink($err_file);
  2214. # Remove the .result file the check generated
  2215. unlink("$base_file.result");
  2216. }
  2217. }
  2218. else {
  2219. # Unknown process returned, most likley a crash, abort everything
  2220. $tinfo->{comment}=
  2221. "Unexpected process $proc returned during ".
  2222. "check testcase $mode test";
  2223. $result= 3;
  2224. }
  2225. # Kill any check processes still running
  2226. map($_->kill(), values(%started));
  2227. return $result;
  2228. }
  2229. }
  2230. sub mark_log {
  2231. my ($log, $tinfo)= @_;
  2232. my $log_msg= "CURRENT_TEST: $tinfo->{name}\n";
  2233. mtr_tofile($log, $log_msg);
  2234. }
  2235. sub find_testcase_skipped_reason($)
  2236. {
  2237. my ($tinfo)= @_;
  2238. # Set default message
  2239. $tinfo->{'comment'}= "Detected by testcase(no log file)";
  2240. # Open the test log file
  2241. my $F= IO::File->new($path_current_testlog)
  2242. or return;
  2243. my $reason;
  2244. while ( my $line= <$F> )
  2245. {
  2246. # Look for "reason: <reason for skipping test>"
  2247. if ( $line =~ /reason: (.*)/ )
  2248. {
  2249. $reason= $1;
  2250. }
  2251. }
  2252. if ( ! $reason )
  2253. {
  2254. mtr_warning("Could not find reason for skipping test in $path_current_testlog");
  2255. $reason= "Detected by testcase(reason unknown) ";
  2256. }
  2257. $tinfo->{'comment'}= $reason;
  2258. }
  2259. # Return timezone value of tinfo or default value
  2260. sub timezone {
  2261. my ($tinfo)= @_;
  2262. return $tinfo->{timezone} || "GMT-3";
  2263. }
  2264. # Storage for changed environment variables
  2265. my %old_env;
  2266. #
  2267. # Run a single test case
  2268. #
  2269. # RETURN VALUE
  2270. # 0 OK
  2271. # > 0 failure
  2272. #
  2273. sub run_testcase ($) {
  2274. my $tinfo= shift;
  2275. mtr_verbose("Running test:", $tinfo->{name});
  2276. # -------------------------------------------------------
  2277. # Init variables that can change between each test case
  2278. # -------------------------------------------------------
  2279. my $timezone= timezone($tinfo);
  2280. $ENV{'TZ'}= $timezone;
  2281. mtr_verbose("Setting timezone: $timezone");
  2282. if ( ! using_extern() )
  2283. {
  2284. my @restart= servers_need_restart($tinfo);
  2285. if ( @restart != 0) {
  2286. stop_servers($tinfo, @restart );
  2287. }
  2288. if ( started(all_servers()) == 0 )
  2289. {
  2290. # Remove old datadirs
  2291. clean_datadir();
  2292. # Restore old ENV
  2293. while (my ($option, $value)= each( %old_env )) {
  2294. if (defined $value){
  2295. mtr_verbose("Restoring $option to $value");
  2296. $ENV{$option}= $value;
  2297. } else {
  2298. mtr_verbose("Removing $option");
  2299. delete($ENV{$option});
  2300. }
  2301. }
  2302. %old_env= ();
  2303. mtr_verbose("Generating my.cnf from '$tinfo->{template_path}'");
  2304. # Generate new config file from template
  2305. $config= My::ConfigFactory->new_config
  2306. ( {
  2307. basedir => $basedir,
  2308. template_path => $tinfo->{template_path},
  2309. extra_template_path => $tinfo->{extra_template_path},
  2310. vardir => $opt_vardir,
  2311. tmpdir => $opt_tmpdir,
  2312. baseport => $opt_baseport,
  2313. #hosts => [ 'host1', 'host2' ],
  2314. user => $opt_user,
  2315. password => '',
  2316. ssl => $opt_ssl_supported,
  2317. embedded => $opt_embedded_server,
  2318. }
  2319. );
  2320. # Write the new my.cnf
  2321. $config->save($path_config_file);
  2322. # Remember current config so a restart can occur when a test need
  2323. # to use a different one
  2324. $current_config_name= $tinfo->{template_path};
  2325. #
  2326. # Set variables in the ENV section
  2327. #
  2328. foreach my $option ($config->options_in_group("ENV"))
  2329. {
  2330. # Save old value to restore it before next time
  2331. $old_env{$option->name()}= $ENV{$option->name()};
  2332. mtr_verbose($option->name(), "=",$option->value());
  2333. $ENV{$option->name()}= $option->value();
  2334. }
  2335. }
  2336. # Write start of testcase to log
  2337. mark_log($path_current_testlog, $tinfo);
  2338. if (start_servers($tinfo))
  2339. {
  2340. report_failure_and_restart($tinfo);
  2341. return 1;
  2342. }
  2343. }
  2344. # --------------------------------------------------------------------
  2345. # If --start or --start-dirty given, stop here to let user manually
  2346. # run tests
  2347. # ----------------------------------------------------------------------
  2348. if ( $opt_start or $opt_start_dirty )
  2349. {
  2350. mtr_report("\nStarted", started(all_servers()));
  2351. mtr_report("Waiting for server(s) to exit...");
  2352. my $proc= My::SafeProcess->wait_any();
  2353. if ( grep($proc eq $_, started(all_servers())) )
  2354. {
  2355. mtr_report("Server $proc died");
  2356. exit(1);
  2357. }
  2358. mtr_report("Unknown process $proc died");
  2359. exit(1);
  2360. }
  2361. my $test_timeout_proc= My::SafeProcess->timer($opt_testcase_timeout * 60);
  2362. do_before_run_mysqltest($tinfo);
  2363. if ( $opt_check_testcases and check_testcase($tinfo, "before") ){
  2364. # Failed to record state of server or server crashed
  2365. report_failure_and_restart($tinfo);
  2366. # Stop the test case timer
  2367. $test_timeout_proc->kill();
  2368. return 1;
  2369. }
  2370. my $test= start_mysqltest($tinfo);
  2371. while (1)
  2372. {
  2373. my $proc= My::SafeProcess->wait_any();
  2374. unless ( defined $proc )
  2375. {
  2376. mtr_error("wait_any failed");
  2377. }
  2378. mtr_verbose("Got $proc");
  2379. # ----------------------------------------------------
  2380. # Was it the test program that exited
  2381. # ----------------------------------------------------
  2382. if ($proc eq $test)
  2383. {
  2384. # Stop the test case timer
  2385. $test_timeout_proc->kill();
  2386. my $res= $test->exit_status();
  2387. if ( $res == 0 )
  2388. {
  2389. if ( $opt_warnings and check_warnings($tinfo) )
  2390. {
  2391. # Found unexpected warnings
  2392. report_failure_and_restart($tinfo);
  2393. $res= 1;
  2394. }
  2395. else
  2396. {
  2397. mtr_report_test_passed($tinfo);
  2398. }
  2399. my $check_res;
  2400. if ( $opt_check_testcases and
  2401. $check_res= check_testcase($tinfo, "after"))
  2402. {
  2403. if ($check_res == 1) {
  2404. # Test case had sideeffects, not fatal error, just continue
  2405. stop_all_servers();
  2406. mtr_report("Resuming tests...\n");
  2407. }
  2408. else {
  2409. # Test case check failed fatally, probably a server crashed
  2410. report_failure_and_restart($tinfo);
  2411. return 1;
  2412. }
  2413. }
  2414. }
  2415. elsif ( $res == 62 )
  2416. {
  2417. # Testcase itself tell us to skip this one
  2418. $tinfo->{skip_detected_by_test}= 1;
  2419. # Try to get reason from test log file
  2420. find_testcase_skipped_reason($tinfo);
  2421. mtr_report_test_skipped($tinfo);
  2422. }
  2423. elsif ( $res == 65 )
  2424. {
  2425. # Testprogram killed by signal
  2426. $tinfo->{comment}=
  2427. "testprogram crashed(returned code $res)";
  2428. report_failure_and_restart($tinfo);
  2429. }
  2430. elsif ( $res == 1 )
  2431. {
  2432. # Test case failure reported by mysqltest
  2433. report_failure_and_restart($tinfo);
  2434. }
  2435. else
  2436. {
  2437. # mysqltest failed, probably crashed
  2438. $tinfo->{comment}=
  2439. "mysqltest failed with unexpected return code $res";
  2440. report_failure_and_restart($tinfo);
  2441. }
  2442. # Save info from this testcase run to mysqltest.log
  2443. if( -f $path_current_testlog)
  2444. {
  2445. mtr_appendfile_to_file($path_current_testlog, $path_testlog);
  2446. unlink($path_current_testlog);
  2447. }
  2448. return ($res == 62) ? 0 : $res;
  2449. }
  2450. # ----------------------------------------------------
  2451. # Check if it was an expected crash
  2452. # ----------------------------------------------------
  2453. if ( check_expected_crash_and_restart($proc) )
  2454. {
  2455. next;
  2456. }
  2457. # ----------------------------------------------------
  2458. # Stop the test case timer
  2459. # ----------------------------------------------------
  2460. $test_timeout_proc->kill();
  2461. # ----------------------------------------------------
  2462. # It's not mysqltest that has exited, kill it
  2463. # ----------------------------------------------------
  2464. $test->kill();
  2465. # ----------------------------------------------------
  2466. # Check if it was a server that died
  2467. # ----------------------------------------------------
  2468. if ( grep($proc eq $_, started(all_servers())) )
  2469. {
  2470. # Server failed, probably crashed
  2471. $tinfo->{comment}=
  2472. "Server $proc failed during test run";
  2473. report_failure_and_restart($tinfo);
  2474. return 1;
  2475. }
  2476. # ----------------------------------------------------
  2477. # Check if testcase timer expired
  2478. # ----------------------------------------------------
  2479. if ( $proc eq $test_timeout_proc )
  2480. {
  2481. mtr_report("Test case timeout!");
  2482. $tinfo->{'timeout'}= 1; # Mark as timeout
  2483. report_failure_and_restart($tinfo);
  2484. return 1;
  2485. }
  2486. mtr_error("Unhandled process $proc exited");
  2487. }
  2488. mtr_error("Should never come here");
  2489. }
  2490. # Run include/check-warnings.test
  2491. #
  2492. # RETURN VALUE
  2493. # 0 OK
  2494. # 1 Check failed
  2495. #
  2496. sub start_check_warnings ($$) {
  2497. my $tinfo= shift;
  2498. my $mysqld= shift;
  2499. my $name= "warnings-".$mysqld->name();
  2500. my $tname= $tinfo->{name};
  2501. my $args;
  2502. mtr_init_args(\$args);
  2503. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2504. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  2505. mtr_add_arg($args, "--silent");
  2506. mtr_add_arg($args, "--skip-safemalloc");
  2507. mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test");
  2508. my $errfile= "$opt_vardir/tmp/$name.err";
  2509. my $proc= My::SafeProcess->new
  2510. (
  2511. name => $name,
  2512. path => $exe_mysqltest,
  2513. error => $errfile,
  2514. output => $errfile,
  2515. args => \$args,
  2516. user_data => $errfile,
  2517. );
  2518. mtr_verbose("Started $proc");
  2519. return $proc;
  2520. }
  2521. #
  2522. # Loop through our list of processes and check the error log
  2523. # for unexepcted errors and warnings
  2524. #
  2525. sub check_warnings ($) {
  2526. my ($tinfo)= @_;
  2527. my $res= 0;
  2528. my $tname= $tinfo->{name};
  2529. # Clear previous warnings
  2530. delete($tinfo->{warnings});
  2531. # Start the mysqltest processes in parallel to save time
  2532. # also makes it possible to wait for any process to exit during the check
  2533. my %started;
  2534. foreach my $mysqld ( mysqlds() )
  2535. {
  2536. if ( defined $mysqld->{'proc'} )
  2537. {
  2538. my $proc= start_check_warnings($tinfo, $mysqld);
  2539. $started{$proc->pid()}= $proc;
  2540. }
  2541. }
  2542. # Return immediately if no check proceess was started
  2543. return 0 unless ( keys %started );
  2544. while (1){
  2545. my $result= 0;
  2546. my $proc= My::SafeProcess->wait_any();
  2547. mtr_report("Got $proc");
  2548. if ( delete $started{$proc->pid()} ) {
  2549. # One check warning process returned
  2550. my $res= $proc->exit_status();
  2551. my $err_file= $proc->user_data();
  2552. if ( $res == 0 or $res == 62 ){
  2553. if ( $res == 0 ) {
  2554. # Check completed with problem
  2555. my $report= mtr_grab_file($err_file);
  2556. # Log to var/log/warnings file
  2557. mtr_tofile("$opt_vardir/log/warnings",
  2558. $tname."\n".$report);
  2559. $tinfo->{'warnings'}.= $report;
  2560. $result= 1;
  2561. }
  2562. if ( $res == 62 ) {
  2563. # Test case was ok and called "skip"
  2564. ;
  2565. }
  2566. # Remove the .err file the check generated
  2567. unlink($err_file);
  2568. if ( keys(%started) == 0){
  2569. # All checks completed
  2570. return $result;
  2571. }
  2572. # Wait for next process to exit
  2573. next;
  2574. }
  2575. else
  2576. {
  2577. my $report= mtr_grab_file($err_file);
  2578. $tinfo->{comment}.=
  2579. "Could not execute 'check-warnings' for testcase '$tname':";
  2580. $tinfo->{comment}.= $report;
  2581. $result= 2;
  2582. }
  2583. # Remove the .err file the check generated
  2584. unlink($err_file);
  2585. }
  2586. else {
  2587. # Unknown process returned, most likley a crash, abort everything
  2588. $tinfo->{comment}=
  2589. "Unexpected process $proc returned during ".
  2590. "check warnings";
  2591. $result= 3;
  2592. }
  2593. # Kill any check processes still running
  2594. map($_->kill(), values(%started));
  2595. return $result;
  2596. }
  2597. return $res;
  2598. return $res;
  2599. }
  2600. #
  2601. # Loop through our list of processes and look for and entry
  2602. # with the provided pid, if found check for the file indicating
  2603. # expected crash and restart it.
  2604. #
  2605. sub check_expected_crash_and_restart {
  2606. my ($proc)= @_;
  2607. foreach my $mysqld ( mysqlds() )
  2608. {
  2609. next unless ( $mysqld->{proc} eq $proc );
  2610. # Check if crash expected by looking at the .expect file
  2611. # in var/tmp
  2612. my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
  2613. if ( -f $expect_file )
  2614. {
  2615. mtr_report("Crash was expected, file '$expect_file' exists");
  2616. # Start server with same settings as last time
  2617. mysqld_start($mysqld, $mysqld->{'started_opts'});
  2618. unlink($expect_file);
  2619. }
  2620. return 1;
  2621. }
  2622. # Not an expected crash
  2623. return 0;
  2624. }
  2625. # Remove all files and subdirectories of a directory
  2626. sub clean_dir {
  2627. my ($dir)= @_;
  2628. mtr_print("clean_dir: $dir");
  2629. finddepth(
  2630. { no_chdir => 1,
  2631. wanted => sub {
  2632. if (-d $_){
  2633. # A dir
  2634. if ($_ eq $dir){
  2635. # The dir to clean
  2636. return;
  2637. } else {
  2638. mtr_print("rmdir: '$_'");
  2639. rmdir($_) or mtr_warning("rmdir($_) failed: $!");
  2640. }
  2641. } else {
  2642. # Hopefully a file
  2643. mtr_print("unlink: '$_'");
  2644. unlink($_) or mtr_warning("unlink($_) failed: $!");
  2645. }
  2646. }
  2647. },
  2648. $dir);
  2649. }
  2650. sub clean_datadir {
  2651. mtr_verbose("Cleaning datadirs...");
  2652. if (started(all_servers()) != 0){
  2653. mtr_error("Trying to clean datadir before all servers stopped");
  2654. }
  2655. foreach my $cluster ( clusters() )
  2656. {
  2657. my $cluster_dir= "$opt_vardir/".$cluster->{name};
  2658. mtr_print(" - removing '$cluster_dir'");
  2659. rmtree($cluster_dir);
  2660. }
  2661. foreach my $mysqld ( mysqlds() )
  2662. {
  2663. my $mysqld_dir= dirname($mysqld->value('datadir'));
  2664. if (-d $mysqld_dir ) {
  2665. mtr_print(" - removing '$mysqld_dir'");
  2666. rmtree($mysqld_dir);
  2667. }
  2668. }
  2669. # Remove all files in tmp and var/tmp
  2670. clean_dir("$opt_vardir/tmp");
  2671. if ($opt_tmpdir ne "$opt_vardir/tmp"){
  2672. clean_dir($opt_tmpdir);
  2673. }
  2674. }
  2675. #
  2676. # Save datadir before it's removed
  2677. #
  2678. sub save_datadir_after_failure($$) {
  2679. my ($dir, $savedir)= @_;
  2680. mtr_report(" - saving '$dir'");
  2681. my $dir_name= basename($dir);
  2682. rename("$dir", "$savedir/$dir_name");
  2683. }
  2684. sub after_failure ($) {
  2685. my ($tinfo)= @_;
  2686. mtr_report("Saving datadirs...");
  2687. my $save_dir= "$opt_vardir/log/";
  2688. $save_dir.= $tinfo->{name};
  2689. # Add combination name if any
  2690. $save_dir.= "-$tinfo->{combination}"
  2691. if defined $tinfo->{combination};
  2692. # Save savedir path for server
  2693. $tinfo->{savedir}= $save_dir;
  2694. mkpath($save_dir) if ! -d $save_dir;
  2695. # Save the used my.cnf file
  2696. copy($path_config_file, $save_dir);
  2697. # Copy the tmp dir
  2698. copytree("$opt_vardir/tmp/", "$save_dir/tmp/");
  2699. if ( clusters() ) {
  2700. foreach my $cluster ( clusters() ) {
  2701. my $cluster_dir= "$opt_vardir/".$cluster->{name};
  2702. save_datadir_after_failure($cluster_dir, $save_dir);
  2703. }
  2704. }
  2705. else {
  2706. foreach my $mysqld ( mysqlds() ) {
  2707. my $data_dir= $mysqld->value('datadir');
  2708. save_datadir_after_failure(dirname($data_dir), $save_dir);
  2709. }
  2710. }
  2711. }
  2712. sub report_failure_and_restart ($) {
  2713. my $tinfo= shift;
  2714. stop_all_servers();
  2715. $tinfo->{'result'}= 'MTR_RES_FAILED';
  2716. my $test_failures= $tinfo->{'failures'} || 0;
  2717. $tinfo->{'failures'}= $test_failures + 1;
  2718. my $logfile= $path_current_testlog;
  2719. if ( $tinfo->{comment} )
  2720. {
  2721. # The test failure has been detected by mysql-test-run.pl
  2722. # when starting the servers or due to other error, the reason for
  2723. # failing the test is saved in "comment"
  2724. ;
  2725. }
  2726. elsif ( defined $logfile and -f $logfile )
  2727. {
  2728. # Test failure was detected by test tool and its report
  2729. # about what failed has been saved to file. Save the report
  2730. # in tinfo
  2731. $tinfo->{logfile}= mtr_fromfile($logfile);
  2732. }
  2733. after_failure($tinfo);
  2734. mtr_report_test($tinfo);
  2735. }
  2736. sub run_sh_script {
  2737. my ($script)= @_;
  2738. return 0 unless defined $script;
  2739. mtr_verbose("Running '$script'");
  2740. my $ret= system("/bin/sh $script") >> 8;
  2741. return $ret;
  2742. }
  2743. sub mysqld_stop {
  2744. my $mysqld= shift or die "usage: mysqld_stop(<mysqld>)";
  2745. my $args;
  2746. mtr_init_args(\$args);
  2747. mtr_add_arg($args, "--no-defaults");
  2748. mtr_add_arg($args, "--user=%s", $opt_user);
  2749. mtr_add_arg($args, "--password=");
  2750. mtr_add_arg($args, "--port=%d", $mysqld->value('port'));
  2751. mtr_add_arg($args, "--host=%s", $mysqld->value('#host'));
  2752. mtr_add_arg($args, "--connect_timeout=20");
  2753. mtr_add_arg($args, "--protocol=tcp");
  2754. mtr_add_arg($args, "shutdown");
  2755. My::SafeProcess->run
  2756. (
  2757. name => "mysqladmin shutdown ".$mysqld->name(),
  2758. path => $exe_mysqladmin,
  2759. args => \$args,
  2760. error => "/dev/null",
  2761. );
  2762. }
  2763. sub mysqld_arguments ($$$) {
  2764. my $args= shift;
  2765. my $mysqld= shift;
  2766. my $extra_opts= shift;
  2767. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  2768. # When mysqld is run by a root user(euid is 0), it will fail
  2769. # to start unless we specify what user to run as, see BUG#30630
  2770. my $euid= $>;
  2771. if (!IS_WINDOWS and $euid == 0 and
  2772. (grep(/^--user/, @$extra_opts)) == 0) {
  2773. mtr_add_arg($args, "--user=root");
  2774. }
  2775. if ( $opt_valgrind_mysqld )
  2776. {
  2777. mtr_add_arg($args, "--skip-safemalloc");
  2778. if ( $mysql_version_id < 50100 )
  2779. {
  2780. mtr_add_arg($args, "--skip-bdb");
  2781. }
  2782. }
  2783. if ( $mysql_version_id >= 50106 )
  2784. {
  2785. # Turn on logging to both tables and file
  2786. mtr_add_arg($args, "--log-output=table,file");
  2787. }
  2788. # Check if "extra_opt" contains skip-log-bin
  2789. my $skip_binlog= grep(/^(--|--loose-)skip-log-bin/, @$extra_opts);
  2790. # Indicate to mysqld it will be debugged in debugger
  2791. if ( $glob_debugger )
  2792. {
  2793. mtr_add_arg($args, "--gdb");
  2794. }
  2795. my $found_skip_core= 0;
  2796. foreach my $arg ( @$extra_opts )
  2797. {
  2798. # Allow --skip-core-file to be set in <testname>-[master|slave].opt file
  2799. if ($arg eq "--skip-core-file")
  2800. {
  2801. $found_skip_core= 1;
  2802. }
  2803. elsif ($skip_binlog and mtr_match_prefix($arg, "--binlog-format"))
  2804. {
  2805. ; # Dont add --binlog-format when running without binlog
  2806. }
  2807. else
  2808. {
  2809. mtr_add_arg($args, "%s", $arg);
  2810. }
  2811. }
  2812. if ( !$found_skip_core )
  2813. {
  2814. mtr_add_arg($args, "%s", "--core-file");
  2815. }
  2816. return $args;
  2817. }
  2818. sub mysqld_start ($$) {
  2819. my $mysqld= shift;
  2820. my $extra_opts= shift;
  2821. mtr_verbose(My::Options::toStr("mysqld_start", @$extra_opts));
  2822. my $exe= find_mysqld($mysqld->value('basedir'));
  2823. my $wait_for_pid_file= 1;
  2824. mtr_error("Internal error: mysqld should never be started for embedded")
  2825. if $opt_embedded_server;
  2826. my $args;
  2827. mtr_init_args(\$args);
  2828. if ( $opt_valgrind_mysqld )
  2829. {
  2830. valgrind_arguments($args, \$exe);
  2831. }
  2832. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  2833. mysqld_arguments($args,$mysqld,$extra_opts);
  2834. if ( $opt_debug )
  2835. {
  2836. mtr_add_arg($args, "--debug=d:t:i:A,%s/log/%s.trace",
  2837. $path_vardir_trace, $mysqld->name());
  2838. }
  2839. if ( $opt_gdb || $opt_manual_gdb )
  2840. {
  2841. gdb_arguments(\$args, \$exe, $mysqld->name());
  2842. }
  2843. elsif ( $opt_ddd || $opt_manual_ddd )
  2844. {
  2845. ddd_arguments(\$args, \$exe, $mysqld->name());
  2846. }
  2847. elsif ( $opt_debugger )
  2848. {
  2849. debugger_arguments(\$args, \$exe, $mysqld->name());
  2850. }
  2851. elsif ( $opt_manual_debug )
  2852. {
  2853. print "\nStart $mysqld->name() in your debugger\n" .
  2854. "dir: $glob_mysql_test_dir\n" .
  2855. "exe: $exe\n" .
  2856. "args: " . join(" ", @$args) . "\n\n" .
  2857. "Waiting ....\n";
  2858. # Indicate the exe should not be started
  2859. $exe= undef;
  2860. }
  2861. else
  2862. {
  2863. # Default to not wait until pid file has been created
  2864. $wait_for_pid_file= 0;
  2865. }
  2866. # Remove the old pidfile if any
  2867. unlink($mysqld->value('pid-file'));
  2868. my $output= $mysqld->value('log-error');
  2869. if ( $opt_valgrind and $opt_debug )
  2870. {
  2871. # When both --valgrind and --debug is selected, send
  2872. # all output to the trace file, making it possible to
  2873. # see the exact location where valgrind complains
  2874. $output= "$opt_vardir/log/".$mysqld->name().".trace";
  2875. }
  2876. if ( defined $exe )
  2877. {
  2878. $mysqld->{'proc'}= My::SafeProcess->new
  2879. (
  2880. name => $mysqld->name(),
  2881. path => $exe,
  2882. args => \$args,
  2883. output => $output,
  2884. error => $output,
  2885. append => 1,
  2886. verbose => $opt_verbose,
  2887. host => undef,
  2888. shutdown => sub { mysqld_stop($mysqld) },
  2889. );
  2890. mtr_verbose("Started $mysqld->{proc}");
  2891. }
  2892. if ( $wait_for_pid_file &&
  2893. !sleep_until_file_created($mysqld->value('pid-file'),
  2894. $opt_start_timeout,
  2895. $mysqld->{'proc'}))
  2896. {
  2897. mtr_error("Failed to start mysqld $mysqld->name()");
  2898. }
  2899. # Remember options used when starting
  2900. $mysqld->{'started_opts'}= $extra_opts;
  2901. return;
  2902. }
  2903. sub stop_all_servers () {
  2904. mtr_print("Stopping all servers...");
  2905. # Kill all started servers
  2906. My::SafeProcess::shutdown(0, # shutdown timeout 0 => kill
  2907. started(all_servers()));
  2908. # Remove pidfiles
  2909. foreach my $server ( all_servers() )
  2910. {
  2911. my $pid_file= $server->if_exist('pid-file');
  2912. unlink($pid_file) if defined $pid_file;
  2913. }
  2914. # Mark servers as stopped
  2915. map($_->{proc}= undef, all_servers());
  2916. }
  2917. # Find out if server should be restarted for this test
  2918. sub server_need_restart {
  2919. my ($tinfo, $server)= @_;
  2920. if ( using_extern() )
  2921. {
  2922. mtr_verbose_restart($server, "no restart for --extern server");
  2923. return 0;
  2924. }
  2925. if ( $opt_embedded_server )
  2926. {
  2927. mtr_verbose_restart($server, "no start or restart for embedded server");
  2928. return 0;
  2929. }
  2930. if ( $tinfo->{'force_restart'} ) {
  2931. mtr_verbose_restart($server, "forced in .opt file");
  2932. return 1;
  2933. }
  2934. if ( $tinfo->{template_path} ne $current_config_name)
  2935. {
  2936. mtr_verbose_restart($server, "using different config file");
  2937. return 1;
  2938. }
  2939. if ( $tinfo->{'master_sh'} || $tinfo->{'slave_sh'} )
  2940. {
  2941. mtr_verbose_restart($server, "sh script to run");
  2942. return 1;
  2943. }
  2944. if ( ! started($server) )
  2945. {
  2946. mtr_verbose_restart($server, "not started");
  2947. return 1;
  2948. }
  2949. my $started_tinfo= $server->{'started_tinfo'};
  2950. if ( defined $started_tinfo )
  2951. {
  2952. # Check if timezone of test that server was started
  2953. # with differs from timezone of next test
  2954. if ( timezone($started_tinfo) ne timezone($tinfo) )
  2955. {
  2956. mtr_verbose_restart($server, "different timezone");
  2957. return 1;
  2958. }
  2959. }
  2960. # Temporary re-enable the "always restart slave" hack
  2961. # this should be removed asap, but will require that each rpl
  2962. # testcase cleanup better after itself - ie. stop and reset
  2963. # replication
  2964. # Use the "#!use-slave-opt" marker to detect that this is a "slave"
  2965. # server
  2966. if ( $server->option("#!use-slave-opt") ){
  2967. mtr_verbose_restart($server, "Always restart slave(s)");
  2968. return 1;
  2969. }
  2970. my $is_mysqld= grep ($server eq $_, mysqlds());
  2971. if ($is_mysqld)
  2972. {
  2973. # Check that running process was started with same options
  2974. # as the current test requires
  2975. my $extra_opts= get_extra_opts($server, $tinfo);
  2976. my $started_opts= $server->{'started_opts'};
  2977. if (!My::Options::same($started_opts, $extra_opts) )
  2978. {
  2979. my $use_dynamic_option_switch= 0;
  2980. if (!$use_dynamic_option_switch)
  2981. {
  2982. mtr_verbose_restart($server, "running with different options '" .
  2983. join(" ", @{$extra_opts}) . "' != '" .
  2984. join(" ", @{$started_opts}) . "'" );
  2985. return 1;
  2986. }
  2987. mtr_verbose(My::Options::toStr("started_opts", @$started_opts));
  2988. mtr_verbose(My::Options::toStr("extra_opts", @$extra_opts));
  2989. # Get diff and check if dynamic switch is possible
  2990. my @diff_opts= My::Options::diff($started_opts, $extra_opts);
  2991. mtr_verbose(My::Options::toStr("diff_opts", @diff_opts));
  2992. my $query= My::Options::toSQL(@diff_opts);
  2993. mtr_verbose("Attempting dynamic switch '$query'");
  2994. if (run_query($tinfo, $server, $query)){
  2995. mtr_verbose("Restart: running with different options '" .
  2996. join(" ", @{$extra_opts}) . "' != '" .
  2997. join(" ", @{$started_opts}) . "'" );
  2998. return 1;
  2999. }
  3000. # Remember the dynamically set options
  3001. $server->{'started_opts'}= $extra_opts;
  3002. }
  3003. }
  3004. # Default, no restart
  3005. return 0;
  3006. }
  3007. sub servers_need_restart($) {
  3008. my ($tinfo)= @_;
  3009. return grep { server_need_restart($tinfo, $_); } all_servers();
  3010. }
  3011. #
  3012. # Return list of specific servers
  3013. # - there is no servers in an empty config
  3014. #
  3015. sub _like { return $config ? $config->like($_[0]) : (); }
  3016. sub mysqlds { return _like('mysqld.'); }
  3017. sub ndbds { return _like('cluster_config.ndbd.');}
  3018. sub ndb_mgmds { return _like('cluster_config.ndb_mgmd.'); }
  3019. sub clusters { return _like('mysql_cluster.'); }
  3020. sub all_servers { return ( mysqlds(), ndb_mgmds(), ndbds() ); }
  3021. #
  3022. # Filter a list of servers and return only those that are part
  3023. # of the specified cluster
  3024. #
  3025. sub in_cluster {
  3026. my ($cluster)= shift;
  3027. # Return only processes for a specific cluster
  3028. return grep { $_->suffix() eq $cluster->suffix() } @_;
  3029. }
  3030. #
  3031. # Filter a list of servers and return the SafeProcess
  3032. # for only those that are started or stopped
  3033. #
  3034. sub started { return grep(defined $_, map($_->{proc}, @_)); }
  3035. sub stopped { return grep(!defined $_, map($_->{proc}, @_)); }
  3036. sub envsubst {
  3037. my $string= shift;
  3038. if ( ! defined $ENV{$string} )
  3039. {
  3040. mtr_error(".opt file references '$string' which is not set");
  3041. }
  3042. return $ENV{$string};
  3043. }
  3044. sub get_extra_opts {
  3045. my ($mysqld, $tinfo)= @_;
  3046. my $opts=
  3047. $mysqld->option("#!use-slave-opt") ?
  3048. $tinfo->{slave_opt} : $tinfo->{master_opt};
  3049. # Expand environment variables
  3050. foreach my $opt ( @$opts )
  3051. {
  3052. $opt =~ s/\$\{(\w+)\}/envsubst($1)/ge;
  3053. $opt =~ s/\$(\w+)/envsubst($1)/ge;
  3054. }
  3055. return $opts;
  3056. }
  3057. sub stop_servers($$) {
  3058. my ($tinfo, @servers)= @_;
  3059. # Remember if we restarted for this test case (count restarts)
  3060. $tinfo->{'restarted'}= 1;
  3061. if ( join('|', @servers) eq join('|', all_servers()) )
  3062. {
  3063. # All servers are going down, use some kind of order to
  3064. # avoid too many warnings in the log files
  3065. mtr_report("Restarting all servers");
  3066. # mysqld processes
  3067. My::SafeProcess::shutdown( $opt_shutdown_timeout, started(mysqlds()) );
  3068. # cluster processes
  3069. My::SafeProcess::shutdown( $opt_shutdown_timeout,
  3070. started(ndbds(), ndb_mgmds()) );
  3071. }
  3072. else
  3073. {
  3074. mtr_report("Restarting ", started(@servers));
  3075. # Stop only some servers
  3076. My::SafeProcess::shutdown( $opt_shutdown_timeout,
  3077. started(@servers) );
  3078. }
  3079. foreach my $server (@servers)
  3080. {
  3081. # Mark server as stopped
  3082. $server->{proc}= undef;
  3083. # Forget history
  3084. delete $server->{'started_tinfo'};
  3085. delete $server->{'started_opts'};
  3086. delete $server->{'started_cnf'};
  3087. }
  3088. }
  3089. #
  3090. # start_servers
  3091. #
  3092. # Start servers not already started
  3093. #
  3094. # RETURN
  3095. # 0 OK
  3096. # 1 Start failed
  3097. #
  3098. sub start_servers($) {
  3099. my ($tinfo)= @_;
  3100. # Start clusters
  3101. foreach my $cluster ( clusters() )
  3102. {
  3103. ndbcluster_start($cluster);
  3104. }
  3105. # Start mysqlds
  3106. foreach my $mysqld ( mysqlds() )
  3107. {
  3108. if ( $mysqld->{proc} )
  3109. {
  3110. # Already started
  3111. # Write start of testcase to log file
  3112. mark_log($mysqld->value('log-error'), $tinfo);
  3113. next;
  3114. }
  3115. my $datadir= $mysqld->value('datadir');
  3116. # Don't delete anything if starting dirty
  3117. if (!$opt_start_dirty)
  3118. {
  3119. my @options= ('log-bin', 'relay-log');
  3120. foreach my $option_name ( @options ) {
  3121. next unless $mysqld->option($option_name);
  3122. my $value= $mysqld->value($option_name);
  3123. foreach my $file ( glob("$datadir/$value*") )
  3124. {
  3125. #print "removing: $file\n";
  3126. mtr_debug("Removing '$file'");
  3127. unlink($file);
  3128. }
  3129. }
  3130. # Remove old master.info and relay-log.info files
  3131. # from the servers datadir
  3132. unlink("$datadir/master.info");
  3133. unlink("$datadir/relay-log.info");
  3134. }
  3135. # Copy datadir from installed system db
  3136. for my $path ( "$opt_vardir", "$opt_vardir/..") {
  3137. my $install_db= "$path/install.db";
  3138. copytree($install_db, $datadir)
  3139. if -d $install_db;
  3140. }
  3141. mtr_error("Failed to copy system db to '$datadir'")
  3142. unless -d $datadir;
  3143. # Write start of testcase to log file
  3144. mark_log($mysqld->value('log-error'), $tinfo);
  3145. # Run <tname>-master.sh
  3146. if ($mysqld->option('#!run-master-sh') and
  3147. run_sh_script($tinfo->{master_sh}) )
  3148. {
  3149. $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'";
  3150. return 1;
  3151. }
  3152. # Run <tname>-slave.sh
  3153. if ($mysqld->option('#!run-slave-sh') and
  3154. run_sh_script($tinfo->{slave_sh}))
  3155. {
  3156. $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'";
  3157. return 1;
  3158. }
  3159. if (!$opt_embedded_server)
  3160. {
  3161. my $extra_opts= get_extra_opts($mysqld, $tinfo);
  3162. mysqld_start($mysqld,$extra_opts);
  3163. # Save this test case information, so next can examine it
  3164. $mysqld->{'started_tinfo'}= $tinfo;
  3165. }
  3166. }
  3167. # Wait for clusters to start
  3168. foreach my $cluster ( clusters() )
  3169. {
  3170. if (ndbcluster_wait_started($cluster, ""))
  3171. {
  3172. # failed to start
  3173. $tinfo->{'comment'}= "Start of '".$cluster->name()."' cluster failed";
  3174. return 1;
  3175. }
  3176. }
  3177. # Wait for mysqlds to start
  3178. foreach my $mysqld ( mysqlds() )
  3179. {
  3180. next if !started($mysqld);
  3181. if (sleep_until_file_created($mysqld->value('pid-file'),
  3182. $opt_start_timeout,
  3183. $mysqld->{'proc'}) == 0) {
  3184. $tinfo->{comment}=
  3185. "Failed to start ".$mysqld->name();
  3186. return 1;
  3187. }
  3188. }
  3189. return 0;
  3190. }
  3191. #
  3192. # Run include/check-testcase.test
  3193. # Before a testcase, run in record mode and save result file to var/tmp
  3194. # After testcase, run and compare with the recorded file, they should be equal!
  3195. #
  3196. # RETURN VALUE
  3197. # The newly started process
  3198. #
  3199. sub start_check_testcase ($$$) {
  3200. my $tinfo= shift;
  3201. my $mode= shift;
  3202. my $mysqld= shift;
  3203. my $name= "check-".$mysqld->name();
  3204. my $tname= $tinfo->{name};
  3205. my $args;
  3206. mtr_init_args(\$args);
  3207. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  3208. mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
  3209. mtr_add_arg($args, "--silent");
  3210. mtr_add_arg($args, "--skip-safemalloc");
  3211. mtr_add_arg($args, "--result-file=%s", "$opt_vardir/tmp/$name.result");
  3212. mtr_add_arg($args, "--test-file=%s", "include/check-testcase.test");
  3213. if ( $mode eq "before" )
  3214. {
  3215. mtr_add_arg($args, "--record");
  3216. }
  3217. my $errfile= "$opt_vardir/tmp/$name.err";
  3218. my $proc= My::SafeProcess->new
  3219. (
  3220. name => $name,
  3221. path => $exe_mysqltest,
  3222. error => $errfile,
  3223. args => \$args,
  3224. user_data => $errfile,
  3225. );
  3226. mtr_report("Started $proc");
  3227. return $proc;
  3228. }
  3229. sub run_mysqltest ($) {
  3230. my $proc= start_mysqltest(@_);
  3231. $proc->wait();
  3232. }
  3233. sub start_mysqltest ($) {
  3234. my ($tinfo)= @_;
  3235. my $exe= $exe_mysqltest;
  3236. my $args;
  3237. mtr_init_args(\$args);
  3238. mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
  3239. mtr_add_arg($args, "--silent");
  3240. mtr_add_arg($args, "--skip-safemalloc");
  3241. mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
  3242. mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
  3243. mtr_add_arg($args, "--logdir=%s/log", $opt_vardir);
  3244. # Log line number and time for each line in .test file
  3245. mtr_add_arg($args, "--mark-progress")
  3246. if $opt_mark_progress;
  3247. mtr_add_arg($args, "--database=test");
  3248. if ( $opt_ps_protocol )
  3249. {
  3250. mtr_add_arg($args, "--ps-protocol");
  3251. }
  3252. if ( $opt_sp_protocol )
  3253. {
  3254. mtr_add_arg($args, "--sp-protocol");
  3255. }
  3256. if ( $opt_view_protocol )
  3257. {
  3258. mtr_add_arg($args, "--view-protocol");
  3259. }
  3260. if ( $opt_cursor_protocol )
  3261. {
  3262. mtr_add_arg($args, "--cursor-protocol");
  3263. }
  3264. if ( $opt_strace_client )
  3265. {
  3266. $exe= $opt_strace_client || "strace";
  3267. mtr_add_arg($args, "-o");
  3268. mtr_add_arg($args, "%s/log/mysqltest.strace", $opt_vardir);
  3269. mtr_add_arg($args, "$exe_mysqltest");
  3270. }
  3271. mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir);
  3272. if ( $opt_compress )
  3273. {
  3274. mtr_add_arg($args, "--compress");
  3275. }
  3276. if ( $opt_sleep )
  3277. {
  3278. mtr_add_arg($args, "--sleep=%d", $opt_sleep);
  3279. }
  3280. client_debug_arg($args, "mysqltest");
  3281. if ( $opt_ssl )
  3282. {
  3283. # Turn on SSL for _all_ test cases if option --ssl was used
  3284. mtr_add_arg($args, "--ssl");
  3285. }
  3286. elsif ( $opt_ssl_supported )
  3287. {
  3288. mtr_add_arg($args, "--skip-ssl");
  3289. }
  3290. if ( $opt_embedded_server )
  3291. {
  3292. # Get the args needed for the embedded server
  3293. # and append them to args prefixed
  3294. # with --sever-arg=
  3295. my $mysqld= $config->group('embedded')
  3296. or mtr_error("Could not get [embedded] section");
  3297. my $mysqld_args;
  3298. mtr_init_args(\$mysqld_args);
  3299. my $extra_opts= get_extra_opts($mysqld, $tinfo);
  3300. mysqld_arguments($mysqld_args, $mysqld, $extra_opts);
  3301. mtr_add_arg($args, "--server-arg=%s", $_) for @$mysqld_args;
  3302. }
  3303. # ----------------------------------------------------------------------
  3304. # export MYSQL_TEST variable containing <path>/mysqltest <args>
  3305. # ----------------------------------------------------------------------
  3306. $ENV{'MYSQL_TEST'}= mtr_args2str($exe_mysqltest, @$args);
  3307. # ----------------------------------------------------------------------
  3308. # Add arguments that should not go into the MYSQL_TEST env var
  3309. # ----------------------------------------------------------------------
  3310. if ( $opt_valgrind_mysqltest )
  3311. {
  3312. # Prefix the Valgrind options to the argument list.
  3313. # We do this here, since we do not want to Valgrind the nested invocations
  3314. # of mysqltest; that would mess up the stderr output causing test failure.
  3315. my @args_saved = @$args;
  3316. mtr_init_args(\$args);
  3317. valgrind_arguments($args, \$exe);
  3318. mtr_add_arg($args, "%s", $_) for @args_saved;
  3319. }
  3320. mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
  3321. # Number of lines of resut to include in failure report
  3322. mtr_add_arg($args, "--tail-lines=20");
  3323. if ( defined $tinfo->{'result_file'} ) {
  3324. mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
  3325. }
  3326. if ( $opt_record )
  3327. {
  3328. mtr_add_arg($args, "--record");
  3329. }
  3330. if ( $opt_client_gdb )
  3331. {
  3332. gdb_arguments(\$args, \$exe, "client");
  3333. }
  3334. elsif ( $opt_client_ddd )
  3335. {
  3336. ddd_arguments(\$args, \$exe, "client");
  3337. }
  3338. elsif ( $opt_client_debugger )
  3339. {
  3340. debugger_arguments(\$args, \$exe, "client");
  3341. }
  3342. my $proc= My::SafeProcess->new
  3343. (
  3344. name => "mysqltest",
  3345. path => $exe,
  3346. args => \$args,
  3347. append => 1,
  3348. error => $path_current_testlog,
  3349. verbose => $opt_verbose,
  3350. );
  3351. mtr_verbose("Started $proc");
  3352. return $proc;
  3353. }
  3354. #
  3355. # Modify the exe and args so that program is run in gdb in xterm
  3356. #
  3357. sub gdb_arguments {
  3358. my $args= shift;
  3359. my $exe= shift;
  3360. my $type= shift;
  3361. # Write $args to gdb init file
  3362. my $str= join(" ", @$$args);
  3363. my $gdb_init_file= "$opt_tmpdir/gdbinit.$type";
  3364. # Remove the old gdbinit file
  3365. unlink($gdb_init_file);
  3366. if ( $type eq "client" )
  3367. {
  3368. # write init file for client
  3369. mtr_tofile($gdb_init_file,
  3370. "set args $str\n" .
  3371. "break main\n");
  3372. }
  3373. else
  3374. {
  3375. # write init file for mysqld
  3376. mtr_tofile($gdb_init_file,
  3377. "set args $str\n" .
  3378. "break mysql_parse\n" .
  3379. "commands 1\n" .
  3380. "disable 1\n" .
  3381. "end\n" .
  3382. "run");
  3383. }
  3384. if ( $opt_manual_gdb )
  3385. {
  3386. print "\nTo start gdb for $type, type in another window:\n";
  3387. print "gdb -cd $glob_mysql_test_dir -x $gdb_init_file $$exe\n";
  3388. # Indicate the exe should not be started
  3389. $$exe= undef;
  3390. return;
  3391. }
  3392. $$args= [];
  3393. mtr_add_arg($$args, "-title");
  3394. mtr_add_arg($$args, "$type");
  3395. mtr_add_arg($$args, "-e");
  3396. if ( $exe_libtool )
  3397. {
  3398. mtr_add_arg($$args, $exe_libtool);
  3399. mtr_add_arg($$args, "--mode=execute");
  3400. }
  3401. mtr_add_arg($$args, "gdb");
  3402. mtr_add_arg($$args, "-x");
  3403. mtr_add_arg($$args, "$gdb_init_file");
  3404. mtr_add_arg($$args, "$$exe");
  3405. $$exe= "xterm";
  3406. }
  3407. #
  3408. # Modify the exe and args so that program is run in ddd
  3409. #
  3410. sub ddd_arguments {
  3411. my $args= shift;
  3412. my $exe= shift;
  3413. my $type= shift;
  3414. # Write $args to ddd init file
  3415. my $str= join(" ", @$$args);
  3416. my $gdb_init_file= "$opt_tmpdir/gdbinit.$type";
  3417. # Remove the old gdbinit file
  3418. unlink($gdb_init_file);
  3419. if ( $type eq "client" )
  3420. {
  3421. # write init file for client
  3422. mtr_tofile($gdb_init_file,
  3423. "set args $str\n" .
  3424. "break main\n");
  3425. }
  3426. else
  3427. {
  3428. # write init file for mysqld
  3429. mtr_tofile($gdb_init_file,
  3430. "file $$exe\n" .
  3431. "set args $str\n" .
  3432. "break mysql_parse\n" .
  3433. "commands 1\n" .
  3434. "disable 1\n" .
  3435. "end");
  3436. }
  3437. if ( $opt_manual_ddd )
  3438. {
  3439. print "\nTo start ddd for $type, type in another window:\n";
  3440. print "ddd -cd $glob_mysql_test_dir -x $gdb_init_file $$exe\n";
  3441. # Indicate the exe should not be started
  3442. $$exe= undef;
  3443. return;
  3444. }
  3445. my $save_exe= $$exe;
  3446. $$args= [];
  3447. if ( $exe_libtool )
  3448. {
  3449. $$exe= $exe_libtool;
  3450. mtr_add_arg($$args, "--mode=execute");
  3451. mtr_add_arg($$args, "ddd");
  3452. }
  3453. else
  3454. {
  3455. $$exe= "ddd";
  3456. }
  3457. mtr_add_arg($$args, "--command=$gdb_init_file");
  3458. mtr_add_arg($$args, "$save_exe");
  3459. }
  3460. #
  3461. # Modify the exe and args so that program is run in the selected debugger
  3462. #
  3463. sub debugger_arguments {
  3464. my $args= shift;
  3465. my $exe= shift;
  3466. my $debugger= $opt_debugger || $opt_client_debugger;
  3467. if ( $debugger =~ /vcexpress|vc|devenv/ )
  3468. {
  3469. # vc[express] /debugexe exe arg1 .. argn
  3470. # Add /debugexe and name of the exe before args
  3471. unshift(@$$args, "/debugexe");
  3472. unshift(@$$args, "$$exe");
  3473. # Set exe to debuggername
  3474. $$exe= $debugger;
  3475. }
  3476. elsif ( $debugger =~ /windbg/ )
  3477. {
  3478. # windbg exe arg1 .. argn
  3479. # Add name of the exe before args
  3480. unshift(@$$args, "$$exe");
  3481. # Set exe to debuggername
  3482. $$exe= $debugger;
  3483. }
  3484. elsif ( $debugger eq "dbx" )
  3485. {
  3486. # xterm -e dbx -r exe arg1 .. argn
  3487. unshift(@$$args, $$exe);
  3488. unshift(@$$args, "-r");
  3489. unshift(@$$args, $debugger);
  3490. unshift(@$$args, "-e");
  3491. $$exe= "xterm";
  3492. }
  3493. else
  3494. {
  3495. mtr_error("Unknown argument \"$debugger\" passed to --debugger");
  3496. }
  3497. }
  3498. #
  3499. # Modify the exe and args so that program is run in valgrind
  3500. #
  3501. sub valgrind_arguments {
  3502. my $args= shift;
  3503. my $exe= shift;
  3504. if ( $opt_callgrind)
  3505. {
  3506. mtr_add_arg($args, "--tool=callgrind");
  3507. mtr_add_arg($args, "--base=$opt_vardir/log");
  3508. }
  3509. else
  3510. {
  3511. mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
  3512. mtr_add_arg($args, "--alignment=8");
  3513. mtr_add_arg($args, "--leak-check=yes");
  3514. mtr_add_arg($args, "--num-callers=16");
  3515. mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
  3516. if -f "$glob_mysql_test_dir/valgrind.supp";
  3517. }
  3518. # Add valgrind options, can be overriden by user
  3519. mtr_add_arg($args, '%s', $_) for (@valgrind_args);
  3520. mtr_add_arg($args, $$exe);
  3521. $$exe= $opt_valgrind_path || "valgrind";
  3522. if ($exe_libtool)
  3523. {
  3524. # Add "libtool --mode-execute" before the test to execute
  3525. # if running in valgrind(to avoid valgrinding bash)
  3526. unshift(@$args, "--mode=execute", $$exe);
  3527. $$exe= $exe_libtool;
  3528. }
  3529. }
  3530. #
  3531. # Usage
  3532. #
  3533. sub usage ($) {
  3534. my $message= shift;
  3535. if ( $message )
  3536. {
  3537. print STDERR "$message\n";
  3538. }
  3539. print <<HERE;
  3540. $0 [ OPTIONS ] [ TESTCASE ]
  3541. Options to control what engine/variation to run
  3542. embedded-server Use the embedded server, i.e. no mysqld daemons
  3543. ps-protocol Use the binary protocol between client and server
  3544. cursor-protocol Use the cursor protocol between client and server
  3545. (implies --ps-protocol)
  3546. view-protocol Create a view to execute all non updating queries
  3547. sp-protocol Create a stored procedure to execute all queries
  3548. compress Use the compressed protocol between client and server
  3549. ssl Use ssl protocol between client and server
  3550. skip-ssl Dont start server with support for ssl connections
  3551. ndb|with-ndbcluster Use cluster as default table type
  3552. vs-config Visual Studio configuration used to create executables
  3553. (default: MTR_VS_CONFIG environment variable)
  3554. config|defaults-file=<config template> Use fixed config template for all
  3555. tests
  3556. defaults_extra_file=<config template> Extra config template to add to
  3557. all generated configs
  3558. Options to control directories to use
  3559. tmpdir=DIR The directory where temporary files are stored
  3560. (default: ./var/tmp).
  3561. vardir=DIR The directory where files generated from the test run
  3562. is stored (default: ./var). Specifying a ramdisk or
  3563. tmpfs will speed up tests.
  3564. mem Run testsuite in "memory" using tmpfs or ramdisk
  3565. Attempts to find a suitable location
  3566. using a builtin list of standard locations
  3567. for tmpfs (/dev/shm)
  3568. The option can also be set using environment
  3569. variable MTR_MEM=[DIR]
  3570. client-bindir=PATH Path to the directory where client binaries are located
  3571. client-libdir=PATH Path to the directory where client libraries are located
  3572. Options to control what test suites or cases to run
  3573. force Continue to run the suite after failure
  3574. with-ndbcluster-only Run only tests that include "ndb" in the filename
  3575. skip-ndb[cluster] Skip all tests that need cluster
  3576. skip-ndb[cluster]-slave Skip all tests that need a slave cluster
  3577. do-test=PREFIX or REGEX
  3578. Run test cases which name are prefixed with PREFIX
  3579. or fulfills REGEX
  3580. skip-test=PREFIX or REGEX
  3581. Skip test cases which name are prefixed with PREFIX
  3582. or fulfills REGEX
  3583. start-from=PREFIX Run test cases starting test prefixed with PREFIX where
  3584. prefix may be suite.testname or just testname
  3585. suite[s]=NAME1,..,NAMEN
  3586. Collect tests in suites from the comma separated
  3587. list of suite names.
  3588. The default is: "$DEFAULT_SUITES"
  3589. skip-rpl Skip the replication test cases.
  3590. big-test Set the environment variable BIG_TEST, which can be
  3591. checked from test cases.
  3592. Options that specify ports
  3593. mtr-build-thread=# Specify unique number to calculate port number(s) from.
  3594. build-thread=# Can be set in environment variable MTR_BUILD_THREAD.
  3595. Set MTR_BUILD_THREAD="auto" to automatically aquire
  3596. a build thread id that is unique to current host
  3597. Options for test case authoring
  3598. record TESTNAME (Re)genereate the result file for TESTNAME
  3599. check-testcases Check testcases for sideeffects
  3600. mark-progress Log line number and elapsed time to <testname>.progress
  3601. Options that pass on options
  3602. mysqld=ARGS Specify additional arguments to "mysqld"
  3603. Options to run test on running server
  3604. extern option=value Run only the tests against an already started server
  3605. the options to use for connection to the extern server
  3606. must be specified using name-value pair notation
  3607. For example:
  3608. ./$0 --extern socket=/tmp/mysqld.sock
  3609. user=USER User for connection to extern server
  3610. socket=PATH Socket for connection to extern server
  3611. Options for debugging the product
  3612. client-ddd Start mysqltest client in ddd
  3613. client-debugger=NAME Start mysqltest in the selected debugger
  3614. client-gdb Start mysqltest client in gdb
  3615. ddd Start mysqld in ddd
  3616. debug Dump trace output for all servers and client programs
  3617. debugger=NAME Start mysqld in the selected debugger
  3618. gdb Start the mysqld(s) in gdb
  3619. manual-debug Let user manually start mysqld in debugger, before
  3620. running test(s)
  3621. manual-gdb Let user manually start mysqld in gdb, before running
  3622. test(s)
  3623. manual-ddd Let user manually start mysqld in ddd, before running
  3624. test(s)
  3625. strace-client=[path] Create strace output for mysqltest client, optionally
  3626. specifying name and path to the trace program to use.
  3627. Example: $0 --strace-client=ktrace
  3628. max-save-core Limit the number of core files saved (to avoid filling
  3629. up disks for heavily crashing server). Defaults to
  3630. $opt_max_save_core, set to 0 for no limit. Set
  3631. it's default with MTR_MAX_SAVE_CORE
  3632. max-save-datadir Limit the number of datadir saved (to avoid filling
  3633. up disks for heavily crashing server). Defaults to
  3634. $opt_max_save_datadir, set to 0 for no limit. Set
  3635. it's default with MTR_MAX_SAVE_DATDIR
  3636. max-test-fail Limit the number of test failurs before aborting
  3637. the current test run. Defaults to
  3638. $opt_max_test_fail, set to 0 for no limit. Set
  3639. it's default with MTR_MAX_TEST_FAIL
  3640. Options for valgrind
  3641. valgrind Run the "mysqltest" and "mysqld" executables using
  3642. valgrind with default options
  3643. valgrind-all Synonym for --valgrind
  3644. valgrind-mysqltest Run the "mysqltest" and "mysql_client_test" executable
  3645. with valgrind
  3646. valgrind-mysqld Run the "mysqld" executable with valgrind
  3647. valgrind-options=ARGS Deprecated, use --valgrind-option
  3648. valgrind-option=ARGS Option to give valgrind, replaces default option(s),
  3649. can be specified more then once
  3650. valgrind-path=[EXE] Path to the valgrind executable
  3651. callgrind Instruct valgrind to use callgrind
  3652. Misc options
  3653. comment=STR Write STR to the output
  3654. notimer Don't show test case execution time
  3655. verbose More verbose output(use multiple times for even more)
  3656. start Only initialize and start the servers, using the
  3657. startup settings for the first specified test case
  3658. Example:
  3659. $0 --start alias &
  3660. start-dirty Only start the servers (without initialization) for
  3661. the first specified test case
  3662. fast Run as fast as possible, dont't wait for servers
  3663. to shutdown etc.
  3664. repeat=N Run each test N number of times
  3665. retry=N Retry tests that fail N times, limit number of failures
  3666. to $opt_retry_failure
  3667. retry-failure=N Limit number of retries for a failed test
  3668. reorder Reorder tests to get fewer server restarts
  3669. help Get this help text
  3670. testcase-timeout=MINUTES Max test case run time (default $opt_testcase_timeout)
  3671. suite-timeout=MINUTES Max test suite run time (default $opt_suite_timeout)
  3672. shutdown-timeout=SECONDS Max number of seconds to wait for server shutdown
  3673. before killing servers (default $opt_shutdown_timeout)
  3674. warnings Scan the log files for warnings. Use --nowarnings
  3675. to turn off.
  3676. sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time
  3677. HERE
  3678. exit(1);
  3679. }