summaryrefslogtreecommitdiff
path: root/mysql-test/mysql-test-run.pl
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/mysql-test-run.pl')
-rwxr-xr-xmysql-test/mysql-test-run.pl2021
1 files changed, 1143 insertions, 878 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 2df6087f2b4..a22271bb15f 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1,7 +1,8 @@
#!/usr/bin/perl
# -*- cperl -*-
-# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates.
+# Copyright (c) 2009-2011 Monty Program Ab
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -84,7 +85,7 @@ use File::Basename;
use File::Copy;
use File::Find;
use File::Temp qw/tempdir/;
-use File::Spec::Functions qw/splitdir/;
+use File::Spec::Functions qw/splitdir rel2abs/;
use My::Platform;
use My::SafeProcess;
use My::ConfigFactory;
@@ -124,6 +125,7 @@ our $path_testlog;
our $default_vardir;
our $opt_vardir; # Path to use for var/ dir
+our $plugindir;
my $path_vardir_trace; # unix formatted opt_vardir for trace files
my $opt_tmpdir; # Path to use for tmp/ dir
my $opt_tmpdir_pid;
@@ -133,8 +135,6 @@ my $opt_start_dirty;
my $opt_start_exit;
my $start_only;
-my $auth_plugin; # the path to the authentication test plugin
-
END {
if ( defined $opt_tmpdir_pid and $opt_tmpdir_pid == $$ )
{
@@ -161,12 +161,31 @@ my $path_config_file; # The generated config file, var/my.cnf
# executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
-# If you add a new suite, please check TEST_DIRS in Makefile.am.
-#
-my $DEFAULT_SUITES= "main,sys_vars,binlog,federated,rpl,innodb,perfschema";
+my $DEFAULT_SUITES= join(',', map { "$_-" } qw(
+ main
+ binlog
+ federated
+ funcs_1
+ funcs_2
+ handler
+ innodb
+ maria
+ optimizer_unfixed_bugs
+ oqgraph
+ parts
+ percona
+ perfschema
+ plugins
+ rpl
+ sphinx
+ sys_vars
+ unit
+ vcol
+ ));
my $opt_suites;
our $opt_verbose= 0; # Verbose output, enable with --verbose
+our $exe_patch;
our $exe_mysql;
our $exe_mysql_plugin;
our $exe_mysqladmin;
@@ -175,6 +194,7 @@ our $exe_libtool;
our $exe_mysql_embedded;
our $opt_big_test= 0;
+our $opt_staging_run= 0;
our @opt_combinations;
@@ -192,17 +212,14 @@ my $opt_ps_protocol;
my $opt_sp_protocol;
my $opt_cursor_protocol;
my $opt_view_protocol;
+my $opt_non_blocking_api;
our $opt_debug;
-my $debug_d= "d";
+my $debug_d= "d,*";
my $opt_debug_common;
our $opt_debug_server;
our @opt_cases; # The test cases names in argv
our $opt_embedded_server;
-# -1 indicates use default, override with env.var.
-our $opt_ctest= env_or_val(MTR_UNIT_TESTS => -1);
-# Unit test report stored here for delayed printing
-my $ctest_report;
# Options used when connecting to an already running server
my %opts_extern;
@@ -214,6 +231,7 @@ our $opt_mem= $ENV{'MTR_MEM'};
our $opt_clean_vardir= $ENV{'MTR_CLEAN_VARDIR'};
our $opt_gcov;
+our $opt_gcov_src_dir;
our $opt_gcov_exe= "gcov";
our $opt_gcov_err= "mysql-test-gcov.err";
our $opt_gcov_msg= "mysql-test-gcov.msg";
@@ -265,7 +283,7 @@ our $opt_report_times= 0;
my $opt_sleep;
my $opt_testcase_timeout= $ENV{MTR_TESTCASE_TIMEOUT} || 15; # minutes
-my $opt_suite_timeout = $ENV{MTR_SUITE_TIMEOUT} || 300; # minutes
+my $opt_suite_timeout = $ENV{MTR_SUITE_TIMEOUT} || 360; # minutes
my $opt_shutdown_timeout= $ENV{MTR_SHUTDOWN_TIMEOUT} || 10; # seconds
my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds
@@ -274,14 +292,11 @@ sub suite_timeout { return $opt_suite_timeout * 60; };
my $opt_wait_all;
my $opt_user_args;
my $opt_repeat= 1;
-my $opt_retry= 3;
+my $opt_retry= 1;
my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2);
my $opt_reorder= 1;
my $opt_force_restart= 0;
-my $opt_strace_client;
-my $opt_strace_server;
-
our $opt_user = "root";
our $opt_valgrind= 0;
@@ -289,11 +304,15 @@ my $opt_valgrind_mysqld= 0;
my $opt_valgrind_mysqltest= 0;
my @default_valgrind_args= ("--show-reachable=yes");
my @valgrind_args;
+my $opt_strace= 0;
+my $opt_strace_client;
+my @strace_args;
my $opt_valgrind_path;
my $valgrind_reports= 0;
my $opt_callgrind;
my %mysqld_logs;
my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
+my $warn_seconds = 60;
sub testcase_timeout ($) {
my ($tinfo)= @_;
@@ -319,9 +338,8 @@ my $exe_ndb_mgmd;
my $exe_ndb_waiter;
my $exe_ndb_mgm;
-our $debug_compiled_binaries;
-
our %mysqld_variables;
+our @optional_plugins;
my $source_dist= 0;
@@ -331,6 +349,11 @@ my $opt_max_test_fail= env_or_val(MTR_MAX_TEST_FAIL => 10);
my $opt_parallel= $ENV{MTR_PARALLEL} || 1;
+# lock file to stop tests
+my $opt_stop_file= $ENV{MTR_STOP_FILE};
+# print messages when test suite is stopped (for buildbot)
+my $opt_stop_keep_alive= $ENV{MTR_STOP_KEEP_ALIVE};
+
select(STDOUT);
$| = 1; # Automatically flush STDOUT
@@ -360,12 +383,13 @@ sub main {
My::SafeProcess::find_bin();
if ( $opt_gcov ) {
- gcov_prepare($basedir);
+ gcov_prepare($basedir . "/" . $opt_gcov_src_dir);
}
+
if (!$opt_suites) {
$opt_suites= $DEFAULT_SUITES;
-
+
# Check for any extra suites to enable based on the path name
my %extra_suites=
(
@@ -388,8 +412,32 @@ sub main {
}
mtr_report("Using suites: $opt_suites") unless @opt_cases;
+ print "vardir: $opt_vardir\n";
+ initialize_servers();
init_timers();
+ mtr_report("Checking supported features...");
+
+ # --debug[-common] implies we run debug server
+ $opt_debug_server= 1 if $opt_debug || $opt_debug_common;
+
+ if (using_extern())
+ {
+ # Connect to the running mysqld and find out what it supports
+ collect_mysqld_features_from_running_server();
+ }
+ else
+ {
+ # Run the mysqld to find out what features are available
+ collect_mysqld_features();
+ mysql_install_db(default_mysqld(), "$opt_vardir/install.db");
+ }
+ check_ndbcluster_support();
+ check_ssl_support();
+ check_debug_support();
+
+ executable_setup();
+
mtr_report("Collecting tests...");
my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases, \@opt_skip_test_list);
mark_time_used('collect');
@@ -404,13 +452,11 @@ sub main {
template_path => "include/default_my.cnf",
master_opt => [],
slave_opt => [],
+ suite => 'main',
);
unshift(@$tests, $tinfo);
}
- print "vardir: $opt_vardir\n";
- initialize_servers();
-
#######################################################################
my $num_tests= @$tests;
if ( $opt_parallel eq "auto" ) {
@@ -452,20 +498,6 @@ sub main {
print_global_resfile();
}
- # --------------------------------------------------------------------------
- # Read definitions from include/plugin.defs
- #
- read_plugin_defs("include/plugin.defs");
-
- # Also read from any plugin local or suite specific plugin.defs
- for (glob "$basedir/plugin/*/tests/mtr/plugin.defs".
- " suite/*/plugin.defs") {
- read_plugin_defs($_);
- }
-
- # Simplify reference to semisync plugins
- $ENV{'SEMISYNC_PLUGIN_OPT'}= $ENV{'SEMISYNC_MASTER_PLUGIN_OPT'};
-
# Create child processes
my %children;
for my $child_num (1..$opt_parallel){
@@ -495,7 +527,8 @@ sub main {
mark_time_used('init');
- my $completed= run_test_server($server, $tests, $opt_parallel);
+ my ($prefix, $fail, $completed, $extra_warnings)=
+ run_test_server($server, $tests, $opt_parallel);
exit(0) if $opt_start_exit;
@@ -520,23 +553,11 @@ sub main {
if ( @$completed != $num_tests){
- if ($opt_force){
- # All test should have been run, print any that are still in $tests
- #foreach my $test ( @$tests ){
- # $test->print_test();
- #}
- }
-
# Not all tests completed, failure
mtr_report();
mtr_report("Only ", int(@$completed), " of $num_tests completed.");
- mtr_error("Not all tests completed");
}
- mark_time_used('init');
-
- push @$completed, run_ctest() if $opt_ctest;
-
if ($opt_valgrind) {
# Create minimalistic "test" for the reporting
my $tinfo = My::Test->new
@@ -554,23 +575,25 @@ sub main {
}
mtr_report_test($tinfo);
push @$completed, $tinfo;
+ ++$num_tests
}
mtr_print_line();
if ( $opt_gcov ) {
- gcov_collect($bindir, $opt_gcov_exe,
+ gcov_collect($basedir . "/" . $opt_gcov_src_dir, $opt_gcov_exe,
$opt_gcov_msg, $opt_gcov_err);
}
- if ($ctest_report) {
- print "$ctest_report\n";
- mtr_print_line();
- }
-
print_total_times($opt_parallel) if $opt_report_times;
- mtr_report_stats("Completed", $completed);
+ mtr_report_stats($prefix, $fail, $completed, $extra_warnings);
+
+ if ( @$completed != $num_tests)
+ {
+ mtr_error("Not all tests completed (only ". scalar(@$completed) .
+ " of $num_tests)");
+ }
remove_vardir_subs() if $opt_clean_vardir;
@@ -584,6 +607,8 @@ sub run_test_server ($$$) {
my $num_saved_cores= 0; # Number of core files saved in vardir/log/ so far.
my $num_saved_datadir= 0; # Number of datadirs saved in vardir/log/ so far.
my $num_failed_test= 0; # Number of tests failed so far
+ my $test_failure= 0; # Set true if test suite failed
+ my $extra_warnings= []; # Warnings found during server shutdowns
# Scheduler variables
my $max_ndb= $ENV{MTR_MAX_NDB} || $childs / 2;
@@ -594,13 +619,22 @@ sub run_test_server ($$$) {
my $completed= [];
my %running;
my $result;
- my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump
+ my $exe_mysqld= find_mysqld($bindir) || ""; # Used as hint to CoreDump
my $suite_timeout= start_timer(suite_timeout());
my $s= IO::Select->new();
$s->add($server);
while (1) {
+ if ($opt_stop_file)
+ {
+ if (mtr_wait_lock_file($opt_stop_file, $opt_stop_keep_alive))
+ {
+ # We were waiting so restart timer process
+ my $suite_timeout= start_timer(suite_timeout());
+ }
+ }
+
mark_time_used('admin');
my @ready = $s->can_read(1); # Wake up once every second
mark_time_idle();
@@ -619,7 +653,7 @@ sub run_test_server ($$$) {
mtr_verbose("Child closed socket");
$s->remove($sock);
if (--$childs == 0){
- return $completed;
+ return ("Completed", $test_failure, $completed, $extra_warnings);
}
next;
}
@@ -627,7 +661,6 @@ sub run_test_server ($$$) {
if ($line eq 'TESTRESULT'){
$result= My::Test::read_test($sock);
- # $result->print_test();
# Report test status
mtr_report_test($result);
@@ -689,21 +722,23 @@ sub run_test_server ($$$) {
$num_failed_test++ unless ($result->{retries} ||
$result->{exp_fail});
+ $test_failure= 1;
if ( !$opt_force ) {
# Test has failed, force is off
push(@$completed, $result);
- return $completed unless $result->{'dont_kill_server'};
- # Prevent kill of server, to get valgrind report
- print $sock "BYE\n";
- next;
+ if ($result->{'dont_kill_server'})
+ {
+ print $sock "BYE\n";
+ next;
+ }
+ return ("Failure", 1, $completed, $extra_warnings);
}
elsif ($opt_max_test_fail > 0 and
$num_failed_test >= $opt_max_test_fail) {
push(@$completed, $result);
- mtr_report_stats("Too many failed", $completed, 1);
mtr_report("Too many tests($num_failed_test) failed!",
"Terminating...");
- return undef;
+ return ("Too many failed", 1, $completed, $extra_warnings);
}
}
@@ -758,6 +793,19 @@ sub run_test_server ($$$) {
elsif ($line eq 'START'){
; # Send first test
}
+ elsif ($line eq 'WARNINGS'){
+ my $fake_test= My::Test::read_test($sock);
+ my $test_list= join (" ", @{$fake_test->{testnames}});
+ push @$extra_warnings, $test_list;
+ my $report= $fake_test->{'warnings'};
+ mtr_report("***Warnings generated in error logs during shutdown ".
+ "after running tests: $test_list\n\n$report");
+ $test_failure= 1;
+ if ( !$opt_force ) {
+ # Test failure due to warnings, force is off
+ return ("Warnings in log", 1, $completed, $extra_warnings);
+ }
+ }
elsif ($line =~ /^SPENT/) {
add_total_times($line);
}
@@ -796,9 +844,11 @@ sub run_test_server ($$$) {
next;
}
- # Second best choice is the first that does not fulfill
- # any of the above conditions
- if (!defined $second_best){
+ # From secondary choices, we prefer to pick a 'long-running' test if
+ # possible; this helps avoid getting stuck with a few of those at the
+ # end of high --parallel runs, with most workers being idle.
+ if (!defined $second_best ||
+ ($t->{'long_test'} && !($tests->[$second_best]{'long_test'}))){
#mtr_report("Setting second_best to $i");
$second_best= $i;
}
@@ -812,8 +862,6 @@ sub run_test_server ($$$) {
next if (defined $t->{reserved} and $t->{reserved} != $wid);
if (! defined $t->{reserved})
{
- # Force-restart not relevant when comparing *next* test
- $t->{criteria} =~ s/force-restart$/no-restart/;
my $criteria= $t->{criteria};
# Reserve similar tests for this worker, but not too many
my $maxres= (@$tests - $i) / $opt_parallel + 1;
@@ -841,6 +889,8 @@ sub run_test_server ($$$) {
delete $next->{reserved};
}
+ xterm_stat(scalar(@$tests));
+
if ($next) {
# We don't need this any more
delete $next->{criteria};
@@ -861,9 +911,8 @@ sub run_test_server ($$$) {
# ----------------------------------------------------
if ( has_expired($suite_timeout) )
{
- mtr_report_stats("Timeout", $completed, 1);
mtr_report("Test suite timeout! Terminating...");
- return undef;
+ return ("Timeout", 1, $completed, $extra_warnings);
}
}
}
@@ -921,7 +970,6 @@ sub run_worker ($) {
chomp($line);
if ($line eq 'TESTCASE'){
my $test= My::Test::read_test($server);
- #$test->print_test();
# Clear comment and logfile, to avoid
# reusing them from previous test
@@ -935,16 +983,26 @@ sub run_worker ($) {
}
$test->{worker} = $thread_num if $opt_parallel > 1;
- run_testcase($test);
+ run_testcase($test, $server);
#$test->{result}= 'MTR_RES_PASSED';
# Send it back, now with results set
- #$test->print_test();
$test->write_test($server, 'TESTRESULT');
mark_time_used('restart');
}
elsif ($line eq 'BYE'){
mtr_report("Server said BYE");
- stop_all_servers($opt_shutdown_timeout);
+ # We need to gracefully shut down the servers to see any
+ # Valgrind memory leak errors etc. since last server restart.
+ if ($opt_warnings) {
+ stop_servers(reverse all_servers());
+ if(check_warnings_post_shutdown($server)) {
+ # Warnings appeared in log file(s) during final server shutdown.
+ exit(1);
+ }
+ }
+ else {
+ stop_all_servers($opt_shutdown_timeout);
+ }
mark_time_used('restart');
my $valgrind_reports= 0;
if ($opt_valgrind_mysqld) {
@@ -952,7 +1010,7 @@ sub run_worker ($) {
print $server "VALGREP\n" if $valgrind_reports;
}
if ( $opt_gprof ) {
- gprof_collect (find_mysqld($basedir), keys %gprof_dirs);
+ gprof_collect (find_mysqld($bindir), keys %gprof_dirs);
}
mark_time_used('admin');
print_times_used($server, $thread_num);
@@ -1053,6 +1111,7 @@ sub command_line_setup {
'sp-protocol' => \$opt_sp_protocol,
'view-protocol' => \$opt_view_protocol,
'cursor-protocol' => \$opt_cursor_protocol,
+ 'non-blocking-api' => \$opt_non_blocking_api,
'ssl|with-openssl' => \$opt_ssl,
'skip-ssl' => \$opt_skip_ssl,
'compress' => \$opt_compress,
@@ -1076,12 +1135,13 @@ sub command_line_setup {
'skip-test=s' => \&collect_option,
'do-test=s' => \&collect_option,
'start-from=s' => \&collect_option,
- 'big-test' => \$opt_big_test,
+ 'big-test+' => \$opt_big_test,
'combination=s' => \@opt_combinations,
'skip-combinations' => \&collect_option,
'experimental=s' => \@opt_experimentals,
# skip-im is deprecated and silently ignored
'skip-im' => \&ignore_option,
+ 'staging-run' => \$opt_staging_run,
# Specify ports
'build-thread|mtr-build-thread=i' => \$opt_build_thread,
@@ -1118,14 +1178,16 @@ sub command_line_setup {
'debugger=s' => \$opt_debugger,
'boot-dbx' => \$opt_boot_dbx,
'client-debugger=s' => \$opt_client_debugger,
- 'strace-server' => \$opt_strace_server,
+ 'strace' => \$opt_strace,
'strace-client' => \$opt_strace_client,
+ 'strace-option=s' => \@strace_args,
'max-save-core=i' => \$opt_max_save_core,
'max-save-datadir=i' => \$opt_max_save_datadir,
'max-test-fail=i' => \$opt_max_test_fail,
# Coverage, profiling etc
'gcov' => \$opt_gcov,
+ 'gcov-src-dir=s' => \$opt_gcov_src_dir,
'gprof' => \$opt_gprof,
'valgrind|valgrind-all' => \$opt_valgrind,
'valgrind-mysqltest' => \$opt_valgrind_mysqltest,
@@ -1181,11 +1243,12 @@ sub command_line_setup {
'warnings!' => \$opt_warnings,
'timestamp' => \&report_option,
'timediff' => \&report_option,
+ 'stop-file=s' => \$opt_stop_file,
+ 'stop-keep-alive=i' => \$opt_stop_keep_alive,
'max-connections=i' => \$opt_max_connections,
'default-myisam!' => \&collect_option,
'report-times' => \$opt_report_times,
'result-file' => \$opt_resfile,
- 'unit-tests!' => \$opt_ctest,
'stress=s' => \$opt_stress,
'help|h' => \$opt_usage,
@@ -1195,7 +1258,6 @@ sub command_line_setup {
);
GetOptions(%options) or usage("Can't read options");
-
usage("") if $opt_usage;
list_options(\%options) if $opt_list_options;
@@ -1238,7 +1300,19 @@ sub command_line_setup {
{
$basedir= dirname($basedir);
}
+ # For .deb, it's like RPM, but installed in /usr/share/mysql/mysql-test.
+ # So move up one more directory level yet.
+ if ( ! $source_dist and ! -d "$basedir/bin" )
+ {
+ $basedir= dirname($basedir);
+ }
+
+ # Respect MTR_BINDIR variable, which is typically set in to the
+ # build directory in out-of-source builds.
+ $bindir=$ENV{MTR_BINDIR}||$basedir;
+ fix_vs_config_dir();
+
# Respect MTR_BINDIR variable, which is typically set in to the
# build directory in out-of-source builds.
$bindir=$ENV{MTR_BINDIR}||$basedir;
@@ -1253,36 +1327,21 @@ sub command_line_setup {
{
$path_client_bindir= mtr_path_exists("$bindir/client_release",
"$bindir/client_debug",
- vs_config_dirs('client', ''),
+ "$bindir/client$opt_vs_config",
"$bindir/client",
"$bindir/bin");
}
# Look for language files and charsetsdir, use same share
- $path_language= mtr_path_exists("$bindir/share/mysql",
+ $path_language= mtr_path_exists("$bindir/share/mariadb",
+ "$bindir/share/mysql",
"$bindir/sql/share",
"$bindir/share");
my $path_share= $path_language;
- $path_charsetsdir = mtr_path_exists("$basedir/share/mysql/charsets",
+ $path_charsetsdir = mtr_path_exists("$basedir/share/mariadb/charsets",
+ "$basedir/share/mysql/charsets",
"$basedir/sql/share/charsets",
"$basedir/share/charsets");
-
- ($auth_plugin)= find_plugin("auth_test_plugin", "plugin/auth");
-
- # --debug[-common] implies we run debug server
- $opt_debug_server= 1 if $opt_debug || $opt_debug_common;
-
- if (using_extern())
- {
- # Connect to the running mysqld and find out what it supports
- collect_mysqld_features_from_running_server();
- }
- else
- {
- # Run the mysqld to find out what features are available
- collect_mysqld_features();
- }
-
if ( $opt_comment )
{
mtr_report();
@@ -1356,6 +1415,12 @@ sub command_line_setup {
}
}
+ if ( @opt_cases )
+ {
+ # Run big tests if explicitely specified on command line
+ $opt_big_test= 1;
+ }
+
# --------------------------------------------------------------------------
# Find out type of logging that are being used
# --------------------------------------------------------------------------
@@ -1435,6 +1500,7 @@ sub command_line_setup {
{
$default_vardir= "$glob_mysql_test_dir/var";
}
+
if ( ! $opt_vardir )
{
$opt_vardir= $default_vardir;
@@ -1505,19 +1571,6 @@ sub command_line_setup {
# --------------------------------------------------------------------------
if ( $opt_embedded_server )
{
- if ( IS_WINDOWS )
- {
- # Add the location for libmysqld.dll to the path.
- my $separator= ";";
- my $lib_mysqld=
- mtr_path_exists("$bindir/lib", vs_config_dirs('libmysqld',''));
- if ( IS_CYGWIN )
- {
- $lib_mysqld= posix_path($lib_mysqld);
- $separator= ":";
- }
- $ENV{'PATH'}= "$ENV{'PATH'}".$separator.$lib_mysqld;
- }
$opt_skip_ndbcluster= 1; # Turn off use of NDB cluster
$opt_skip_ssl= 1; # Turn off use of SSL
@@ -1532,14 +1585,12 @@ sub command_line_setup {
if ($opt_gdb)
{
- mtr_warning("Silently converting --gdb to --client-gdb in embedded mode");
$opt_client_gdb= $opt_gdb;
$opt_gdb= undef;
}
if ($opt_ddd)
{
- mtr_warning("Silently converting --ddd to --client-ddd in embedded mode");
$opt_client_ddd= $opt_ddd;
$opt_ddd= undef;
}
@@ -1552,7 +1603,6 @@ sub command_line_setup {
if ($opt_debugger)
{
- mtr_warning("Silently converting --debugger to --client-debugger in embedded mode");
$opt_client_debugger= $opt_debugger;
$opt_debugger= undef;
}
@@ -1566,12 +1616,13 @@ sub command_line_setup {
}
# --------------------------------------------------------------------------
- # Big test flags
+ # Big test and staging_run flags
# --------------------------------------------------------------------------
if ( $opt_big_test )
{
$ENV{'BIG_TEST'}= 1;
}
+ $ENV{'STAGING_RUN'}= $opt_staging_run;
# --------------------------------------------------------------------------
# Gcov flag
@@ -1589,12 +1640,14 @@ sub command_line_setup {
$opt_dbx || $opt_client_dbx || $opt_manual_dbx ||
$opt_debugger || $opt_client_debugger )
{
- # Indicate that we are using debugger
- $glob_debugger= 1;
if ( using_extern() )
{
mtr_error("Can't use --extern when using debugger");
}
+ # Indicate that we are using debugger
+ $glob_debugger= 1;
+ $opt_retry= 1;
+ $opt_retry_failure= 1;
# Set one week timeout (check-testcase timeout will be 1/10th)
$opt_testcase_timeout= 7 * 24 * 60;
$opt_suite_timeout= 7 * 24 * 60;
@@ -1611,6 +1664,13 @@ sub command_line_setup {
collect_option ('quick-collect', 1);
$start_only= 1;
}
+ if ($opt_debug)
+ {
+ $opt_testcase_timeout= 7 * 24 * 60;
+ $opt_suite_timeout= 7 * 24 * 60;
+ $opt_retry= 1;
+ $opt_retry_failure= 1;
+ }
# --------------------------------------------------------------------------
# Check use of user-args
@@ -1624,14 +1684,6 @@ sub command_line_setup {
}
# --------------------------------------------------------------------------
- # Don't run ctest if tests or suites named
- # --------------------------------------------------------------------------
-
- $opt_ctest= 0 if $opt_ctest == -1 && ($opt_suites || @opt_cases);
- # Override: disable if running in the PB test environment
- $opt_ctest= 0 if $opt_ctest == -1 && defined $ENV{PB2WORKDIR};
-
- # --------------------------------------------------------------------------
# Check use of wait-all
# --------------------------------------------------------------------------
@@ -1653,7 +1705,6 @@ sub command_line_setup {
$opt_suites="stress";
@opt_cases= ("wrapper");
$ENV{MST_OPTIONS}= $opt_stress;
- $opt_ctest= 0;
}
# --------------------------------------------------------------------------
@@ -1676,12 +1727,6 @@ sub command_line_setup {
$opt_valgrind= 1;
$opt_valgrind_mysqld= 1;
$opt_valgrind_mysqltest= 1;
-
- # Increase the timeouts when running with valgrind
- $opt_testcase_timeout*= 10;
- $opt_suite_timeout*= 6;
- $opt_start_timeout*= 10;
-
}
elsif ( $opt_valgrind_mysqld )
{
@@ -1694,6 +1739,15 @@ sub command_line_setup {
$opt_valgrind= 1;
}
+ if ($opt_valgrind)
+ {
+ # Increase the timeouts when running with valgrind
+ $opt_testcase_timeout*= 10;
+ $opt_suite_timeout*= 6;
+ $opt_start_timeout*= 10;
+ $warn_seconds*= 10;
+ }
+
if ( $opt_callgrind )
{
mtr_report("Turning on valgrind with callgrind for mysqld(s)");
@@ -1711,39 +1765,35 @@ sub command_line_setup {
push(@valgrind_args, @default_valgrind_args)
unless @valgrind_args;
- # Don't add --quiet; you will loose the summary reports.
+ # Make valgrind run in quiet mode so it only print errors
+ push(@valgrind_args, "--quiet" );
mtr_report("Running valgrind with options \"",
join(" ", @valgrind_args), "\"");
}
- if ($opt_debug_common)
+ if (@strace_args)
{
- $opt_debug= 1;
- $debug_d= "d,query,info,error,enter,exit";
+ $opt_strace=1;
}
- if ( $opt_strace_server && ($^O ne "linux") )
+ # InnoDB does not bother to do individual de-allocations at exit. Instead it
+ # relies on a custom allocator to track every allocation, and frees all at
+ # once during exit.
+ # In XtraDB, an option use-sys-malloc is introduced (and on by default) to
+ # disable this (for performance). But this exposes Valgrind to all the
+ # missing de-allocations, so we need to disable it to at least get
+ # meaningful leak checking for the rest of the server.
+ if ($opt_valgrind_mysqld)
{
- $opt_strace_server=0;
- mtr_warning("Strace only supported in Linux ");
+ push(@opt_extra_mysqld_opt, "--loose-skip-innodb-use-sys-malloc");
}
- if ( $opt_strace_client && ($^O ne "linux") )
+ if ($opt_debug_common)
{
- $opt_strace_client=0;
- mtr_warning("Strace only supported in Linux ");
+ $opt_debug= 1;
+ $debug_d= "d,query,info,error,enter,exit";
}
-
-
- mtr_report("Checking supported features...");
-
- check_ndbcluster_support(\%mysqld_variables);
- check_ssl_support(\%mysqld_variables);
- check_debug_support(\%mysqld_variables);
-
- executable_setup();
-
}
@@ -1793,30 +1843,21 @@ sub set_build_thread_ports($) {
$ENV{MTR_BUILD_THREAD}= $build_thread;
# Calculate baseport
- $baseport= $build_thread * 10 + 10000;
- if ( $baseport < 5001 or $baseport + 9 >= 32767 )
+ $baseport= $build_thread * 20 + 10000;
+ if ( $baseport < 5001 or $baseport + 19 >= 32767 )
{
mtr_error("MTR_BUILD_THREAD number results in a port",
"outside 5001 - 32767",
- "($baseport - $baseport + 9)");
+ "($baseport - $baseport + 19)");
}
mtr_report("Using MTR_BUILD_THREAD $build_thread,",
- "with reserved ports $baseport..".($baseport+9));
+ "with reserved ports $baseport..".($baseport+19));
}
sub collect_mysqld_features {
- my $found_variable_list_start= 0;
- my $use_tmpdir;
- if ( defined $opt_tmpdir and -d $opt_tmpdir){
- # Create the tempdir in $opt_tmpdir
- $use_tmpdir= $opt_tmpdir;
- }
- my $tmpdir= tempdir(CLEANUP => 0, # Directory removed by this function
- DIR => $use_tmpdir);
-
#
# Execute "mysqld --no-defaults --help --verbose" to get a
# list of all features and settings
@@ -1829,9 +1870,18 @@ sub collect_mysqld_features {
my $args;
mtr_init_args(\$args);
mtr_add_arg($args, "--no-defaults");
- mtr_add_arg($args, "--datadir=%s", mixed_path($tmpdir));
+ mtr_add_arg($args, "--datadir=.");
+ mtr_add_arg($args, "--basedir=%s", $basedir);
mtr_add_arg($args, "--lc-messages-dir=%s", $path_language);
mtr_add_arg($args, "--skip-grant-tables");
+ mtr_add_arg($args, "--log-warnings=0");
+ for (@opt_extra_mysqld_opt) {
+ mtr_add_arg($args, $_) unless /^--binlog-format\b/;
+ }
+ my $euid= $>;
+ if (!IS_WINDOWS and $euid == 0) {
+ mtr_add_arg($args, "--user=root");
+ }
mtr_add_arg($args, "--verbose");
mtr_add_arg($args, "--help");
@@ -1841,68 +1891,42 @@ sub collect_mysqld_features {
mtr_add_arg($args, "--user=root");
}
- my $exe_mysqld= find_mysqld($basedir);
+ my $exe_mysqld= find_mysqld($bindir);
my $cmd= join(" ", $exe_mysqld, @$args);
+
+ mtr_verbose("cmd: $cmd");
+
my $list= `$cmd`;
- foreach my $line (split('\n', $list))
- {
- # First look for version
- if ( !$mysql_version_id )
- {
- # Look for version
- my $exe_name= basename($exe_mysqld);
- mtr_verbose("exe_name: $exe_name");
- if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)([^\s]*)/ )
- {
- #print "Major: $1 Minor: $2 Build: $3\n";
- $mysql_version_id= $1*10000 + $2*100 + $3;
- #print "mysql_version_id: $mysql_version_id\n";
- mtr_report("MySQL Version $1.$2.$3");
- $mysql_version_extra= $4;
- }
- }
- else
- {
- if (!$found_variable_list_start)
- {
- # Look for start of variables list
- if ( $line =~ /[\-]+\s[\-]+/ )
- {
- $found_variable_list_start= 1;
- }
- }
- else
- {
- # Put variables into hash
- if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
- {
- # print "$1=\"$2\"\n";
- $mysqld_variables{$1}= $2;
- }
- else
- {
- # The variable list is ended with a blank line
- if ( $line =~ /^[\s]*$/ )
- {
- last;
- }
- else
- {
- # Send out a warning, we should fix the variables that has no
- # space between variable name and it's value
- # or should it be fixed width column parsing? It does not
- # look like that in function my_print_variables in my_getopt.c
- mtr_warning("Could not parse variable list line : $line");
- }
- }
- }
+ # to simplify the parsing, we'll merge all nicely formatted --help texts
+ $list =~ s/\n {22}(\S)/ $1/g;
+
+ my @list= split '\n', $list;
+ mtr_error("Could not find version of MariaDB")
+ unless shift(@list) =~ /^$exe_mysqld\s+Ver\s(\d+)\.(\d+)\.(\d+)(\S*)/;
+ $mysql_version_id= $1*10000 + $2*100 + $3;
+ $mysql_version_extra= $4;
+ mtr_report("MariaDB Version $1.$2.$3$4");
+
+ for (@list)
+ {
+ # first part of the help - command-line options.
+ if (/Copyright/ .. /^-{30,}/) {
+ # here we want to detect all not mandatory plugins
+ # they are listed in the --help output as
+ # --archive[=name] Enable or disable ARCHIVE plugin. Possible values are ON, OFF, FORCE (don't start if the plugin fails to load).
+ push @optional_plugins, $1
+ if /^ --([-a-z0-9]+)\[=name\] +Enable or disable \w+ plugin. Possible values are ON, OFF, FORCE/;
+ next;
}
- }
- rmtree($tmpdir);
- mtr_error("Could not find version of MySQL") unless $mysql_version_id;
- mtr_error("Could not find variabes list") unless $found_variable_list_start;
+ last if /^$/; # then goes a list of variables, it ends with an empty line
+
+ # Put a variable into hash
+ /^([\S]+)[ \t]+(.*?)\r?$/ or die "Could not parse mysqld --help: $_\n";
+ $mysqld_variables{$1}= $2;
+ }
+ mtr_error("Could not find variabes list") unless %mysqld_variables;
}
@@ -1933,8 +1957,11 @@ sub collect_mysqld_features_from_running_server ()
# Put variables into hash
if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
{
- # print "$1=\"$2\"\n";
- $mysqld_variables{$1}= $2;
+ my $name= $1;
+ my $value=$2;
+ $name =~ s/_/-/g;
+ # print "$name=\"$value\"\n";
+ $mysqld_variables{$name}= $value;
}
}
@@ -1968,7 +1995,7 @@ sub find_mysqld {
unshift(@mysqld_names, "mysqld-debug");
}
- return my_find_bin($mysqld_basedir,
+ return my_find_bin($bindir,
["sql", "libexec", "sbin", "bin"],
[@mysqld_names]);
}
@@ -1976,6 +2003,8 @@ sub find_mysqld {
sub executable_setup () {
+ $exe_patch='patch' if `patch -v`;
+
#
# Check if libtool is available in this distribution/clone
# we need it when valgrinding or debugging non installed binary
@@ -1985,9 +2014,9 @@ sub executable_setup () {
if ( -x "../libtool")
{
$exe_libtool= "../libtool";
- if ($opt_valgrind or $glob_debugger)
+ if ($opt_valgrind or $glob_debugger or $opt_strace)
{
- mtr_report("Using \"$exe_libtool\" when running valgrind or debugger");
+ mtr_report("Using \"$exe_libtool\" when running valgrind, strace or debugger");
}
}
@@ -2047,8 +2076,7 @@ sub executable_setup () {
if ( $opt_embedded_server )
{
$exe_mysqltest=
- mtr_exe_exists(vs_config_dirs('libmysqld/examples','mysqltest_embedded'),
- "$basedir/libmysqld/examples/mysqltest_embedded",
+ mtr_exe_exists("$bindir/libmysqld/examples$opt_vs_config/mysqltest_embedded",
"$path_client_bindir/mysqltest_embedded");
}
else
@@ -2093,6 +2121,18 @@ sub client_arguments ($;$) {
}
+sub mysqlbinlog_arguments () {
+ my $exe= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
+
+ my $args;
+ mtr_init_args(\$args);
+ mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
+ mtr_add_arg($args, "--local-load=%s", $opt_tmpdir);
+ client_debug_arg($args, "mysqlbinlog");
+ return mtr_args2str($exe, @$args);
+}
+
+
sub mysqlslap_arguments () {
my $exe= mtr_exe_maybe_exists("$path_client_bindir/mysqlslap");
if ( $exe eq "" ) {
@@ -2130,13 +2170,11 @@ sub mysql_client_test_arguments(){
# mysql_client_test executable may _not_ exist
if ( $opt_embedded_server ) {
$exe= mtr_exe_maybe_exists(
- vs_config_dirs('libmysqld/examples','mysql_client_test_embedded'),
- "$basedir/libmysqld/examples/mysql_client_test_embedded",
- "$basedir/bin/mysql_client_test_embedded");
+ "$bindir/libmysqld/examples$opt_vs_config/mysql_client_test_embedded",
+ "$bindir/bin/mysql_client_test_embedded");
} else {
- $exe= mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'),
- "$basedir/tests/mysql_client_test",
- "$basedir/bin/mysql_client_test");
+ $exe= mtr_exe_maybe_exists("$bindir/tests$opt_vs_config/mysql_client_test",
+ "$bindir/bin/mysql_client_test");
}
my $args;
@@ -2148,11 +2186,42 @@ sub mysql_client_test_arguments(){
mtr_add_arg($args, "--testcase");
mtr_add_arg($args, "--vardir=$opt_vardir");
client_debug_arg($args,"mysql_client_test");
+ my $ret=mtr_args2str($exe, @$args);
+ return $ret;
+}
+
+sub tool_arguments ($$) {
+ my($sedir, $tool_name) = @_;
+ my $exe= my_find_bin($bindir,
+ [$sedir, "bin"],
+ $tool_name);
+
+ my $args;
+ mtr_init_args(\$args);
+ client_debug_arg($args, $tool_name);
+ return mtr_args2str($exe, @$args);
+}
+# This is not used to actually start a mysqld server, just to allow test
+# scripts to run the mysqld binary to test invalid server startup options.
+sub mysqld_client_arguments () {
+ my $default_mysqld= default_mysqld();
+ my $exe = find_mysqld($bindir);
+ my $args;
+ mtr_init_args(\$args);
+ mtr_add_arg($args, "--no-defaults");
+ mtr_add_arg($args, "--basedir=%s", $basedir);
+ mtr_add_arg($args, "--character-sets-dir=%s", $default_mysqld->value("character-sets-dir"));
+ mtr_add_arg($args, "--language=%s", $default_mysqld->value("language"));
return mtr_args2str($exe, @$args);
}
+sub have_maria_support () {
+ my $maria_var= $mysqld_variables{'aria-recover'};
+ return defined $maria_var;
+}
+
#
# Set environment to be used by childs of this process for
# things that are constant during the whole lifetime of mysql-test-run
@@ -2183,62 +2252,6 @@ sub find_plugin($$)
return $lib_plugin;
}
-#
-# Read plugin defintions file
-#
-
-sub read_plugin_defs($)
-{
- my ($defs_file)= @_;
- my $running_debug= 0;
-
- open(PLUGDEF, '<', $defs_file)
- or mtr_error("Can't read plugin defintions file $defs_file");
-
- # Need to check if we will be running mysqld-debug
- if ($opt_debug_server) {
- $running_debug= 1 if find_mysqld($basedir) =~ /mysqld-debug/;
- }
-
- while (<PLUGDEF>) {
- next if /^#/;
- my ($plug_file, $plug_loc, $plug_var, $plug_names)= split;
- # Allow empty lines
- next unless $plug_file;
- mtr_error("Lines in $defs_file must have 3 or 4 items") unless $plug_var;
-
- # If running debug server, plugins will be in 'debug' subdirectory
- $plug_file= "debug/$plug_file" if $running_debug;
-
- my ($plugin)= find_plugin($plug_file, $plug_loc);
-
- # Set env. variables that tests may use, set to empty if plugin
- # listed in def. file but not found.
-
- if ($plugin) {
- $ENV{$plug_var}= basename($plugin);
- $ENV{$plug_var.'_DIR'}= dirname($plugin);
- $ENV{$plug_var.'_OPT'}= "--plugin-dir=".dirname($plugin);
- if ($plug_names) {
- my $lib_name= basename($plugin);
- my $load_var= "--plugin_load=";
- my $semi= '';
- foreach my $plug_name (split (',', $plug_names)) {
- $load_var .= $semi . "$plug_name=$lib_name";
- $semi= ';';
- }
- $ENV{$plug_var.'_LOAD'}= $load_var;
- }
- } else {
- $ENV{$plug_var}= "";
- $ENV{$plug_var.'_DIR'}= "";
- $ENV{$plug_var.'_OPT'}= "";
- $ENV{$plug_var.'_LOAD'}= "" if $plug_names;
- }
- }
- close PLUGDEF;
-}
-
sub environment_setup {
umask(022);
@@ -2259,6 +2272,13 @@ sub environment_setup {
push(@ld_library_paths, "$basedir/libmysql/.libs/",
"$basedir/libmysql_r/.libs/",
"$basedir/zlib/.libs/");
+ if ($^O eq "darwin")
+ {
+ # it is MAC OS and we have to add dynamic libraries paths
+ push @ld_library_paths, grep {<$_/*.dylib>}
+ (<$bindir/storage/*/.libs/>,<$bindir/plugin/*/.libs/>,
+ <$bindir/plugin/*/*/.libs/>,<$bindir/storage/*/*/.libs>);
+ }
}
else
{
@@ -2274,9 +2294,6 @@ sub environment_setup {
push(@ld_library_paths, "$basedir/storage/ndb/src/.libs");
}
- # Plugin settings should no longer be added here, instead
- # place definitions in include/plugin.defs.
- # See comment in that file for details.
# --------------------------------------------------------------------------
# Valgrind need to be run with debug libraries otherwise it's almost
# impossible to add correct supressions, that means if "/usr/lib/debug"
@@ -2340,7 +2357,7 @@ sub environment_setup {
$ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'port'};
$ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir;
$ENV{'MYSQLTEST_VARDIR'}= $opt_vardir;
- $ENV{'MYSQL_BINDIR'}= "$bindir";
+ $ENV{'MYSQL_BINDIR'}= $bindir;
$ENV{'MYSQL_SHAREDIR'}= $path_language;
$ENV{'MYSQL_CHARSETSDIR'}= $path_charsetsdir;
@@ -2352,7 +2369,15 @@ sub environment_setup {
{
$ENV{'SECURE_LOAD_PATH'}= $glob_mysql_test_dir."/std_data";
}
-
+
+ #
+ # Some stupid^H^H^H^H^H^Hignorant network providers set up "wildcard DNS"
+ # servers that return some given web server address for any lookup of a
+ # non-existent host name. This confuses test cases that want to test the
+ # behaviour when connecting to a non-existing host, so we need to be able
+ # to disable those tests when DNS is broken.
+ #
+ $ENV{HAVE_BROKEN_DNS}= defined(gethostbyname('invalid_hostname'));
# ----------------------------------------------------
# Setup env for NDB
@@ -2391,11 +2416,11 @@ sub environment_setup {
$ENV{'MYSQL_SLAP'}= mysqlslap_arguments();
$ENV{'MYSQL_IMPORT'}= client_arguments("mysqlimport");
$ENV{'MYSQL_SHOW'}= client_arguments("mysqlshow");
- $ENV{'MYSQL_BINLOG'}= client_arguments("mysqlbinlog");
+ $ENV{'MYSQL_BINLOG'}= mysqlbinlog_arguments();
$ENV{'MYSQL'}= client_arguments("mysql");
$ENV{'MYSQL_SLAVE'}= client_arguments("mysql", ".2");
$ENV{'MYSQL_UPGRADE'}= client_arguments("mysql_upgrade");
- $ENV{'MYSQLADMIN'}= native_path($exe_mysqladmin);
+ $ENV{'MYSQLADMIN'}= client_arguments("mysqladmin");
$ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments();
$ENV{'EXE_MYSQL'}= $exe_mysql;
$ENV{'MYSQL_PLUGIN'}= $exe_mysql_plugin;
@@ -2412,43 +2437,43 @@ sub environment_setup {
# some versions, test using it should be skipped
# ----------------------------------------------------
my $exe_bug25714=
- mtr_exe_maybe_exists(vs_config_dirs('tests', 'bug25714'),
- "$basedir/tests/bug25714");
+ mtr_exe_maybe_exists("$bindir/tests$opt_vs_config/bug25714");
$ENV{'MYSQL_BUG25714'}= native_path($exe_bug25714);
# ----------------------------------------------------
# mysql_fix_privilege_tables.sql
# ----------------------------------------------------
my $file_mysql_fix_privilege_tables=
- mtr_file_exists("$basedir/scripts/mysql_fix_privilege_tables.sql",
- "$basedir/share/mysql_fix_privilege_tables.sql",
- "$basedir/share/mysql/mysql_fix_privilege_tables.sql");
+ mtr_file_exists("$bindir/scripts/mysql_fix_privilege_tables.sql",
+ "$bindir/share/mysql_fix_privilege_tables.sql",
+ "$bindir/share/mariadb/mysql_fix_privilege_tables.sql",
+ "$bindir/share/mysql/mysql_fix_privilege_tables.sql");
$ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables;
# ----------------------------------------------------
# my_print_defaults
# ----------------------------------------------------
my $exe_my_print_defaults=
- mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'),
- "$path_client_bindir/my_print_defaults",
- "$basedir/extra/my_print_defaults");
+ mtr_exe_exists("$bindir/extra$opt_vs_config/my_print_defaults",
+ "$path_client_bindir/my_print_defaults");
$ENV{'MYSQL_MY_PRINT_DEFAULTS'}= native_path($exe_my_print_defaults);
# ----------------------------------------------------
- # Setup env so childs can execute myisampack and myisamchk
+ # myisam tools
# ----------------------------------------------------
- $ENV{'MYISAMCHK'}= native_path(mtr_exe_exists(
- vs_config_dirs('storage/myisam', 'myisamchk'),
- vs_config_dirs('myisam', 'myisamchk'),
- "$path_client_bindir/myisamchk",
- "$basedir/storage/myisam/myisamchk",
- "$basedir/myisam/myisamchk"));
- $ENV{'MYISAMPACK'}= native_path(mtr_exe_exists(
- vs_config_dirs('storage/myisam', 'myisampack'),
- vs_config_dirs('myisam', 'myisampack'),
- "$path_client_bindir/myisampack",
- "$basedir/storage/myisam/myisampack",
- "$basedir/myisam/myisampack"));
+ $ENV{'MYISAMLOG'}= tool_arguments("storage/myisam", "myisamlog", );
+ $ENV{'MYISAMCHK'}= tool_arguments("storage/myisam", "myisamchk");
+ $ENV{'MYISAMPACK'}= tool_arguments("storage/myisam", "myisampack");
+ $ENV{'MYISAM_FTDUMP'}= tool_arguments("storage/myisam", "myisam_ftdump");
+
+ # ----------------------------------------------------
+ # aria tools
+ # ----------------------------------------------------
+ if (have_maria_support())
+ {
+ $ENV{'MARIA_CHK'}= tool_arguments("storage/maria", "aria_chk");
+ $ENV{'MARIA_PACK'}= tool_arguments("storage/maria", "aria_pack");
+ }
# ----------------------------------------------------
# mysqlhotcopy
@@ -2464,8 +2489,7 @@ sub environment_setup {
# ----------------------------------------------------
# perror
# ----------------------------------------------------
- my $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'),
- "$basedir/extra/perror",
+ my $exe_perror= mtr_exe_exists("$bindir/extra$opt_vs_config/perror",
"$path_client_bindir/perror");
$ENV{'MY_PERROR'}= native_path($exe_perror);
@@ -2528,9 +2552,11 @@ sub remove_stale_vardir () {
mtr_report(" - WARNING: Using the 'mysql-test/var' symlink");
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
-
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
remove_vardir_subs();
}
}
@@ -2557,10 +2583,10 @@ sub remove_stale_vardir () {
# Running with "var" in some other place
#
- # Remove the var/ dir in mysql-test dir if any
- # this could be an old symlink that shouldn't be there
- mtr_verbose("Removing $default_vardir");
- rmtree($default_vardir);
+ # Don't remove the var/ dir in mysql-test dir as it may be in
+ # use by another mysql-test-run run with --vardir
+ # mtr_verbose("Removing $default_vardir");
+ # rmtree($default_vardir);
# Remove the "var" dir
mtr_verbose("Removing $opt_vardir/");
@@ -2571,7 +2597,11 @@ sub remove_stale_vardir () {
rmtree("$opt_tmpdir/");
}
-
+sub set_plugin_var($) {
+ local $_ = $_[0];
+ s/\.\w+$//;
+ $ENV{"\U${_}_SO"} = $_[0];
+}
#
# Create var and the directories needed in var
@@ -2589,8 +2619,11 @@ sub setup_vardir() {
# it's a symlink
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
}
elsif ( $opt_mem )
{
@@ -2636,6 +2669,51 @@ sub setup_vardir() {
# and make them world readable
copytree("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data", "0022");
+ # create a plugin dir and copy plugins into it
+ if ($source_dist)
+ {
+ $plugindir="$opt_vardir/plugins";
+ mkpath($plugindir);
+ if (IS_WINDOWS && !$opt_embedded_server)
+ {
+ for (<$bindir/storage/*$opt_vs_config/*.dll>,
+ <$bindir/plugin/*$opt_vs_config/*.dll>,
+ <$bindir/sql$opt_vs_config/*.dll>)
+ {
+ my $pname=basename($_);
+ copy rel2abs($_), "$plugindir/$pname";
+ set_plugin_var($pname);
+ }
+ }
+ else
+ {
+ for (<../storage/*/.libs/*.so>,
+ <../plugin/*/.libs/*.so>,
+ <../plugin/*/*/.libs/*.so>,
+ <../sql/.libs/*.so>,
+ <$bindir/storage/*/*.so>,
+ <$bindir/plugin/*/*.so>,
+ <$bindir/sql/*.so>)
+ {
+ my $pname=basename($_);
+ symlink rel2abs($_), "$plugindir/$pname";
+ set_plugin_var($pname);
+ }
+ }
+ }
+ else
+ {
+ $plugindir= $mysqld_variables{'plugin-dir'} || '.';
+ # hm, what paths work for debs and for rpms ?
+ for (<$bindir/lib64/mysql/plugin/*.so>,
+ <$bindir/lib/mysql/plugin/*.so>,
+ <$bindir/lib/plugin/*.dll>)
+ {
+ my $pname=basename($_);
+ set_plugin_var($pname);
+ }
+ }
+
# Remove old log files
foreach my $name (glob("r/*.progress r/*.log r/*.warnings"))
{
@@ -2670,7 +2748,7 @@ sub check_running_as_root () {
{
mtr_warning("running this script as _root_ will cause some " .
"tests to be skipped");
- $ENV{'MYSQL_TEST_ROOT'}= "YES";
+ $ENV{'MYSQL_TEST_ROOT'}= "1";
}
chmod(oct("0755"), $test_file);
@@ -2678,9 +2756,7 @@ sub check_running_as_root () {
}
-sub check_ssl_support ($) {
- my $mysqld_variables= shift;
-
+sub check_ssl_support {
if ($opt_skip_ssl)
{
mtr_report(" - skipping SSL");
@@ -2689,7 +2765,7 @@ sub check_ssl_support ($) {
return;
}
- if ( ! $mysqld_variables->{'ssl'} )
+ if ( ! $mysqld_variables{'ssl'} )
{
if ( $opt_ssl)
{
@@ -2705,23 +2781,47 @@ sub check_ssl_support ($) {
$opt_ssl_supported= 1;
}
+sub check_debug_support {
+ if (defined $mysqld_variables{'debug-dbug'})
+ {
+ mtr_report(" - binaries are debug compiled");
+ }
+ elsif ($opt_debug_server)
+ {
+ mtr_error("Can't use --debug[-server], binary does not support it");
+ }
+}
-sub check_debug_support ($) {
- my $mysqld_variables= shift;
- if ( ! $mysqld_variables->{'debug'} )
- {
- #mtr_report(" - binaries are not debug compiled");
- $debug_compiled_binaries= 0;
+#
+# Helper function to find the correct value for the opt_vs_config
+# if it was not set explicitly.
+#
+# the configuration with the most recent build dir in sql/ is selected.
+#
+# note: looking for all BuildLog.htm files everywhere in the tree with the
+# help of File::Find would be possibly more precise, but it is also
+# many times slower. Thus we are only looking at the server, client
+# executables, and plugins - that is, something that can affect the test suite
+#
+sub fix_vs_config_dir () {
+ return $opt_vs_config="" unless IS_WINDOWS;
+ return $opt_vs_config="/$opt_vs_config" if $opt_vs_config;
- if ( $opt_debug_server )
+ my $modified = 1e30;
+ $opt_vs_config="";
+
+
+ for (<$bindir/sql/*/mysqld.exe>) {
+ if (-M $_ < $modified)
{
- mtr_error("Can't use --debug[-server], binary does not support it");
+ $modified = -M _;
+ $opt_vs_config = basename(dirname($_));
}
- return;
}
- mtr_report(" - binaries are debug compiled");
- $debug_compiled_binaries= 1;
+
+ mtr_report("VS config: $opt_vs_config");
+ $opt_vs_config="/$opt_vs_config" if $opt_vs_config;
}
@@ -2737,20 +2837,22 @@ sub vs_config_dirs ($$) {
my ($path_part, $exe) = @_;
$exe = "" if not defined $exe;
+
+ # Don't look in these dirs when not on windows
+ return () unless IS_WINDOWS;
+
if ($opt_vs_config)
{
- return ("$bindir/$path_part/$opt_vs_config/$exe");
+ return ("$basedir/$path_part/$opt_vs_config/$exe");
}
- return ("$bindir/$path_part/Release/$exe",
- "$bindir/$path_part/RelWithDebinfo/$exe",
- "$bindir/$path_part/Debug/$exe",
- "$bindir/$path_part/$exe");
+ return ("$basedir/$path_part/release/$exe",
+ "$basedir/$path_part/relwithdebinfo/$exe",
+ "$basedir/$path_part/debug/$exe");
}
-sub check_ndbcluster_support ($) {
- my $mysqld_variables= shift;
+sub check_ndbcluster_support {
# Check if this is MySQL Cluster, ie. mysql version string ends
# with -ndb-Y.Y.Y[-status]
@@ -2776,7 +2878,7 @@ sub check_ndbcluster_support ($) {
if ( ! $mysqld_variables{'ndb-connectstring'} )
{
- mtr_report(" - skipping ndbcluster, mysqld not compiled with ndbcluster");
+ #mtr_report(" - skipping ndbcluster, mysqld not compiled with ndbcluster");
$opt_skip_ndbcluster= 2;
return;
}
@@ -2787,7 +2889,7 @@ sub check_ndbcluster_support ($) {
}
-sub ndbcluster_wait_started($$){
+sub ndbcluster_wait_started {
my $cluster= shift;
my $ndb_waiter_extra_opt= shift;
my $path_waitlog= join('/', $opt_vardir, $cluster->name(), "ndb_waiter.log");
@@ -2944,7 +3046,7 @@ sub ndbd_stop {
# by sending "shutdown" to ndb_mgmd
}
-my $exe_ndbmtd_counter= 0;
+our $exe_ndbmtd_counter= 0;
sub ndbd_start {
my ($cluster, $ndbd)= @_;
@@ -2990,7 +3092,7 @@ sub ndbd_start {
sub ndbcluster_start ($) {
- my $cluster= shift;
+ my ($cluster) = @_;
mtr_verbose("ndbcluster_start '".$cluster->name()."'");
@@ -3010,6 +3112,110 @@ sub ndbcluster_start ($) {
}
+sub mysql_server_start($) {
+ my ($mysqld, $tinfo) = @_;
+
+ if ( $mysqld->{proc} )
+ {
+ # Already started
+
+ # Write start of testcase to log file
+ mark_log($mysqld->value('#log-error'), $tinfo);
+
+ return;
+ }
+
+ my $datadir= $mysqld->value('datadir');
+ if (not $opt_start_dirty)
+ {
+
+ my @options= ('log-bin', 'relay-log');
+ foreach my $option_name ( @options ) {
+ next unless $mysqld->option($option_name);
+
+ my $file_name= $mysqld->value($option_name);
+ next unless
+ defined $file_name and
+ -e $file_name;
+
+ mtr_debug(" -removing '$file_name'");
+ unlink($file_name) or die ("unable to remove file '$file_name'");
+ }
+
+ if (-d $datadir ) {
+ mtr_verbose(" - removing '$datadir'");
+ rmtree($datadir);
+ }
+ }
+
+ my $mysqld_basedir= $mysqld->value('basedir');
+ if ( $basedir eq $mysqld_basedir )
+ {
+ if (! $opt_start_dirty) # If dirty, keep possibly grown system db
+ {
+ # Copy datadir from installed system db
+ for my $path ( "$opt_vardir", "$opt_vardir/..") {
+ my $install_db= "$path/install.db";
+ copytree($install_db, $datadir)
+ if -d $install_db;
+ }
+ mtr_error("Failed to copy system db to '$datadir'")
+ unless -d $datadir;
+ }
+ }
+ else
+ {
+ mysql_install_db($mysqld); # For versional testing
+
+ mtr_error("Failed to install system db to '$datadir'")
+ unless -d $datadir;
+
+ }
+
+ # Create the servers tmpdir
+ my $tmpdir= $mysqld->value('tmpdir');
+ mkpath($tmpdir) unless -d $tmpdir;
+
+ # Write start of testcase to log file
+ mark_log($mysqld->value('#log-error'), $tinfo);
+
+ # Run <tname>-master.sh
+ if ($mysqld->option('#!run-master-sh') and
+ defined $tinfo->{master_sh} and
+ run_system('/bin/sh ' . $tinfo->{master_sh}) )
+ {
+ $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'";
+ return 1;
+ }
+
+ # Run <tname>-slave.sh
+ if ($mysqld->option('#!run-slave-sh') and
+ defined $tinfo->{slave_sh} and
+ run_system('/bin/sh ' . $tinfo->{slave_sh}))
+ {
+ $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'";
+ return 1;
+ }
+
+ if (!$opt_embedded_server)
+ {
+ my $extra_opts= get_extra_opts($mysqld, $tinfo);
+ mysqld_start($mysqld,$extra_opts);
+
+ # Save this test case information, so next can examine it
+ $mysqld->{'started_tinfo'}= $tinfo;
+ }
+}
+
+sub mysql_server_wait {
+ my ($mysqld) = @_;
+
+ return not sleep_until_file_created($mysqld->value('pid-file'),
+ $opt_start_timeout,
+ $mysqld->{'proc'},
+ $warn_seconds);
+}
+
sub create_config_file_for_extern {
my %opts=
(
@@ -3140,8 +3346,6 @@ sub initialize_servers {
{
remove_stale_vardir();
setup_vardir();
-
- mysql_install_db(default_mysqld(), "$opt_vardir/install.db");
}
}
}
@@ -3198,6 +3402,7 @@ sub sql_to_bootstrap {
sub default_mysqld {
# Generate new config file from template
+ environment_setup();
my $config= My::ConfigFactory->new_config
( {
basedir => $basedir,
@@ -3233,14 +3438,15 @@ sub mysql_install_db {
mtr_add_arg($args, "--bootstrap");
mtr_add_arg($args, "--basedir=%s", $install_basedir);
mtr_add_arg($args, "--datadir=%s", $install_datadir);
- mtr_add_arg($args, "--loose-skip-falcon");
- mtr_add_arg($args, "--loose-skip-ndbcluster");
+ mtr_add_arg($args, "--default-storage-engine=myisam");
+ mtr_add_arg($args, "--skip-$_") for @optional_plugins;
+ mtr_add_arg($args, "--disable-sync-frm");
mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/");
mtr_add_arg($args, "--core-file");
if ( $opt_debug )
{
- mtr_add_arg($args, "--debug=$debug_d:t:i:A,%s/log/bootstrap.trace",
+ mtr_add_arg($args, "--debug-dbug=$debug_d:t:i:A,%s/log/bootstrap.trace",
$path_vardir_trace);
}
@@ -3296,8 +3502,8 @@ sub mysql_install_db {
}
my $path_sql= my_find_file($install_basedir,
- ["mysql", "sql/share", "share/mysql",
- "share", "scripts"],
+ ["mysql", "sql/share", "share/mariadb",
+ "share/mysql", "share", "scripts"],
"mysql_system_tables.sql",
NOT_REQUIRED);
@@ -3392,6 +3598,26 @@ sub run_testcase_check_skip_test($)
my ($tinfo)= @_;
# ----------------------------------------------------------------------
+ # Skip some tests silently
+ # ----------------------------------------------------------------------
+
+ my $start_from= $mtr_cases::start_from;
+ if ( $start_from )
+ {
+ if ($tinfo->{'name'} eq $start_from ||
+ $tinfo->{'shortname'} eq $start_from)
+ {
+ ## Found parting test. Run this test and all tests after this one
+ $mtr_cases::start_from= "";
+ }
+ else
+ {
+ $tinfo->{'result'}= 'MTR_RES_SKIPPED';
+ return 1;
+ }
+ }
+
+ # ----------------------------------------------------------------------
# If marked to skip, just print out and return.
# Note that a test case not marked as 'skip' can still be
# skipped later, because of the test case itself in cooperation
@@ -3434,26 +3660,40 @@ sub run_query {
sub do_before_run_mysqltest($)
{
my $tinfo= shift;
+ my $resfile= $tinfo->{result_file};
+ return unless defined $resfile;
# Remove old files produced by mysqltest
- my $base_file= mtr_match_extension($tinfo->{result_file},
- "result"); # Trim extension
- if (defined $base_file ){
- unlink("$base_file.reject");
- unlink("$base_file.progress");
- unlink("$base_file.log");
- unlink("$base_file.warnings");
- }
-
- if ( $mysql_version_id < 50000 ) {
- # Set environment variable NDB_STATUS_OK to 1
- # if script decided to run mysqltest cluster _is_ installed ok
- $ENV{'NDB_STATUS_OK'} = "1";
- } elsif ( $mysql_version_id < 50100 ) {
- # Set environment variable NDB_STATUS_OK to YES
- # if script decided to run mysqltest cluster _is_ installed ok
- $ENV{'NDB_STATUS_OK'} = "YES";
+ die "unsupported result file name $resfile, stoping" unless
+ $resfile =~ /^(.*?)((?:,\w+)*)\.(rdiff|result|result~)$/;
+ my ($base_file, $suites, $ext)= ($1, $2, $3);
+ # if the result file is a diff, make a proper result file
+ if ($ext eq 'rdiff') {
+ my $base_result = $tinfo->{base_result};
+ my $resdir= dirname($resfile);
+ # we'll use a separate extension for generated result files
+ # to be able to distinguish them from manually created
+ # version-controlled results, and to ignore them in bzr.
+ my $dest = "$base_file$suites.result~";
+ my @cmd = ($exe_patch, qw/--binary -r - -f -s -o/,
+ $dest, $base_result, $resfile);
+ if (-w $resdir) {
+ # don't rebuild a file if it's up to date
+ unless (-e $dest and -M $dest < -M $resfile
+ and -M $dest < -M $base_result) {
+ run_system(@cmd);
+ }
+ } else {
+ $cmd[-3] = $dest = $opt_tmpdir . '/' . basename($dest);
+ run_system(@cmd);
+ }
+ $tinfo->{result_file} = $dest;
}
+
+ unlink("$base_file.reject");
+ unlink("$base_file.progress");
+ unlink("$base_file.log");
+ unlink("$base_file.warnings");
}
@@ -3550,9 +3790,13 @@ test case was executed:\n";
$result= 2;
}
-
- # Remove the .result file the check generated
- unlink("$base_file.result");
+ else
+ {
+ # Remove the .result file the check generated
+ unlink("$base_file.result");
+ }
+ # Remove the .err file the check generated
+ unlink($err_file);
}
}
@@ -3700,6 +3944,7 @@ sub run_on_all($$)
sub mark_log {
my ($log, $tinfo)= @_;
my $log_msg= "CURRENT_TEST: $tinfo->{name}\n";
+ pre_write_errorlog($log, $tinfo->{name});
mtr_tofile($log, $log_msg);
}
@@ -3754,36 +3999,89 @@ sub find_analyze_request
}
-# The test can leave a file in var/tmp/ to signal
-# that all servers should be restarted
-sub restart_forced_by_test($)
-{
- my $file = shift;
- my $restart = 0;
- foreach my $mysqld ( mysqlds() )
- {
- my $datadir = $mysqld->value('datadir');
- my $force_restart_file = "$datadir/mtr/$file";
- if ( -f $force_restart_file )
- {
- mtr_verbose("Restart of servers forced by test");
- $restart = 1;
- last;
+# Return timezone value of tinfo or default value
+sub timezone {
+ my ($tinfo)= @_;
+ local $_ = $tinfo->{timezone};
+ return 'DEFAULT' unless defined $_;
+ no warnings 'uninitialized';
+ s/\$\{(\w+)\}/$ENV{$1}/ge;
+ s/\$(\w+)/$ENV{$1}/ge;
+ $_;
+}
+
+sub mycnf_create {
+ my ($config) = @_;
+ my $res;
+
+ foreach my $group ($config->option_groups()) {
+ $res .= "[$group->{name}]\n";
+
+ foreach my $option ($group->options()) {
+ $res .= $option->name();
+ my $value= $option->value();
+ if (defined $value) {
+ $res .= "=$value";
+ }
+ $res .= "\n";
}
+ $res .= "\n";
}
- return $restart;
+ $res;
}
+sub config_files($) {
+ my ($tinfo) = @_;
+ (
+ 'my.cnf' => \&mycnf_create,
+ $tinfo->{suite}->config_files()
+ );
+}
-# Return timezone value of tinfo or default value
-sub timezone {
- my ($tinfo)= @_;
- return $tinfo->{timezone} || "GMT-3";
+sub _like { return $config ? $config->like($_[0]) : (); }
+sub mysqlds { return _like('mysqld\.'); }
+sub ndbds { return _like('cluster_config\.ndbd\.');}
+sub ndb_mgmds { return _like('cluster_config\.ndb_mgmd\.'); }
+
+sub fix_servers($) {
+ my ($tinfo) = @_;
+ return () unless $config;
+ my %servers = (
+ qr/mysqld\./ => {
+ SORT => 300,
+ START => \&mysql_server_start,
+ WAIT => \&mysql_server_wait,
+ },
+ qr/mysql_cluster\./ => {
+ SORT => 200,
+ START => \&ndbcluster_start,
+ WAIT => \&ndbcluster_wait_started,
+ },
+ qr/cluster_config\.ndb_mgmd\./ => {
+ SORT => 210,
+ START => undef,
+ },
+ qr/cluster_config\.ndbd\./ => {
+ SORT => 220,
+ START => undef,
+ },
+ $tinfo->{suite}->servers()
+ );
+ for ($config->groups()) {
+ while (my ($re,$prop) = each %servers) {
+ @$_{keys %$prop} = values %$prop if $_->{name} =~ /^$re/;
+ }
+ }
}
+sub all_servers {
+ return unless $config;
+ ( sort { $a->{SORT} <=> $b->{SORT} }
+ grep { defined $_->{SORT} } $config->groups() );
+}
# Storage for changed environment variables
-my %old_env;
+our %old_env;
sub resfile_report_test ($) {
my $tinfo= shift;
@@ -3805,8 +4103,8 @@ sub resfile_report_test ($) {
# > 0 failure
#
-sub run_testcase ($) {
- my $tinfo= shift;
+sub run_testcase ($$) {
+ my ($tinfo, $server_socket)= @_;
mtr_verbose("Running test:", $tinfo->{name});
resfile_report_test($tinfo) if $opt_resfile;
@@ -3814,7 +4112,7 @@ sub run_testcase ($) {
# Allow only alpanumerics pluss _ - + . in combination names,
# or anything beginning with -- (the latter comes from --combination)
my $combination= $tinfo->{combination};
- if ($combination && $combination !~ /^\w[-\w\.\+]+$/
+ if ($combination && $combination !~ /^\w[-\w\.\+]*$/
&& $combination !~ /^--/)
{
mtr_error("Combination '$combination' contains illegal characters");
@@ -3823,14 +4121,24 @@ sub run_testcase ($) {
# Init variables that can change between each test case
# -------------------------------------------------------
my $timezone= timezone($tinfo);
- $ENV{'TZ'}= $timezone;
+ if ($timezone ne 'DEFAULT') {
+ $ENV{'TZ'}= $timezone;
+ } else {
+ delete($ENV{'TZ'});
+ }
+ $ENV{MTR_SUITE_DIR} = $tinfo->{suite}->{dir};
mtr_verbose("Setting timezone: $timezone");
if ( ! using_extern() )
{
my @restart= servers_need_restart($tinfo);
if ( @restart != 0) {
- stop_servers($tinfo, @restart );
+ # Remember that we restarted for this test case (count restarts)
+ $tinfo->{'restarted'}= 1;
+ stop_servers(reverse @restart);
+ if ($opt_warnings) {
+ check_warnings_post_shutdown($server_socket);
+ }
}
if ( started(all_servers()) == 0 )
@@ -3857,6 +4165,7 @@ sub run_testcase ($) {
# Generate new config file from template
$config= My::ConfigFactory->new_config
( {
+ testname => $tinfo->{name},
basedir => $basedir,
testdir => $glob_mysql_test_dir,
template_path => $tinfo->{template_path},
@@ -3864,7 +4173,6 @@ sub run_testcase ($) {
vardir => $opt_vardir,
tmpdir => $opt_tmpdir,
baseport => $baseport,
- #hosts => [ 'host1', 'host2' ],
user => $opt_user,
password => '',
ssl => $opt_ssl_supported,
@@ -3872,8 +4180,17 @@ sub run_testcase ($) {
}
);
- # Write the new my.cnf
- $config->save($path_config_file);
+ fix_servers($tinfo);
+
+ # Write config files:
+ my %config_files = config_files($tinfo);
+ while (my ($file, $generate) = each %config_files) {
+ next unless $generate;
+ my ($path) = "$opt_vardir/$file";
+ open (F, '>', $path) or die "Could not open '$path': $!";
+ print F &$generate($config);
+ close F;
+ }
# Remember current config so a restart can occur when a test need
# to use a different one
@@ -3895,6 +4212,11 @@ sub run_testcase ($) {
# Write start of testcase to log
mark_log($path_current_testlog, $tinfo);
+ # Make sure the safe_process also exits from now on
+ if ($opt_start_exit) {
+ My::SafeProcess->start_exit();
+ }
+
if (start_servers($tinfo))
{
report_failure_and_restart($tinfo);
@@ -3963,7 +4285,7 @@ sub run_testcase ($) {
return 1;
}
- my $test= start_mysqltest($tinfo);
+ my $test= $tinfo->{suite}->start_test($tinfo);
# Set only when we have to keep waiting after expectedly died server
my $keep_waiting_proc = 0;
@@ -4021,16 +4343,23 @@ sub run_testcase ($) {
if ( $res == 0 )
{
my $check_res;
- if ( restart_forced_by_test('force_restart') )
- {
- stop_all_servers($opt_shutdown_timeout);
- }
- elsif ( $opt_check_testcases and
+ if ( $opt_check_testcases and
$check_res= check_testcase($tinfo, "after"))
{
if ($check_res == 1) {
# Test case had sideeffects, not fatal error, just continue
- stop_all_servers($opt_shutdown_timeout);
+ if ($opt_warnings) {
+ # Checking error logs for warnings, so need to stop server
+ # gracefully so that memory leaks etc. can be properly detected.
+ stop_servers(reverse all_servers());
+ check_warnings_post_shutdown($server_socket);
+ # Even if we got warnings here, we should not fail this
+ # particular test, as the warnings may be caused by an earlier
+ # test.
+ } else {
+ # Not checking warnings, so can do a hard shutdown.
+ stop_all_servers($opt_shutdown_timeout);
+ }
mtr_report("Resuming tests...\n");
resfile_output($tinfo->{'check'}) if $opt_resfile;
}
@@ -4050,8 +4379,7 @@ sub run_testcase ($) {
find_testcase_skipped_reason($tinfo);
mtr_report_test_skipped($tinfo);
# Restart if skipped due to missing perl, it may have had side effects
- if ( restart_forced_by_test('force_restart_if_skipped') ||
- $tinfo->{'comment'} =~ /^perl not found/ )
+ if ( $tinfo->{'comment'} =~ /^perl not found/ )
{
stop_all_servers($opt_shutdown_timeout);
}
@@ -4186,15 +4514,52 @@ sub run_testcase ($) {
}
+# Keep track of last position in mysqld error log where we scanned for
+# warnings, so we can attribute any warnings found to the correct test
+# suite or server restart.
+our $last_warning_position= { };
+
+# Called just before a mysqld server is started or a testcase is run,
+# to keep track of which tests have been run since last restart, and
+# of when the error log is reset.
+#
+# Second argument $test_name is test name, or undef for server restart.
+sub pre_write_errorlog {
+ my ($error_log, $test_name)= @_;
+
+ if (! -e $error_log) {
+ # If the error log is moved away, reset the warning parse position.
+ delete $last_warning_position->{$error_log};
+ }
+
+ if (defined($test_name)) {
+ $last_warning_position->{$error_log}{test_names}= []
+ unless exists($last_warning_position->{$error_log}{test_names});
+ push @{$last_warning_position->{$error_log}{test_names}}, $test_name;
+ } else {
+ # Server restart, so clear the list of tests run since last restart.
+ # (except the last one (if any), which is the test about to be run).
+ if (defined($last_warning_position->{$error_log}{test_names}) &&
+ @{$last_warning_position->{$error_log}{test_names}}) {
+ $last_warning_position->{$error_log}{test_names}=
+ [$last_warning_position->{$error_log}{test_names}[-1]];
+ } else {
+ $last_warning_position->{$error_log}{test_names}= [];
+ }
+ }
+}
+
# Extract server log from after the last occurrence of named test
# Return as an array of lines
#
sub extract_server_log ($$) {
my ($error_log, $tname) = @_;
+
+ return unless $error_log;
# Open the servers .err log file and read all lines
- # belonging to current tets into @lines
+ # belonging to current test into @lines
my $Ferr = IO::File->new($error_log)
or mtr_error("Could not open file '$error_log' for reading: $!");
@@ -4239,9 +4604,9 @@ sub get_log_from_proc ($$) {
my ($proc, $name)= @_;
my $srv_log= "";
- foreach my $mysqld (mysqlds()) {
+ foreach my $mysqld (all_servers()) {
if ($mysqld->{proc} eq $proc) {
- my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name);
+ my @srv_lines= extract_server_log($mysqld->if_exist('#log-error'), $name);
$srv_log= "\nServer log from this test:\n" .
"----------SERVER LOG START-----------\n". join ("", @srv_lines) .
"----------SERVER LOG END-------------\n";
@@ -4251,24 +4616,60 @@ sub get_log_from_proc ($$) {
return $srv_log;
}
+#
# Perform a rough examination of the servers
# error log and write all lines that look
# suspicious into $error_log.warnings
#
+
sub extract_warning_lines ($$) {
- my ($error_log, $tname) = @_;
+ my ($error_log, $append) = @_;
+
+ # Open the servers .err log file and read all lines
+ # belonging to current tets into @lines
+ my $Ferr = IO::File->new($error_log)
+ or return [];
+ my $last_pos= $last_warning_position->{$error_log}{seek_pos};
+ $Ferr->seek($last_pos, 0) if defined($last_pos);
+ # If the seek fails, we will parse the whole error log, at least we will not
+ # miss any warnings.
+
+ my @lines= <$Ferr>;
+ $last_warning_position->{$error_log}{seek_pos}= $Ferr->tell();
+ $Ferr = undef; # Close error log file
+
+ # mysql_client_test.test sends a COM_DEBUG packet to the server
+ # to provoke a safemalloc leak report, ignore any warnings
+ # between "Begin/end safemalloc memory dump"
+ if ( grep(/Begin safemalloc memory dump:/, @lines) > 0)
+ {
+ my $discard_lines= 1;
+ foreach my $line ( @lines )
+ {
+ if ($line =~ /Begin safemalloc memory dump:/){
+ $discard_lines = 1;
+ } elsif ($line =~ /End safemalloc memory dump./){
+ $discard_lines = 0;
+ }
- my @lines= extract_server_log($error_log, $tname);
+ if ($discard_lines){
+ $line = "ignored";
+ }
+ }
+ }
-# Write all suspicious lines to $error_log.warnings file
+ # Write all suspicious lines to $error_log.warnings file
my $warning_log = "$error_log.warnings";
- my $Fwarn = IO::File->new($warning_log, "w")
+ my $Fwarn = IO::File->new($warning_log, $append ? "a+" : "w")
or die("Could not open file '$warning_log' for writing: $!");
- print $Fwarn "Suspicious lines from $error_log\n";
+ if (!$append)
+ {
+ print $Fwarn "Suspicious lines from $error_log\n";
+ }
my @patterns =
(
- qr/^Warning:|mysqld: Warning|\[Warning\]/,
+ qr/^Warning|mysqld: Warning|\[Warning\]/,
qr/^Error:|\[ERROR\]/,
qr/^==\d+==\s+\S/, # valgrind errors
qr/InnoDB: Warning|InnoDB: Error/,
@@ -4277,50 +4678,87 @@ sub extract_warning_lines ($$) {
qr/Attempting backtrace/,
qr/Assertion .* failed/,
);
- my $skip_valgrind= 0;
-
- my $last_pat= "";
- my $num_rep= 0;
+ # These are taken from the include/mtr_warnings.sql global suppression
+ # list. They occur delayed, so they can be parsed during shutdown rather
+ # than during the per-test check.
+ #
+ # ToDo: having the warning suppressions inside the mysqld we are trying to
+ # check is in any case horrible. We should change it to all be done here
+ # within the Perl code, which is both simpler, easier, faster, and more
+ # robust. We could still have individual test cases put in suppressions by
+ # parsing statically or by writing dynamically to a CSV table read by the
+ # Perl code.
+ my @antipatterns =
+ (
+ qr/error .*connecting to master/,
+ qr/Plugin 'ndbcluster' will be forced to shutdown/,
+ qr/InnoDB: Error: in ALTER TABLE `test`.`t[12]`/,
+ qr/InnoDB: Error: table `test`.`t[12]` does not exist in the InnoDB internal/,
+ qr/InnoDB: Warning: a long semaphore wait:/,
+ qr/Slave: Unknown table 't1' Error_code: 1051/,
+ qr/Slave SQL:.*(Error_code: [[:digit:]]+|Query:.*)/,
+ qr/slave SQL thread aborted/,
+ qr/unknown option '--loose[-_]/,
+ qr/unknown variable 'loose[-_]/,
+ qr/Invalid .*old.* table or database name/,
+ qr/Now setting lower_case_table_names to [02]/,
+ qr/Setting lower_case_table_names=2/,
+ qr/You have forced lower_case_table_names to 0/,
+ qr/Plugin 'ndbcluster' will be forced to shutdow/,
+ qr/deprecated/,
+ qr/Slave SQL thread retried transaction/,
+ qr/Slave \(additional info\)/,
+ qr/Incorrect information in file/,
+ qr/Incorrect key file for table .*crashed.*/,
+ qr/Slave I\/O: Get master SERVER_ID failed with error:.*/,
+ qr/Slave I\/O: Get master clock failed with error:.*/,
+ qr/Slave I\/O: Get master COLLATION_SERVER failed with error:.*/,
+ qr/Slave I\/O: Get master TIME_ZONE failed with error:.*/,
+ qr/Slave I\/O: error reconnecting to master '.*' - retry-time: [1-3] retries/,
+ qr/Slave I\/0: Master command COM_BINLOG_DUMP failed/,
+ qr/Error reading packet/,
+ qr/Lost connection to MySQL server at 'reading initial communication packet'/,
+ qr/Failed on request_dump/,
+ qr/Slave: Can't drop database.* database doesn't exist/,
+ qr/Slave: Operation DROP USER failed for 'create_rout_db'/,
+ qr|Checking table: '\..mtr.test_suppressions'|,
+ qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|,
+ qr|Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|,
+ qr|Can't open shared library.*ha_archive|,
+ qr|InnoDB: Error: table 'test/bug39438'|,
+ qr| entry '.*' ignored in --skip-name-resolve mode|,
+ qr|mysqld got signal 6|,
+ qr|Error while setting value 'pool-of-threads' to 'thread_handling'|,
+ qr|Access denied for user|,
+ qr|Aborted connection|,
+ qr|table.*is full|,
+ );
- foreach my $line ( @lines )
+ my $matched_lines= [];
+ LINE: foreach my $line ( @lines )
{
- if ($opt_valgrind_mysqld) {
- # Skip valgrind summary from tests where server has been restarted
- # Should this contain memory leaks, the final report will find it
- # Use a generic pattern for summaries
- $skip_valgrind= 1 if $line =~ /^==\d+== [A-Z ]+ SUMMARY:/;
- $skip_valgrind= 0 unless $line =~ /^==\d+==/;
- next if $skip_valgrind;
- }
- foreach my $pat ( @patterns )
+ PAT: foreach my $pat ( @patterns )
{
if ( $line =~ /$pat/ )
{
- # Remove initial timestamp and look for consecutive identical lines
- my $line_pat= $line;
- $line_pat =~ s/^[0-9: ]*//;
- if ($line_pat eq $last_pat) {
- $num_rep++;
- } else {
- # Previous line had been repeated, report that first
- if ($num_rep) {
- print $Fwarn ".... repeated $num_rep times: $last_pat";
- $num_rep= 0;
- }
- $last_pat= $line_pat;
- print $Fwarn $line;
- }
- last;
+ foreach my $apat (@antipatterns)
+ {
+ next LINE if $line =~ $apat;
+ }
+ print $Fwarn $line;
+ push @$matched_lines, $line;
+ last PAT;
}
}
}
- # Catch the case of last warning being repeated
- if ($num_rep) {
- print $Fwarn ".... repeated $num_rep times: $last_pat";
- }
-
$Fwarn = undef; # Close file
+ if (scalar(@$matched_lines) > 0 &&
+ defined($last_warning_position->{$error_log}{test_names})) {
+ return ($last_warning_position->{$error_log}{test_names}, $matched_lines);
+ } else {
+ return ([], $matched_lines);
+ }
}
@@ -4339,7 +4777,7 @@ sub start_check_warnings ($$) {
my $log_error= $mysqld->value('#log-error');
# To be communicated to the test
$ENV{MTR_LOG_ERROR}= $log_error;
- extract_warning_lines($log_error, $tinfo->{name});
+ extract_warning_lines($log_error, 0);
my $args;
mtr_init_args(\$args);
@@ -4373,7 +4811,7 @@ sub start_check_warnings ($$) {
error => $errfile,
output => $errfile,
args => \$args,
- user_data => $errfile,
+ user_data => [$errfile, $mysqld],
verbose => $opt_verbose,
);
mtr_verbose("Started $proc");
@@ -4383,7 +4821,7 @@ sub start_check_warnings ($$) {
#
# Loop through our list of processes and check the error log
-# for unexepcted errors and warnings
+# for unexpected errors and warnings
#
sub check_warnings ($) {
my ($tinfo)= @_;
@@ -4419,7 +4857,7 @@ sub check_warnings ($) {
if ( delete $started{$proc->pid()} ) {
# One check warning process returned
my $res= $proc->exit_status();
- my $err_file= $proc->user_data();
+ my ($err_file, $mysqld)= @{$proc->user_data()};
if ( $res == 0 or $res == 62 ){
@@ -4453,7 +4891,8 @@ sub check_warnings ($) {
my $report= mtr_grab_file($err_file);
$tinfo->{comment}.=
"Could not execute 'check-warnings' for ".
- "testcase '$tname' (res: $res):\n";
+ "testcase '$tname' (res: $res) server: '".
+ $mysqld->name() .":\n";
$tinfo->{comment}.= $report;
$result= 2;
@@ -4482,6 +4921,28 @@ sub check_warnings ($) {
mtr_error("INTERNAL_ERROR: check_warnings");
}
+# Check for warnings generated during shutdown of a mysqld server.
+# If any, report them to master server, and return true; else just return
+# false.
+
+sub check_warnings_post_shutdown {
+ my ($server_socket)= @_;
+ my $testname_hash= { };
+ my $report= '';
+ foreach my $mysqld ( mysqlds())
+ {
+ my ($testlist, $match_lines)=
+ extract_warning_lines($mysqld->value('#log-error'), 1);
+ $testname_hash->{$_}= 1 for @$testlist;
+ $report.= join('', @$match_lines);
+ }
+ my @warning_tests= keys(%$testname_hash);
+ if (@warning_tests) {
+ my $fake_test= My::Test->new(testnames => \@warning_tests);
+ $fake_test->{'warnings'}= $report;
+ $fake_test->write_test($server_socket, 'WARNINGS');
+ }
+}
#
# Loop through our list of processes and look for and entry
@@ -4574,28 +5035,17 @@ sub clean_dir {
sub clean_datadir {
-
mtr_verbose("Cleaning datadirs...");
if (started(all_servers()) != 0){
mtr_error("Trying to clean datadir before all servers stopped");
}
- foreach my $cluster ( clusters() )
- {
- my $cluster_dir= "$opt_vardir/".$cluster->{name};
- mtr_verbose(" - removing '$cluster_dir'");
- rmtree($cluster_dir);
-
- }
-
- foreach my $mysqld ( mysqlds() )
+ for (all_servers())
{
- my $mysqld_dir= dirname($mysqld->value('datadir'));
- if (-d $mysqld_dir ) {
- mtr_verbose(" - removing '$mysqld_dir'");
- rmtree($mysqld_dir);
- }
+ my $dir= "$opt_vardir/".$_->{name};
+ mtr_verbose(" - removing '$dir'");
+ rmtree($dir);
}
# Remove all files in tmp and var/tmp
@@ -4618,17 +5068,6 @@ sub save_datadir_after_failure($$) {
}
-sub remove_ndbfs_from_ndbd_datadir {
- my ($ndbd_datadir)= @_;
- # Remove the ndb_*_fs directory from ndbd.X/ dir
- foreach my $ndbfs_dir ( glob("$ndbd_datadir/ndb_*_fs") )
- {
- next unless -d $ndbfs_dir; # Skip if not a directory
- rmtree($ndbfs_dir);
- }
-}
-
-
sub after_failure ($) {
my ($tinfo)= @_;
@@ -4637,39 +5076,39 @@ sub after_failure ($) {
my $save_dir= "$opt_vardir/log/";
$save_dir.= $tinfo->{name};
# Add combination name if any
- $save_dir.= "-$tinfo->{combination}"
- if defined $tinfo->{combination};
+ $save_dir.= '-' . join(',', sort @{$tinfo->{combinations}})
+ if defined $tinfo->{combinations};
# Save savedir path for server
$tinfo->{savedir}= $save_dir;
mkpath($save_dir) if ! -d $save_dir;
- # Save the used my.cnf file
- copy($path_config_file, $save_dir);
+ #
+ # Create a log of files in vardir (good for buildbot)
+ #
+ if (!IS_WINDOWS)
+ {
+ my $Flog= IO::File->new("$opt_vardir/log/files.log", "w");
+ if ($Flog)
+ {
+ print $Flog scalar(`/bin/ls -Rl $opt_vardir/*`);
+ close($Flog);
+ }
+ }
+
+ # Save the used config files
+ my %config_files = config_files($tinfo);
+ while (my ($file, $generate) = each %config_files) {
+ copy("$opt_vardir/$file", $save_dir);
+ }
# Copy the tmp dir
copytree("$opt_vardir/tmp/", "$save_dir/tmp/");
- if ( clusters() ) {
- foreach my $cluster ( clusters() ) {
- my $cluster_dir= "$opt_vardir/".$cluster->{name};
-
- # Remove the fileystem of each ndbd
- foreach my $ndbd ( in_cluster($cluster, ndbds()) )
- {
- my $ndbd_datadir= $ndbd->value("DataDir");
- remove_ndbfs_from_ndbd_datadir($ndbd_datadir);
- }
-
- save_datadir_after_failure($cluster_dir, $save_dir);
- }
- }
- else {
- foreach my $mysqld ( mysqlds() ) {
- my $data_dir= $mysqld->value('datadir');
- save_datadir_after_failure(dirname($data_dir), $save_dir);
- }
+ foreach (all_servers()) {
+ my $dir= "$opt_vardir/".$_->{name};
+ save_datadir_after_failure($dir, $save_dir);
}
}
@@ -4740,13 +5179,9 @@ sub report_failure_and_restart ($) {
}
-sub run_sh_script {
- my ($script)= @_;
-
- return 0 unless defined $script;
-
- mtr_verbose("Running '$script'");
- my $ret= system("/bin/sh $script") >> 8;
+sub run_system(@) {
+ mtr_verbose("Running '$_[0]'");
+ my $ret= system(@_) >> 8;
return $ret;
}
@@ -4773,7 +5208,7 @@ sub mysqld_stop {
name => "mysqladmin shutdown ".$mysqld->name(),
path => $exe_mysqladmin,
args => \$args,
- error => "/dev/null",
+ error => "$opt_vardir/log/mysqladmin.err",
);
}
@@ -4800,14 +5235,6 @@ sub mysqld_arguments ($$$) {
mtr_add_arg($args, "--user=root");
}
- if ( $opt_valgrind_mysqld )
- {
- if ( $mysql_version_id < 50100 )
- {
- mtr_add_arg($args, "--skip-bdb");
- }
- }
-
# On some old linux kernels, aio on tmpfs is not supported
# Remove this if/when Bug #58421 fixes this in the server
if ($^O eq "linux" && $opt_mem)
@@ -4815,14 +5242,14 @@ sub mysqld_arguments ($$$) {
mtr_add_arg($args, "--loose-skip-innodb-use-native-aio");
}
- if ( $mysql_version_id >= 50106 && !$opt_user_args)
+ if (!using_extern() and !$opt_user_args)
{
# Turn on logging to file
- mtr_add_arg($args, "--log-output=file");
+ mtr_add_arg($args, "%s--log-output=file");
}
- # Check if "extra_opt" contains skip-log-bin
- my $skip_binlog= grep(/^(--|--loose-)skip-log-bin/, @$extra_opts);
+ # Check if "extra_opt" contains --log-bin
+ my $skip_binlog= not grep /^--(loose-)?log-bin/, @$extra_opts;
# Indicate to mysqld it will be debugged in debugger
if ( $glob_debugger )
@@ -4831,6 +5258,9 @@ sub mysqld_arguments ($$$) {
}
my $found_skip_core= 0;
+ my @plugins;
+ my %seen;
+ my $plugin;
foreach my $arg ( @$extra_opts )
{
# Skip --defaults-file option since it's handled above.
@@ -4850,10 +5280,10 @@ sub mysqld_arguments ($$$) {
{
; # Dont add --skip-log-bin when mysqld have --log-slave-updates in config
}
- elsif ($arg eq "")
+ elsif ($plugin = mtr_match_prefix($arg, "--plugin-load="))
{
- # We can get an empty argument when we set environment variables to ""
- # (e.g plugin not found). Just skip it.
+ push @plugins, $plugin unless $seen{$plugin};
+ $seen{$plugin} = 1;
}
else
{
@@ -4871,6 +5301,11 @@ sub mysqld_arguments ($$$) {
mtr_add_arg($args, "--loose-debug-sync-timeout=%s",
$opt_debug_sync_timeout) unless $opt_user_args;
+ if (@plugins) {
+ my $sep = (IS_WINDOWS) ? ';' : ':';
+ mtr_add_arg($args, "--plugin-load=%s" . join($sep, @plugins));
+ }
+
return $args;
}
@@ -4890,17 +5325,15 @@ sub mysqld_start ($$) {
my $args;
mtr_init_args(\$args);
-# implementation for strace-server
- if ( $opt_strace_server )
- {
- strace_server_arguments($args, \$exe, $mysqld->name());
- }
-
if ( $opt_valgrind_mysqld )
{
valgrind_arguments($args, \$exe);
}
+ if ( $opt_strace)
+ {
+ strace_arguments($args, \$exe, $mysqld->name());
+ }
mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
@@ -4915,14 +5348,16 @@ sub mysqld_start ($$) {
if ( $opt_debug )
{
- mtr_add_arg($args, "--debug=$debug_d:t:i:A,%s/log/%s.trace",
+ mtr_add_arg($args, "--debug-dbug=$debug_d:t:i:A,%s/log/%s.trace",
$path_vardir_trace, $mysqld->name());
}
if (IS_WINDOWS)
{
# Trick the server to send output to stderr, with --console
- mtr_add_arg($args, "--console");
+ if (!(grep(/^--log-error/, @$args))) {
+ mtr_add_arg($args, "--console");
+ }
}
if ( $opt_gdb || $opt_manual_gdb )
@@ -4933,7 +5368,7 @@ sub mysqld_start ($$) {
{
ddd_arguments(\$args, \$exe, $mysqld->name());
}
- if ( $opt_dbx || $opt_manual_dbx ) {
+ elsif ( $opt_dbx || $opt_manual_dbx ) {
dbx_arguments(\$args, \$exe, $mysqld->name());
}
elsif ( $opt_debugger )
@@ -4961,6 +5396,24 @@ sub mysqld_start ($$) {
unlink($mysqld->value('pid-file'));
my $output= $mysqld->value('#log-error');
+
+ if ( $opt_valgrind and $opt_debug )
+ {
+ # When both --valgrind and --debug is selected, send
+ # all output to the trace file, making it possible to
+ # see the exact location where valgrind complains
+
+ # Write a message about this to the normal log file
+ my $trace_name= "$opt_vardir/log/".$mysqld->name().".trace";
+ mtr_tofile($output,
+ "NOTE: When running with --valgrind --debug the output from ",
+ "mysqld (where the valgrind messages shows up) is stored ",
+ "together with the trace file to make it ",
+ "easier to find the exact position of valgrind errors.",
+ "See trace file $trace_name.\n");
+ $output= $trace_name;
+
+ }
# Remember this log file for valgrind error report search
$mysqld_logs{$output}= 1 if $opt_valgrind;
# Remember data dir for gmon.out files if using gprof
@@ -4968,6 +5421,7 @@ sub mysqld_start ($$) {
if ( defined $exe )
{
+ pre_write_errorlog($output);
$mysqld->{'proc'}= My::SafeProcess->new
(
name => $mysqld->name(),
@@ -4988,7 +5442,8 @@ sub mysqld_start ($$) {
if ( $wait_for_pid_file &&
!sleep_until_file_created($mysqld->value('pid-file'),
$opt_start_timeout,
- $mysqld->{'proc'}))
+ $mysqld->{'proc'},
+ $warn_seconds))
{
my $mname= $mysqld->name();
mtr_error("Failed to start mysqld $mname with command $exe");
@@ -5033,11 +5488,6 @@ sub server_need_restart {
return 0;
}
- if ( $tinfo->{'force_restart'} ) {
- mtr_verbose_restart($server, "forced in .opt file");
- return 1;
- }
-
if ( $opt_force_restart ) {
mtr_verbose_restart($server, "forced restart turned on");
return 1;
@@ -5074,8 +5524,7 @@ sub server_need_restart {
}
}
- my $is_mysqld= grep ($server eq $_, mysqlds());
- if ($is_mysqld)
+ if ($server->name() =~ /^mysqld\./)
{
# Check that running process was started with same options
@@ -5130,17 +5579,9 @@ sub servers_need_restart($) {
-#
-# Return list of specific servers
-# - there is no servers in an empty config
-#
-sub _like { return $config ? $config->like($_[0]) : (); }
-sub mysqlds { return _like('mysqld.'); }
-sub ndbds { return _like('cluster_config.ndbd.');}
-sub ndb_mgmds { return _like('cluster_config.ndb_mgmd.'); }
-sub clusters { return _like('mysql_cluster.'); }
-sub all_servers { return ( mysqlds(), ndb_mgmds(), ndbds() ); }
+############################################
+############################################
#
# Filter a list of servers and return only those that are part
@@ -5162,18 +5603,6 @@ sub started { return grep(defined $_, map($_->{proc}, @_)); }
sub stopped { return grep(!defined $_, map($_->{proc}, @_)); }
-sub envsubst {
- my $string= shift;
-
- if ( ! defined $ENV{$string} )
- {
- mtr_error(".opt file references '$string' which is not set");
- }
-
- return $ENV{$string};
-}
-
-
sub get_extra_opts {
# No extra options if --user-args
return \@opt_extra_mysqld_opt if $opt_user_args;
@@ -5187,41 +5616,21 @@ sub get_extra_opts {
# Expand environment variables
foreach my $opt ( @$opts )
{
- $opt =~ s/\$\{(\w+)\}/envsubst($1)/ge;
- $opt =~ s/\$(\w+)/envsubst($1)/ge;
+ no warnings 'uninitialized';
+ $opt =~ s/\$\{(\w+)\}/$ENV{$1}/ge;
+ $opt =~ s/\$(\w+)/$ENV{$1}/ge;
}
return $opts;
}
sub stop_servers($$) {
- my ($tinfo, @servers)= @_;
-
- # Remember if we restarted for this test case (count restarts)
- $tinfo->{'restarted'}= 1;
-
- if ( join('|', @servers) eq join('|', all_servers()) )
- {
- # All servers are going down, use some kind of order to
- # avoid too many warnings in the log files
+ my (@servers)= @_;
- mtr_report("Restarting all servers");
+ mtr_report("Restarting ", started(@servers));
- # mysqld processes
- My::SafeProcess::shutdown( $opt_shutdown_timeout, started(mysqlds()) );
-
- # cluster processes
- My::SafeProcess::shutdown( $opt_shutdown_timeout,
- started(ndbds(), ndb_mgmds()) );
- }
- else
- {
- mtr_report("Restarting ", started(@servers));
-
- # Stop only some servers
- My::SafeProcess::shutdown( $opt_shutdown_timeout,
- started(@servers) );
- }
+ My::SafeProcess::shutdown($opt_shutdown_timeout,
+ started(@servers));
foreach my $server (@servers)
{
@@ -5248,149 +5657,14 @@ sub stop_servers($$) {
sub start_servers($) {
my ($tinfo)= @_;
- # Make sure the safe_process also exits from now on
- # Could not be done before, as we don't want this for the bootstrap
- if ($opt_start_exit) {
- My::SafeProcess->start_exit();
- }
-
- # Start clusters
- foreach my $cluster ( clusters() )
- {
- ndbcluster_start($cluster);
- }
-
- # Start mysqlds
- foreach my $mysqld ( mysqlds() )
- {
- if ( $mysqld->{proc} )
- {
- # Already started
-
- # Write start of testcase to log file
- mark_log($mysqld->value('#log-error'), $tinfo);
-
- next;
- }
-
- my $datadir= $mysqld->value('datadir');
- if ($opt_start_dirty)
- {
- # Don't delete anything if starting dirty
- ;
- }
- else
- {
-
- my @options= ('log-bin', 'relay-log');
- foreach my $option_name ( @options ) {
- next unless $mysqld->option($option_name);
-
- my $file_name= $mysqld->value($option_name);
- next unless
- defined $file_name and
- -e $file_name;
-
- mtr_debug(" -removing '$file_name'");
- unlink($file_name) or die ("unable to remove file '$file_name'");
- }
-
- if (-d $datadir ) {
- mtr_verbose(" - removing '$datadir'");
- rmtree($datadir);
- }
- }
-
- my $mysqld_basedir= $mysqld->value('basedir');
- if ( $basedir eq $mysqld_basedir )
- {
- if (! $opt_start_dirty) # If dirty, keep possibly grown system db
- {
- # Copy datadir from installed system db
- for my $path ( "$opt_vardir", "$opt_vardir/..") {
- my $install_db= "$path/install.db";
- copytree($install_db, $datadir)
- if -d $install_db;
- }
- mtr_error("Failed to copy system db to '$datadir'")
- unless -d $datadir;
- }
- }
- else
- {
- mysql_install_db($mysqld); # For versional testing
-
- mtr_error("Failed to install system db to '$datadir'")
- unless -d $datadir;
-
- }
-
- # Create the servers tmpdir
- my $tmpdir= $mysqld->value('tmpdir');
- mkpath($tmpdir) unless -d $tmpdir;
-
- # Write start of testcase to log file
- mark_log($mysqld->value('#log-error'), $tinfo);
-
- # Run <tname>-master.sh
- if ($mysqld->option('#!run-master-sh') and
- run_sh_script($tinfo->{master_sh}) )
- {
- $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'";
- return 1;
- }
-
- # Run <tname>-slave.sh
- if ($mysqld->option('#!run-slave-sh') and
- run_sh_script($tinfo->{slave_sh}))
- {
- $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'";
- return 1;
- }
-
- if (!$opt_embedded_server)
- {
- my $extra_opts= get_extra_opts($mysqld, $tinfo);
- mysqld_start($mysqld,$extra_opts);
-
- # Save this test case information, so next can examine it
- $mysqld->{'started_tinfo'}= $tinfo;
- }
-
- }
-
- # Wait for clusters to start
- foreach my $cluster ( clusters() )
- {
- if (ndbcluster_wait_started($cluster, ""))
- {
- # failed to start
- $tinfo->{'comment'}= "Start of '".$cluster->name()."' cluster failed";
- return 1;
- }
+ for (all_servers()) {
+ $_->{START}->($_, $tinfo) if $_->{START};
}
- # Wait for mysqlds to start
- foreach my $mysqld ( mysqlds() )
- {
- next if !started($mysqld);
-
- if (sleep_until_file_created($mysqld->value('pid-file'),
- $opt_start_timeout,
- $mysqld->{'proc'}) == 0) {
- $tinfo->{comment}=
- "Failed to start ".$mysqld->name();
-
- my $logfile= $mysqld->value('#log-error');
- if ( defined $logfile and -f $logfile )
- {
- my @srv_lines= extract_server_log($logfile, $tinfo->{name});
- $tinfo->{logfile}= "Server log is:\n" . join ("", @srv_lines);
- }
- else
- {
- $tinfo->{logfile}= "Could not open server logfile: '$logfile'";
- }
+ for (all_servers()) {
+ next unless $_->{WAIT} and started($_);
+ if ($_->{WAIT}->($_)) {
+ $tinfo->{comment}= "Failed to start ".$_->name() . "\n";
return 1;
}
}
@@ -5461,23 +5735,11 @@ sub start_mysqltest ($) {
mtr_init_args(\$args);
- if ( $opt_strace_client )
- {
- $exe= "strace";
- mtr_add_arg($args, "-o");
- mtr_add_arg($args, "%s/log/mysqltest.strace", $opt_vardir);
- mtr_add_arg($args, "$exe_mysqltest");
- }
-
mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
mtr_add_arg($args, "--silent");
mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
mtr_add_arg($args, "--logdir=%s/log", $opt_vardir);
- if ($auth_plugin)
- {
- mtr_add_arg($args, "--plugin_dir=%s", dirname($auth_plugin));
- }
# Log line number and time for each line in .test file
mtr_add_arg($args, "--mark-progress")
@@ -5505,6 +5767,18 @@ sub start_mysqltest ($) {
mtr_add_arg($args, "--cursor-protocol");
}
+ if ( $opt_non_blocking_api )
+ {
+ mtr_add_arg($args, "--non-blocking-api");
+ }
+
+ if ( $opt_strace_client )
+ {
+ $exe= $opt_strace_client || "strace";
+ mtr_add_arg($args, "-o");
+ mtr_add_arg($args, "%s/log/mysqltest.strace", $opt_vardir);
+ mtr_add_arg($args, "$exe_mysqltest");
+ }
mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir);
@@ -5547,7 +5821,9 @@ sub start_mysqltest ($) {
if (IS_WINDOWS)
{
# Trick the server to send output to stderr, with --console
- mtr_add_arg($args, "--server-arg=--console");
+ if (!(grep(/^--server-arg=--log-error/, @$args))) {
+ mtr_add_arg($args, "--server-arg=--console");
+ }
}
}
@@ -5570,6 +5846,14 @@ sub start_mysqltest ($) {
mtr_add_arg($args, "%s", $_) for @args_saved;
}
+ my $suite = $tinfo->{suite};
+ if ($suite->{parent}) {
+ mtr_add_arg($args, "--overlay-dir=%s/", $suite->{dir});
+ mtr_add_arg($args, "--suite-dir=%s/", $suite->{parent}->{dir});
+ } else {
+ mtr_add_arg($args, "--suite-dir=%s/", $suite->{dir});
+ }
+
mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
# Number of lines of resut to include in failure report
@@ -5638,12 +5922,10 @@ sub gdb_arguments {
# Put $args into a single string
my $str= join(" ", @$$args);
- my $runline= $input ? "run $str < $input" : "run $str";
+ $input = $input ? "< $input" : "";
# write init file for mysqld or client
- mtr_tofile($gdb_init_file,
- "break main\n" .
- $runline);
+ mtr_tofile($gdb_init_file, "set args $str $input\n");
if ( $opt_manual_gdb )
{
@@ -5691,13 +5973,10 @@ sub ddd_arguments {
# Put $args into a single string
my $str= join(" ", @$$args);
- my $runline= $input ? "run $str < $input" : "run $str";
+ $input = $input ? "< $input" : "";
# write init file for mysqld or client
- mtr_tofile($gdb_init_file,
- "file $$exe\n" .
- "break main\n" .
- $runline);
+ mtr_tofile($gdb_init_file, "file $$exe\nset args $str $input\n");
if ( $opt_manual_ddd )
{
@@ -5805,19 +6084,6 @@ sub debugger_arguments {
}
}
-#
-# Modify the exe and args so that program is run in strace
-#
-sub strace_server_arguments {
- my $args= shift;
- my $exe= shift;
- my $type= shift;
-
- mtr_add_arg($args, "-o");
- mtr_add_arg($args, "%s/log/%s.strace", $opt_vardir, $type);
- mtr_add_arg($args, $$exe);
- $$exe= "strace";
-}
#
# Modify the exe and args so that program is run in valgrind
@@ -5857,9 +6123,35 @@ sub valgrind_arguments {
}
#
-# Search server logs for valgrind reports printed at mysqld termination
+# Modify the exe and args so that program is run in strace
#
+sub strace_arguments {
+ my $args= shift;
+ my $exe= shift;
+ my $mysqld_name= shift;
+
+ mtr_add_arg($args, "-f");
+ mtr_add_arg($args, "-o%s/var/log/%s.strace", $glob_mysql_test_dir, $mysqld_name);
+
+ # Add strace options, can be overriden by user
+ mtr_add_arg($args, '%s', $_) for (@strace_args);
+
+ mtr_add_arg($args, $$exe);
+ $$exe= "strace";
+
+ if ($exe_libtool)
+ {
+ # Add "libtool --mode-execute" before the test to execute
+ # if running in valgrind(to avoid valgrinding bash)
+ unshift(@$args, "--mode=execute", $$exe);
+ $$exe= $exe_libtool;
+ }
+}
+
+#
+# Search server logs for valgrind reports printed at mysqld termination
+#
sub valgrind_exit_reports() {
my $found_err= 0;
@@ -5923,78 +6215,6 @@ sub valgrind_exit_reports() {
return $found_err;
}
-sub run_ctest() {
- my $olddir= getcwd();
- chdir ($bindir) or die ("Could not chdir to $bindir");
- my $tinfo;
- my $no_ctest= (IS_WINDOWS) ? 256 : -1;
- my $ctest_vs= "";
-
- # Just ignore if not configured/built to run ctest
- if (! -f "CTestTestfile.cmake") {
- chdir($olddir);
- return;
- }
-
- # Add vs-config option if needed
- $ctest_vs= "-C $opt_vs_config" if $opt_vs_config;
-
- # Also silently ignore if we don't have ctest and didn't insist
- # Special override: also ignore in Pushbuild, some platforms may not have it
- # Now, run ctest and collect output
- my $ctest_out= `ctest $ctest_vs 2>&1`;
- if ($? == $no_ctest && $opt_ctest == -1 && ! defined $ENV{PB2WORKDIR}) {
- chdir($olddir);
- return;
- }
-
- # Create minimalistic "test" for the reporting
- $tinfo = My::Test->new
- (
- name => 'unit_tests',
- );
- # Set dummy worker id to align report with normal tests
- $tinfo->{worker} = 0 if $opt_parallel > 1;
-
- my $ctfail= 0; # Did ctest fail?
- if ($?) {
- $ctfail= 1;
- $tinfo->{result}= 'MTR_RES_FAILED';
- $tinfo->{comment}= "ctest failed with exit code $?, see result below";
- $ctest_out= "" unless $ctest_out;
- }
- my $ctfile= "$opt_vardir/ctest.log";
- my $ctres= 0; # Did ctest produce report summary?
-
- open (CTEST, " > $ctfile") or die ("Could not open output file $ctfile");
-
- # Put ctest output in log file, while analyzing results
- for (split ('\n', $ctest_out)) {
- print CTEST "$_\n";
- if (/tests passed/) {
- $ctres= 1;
- $ctest_report .= "\nUnit tests: $_\n";
- }
- if ( /FAILED/ or /\(Failed\)/ ) {
- $ctfail= 1;
- $ctest_report .= " $_\n";
- }
- }
- close CTEST;
-
- # Set needed 'attributes' for test reporting
- $tinfo->{comment}.= "\nctest did not pruduce report summary" if ! $ctres;
- $tinfo->{result}= ($ctres && !$ctfail)
- ? 'MTR_RES_PASSED' : 'MTR_RES_FAILED';
- $ctest_report .= "Report from unit tests in $ctfile";
- $tinfo->{failures}= ($tinfo->{result} eq 'MTR_RES_FAILED');
-
- mark_time_used('test');
- mtr_report_test($tinfo);
- chdir($olddir);
- return $tinfo;
-}
-
#
# Usage
#
@@ -6004,6 +6224,8 @@ sub usage ($) {
if ( $message )
{
print STDERR "$message\n";
+ print STDERR "For full list of options, use $0 --help\n";
+ exit;
}
print <<HERE;
@@ -6018,17 +6240,18 @@ Options to control what engine/variation to run
(implies --ps-protocol)
view-protocol Create a view to execute all non updating queries
sp-protocol Create a stored procedure to execute all queries
+ non-blocking-api Use the non-blocking client API
compress Use the compressed protocol between client and server
ssl Use ssl protocol between client and server
skip-ssl Dont start server with support for ssl connections
vs-config Visual Studio configuration used to create executables
(default: MTR_VS_CONFIG environment variable)
-
+ parallel=# How many parallell test should be run
defaults-file=<config template> Use fixed config template for all
tests
defaults-extra-file=<config template> Extra config template to add to
all generated configs
- combination=<opt> Use at least twice to run tests with specified
+ combination=<opt> Use at least twice to run tests with specified
options to mysqld
skip-combinations Ignore combination file (or options)
@@ -6069,7 +6292,10 @@ Options to control what test suites or cases to run
list of suite names.
The default is: "$DEFAULT_SUITES"
skip-rpl Skip the replication test cases.
- big-test Also run tests marked as "big"
+ big-test Also run tests marked as "big". Repeat this option
+ twice to run only "big" tests.
+ staging-run Run a limited number of tests (no slow tests). Used
+ for running staging trees with valgrind.
enable-disabled Run also tests marked as disabled
print-testcases Don't run the tests but print details about all the
selected tests, in the order they would be run.
@@ -6134,8 +6360,6 @@ Options for debugging the product
test(s)
manual-dbx Let user manually start mysqld in dbx, before running
test(s)
- strace-client Create strace output for mysqltest client,
- strace-server Create strace output for mysqltest server,
max-save-core Limit the number of core files saved (to avoid filling
up disks for heavily crashing server). Defaults to
$opt_max_save_core, set to 0 for no limit. Set
@@ -6143,7 +6367,7 @@ Options for debugging the product
max-save-datadir Limit the number of datadir saved (to avoid filling
up disks for heavily crashing server). Defaults to
$opt_max_save_datadir, set to 0 for no limit. Set
- it's default with MTR_MAX_SAVE_DATDIR
+ it's default with MTR_MAX_SAVE_DATADIR
max-test-fail Limit the number of test failurs before aborting
the current test run. Defaults to
$opt_max_test_fail, set to 0 for no limit. Set
@@ -6163,6 +6387,15 @@ Options for valgrind
valgrind-path=<EXE> Path to the valgrind executable
callgrind Instruct valgrind to use callgrind
+Options for strace
+
+ strace Run the "mysqld" executables using strace. Default
+ options are -f -o var/log/'mysqld-name'.strace
+ strace-option=ARGS Option to give strace, replaces default option(s),
+ strace-client=[path] Create strace output for mysqltest client, optionally
+ specifying name and path to the trace program to use.
+ Example: $0 --strace-client=ktrace
+
Misc options
user=USER User for connecting to mysqld(default: $opt_user)
comment=STR Write STR to the output
@@ -6185,12 +6418,15 @@ Misc options
fast Run as fast as possible, dont't wait for servers
to shutdown etc.
force-restart Always restart servers between tests
- parallel=N Run tests in N parallel threads (default=1)
+ parallel=N Run tests in N parallel threads (default 1)
Use parallel=auto for auto-setting of N
repeat=N Run each test N number of times
- retry=N Retry tests that fail N times, limit number of failures
- to $opt_retry_failure
- retry-failure=N Limit number of retries for a failed test
+ retry=N Retry tests that fail up to N times (default $opt_retry).
+ Retries are also limited by the maximum number of
+ failures before stopping, set with the --retry-failure
+ option
+ retry-failure=N When using the --retry option to retry failed tests,
+ stop when N failures have occured (default $opt_retry_failure)
reorder Reorder tests to get fewer server restarts
help Get this help text
@@ -6201,11 +6437,22 @@ Misc options
warnings Scan the log files for warnings. Use --nowarnings
to turn off.
+ stop-file=file (also MTR_STOP_FILE environment variable) if this
+ file detected mysql test will not start new tests
+ until the file will be removed.
+ stop-keep-alive=sec (also MTR_STOP_KEEP_ALIVE environment variable)
+ works with stop-file, print messages every sec
+ seconds when mysql test is waiting to removing
+ the file (for buildbot)
+
sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time
debug-sync-timeout=NUM Set default timeout for WAIT_FOR debug sync
actions. Disable facility with NUM=0.
gcov Collect coverage information after the test.
The result is a gcov file per source and header file.
+ gcov-src-dir=subdir Colllect coverage only within the given subdirectory.
+ For example, if you're only developing the SQL layer,
+ it makes sense to use --gcov-src-dir=sql
gprof Collect profiling information using gprof.
experimental=<file> Refer to list of tests considered experimental;
failures will be marked exp-fail instead of fail.
@@ -6219,9 +6466,6 @@ Misc options
engine to InnoDB.
report-times Report how much time has been spent on different
phases of test execution.
- nounit-tests Do not run unit tests. Normally run if configured
- and if not running named tests/suites
- unit-tests Run unit tests even if they would otherwise not be run
stress=ARGS Run stress test, providing options to
mysql-stress-test.pl. Options are separated by comma.
@@ -6240,9 +6484,30 @@ sub list_options ($) {
for (keys %$hash) {
s/([:=].*|[+!])$//;
s/\|/\n--/g;
- print "--$_\n" unless /list-options/;
+ print "--$_\n";
}
exit(1);
}
+sub time_format($) {
+ sprintf '%d:%02d:%02d', $_[0]/3600, ($_[0]/60)%60, $_[0]%60;
+}
+
+our $num_tests;
+
+sub xterm_stat {
+ if (-t STDOUT and defined $ENV{TERM} and $ENV{TERM} =~ /xterm/) {
+ my ($left) = @_;
+
+ # 2.5 -> best by test
+ $num_tests = $left + 2.5 unless $num_tests;
+
+ my $done = $num_tests - $left;
+ my $spent = time - $^T;
+
+ printf "\e];mtr: spent %s on %d tests. %s (%d tests) left\a",
+ time_format($spent), $done,
+ time_format($spent/$done * $left), $left;
+ }
+}