summaryrefslogtreecommitdiff
path: root/mysql-test/lib
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/lib')
-rw-r--r--mysql-test/lib/My/Config.pm131
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm68
-rw-r--r--mysql-test/lib/My/File/Path.pm2
-rw-r--r--mysql-test/lib/My/SafeProcess.pm16
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.cc47
-rw-r--r--mysql-test/lib/My/Suite.pm10
-rw-r--r--mysql-test/lib/My/Test.pm81
-rw-r--r--mysql-test/lib/mtr_cases.pm392
-rw-r--r--mysql-test/lib/mtr_gcov.pl6
-rw-r--r--mysql-test/lib/mtr_misc.pl20
-rw-r--r--mysql-test/lib/mtr_report.pm38
-rwxr-xr-xmysql-test/lib/process-purecov-annotations.pl63
-rw-r--r--mysql-test/lib/v1/mtr_process.pl40
-rw-r--r--mysql-test/lib/v1/mtr_report.pl25
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl171
15 files changed, 627 insertions, 483 deletions
diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm
index 315e415e219..bf6629754a1 100644
--- a/mysql-test/lib/My/Config.pm
+++ b/mysql-test/lib/My/Config.pm
@@ -6,7 +6,6 @@ use strict;
use warnings;
use Carp;
-
sub new {
my ($class, $option_name, $option_value)= @_;
my $self= bless { name => $option_name,
@@ -61,7 +60,7 @@ sub insert {
$option->{value}= $value;
}
else {
- my $option= My::Config::Option->new($option_name, $value);
+ $option= My::Config::Option->new($option_name, $value);
# Insert option in list
push(@{$self->{options}}, $option);
# Insert option in hash
@@ -163,6 +162,62 @@ sub if_exist {
return $option->value();
}
+package My::Config::Group::ENV;
+our @ISA=qw(My::Config::Group);
+
+use strict;
+use warnings;
+use Carp;
+
+sub new {
+ my ($class, $group_name)= @_;
+ bless My::Config::Group->new($group_name), $class;
+}
+
+#
+# Return value for an option in the group, fail if it does not exist
+#
+sub value {
+ my ($self, $option_name)= @_;
+ my $option= $self->option($option_name);
+
+ if (! defined($option) and defined $ENV{$option_name}) {
+ my $value= $ENV{$option_name};
+ $option= My::Config::Option->new($option_name, $value);
+ }
+
+ croak "No option named '$option_name' in group '$self->{name}'"
+ if ! defined($option);
+
+ return $option->value();
+}
+
+package My::Config::Group::OPT;
+our @ISA=qw(My::Config::Group);
+
+use strict;
+use warnings;
+use Carp;
+
+sub new {
+ my ($class, $group_name)= @_;
+ bless My::Config::Group->new($group_name), $class;
+}
+
+sub options {
+ my ($self)= @_;
+ ()
+}
+
+sub value {
+ my ($self, $option_name)= @_;
+ my $option= $self->option($option_name);
+
+ croak "No option named '$option_name' in group '$self->{name}'"
+ if ! defined($option);
+
+ return $option->value()->();
+}
package My::Config;
@@ -182,7 +237,10 @@ sub new {
my ($class, $path)= @_;
my $group_name= undef;
- my $self= bless { groups => [] }, $class;
+ my $self= bless { groups => [
+ My::Config::Group::ENV->new('ENV'),
+ My::Config::Group::OPT->new('OPT'),
+ ] }, $class;
my $F= IO::File->new($path, "<")
or croak "Could not open '$path': $!";
@@ -201,19 +259,13 @@ sub new {
}
# Magic #! comments
- elsif ( $line =~ /^#\!/) {
- my $magic= $line;
+ elsif ( $line =~ /^(#\!\S+)(?:\s*(.*?)\s*)?$/) {
+ my ($magic, $arg)= ($1, $2);
croak "Found magic comment '$magic' outside of group"
unless $group_name;
#print "$magic\n";
- $self->insert($group_name, $magic, undef);
- }
-
- # Comments
- elsif ( $line =~ /^#/ || $line =~ /^;/) {
- # Skip comment
- next;
+ $self->insert($group_name, $magic, $arg);
}
# Empty lines
@@ -238,7 +290,7 @@ sub new {
}
# <option>
- elsif ( $line =~ /^([\@\w-]+)\s*$/ ) {
+ elsif ( $line =~ /^(#?[\w-]+)\s*$/ ) {
my $option= $1;
croak "Found option '$option' outside of group"
@@ -249,7 +301,7 @@ sub new {
}
# <option>=<value>
- elsif ( $line =~ /^([\@\w-]+)\s*=\s*(.*?)\s*$/ ) {
+ elsif ( $line =~ /^(#?[\w-]+)\s*=\s*(.*?)\s*$/ ) {
my $option= $1;
my $value= $2;
@@ -258,10 +310,17 @@ sub new {
#print "$option=$value\n";
$self->insert($group_name, $option, $value);
- } else {
- croak "Unexpected line '$line' found in '$path'";
}
+ # Comments
+ elsif ( $line =~ /^#/ || $line =~ /^;/) {
+ # Skip comment
+ next;
+ }
+
+ else {
+ croak "Unexpected line '$line' found in '$path'";
+ }
}
undef $F; # Close the file
@@ -439,44 +498,4 @@ sub exists {
return defined($option);
}
-
-# Overload "to string"-operator with 'stringify'
-use overload
- '""' => \&stringify;
-
-#
-# Return the config as a string in my.cnf file format
-#
-sub stringify {
- my ($self)= @_;
- my $res;
-
- foreach my $group ($self->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 $res;
-}
-
-
-#
-# Save the config to named file
-#
-sub save {
- my ($self, $path)= @_;
- my $F= IO::File->new($path, ">")
- or croak "Could not open '$path': $!";
- print $F $self;
- undef $F; # Close the file
-}
-
1;
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index 19c3ee4d5d8..8fb0e27eb77 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -20,7 +20,7 @@ my @pre_rules=
);
-my @share_locations= ("share/mysql", "sql/share", "share");
+my @share_locations= ("share/mariadb", "share/mysql", "sql/share", "share");
sub get_basedir {
@@ -73,16 +73,12 @@ sub fix_pidfile {
sub fix_port {
my ($self, $config, $group_name, $group)= @_;
- my $hostname= $group->value('#host');
- return $self->{HOSTS}->{$hostname}++;
+ return $self->{PORT}++;
}
sub fix_host {
my ($self)= @_;
- # Get next host from HOSTS array
- my @hosts= keys(%{$self->{HOSTS}});;
- my $host_no= $self->{NEXT_HOST}++ % @hosts;
- return $hosts[$host_no];
+ 'localhost'
}
sub is_unique {
@@ -158,6 +154,7 @@ sub fix_secure_file_priv {
sub fix_std_data {
my ($self, $config, $group_name, $group)= @_;
+ #return "$::opt_vardir/std_data";
my $testdir= $self->get_testdir($group);
return "$testdir/std_data";
}
@@ -219,12 +216,13 @@ my @mysqld_rules=
{ 'pid-file' => \&fix_pidfile },
{ '#host' => \&fix_host },
{ 'port' => \&fix_port },
+ { '#extra-port' => \&fix_port },
{ 'socket' => \&fix_socket },
{ '#log-error' => \&fix_log_error },
- { 'general_log' => 1 },
- { 'general_log_file' => \&fix_log },
- { 'slow_query_log' => 1 },
- { 'slow_query_log_file' => \&fix_log_slow_queries },
+ { 'general-log' => sub { return 1; } },
+ { 'general-log-file' => \&fix_log },
+ { 'slow-query-log' => sub { return 1; } },
+ { 'slow-query-log-file' => \&fix_log_slow_queries },
{ '#user' => sub { return shift->{ARGS}->{user} || ""; } },
{ '#password' => sub { return shift->{ARGS}->{password} || ""; } },
{ 'server-id' => \&fix_server_id, },
@@ -245,7 +243,7 @@ if (IS_WINDOWS)
sub fix_ndb_mgmd_port {
my ($self, $config, $group_name, $group)= @_;
my $hostname= $group->value('HostName');
- return $self->{HOSTS}->{$hostname}++;
+ return $self->{PORT}++;
}
@@ -389,7 +387,7 @@ sub post_check_client_group {
sub post_check_client_groups {
my ($self, $config)= @_;
- my $first_mysqld= $config->first_like('mysqld.');
+ my $first_mysqld= $config->first_like('mysqld\.');
return unless $first_mysqld;
@@ -444,20 +442,24 @@ sub post_check_embedded_group {
sub resolve_at_variable {
my ($self, $config, $group, $option)= @_;
+ local $_ = $option->value();
+ my ($res, $after);
- # Split the options value on last .
- my @parts= split(/\./, $option->value());
- my $option_name= pop(@parts);
- my $group_name= join('.', @parts);
+ while (m/(.*?)\@((?:\w+\.)+)(#?[-\w]+)/g) {
+ my ($before, $group_name, $option_name)= ($1, $2, $3);
+ $after = $';
+ chop($group_name);
- $group_name =~ s/^\@//; # Remove at
+ my $from_group= $config->group($group_name)
+ or croak "There is no group named '$group_name' that ",
+ "can be used to resolve '$option_name'";
- my $from_group= $config->group($group_name)
- or croak "There is no group named '$group_name' that ",
- "can be used to resolve '$option_name'";
+ my $value= $from_group->value($option_name);
+ $res .= $before.$value;
+ }
+ $res .= $after;
- my $from= $from_group->value($option_name);
- $config->insert($group->name(), $option->name(), $from)
+ $config->insert($group->name(), $option->name(), $res)
}
@@ -469,7 +471,7 @@ sub post_fix_resolve_at_variables {
next unless defined $option->value();
$self->resolve_at_variable($config, $group, $option)
- if ($option->value() =~ /^\@/);
+ if ($option->value() =~ /\@/);
}
}
}
@@ -611,28 +613,18 @@ sub new_config {
croak "you must pass '$required'" unless defined $args->{$required};
}
- # Fill in hosts/port hash
- my $hosts= {};
- my $baseport= $args->{baseport};
- $args->{hosts}= [ 'localhost' ] unless exists($args->{hosts});
- foreach my $host ( @{$args->{hosts}} ) {
- $hosts->{$host}= $baseport;
- }
-
# Open the config template
my $config= My::Config->new($args->{'template_path'});
- my $extra_template_path= $args->{'extra_template_path'};
- if ($extra_template_path){
- $config->append(My::Config->new($extra_template_path));
- }
my $self= bless {
CONFIG => $config,
ARGS => $args,
- HOSTS => $hosts,
- NEXT_HOST => 0,
+ PORT => $args->{baseport},
SERVER_ID => 1,
}, $class;
+ # add auto-options
+ $config->insert('OPT', 'port' => sub { fix_port($self, $config) });
+ $config->insert('OPT', 'vardir' => sub { $self->{ARGS}->{vardir} });
{
# Run pre rules
diff --git a/mysql-test/lib/My/File/Path.pm b/mysql-test/lib/My/File/Path.pm
index 25a26568eee..6e6d23ad9f0 100644
--- a/mysql-test/lib/My/File/Path.pm
+++ b/mysql-test/lib/My/File/Path.pm
@@ -18,7 +18,7 @@ use strict;
use Exporter;
use base "Exporter";
-our @EXPORT= qw / rmtree mkpath copytree /;
+our @EXPORT= qw /rmtree mkpath copytree/;
use File::Find;
use File::Copy;
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm
index 461897b56f0..59186f50703 100644
--- a/mysql-test/lib/My/SafeProcess.pm
+++ b/mysql-test/lib/My/SafeProcess.pm
@@ -133,7 +133,7 @@ sub new {
my $input = delete($opts{'input'});
my $output = delete($opts{'output'});
my $error = delete($opts{'error'});
- my $verbose = delete($opts{'verbose'});
+ my $verbose = delete($opts{'verbose'}) || $::opt_verbose;
my $nocore = delete($opts{'nocore'});
my $host = delete($opts{'host'});
my $shutdown = delete($opts{'shutdown'});
@@ -349,9 +349,9 @@ sub kill {
sub _collect {
- my ($self)= @_;
+ my ($self, $exit_code)= @_;
- $self->{EXIT_STATUS}= $?;
+ $self->{EXIT_STATUS}= $exit_code;
_verbose("_collect: $self");
# Take the process out of running list
@@ -418,6 +418,7 @@ sub wait_one {
#_verbose("blocking: $blocking, use_alarm: $use_alarm");
my $retpid;
+ my $exit_code;
eval
{
# alarm should break the wait
@@ -426,6 +427,7 @@ sub wait_one {
alarm($timeout) if $use_alarm;
$retpid= waitpid($pid, $blocking ? 0 : &WNOHANG);
+ $exit_code= $?;
alarm(0) if $use_alarm;
};
@@ -457,7 +459,7 @@ sub wait_one {
#warn "wait_one: expected pid $pid but got $retpid"
# unless( $retpid == $pid );
- $self->_collect();
+ $self->_collect($exit_code);
return 0;
}
@@ -470,6 +472,8 @@ sub wait_one {
#
sub wait_any {
my $ret_pid;
+ my $exit_code;
+
if (IS_WIN32PERL) {
# Can't wait for -1 => use a polling loop
do {
@@ -479,6 +483,7 @@ sub wait_any {
last if $pid == $ret_pid;
}
} while ($ret_pid == 0);
+ $exit_code= $?;
}
else
{
@@ -488,6 +493,7 @@ sub wait_any {
print STDERR "wait_any, got invalid pid: $ret_pid\n";
return undef;
}
+ $exit_code= $?;
}
# Look it up in "running" table
@@ -497,7 +503,7 @@ sub wait_any {
print STDERR "running: ". join(", ", keys(%running)). "\n";
return undef;
}
- $proc->_collect;
+ $proc->_collect($exit_code);
return $proc;
}
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc
index 1c778362975..12b335ec444 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc
@@ -85,17 +85,18 @@ static void die(const char* fmt, ...)
va_end(args);
if (int last_err= errno)
fprintf(stderr, "error: %d, %s\n", last_err, strerror(last_err));
- exit(1);
+ exit(6);
}
-static void kill_child(void)
+static void kill_child(bool was_killed)
{
int status= 0;
message("Killing child: %d", child_pid);
// Terminate whole process group
- kill(-child_pid, SIGKILL);
+ if (! was_killed)
+ kill(-child_pid, SIGKILL);
pid_t ret_pid= waitpid(child_pid, &status, 0);
if (ret_pid == child_pid)
@@ -115,7 +116,7 @@ static void kill_child(void)
exit(exit_code);
}
- exit(1);
+ exit(5);
}
@@ -135,7 +136,7 @@ extern "C" void handle_signal(int sig)
terminated= 1;
if (child_pid > 0)
- kill_child();
+ kill_child(sig == SIGCHLD);
// Ignore further signals
signal(SIGTERM, SIG_IGN);
@@ -240,8 +241,8 @@ int main(int argc, char* const argv[] )
// Close write end
close(pfd[1]);
- if (execvp(child_argv[0], child_argv) < 0)
- die("Failed to exec child");
+ execvp(child_argv[0], child_argv);
+ die("Failed to exec child");
}
close(pfd[1]); // Close unused write end
@@ -257,39 +258,19 @@ int main(int argc, char* const argv[] )
/* Monitor loop */
message("Started child %d, terminated: %d", child_pid, terminated);
- while(!terminated)
+ while (!terminated)
{
// Check if parent is still alive
- if (kill(parent_pid, 0) != 0){
+ if (kill(parent_pid, 0) != 0)
+ {
message("Parent is not alive anymore");
break;
}
-
- // Check if child has exited, normally this will be
- // detected immediately with SIGCHLD handler
- int status= 0;
- pid_t ret_pid= waitpid(child_pid, &status, WNOHANG);
- if (ret_pid == child_pid)
- {
- int ret_code= 2;
- if (WIFEXITED(status))
- {
- // Process has exited, collect return status
- ret_code= WEXITSTATUS(status);
- message("Child exit: %d", ret_code);
- // Exit with exit status of the child
- exit(ret_code);
- }
-
- if (WIFSIGNALED(status))
- message("Child killed by signal: %d", WTERMSIG(status));
-
- exit(ret_code);
- }
+ /* Wait for parent or child to die */
sleep(1);
}
- kill_child();
+ kill_child(0);
- return 1;
+ return 4;
}
diff --git a/mysql-test/lib/My/Suite.pm b/mysql-test/lib/My/Suite.pm
new file mode 100644
index 00000000000..69609e1c4f5
--- /dev/null
+++ b/mysql-test/lib/My/Suite.pm
@@ -0,0 +1,10 @@
+# A default suite class that is used for all suites without their owns suite.pm
+# see README.suites for a description
+
+package My::Suite;
+
+sub config_files { () }
+sub servers { () }
+
+bless { };
+
diff --git a/mysql-test/lib/My/Test.pm b/mysql-test/lib/My/Test.pm
index 68b100f91af..c8bfbd34521 100644
--- a/mysql-test/lib/My/Test.pm
+++ b/mysql-test/lib/My/Test.pm
@@ -9,6 +9,7 @@ package My::Test;
use strict;
use warnings;
use Carp;
+use Storable();
sub new {
@@ -19,6 +20,12 @@ sub new {
return $self;
}
+sub fullname {
+ my ($self)= @_;
+ $self->{name} . (defined $self->{combination}
+ ? " '$self->{combination}'"
+ : "")
+}
#
# Return a unique key that can be used to
@@ -30,18 +37,6 @@ sub key {
}
-sub _encode {
- my ($value)= @_;
- $value =~ s/([|\\\x{0a}\x{0d}])/sprintf('\%02X', ord($1))/eg;
- return $value;
-}
-
-sub _decode {
- my ($value)= @_;
- $value =~ s/\\([0-9a-fA-F]{2})/chr(hex($1))/ge;
- return $value;
-}
-
sub is_failed {
my ($self)= @_;
my $result= $self->{result};
@@ -58,66 +53,22 @@ sub write_test {
# Give the test a unique key before serializing it
$test->{key}= "$test" unless defined $test->{key};
- print $sock $header, "\n";
- while ((my ($key, $value)) = each(%$test)) {
- print $sock $key, "= ";
- if (ref $value eq "ARRAY") {
- print $sock "[", _encode(join(", ", @$value)), "]";
- } else {
- print $sock _encode($value);
- }
- print $sock "\n";
- }
- print $sock "\n";
+ my $serialized= Storable::freeze($test);
+ $serialized =~ s/([\x0d\x0a\\])/sprintf("\\%02x", ord($1))/eg;
+ print $sock $header, "\n", $serialized, "\n";
}
sub read_test {
my ($sock)= @_;
- my $test= My::Test->new();
- # Read the : separated key value pairs until a
- # single newline on it's own line
- my $line;
- while (defined($line= <$sock>)) {
- # List is terminated by newline on it's own
- if ($line eq "\n") {
- # Correctly terminated reply
- # print "Got newline\n";
- last;
- }
- chomp($line);
-
- # Split key/value on the first "="
- my ($key, $value)= split("= ", $line, 2);
-
- if ($value =~ /^\[(.*)\]/){
- my @values= split(", ", _decode($1));
- push(@{$test->{$key}}, @values);
- }
- else
- {
- $test->{$key}= _decode($value);
- }
- }
+ my $serialized= <$sock>;
+ chomp($serialized);
+ $serialized =~ s/\\([0-9a-fA-F]{2})/chr(hex($1))/eg;
+ my $test= Storable::thaw($serialized);
+ die "wrong class (hack attempt?)"
+ unless ref($test) eq 'My::Test';
return $test;
}
-sub print_test {
- my ($self)= @_;
-
- print "[", $self->{name}, "]", "\n";
- while ((my ($key, $value)) = each(%$self)) {
- print " ", $key, "= ";
- if (ref $value eq "ARRAY") {
- print "[", join(", ", @$value), "]";
- } else {
- print $value;
- }
- print "\n";
- }
- print "\n";
-}
-
-
1;
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 87f96496c73..ebdc8fa9f98 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -39,14 +39,7 @@ our $enable_disabled;
our $default_storage_engine;
our $opt_with_ndbcluster_only;
our $defaults_file;
-our $defaults_extra_file;
our $quick_collect;
-# Set to 1 if you want the tests to override
-# default storage engine settings, and use MyISAM
-# as default. (temporary option used in connection
-# with the change of default storage engine to InnoDB)
-our $default_myisam= 1;
-
sub collect_option {
my ($opt, $value)= @_;
@@ -61,7 +54,7 @@ sub collect_option {
}
use File::Basename;
-use File::Spec::Functions qw / splitdir /;
+use File::Spec::Functions qw /splitdir/;
use IO::File();
use My::Config;
use My::Platform;
@@ -74,13 +67,11 @@ require "mtr_misc.pl";
my $do_test_reg;
my $skip_test_reg;
-# Related to adding InnoDB plugin combinations
-my $lib_innodb_plugin;
-my $do_innodb_plugin;
-
# If "Quick collect", set to 1 once a test to run has been found.
my $some_test_found;
+my $default_suite_object = do 'My/Suite.pm';
+
sub init_pattern {
my ($from, $what)= @_;
return undef unless defined $from;
@@ -114,17 +105,6 @@ sub collect_test_cases ($$$$) {
$do_test_reg= init_pattern($do_test, "--do-test");
$skip_test_reg= init_pattern($skip_test, "--skip-test");
- $lib_innodb_plugin=
- my_find_file($::basedir,
- ["storage/innodb_plugin", "storage/innodb_plugin/.libs",
- "lib/mysql/plugin", "lib/plugin"],
- ["ha_innodb_plugin.dll", "ha_innodb_plugin.so",
- "ha_innodb_plugin.sl"],
- NOT_REQUIRED);
- $do_innodb_plugin= ($::mysql_version_id >= 50100 &&
- !(IS_WINDOWS && $::opt_embedded_server) &&
- $lib_innodb_plugin);
-
# If not reordering, we also shouldn't group by suites, unless
# no test cases were named.
# This also effects some logic in the loop following this.
@@ -195,17 +175,17 @@ sub collect_test_cases ($$$$) {
my $opts= $tinfo->{'master_opt'} ? $tinfo->{'master_opt'} : [];
push(@criteria, join("!", sort @{$opts}) . "~");
- $sort_criteria{$tinfo->{name}} = join(" ", @criteria);
+ $sort_criteria{$tinfo->fullname()} = join(" ", @criteria);
}
@$cases = sort {
- $sort_criteria{$a->{'name'}} . $a->{'name'} cmp
- $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases;
+ $sort_criteria{$a->fullname()} . $a->fullname() cmp
+ $sort_criteria{$b->fullname()} . $b->fullname() } @$cases;
# For debugging the sort-order
# foreach my $tinfo (@$cases)
# {
- # print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n");
+ # print $sort_criteria{$tinfo->fullname()}," -> \t",$tinfo->fullname(),"\n";
# }
}
@@ -253,7 +233,7 @@ sub split_testname {
}
-sub collect_one_suite($)
+sub collect_one_suite
{
my $suite= shift; # Test suite name
my $opt_cases= shift;
@@ -315,6 +295,17 @@ sub collect_one_suite($)
mtr_verbose("testdir: $testdir");
mtr_verbose("resdir: $resdir");
+ #
+ # Load the Suite object
+ #
+ unless ($::suites{$suite}) {
+ if (-f "$suitedir/suite.pm") {
+ $::suites{$suite} = do "$suitedir/suite.pm";
+ } else {
+ $::suites{$suite} = $default_suite_object;
+ }
+ }
+
# ----------------------------------------------------------------------
# Build a hash of disabled testcases for this suite
# ----------------------------------------------------------------------
@@ -338,12 +329,8 @@ sub collect_one_suite($)
}
# Read suite.opt file
- my $suite_opt_file= "$testdir/suite.opt";
- my $suite_opts= [];
- if ( -f $suite_opt_file )
- {
- $suite_opts= opts_from_file($suite_opt_file);
- }
+ my $suite_opts= [ opts_from_file("$testdir/suite.opt") ];
+ $suite_opts = [ opts_from_file("$suitedir/suite.opt") ] unless @$suite_opts;
if ( @$opt_cases )
{
@@ -448,14 +435,16 @@ sub collect_one_suite($)
{
# Read combinations file in my.cnf format
mtr_verbose("Read combinations file");
+ my %env_filter = map { $_ => 1 } split /:/, $ENV{"\U${suite}_COMBINATIONS"};
my $config= My::Config->new($combination_file);
foreach my $group ($config->groups()) {
my $comb= {};
$comb->{name}= $group->name();
+ next if %env_filter and not $env_filter{$comb->{name}};
foreach my $option ( $group->options() ) {
push(@{$comb->{comb_opt}}, $option->option());
}
- push(@combinations, $comb);
+ push(@combinations, $comb) if $comb->{comb_opt};
}
}
@@ -534,8 +523,12 @@ sub collect_one_suite($)
sub optimize_cases {
my ($cases)= @_;
+ my @new_cases= ();
+
foreach my $tinfo ( @$cases )
{
+ push @new_cases, $tinfo;
+
# Skip processing if already marked as skipped
next if $tinfo->{skip};
@@ -545,28 +538,7 @@ sub optimize_cases {
# support it
# =======================================================
#print "binlog_format: $binlog_format\n";
- if (defined $binlog_format )
- {
- # =======================================================
- # Fixed --binlog-format=x specified on command line
- # =======================================================
- if ( defined $tinfo->{'binlog_formats'} )
- {
- #print "binlog_formats: ". join(", ", @{$tinfo->{binlog_formats}})."\n";
-
- # The test supports different binlog formats
- # check if the selected one is ok
- my $supported=
- grep { $_ eq $binlog_format } @{$tinfo->{'binlog_formats'}};
- if ( !$supported )
- {
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}=
- "Doesn't support --binlog-format='$binlog_format'";
- }
- }
- }
- else
+ if (not defined $binlog_format )
{
# =======================================================
# Use dynamic switching of binlog format
@@ -589,6 +561,13 @@ sub optimize_cases {
$tinfo->{'skip'}= 1;
$tinfo->{'comment'}=
"Doesn't support --binlog-format='$test_binlog_format'";
+ # This test was added as a replication combination, but it is not
+ # actually ever possible to run it, as it is not made for this
+ # combination.
+ # So delete it from the list, rather than confuse the user with a
+ # message that this test is skipped (it is not really, just run
+ # with other combinations).
+ pop(@new_cases);
next;
}
}
@@ -625,8 +604,6 @@ sub optimize_cases {
$tinfo->{'ndb_test'}= 1
if ( $default_engine =~ /^ndb/i );
- $tinfo->{'innodb_test'}= 1
- if ( $default_engine =~ /^innodb/i );
}
}
@@ -636,6 +613,7 @@ sub optimize_cases {
return;
}
}
+ @$cases= @new_cases;
}
@@ -643,74 +621,88 @@ sub optimize_cases {
# Read options from the given opt file and append them as an array
# to $tinfo->{$opt_name}
#
-sub process_opts_file {
- my ($tinfo, $opt_file, $opt_name)= @_;
+sub process_opts {
+ my ($tinfo, $opt_name)= @_;
+
+ my @opts= @{$tinfo->{$opt_name}};
+ $tinfo->{$opt_name} = [];
+
+ my @plugins;
+ my %seen;
- if ( -f $opt_file )
+ foreach my $opt (@opts)
{
- my $opts= opts_from_file($opt_file);
+ my $value;
- foreach my $opt ( @$opts )
+ # The opt file is used both to send special options to the mysqld
+ # as well as pass special test case specific options to this
+ # script
+
+ $value= mtr_match_prefix($opt, "--timezone=");
+ if ( defined $value )
{
- my $value;
+ $tinfo->{'timezone'}= $value;
+ next;
+ }
- # The opt file is used both to send special options to the mysqld
- # as well as pass special test case specific options to this
- # script
+ $value= mtr_match_prefix($opt, "--plugin-load=");
+ if (defined $value)
+ {
+ push @plugins, $value unless $seen{$value};
+ $seen{$value}=1;
+ next;
+ }
- $value= mtr_match_prefix($opt, "--timezone=");
- if ( defined $value )
- {
- $tinfo->{'timezone'}= $value;
- next;
- }
+ $value= mtr_match_prefix($opt, "--result-file=");
+ if ( defined $value )
+ {
+ # Specifies the file mysqltest should compare
+ # output against
+ $tinfo->{'result_file'}= "r/$value.result";
+ next;
+ }
- $value= mtr_match_prefix($opt, "--result-file=");
- if ( defined $value )
- {
- # Specifies the file mysqltest should compare
- # output against
- $tinfo->{'result_file'}= "r/$value.result";
- next;
- }
+ $value= mtr_match_prefix($opt, "--config-file-template=");
+ if ( defined $value)
+ {
+ # Specifies the configuration file to use for this test
+ $tinfo->{'template_path'}= dirname($tinfo->{path})."/$value";
+ next;
+ }
- $value= mtr_match_prefix($opt, "--config-file-template=");
- if ( defined $value)
- {
- # Specifies the configuration file to use for this test
- $tinfo->{'template_path'}= dirname($tinfo->{path})."/$value";
- next;
- }
+ # If we set default time zone, remove the one we have
+ $value= mtr_match_prefix($opt, "--default-time-zone=");
+ if ( defined $value )
+ {
+ # Set timezone for this test case to something different
+ $tinfo->{'timezone'}= "GMT-8";
+ # Fallthrough, add the --default-time-zone option
+ }
- # If we set default time zone, remove the one we have
- $value= mtr_match_prefix($opt, "--default-time-zone=");
- if ( defined $value )
- {
- # Set timezone for this test case to something different
- $tinfo->{'timezone'}= "GMT-8";
- # Fallthrough, add the --default-time-zone option
- }
+ # The --restart option forces a restart even if no special
+ # option is set. If the options are the same as next testcase
+ # there is no need to restart after the testcase
+ # has completed
+ if ( $opt eq "--force-restart" )
+ {
+ $tinfo->{'force_restart'}= 1;
+ next;
+ }
- # The --restart option forces a restart even if no special
- # option is set. If the options are the same as next testcase
- # there is no need to restart after the testcase
- # has completed
- if ( $opt eq "--force-restart" )
- {
- $tinfo->{'force_restart'}= 1;
- next;
- }
+ $value= mtr_match_prefix($opt, "--testcase-timeout=");
+ if ( defined $value ) {
+ # Overrides test case timeout for this test
+ $tinfo->{'case-timeout'}= $value;
+ next;
+ }
- $value= mtr_match_prefix($opt, "--testcase-timeout=");
- if ( defined $value ) {
- # Overrides test case timeout for this test
- $tinfo->{'case-timeout'}= $value;
- next;
- }
+ # Ok, this was a real option, add it
+ push(@{$tinfo->{$opt_name}}, $opt);
+ }
- # Ok, this was a real option, add it
- push(@{$tinfo->{$opt_name}}, $opt);
- }
+ if (@plugins) {
+ my $sep = (IS_WINDOWS) ? ';' : ':';
+ push @{$tinfo->{$opt_name}}, "--plugin-load=" . join($sep, @plugins);
}
}
@@ -730,6 +722,8 @@ sub collect_one_test_case {
my $disabled= shift;
my $suite_opts= shift;
+ my $local_default_storage_engine= $default_storage_engine;
+
#print "collect_one_test_case\n";
#print " suitedir: $suitedir\n";
#print " testdir: $testdir\n";
@@ -741,7 +735,7 @@ sub collect_one_test_case {
# ----------------------------------------------------------------------
# Check --start-from
# ----------------------------------------------------------------------
- if ( $start_from )
+ if ( $start_from && 0)
{
# start_from can be specified as [suite.].testname_prefix
my ($suite, $test, $ext)= split_testname($start_from);
@@ -749,7 +743,7 @@ sub collect_one_test_case {
if ( $suite and $suitename lt $suite){
return; # Skip silently
}
- if ( $tname lt $test ){
+ if ((!$suite || $suitename == $suite) && $tname lt $test ){
return; # Skip silently
}
}
@@ -762,7 +756,7 @@ sub collect_one_test_case {
name => "$suitename.$tname",
shortname => $tname,
path => "$testdir/$filename",
-
+ suite => $suitename,
);
my $result_file= "$resdir/$tname.result";
@@ -782,7 +776,9 @@ sub collect_one_test_case {
# ----------------------------------------------------------------------
# Skip some tests but include in list, just mark them as skipped
# ----------------------------------------------------------------------
- if ( $skip_test_reg and $tname =~ /$skip_test_reg/o )
+ my $name= basename($suitename) . ".$tname";
+ if ( $skip_test_reg and ($tname =~ /$skip_test_reg/o ||
+ $name =~ /$skip_test/o))
{
$tinfo->{'skip'}= 1;
return $tinfo;
@@ -830,15 +826,6 @@ sub collect_one_test_case {
push(@{$tinfo->{'master_opt'}}, @$suite_opts);
push(@{$tinfo->{'slave_opt'}}, @$suite_opts);
- #-----------------------------------------------------------------------
- # Check for test specific config file
- #-----------------------------------------------------------------------
- my $test_cnf_file= "$testdir/$tname.cnf";
- if ( -f $test_cnf_file) {
- # Specifies the configuration file to use for this test
- $tinfo->{'template_path'}= $test_cnf_file;
- }
-
# ----------------------------------------------------------------------
# Check for test specific config file
# ----------------------------------------------------------------------
@@ -891,17 +878,22 @@ sub collect_one_test_case {
if ( -f "$testdir/$tname.slave-mi");
- tags_from_test_file($tinfo,"$testdir/${tname}.test");
+ my @source_files = tags_from_test_file($tinfo,"$testdir/${tname}.test");
+
+ # Get default storage engine from suite.opt file
+
+ if (defined $suite_opts &&
+ "@$suite_opts" =~ "default-storage-engine=\s*([^\s]*)")
+ {
+ $local_default_storage_engine= $1;
+ }
- if ( defined $default_storage_engine )
+ if ( defined $local_default_storage_engine )
{
# Different default engine is used
# tag test to require that engine
$tinfo->{'ndb_test'}= 1
- if ( $default_storage_engine =~ /^ndb/i );
-
- $tinfo->{'innodb_test'}= 1
- if ( $default_storage_engine =~ /^innodb/i );
+ if ( $local_default_storage_engine =~ /^ndb/i );
}
@@ -949,69 +941,32 @@ sub collect_one_test_case {
}
}
- if ($tinfo->{'federated_test'})
- {
- # This is a test that needs federated, enable it
- push(@{$tinfo->{'master_opt'}}, "--loose-federated");
- push(@{$tinfo->{'slave_opt'}}, "--loose-federated");
- }
-
- if ( $tinfo->{'innodb_test'} )
- {
- # This is a test that needs innodb
- if ( $::mysqld_variables{'innodb'} eq "OFF" ||
- ! exists $::mysqld_variables{'innodb'} )
- {
- # innodb is not supported, skip it
- $tinfo->{'skip'}= 1;
- # This comment is checked for running with innodb plugin (see above),
- # please keep that in mind if changing the text.
- $tinfo->{'comment'}= "No innodb support";
- # But continue processing if we may run it with innodb plugin
- return $tinfo unless $do_innodb_plugin;
- }
- }
- elsif ($default_myisam)
- {
- # This is a temporary fix to allow non-innodb tests to run even if
- # the default storage engine is innodb.
- push(@{$tinfo->{'master_opt'}}, "--default-storage-engine=MyISAM");
- push(@{$tinfo->{'slave_opt'}}, "--default-storage-engine=MyISAM");
- }
-
- if ( $tinfo->{'need_binlog'} )
+ if ( $tinfo->{'rpl_test'} )
{
- if (grep(/^--skip-log-bin/, @::opt_extra_mysqld_opt) )
+ if ( $skip_rpl )
{
$tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "Test needs binlog";
+ $tinfo->{'comment'}= "No replication tests(--skip-rpl)";
return $tinfo;
}
}
- else
- {
- # Test does not need binlog, add --skip-binlog to
- # the options used when starting
- push(@{$tinfo->{'master_opt'}}, "--loose-skip-log-bin");
- push(@{$tinfo->{'slave_opt'}}, "--loose-skip-log-bin");
- }
- if ( $tinfo->{'rpl_test'} )
+ if ( $::opt_embedded_server )
{
- if ( $skip_rpl )
+ if ( $tinfo->{'not_embedded'} )
{
$tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "No replication tests(--skip-rpl)";
+ $tinfo->{'comment'}= "Not run for embedded server";
return $tinfo;
}
}
- if ( $::opt_embedded_server )
+ if ( $tinfo->{'not_valgrind'} )
{
- if ( $tinfo->{'not_embedded'} )
+ if ( $::opt_valgrind_mysqld )
{
$tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "Not run for embedded server";
+ $tinfo->{'comment'}= "Not compatible with Valgrind testing";
return $tinfo;
}
}
@@ -1056,26 +1011,49 @@ sub collect_one_test_case {
$tinfo->{template_path}= $config;
}
- # Set extra config file to use
- if (defined $defaults_extra_file) {
- $tinfo->{extra_template_path}= $defaults_extra_file;
+ if ( $tinfo->{'example_plugin_test'} )
+ {
+ if ( !$ENV{'HA_EXAMPLE_SO'} )
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Test requires the 'example' plugin";
+ return $tinfo;
+ }
+ }
+
+ if ( $tinfo->{'oqgraph_test'} )
+ {
+ if ( !$ENV{'GRAPH_ENGINE_SO'} )
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Test requires the OQGraph storage engine";
+ return $tinfo;
+ }
+ }
+
+ if (not ref $::suites{$tinfo->{suite}})
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= $::suites{$tinfo->{suite}};
+ return $tinfo;
}
# ----------------------------------------------------------------------
- # Append mysqld extra options to both master and slave
+ # Append mysqld extra options to master and slave, as appropriate
# ----------------------------------------------------------------------
+ for (@source_files) {
+ s/\.\w+$//;
+ push @{$tinfo->{master_opt}}, opts_from_file("$_.opt");
+ push @{$tinfo->{slave_opt}}, opts_from_file("$_.opt");
+ push @{$tinfo->{master_opt}}, opts_from_file("$_-master.opt");
+ push @{$tinfo->{slave_opt}}, opts_from_file("$_-slave.opt");
+ }
+
push(@{$tinfo->{'master_opt'}}, @::opt_extra_mysqld_opt);
push(@{$tinfo->{'slave_opt'}}, @::opt_extra_mysqld_opt);
- # ----------------------------------------------------------------------
- # Add master opts, extra options only for master
- # ----------------------------------------------------------------------
- process_opts_file($tinfo, "$testdir/$tname-master.opt", 'master_opt');
-
- # ----------------------------------------------------------------------
- # Add slave opts, list of extra option only for slave
- # ----------------------------------------------------------------------
- process_opts_file($tinfo, "$testdir/$tname-slave.opt", 'slave_opt');
+ process_opts($tinfo, 'master_opt');
+ process_opts($tinfo, 'slave_opt');
return $tinfo;
}
@@ -1085,19 +1063,6 @@ sub collect_one_test_case {
# the specified value in "tinfo"
my @tags=
(
- ["include/have_binlog_format_row.inc", "binlog_formats", ["row"]],
- ["include/have_binlog_format_statement.inc", "binlog_formats", ["statement"]],
- ["include/have_binlog_format_mixed.inc", "binlog_formats", ["mixed"]],
- ["include/have_binlog_format_mixed_or_row.inc",
- "binlog_formats", ["mixed", "row"]],
- ["include/have_binlog_format_mixed_or_statement.inc",
- "binlog_formats", ["mixed", "statement"]],
- ["include/have_binlog_format_row_or_statement.inc",
- "binlog_formats", ["row", "statement"]],
-
- ["include/have_log_bin.inc", "need_binlog", 1],
-
- ["include/have_innodb.inc", "innodb_test", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
@@ -1105,8 +1070,10 @@ my @tags=
["include/master-slave.inc", "rpl_test", 1],
["include/ndb_master-slave.inc", "rpl_test", 1],
["include/ndb_master-slave.inc", "ndb_test", 1],
- ["federated.inc", "federated_test", 1],
["include/not_embedded.inc", "not_embedded", 1],
+ ["include/not_valgrind.inc", "not_valgrind", 1],
+ ["include/have_example_plugin.inc", "example_plugin_test", 1],
+ ["include/have_oqgraph_engine.inc", "oqgraph_test", 1],
["include/have_ssl.inc", "need_ssl", 1],
);
@@ -1116,6 +1083,7 @@ sub tags_from_test_file {
my $file= shift;
#mtr_verbose("$file");
my $F= IO::File->new($file) or mtr_error("can't open file \"$file\": $!");
+ my @all_files=($file);
while ( my $line= <$F> )
{
@@ -1151,13 +1119,13 @@ sub tags_from_test_file {
# Only source the file if it exists, we may get
# false positives in the regexes above if someone
# writes "source nnnn;" in a test case(such as mysqltest.test)
- tags_from_test_file($tinfo, $sourced_file);
+ unshift @all_files, tags_from_test_file($tinfo, $sourced_file);
last;
}
}
}
-
}
+ @all_files;
}
sub unspace {
@@ -1170,6 +1138,9 @@ sub unspace {
sub opts_from_file ($) {
my $file= shift;
+ local $_;
+
+ return () unless -f $file;
open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!");
my @args;
@@ -1211,7 +1182,7 @@ sub opts_from_file ($) {
}
}
close FILE;
- return \@args;
+ return @args;
}
sub print_testcases {
@@ -1226,3 +1197,4 @@ sub print_testcases {
1;
+
diff --git a/mysql-test/lib/mtr_gcov.pl b/mysql-test/lib/mtr_gcov.pl
index f531889b08d..2f211b7566d 100644
--- a/mysql-test/lib/mtr_gcov.pl
+++ b/mysql-test/lib/mtr_gcov.pl
@@ -20,6 +20,8 @@
use strict;
+our $basedir;
+
sub gcov_prepare ($) {
my ($dir)= @_;
print "Purging gcov information from '$dir'...\n";
@@ -42,7 +44,7 @@ sub gcov_collect ($$$) {
# Get current directory to return to later.
my $start_dir= cwd();
- print "Collecting source coverage info using '$gcov'...\n";
+ print "Collecting source coverage info using '$gcov'...$basedir\n";
-f "$start_dir/$gcov_msg" and unlink("$start_dir/$gcov_msg");
-f "$start_dir/$gcov_err" and unlink("$start_dir/$gcov_err");
@@ -62,6 +64,8 @@ sub gcov_collect ($$$) {
$dir_reported= 1;
}
system("$gcov $f 2>>$start_dir/$gcov_err >>$start_dir/$gcov_msg");
+ system("perl", "$basedir/mysql-test/lib/process-purecov-annotations.pl", "$f.gcov");
+
}
chdir($start_dir);
}
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index 32960d866ce..388d252502a 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -198,6 +198,26 @@ sub mtr_milli_sleep ($) {
select(undef, undef, undef, ($millis/1000));
}
+sub mtr_wait_lock_file {
+ die "usage: mtr_wait_lock_file(path_to_file, keep_alive)" unless @_ == 2;
+ my ($file, $keep_alive)= @_;
+ my $waited= 0;
+ my $msg_counter= $keep_alive;
+
+ while ( -e $file)
+ {
+ if ($keep_alive && !$msg_counter)
+ {
+ print "\n-STOPPED- [pass] ".$keep_alive."\n";
+ $msg_counter= $keep_alive;
+ }
+ mtr_milli_sleep(1000);
+ $waited= 1;
+ $msg_counter--;
+ }
+ return ($waited);
+}
+
# Simple functions to start and check timers (have to be actively polled)
# Timer can be "killed" by setting it to 0
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index 77f6920771d..a90c367178d 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -61,14 +61,10 @@ sub _name {
sub _mtr_report_test_name ($) {
my $tinfo= shift;
- my $tname= $tinfo->{name};
+ my $tname= $tinfo->fullname();
return unless defined $verbose;
- # Add combination name if any
- $tname.= " '$tinfo->{combination}'"
- if defined $tinfo->{combination};
-
print _name(). _timestamp();
printf "%-40s ", $tname;
my $worker = $tinfo->{worker};
@@ -222,8 +218,11 @@ sub mtr_report_test ($) {
}
-sub mtr_report_stats ($$;$) {
- my ($prefix, $tests, $dont_error)= @_;
+sub mtr_report_stats ($$$$) {
+ my $prefix= shift;
+ my $fail= shift;
+ my $tests= shift;
+ my $extra_warnings= shift;
# ----------------------------------------------------------------------
# Find out how we where doing
@@ -297,16 +296,14 @@ sub mtr_report_stats ($$;$) {
time - $BASETIME, "seconds executing testcases");
}
-
my $warnlog= "$::opt_vardir/log/warnings";
- if ( -f $warnlog )
+ if ( ! $::glob_use_running_server && !$::opt_extern && -f $warnlog)
{
mtr_warning("Got errors/warnings while running tests, please examine",
"'$warnlog' for details.");
- }
+ }
print "\n";
-
# Print a list of check_testcases that failed(if any)
if ( $::opt_check_testcases )
{
@@ -376,9 +373,26 @@ sub mtr_report_stats ($$;$) {
print "All $tot_tests tests were successful.\n\n";
}
+ if (@$extra_warnings)
+ {
+ print <<MSG;
+Errors/warnings were found in logfiles during server shutdown after running the
+following sequence(s) of tests:
+MSG
+ print " $_\n" for @$extra_warnings;
+ }
+
if ( $tot_failed != 0 || $found_problems)
{
- mtr_error("there were failing test cases") unless $dont_error;
+ mtr_error("there were failing test cases");
+ }
+ elsif (@$extra_warnings)
+ {
+ mtr_error("There where errors/warnings in server logs after running test cases.");
+ }
+ elsif ($fail)
+ {
+ mtr_error("Test suite failure, see messages above for possible cause(s).");
}
}
diff --git a/mysql-test/lib/process-purecov-annotations.pl b/mysql-test/lib/process-purecov-annotations.pl
new file mode 100755
index 00000000000..d533bd02fd6
--- /dev/null
+++ b/mysql-test/lib/process-purecov-annotations.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+# -*- cperl -*-
+
+# This script processes a .gcov coverage report to honor purecov
+# annotations: lines marked as inspected or as deadcode are changed
+# from looking like lines with code that was never executed to look
+# like lines that have no executable code.
+
+use strict;
+use warnings;
+
+foreach my $in_file_name ( @ARGV )
+{
+ my $out_file_name=$in_file_name . ".tmp";
+ my $skipping=0;
+
+ open(IN, "<", $in_file_name) || next;
+ open(OUT, ">", $out_file_name);
+ while(<IN>)
+ {
+ my $line= $_;
+ my $check= $line;
+
+ # process purecov: start/end multi-blocks
+ my $started=0;
+ my $ended= 0;
+ while (($started=($check =~ s/purecov: *begin *(deadcode|inspected)//)) ||
+ ($ended=($check =~ s/purecov: *end//)))
+ {
+ $skipping= $skipping + $started - $ended;
+ }
+ if ($skipping < 0)
+ {
+ print OUT "WARNING: #####: incorrect order of purecov begin/end annotations\n";
+ $skipping= 0;
+ }
+
+ # Besides purecov annotations, also remove uncovered code mark from cases
+ # like the following:
+ #
+ # -: 211:*/
+ # -: 212:class Field_value : public Value_dep
+ # #####: 213:{
+ # -: 214:public:
+ #
+ # I have no idea why would gcov think there is uncovered code there
+ #
+ my @arr= split(/:/, $line);
+ if ($skipping || $line =~ /purecov: *(inspected|deadcode)/ ||
+ $arr[2] =~ m/^{ *$/)
+ {
+ # Change '####' to '-'.
+ $arr[0] =~ s/#####/ -/g;
+ $line= join(":", @arr);
+ }
+ print OUT $line;
+ }
+ close(IN);
+ close(OUT);
+ system("mv", "-f", $out_file_name, $in_file_name);
+}
+
+
diff --git a/mysql-test/lib/v1/mtr_process.pl b/mysql-test/lib/v1/mtr_process.pl
index 4a4e342bff6..33a39d1f0b6 100644
--- a/mysql-test/lib/v1/mtr_process.pl
+++ b/mysql-test/lib/v1/mtr_process.pl
@@ -475,12 +475,6 @@ sub mtr_kill_leftovers () {
}
}
}
- else
- {
- mtr_warning("Found non pid file $elem in $rundir")
- if -f "$rundir/$elem";
- next;
- }
}
closedir(RUNDIR);
@@ -887,15 +881,33 @@ sub check_expected_crash_and_restart($)
mtr_verbose("$mysqld->{'type'} $mysqld->{'idx'} exited, pid: $ret_pid");
$mysqld->{'pid'}= 0;
- # Check if crash expected and restart if it was
+ # Check if crash expected, and restart if it was
my $expect_file= "$::opt_vardir/tmp/" . "$mysqld->{'type'}" .
"$mysqld->{'idx'}" . ".expect";
- if ( -f $expect_file )
+ while ( 1 )
{
- mtr_verbose("Crash was expected, file $expect_file exists");
- mysqld_start($mysqld, $mysqld->{'start_opts'},
- $mysqld->{'start_slave_master_info'});
- unlink($expect_file);
+ if ( -f $expect_file )
+ {
+ mtr_verbose("Crash was expected, file $expect_file exists");
+ my $expect_file_handler;
+ open($expect_file_handler, "<$expect_file") or die;
+ my @expect_lines= <$expect_file_handler>;
+ close $expect_file_handler;
+ # look at most recent order by the test
+ my $expect_content= pop @expect_lines;
+ chomp $expect_content;
+ if ( $expect_content =~ /^wait/ )
+ {
+ mtr_verbose("Test asks that we wait before restart");
+ # Millisceond sleep emulated with select
+ select(undef, undef, undef, (0.1));
+ next;
+ }
+ unlink($expect_file);
+ mysqld_start($mysqld, $mysqld->{'start_opts'},
+ $mysqld->{'start_slave_master_info'});
+ }
+ last;
}
return;
@@ -915,8 +927,8 @@ sub check_expected_crash_and_restart($)
if ( -f $expect_file )
{
mtr_verbose("Crash was expected, file $expect_file exists");
- ndbmgmd_start($cluster);
unlink($expect_file);
+ ndbmgmd_start($cluster);
}
return;
}
@@ -934,9 +946,9 @@ sub check_expected_crash_and_restart($)
if ( -f $expect_file )
{
mtr_verbose("Crash was expected, file $expect_file exists");
+ unlink($expect_file);
ndbd_start($cluster, $ndbd->{'idx'},
$ndbd->{'start_extra_args'});
- unlink($expect_file);
}
return;
}
diff --git a/mysql-test/lib/v1/mtr_report.pl b/mysql-test/lib/v1/mtr_report.pl
index 84784ed19d4..dde093ff674 100644
--- a/mysql-test/lib/v1/mtr_report.pl
+++ b/mysql-test/lib/v1/mtr_report.pl
@@ -220,7 +220,7 @@ sub mtr_report_stats ($) {
# the "var/log/*.err" files. We save this info in "var/log/warnings"
# ----------------------------------------------------------------------
- if ( ! $::glob_use_running_server )
+ if ( ! $::glob_use_running_server && !$::opt_extern)
{
# Save and report if there was any fatal warnings/errors in err logs
@@ -387,11 +387,10 @@ sub mtr_report_stats ($) {
(/Failed during slave.*thread initialization/
)) or
- # rpl_temporary has an error on slave that can be ignored
- ($testname eq 'rpl.rpl_temporary' and
- (/Slave: Can\'t find record in \'user\' Error_code: 1032/
- )) or
-
+ # rpl_temporary has an error on slave that can be ignored
+ ($testname eq 'rpl.rpl_temporary' and
+ (/Slave: Can\'t find record in \'user\' Error_code: 1032/
+ )) or
# Test case for Bug#31590 produces the following error:
/Out of sort memory; increase server sort buffer size/ or
@@ -404,8 +403,18 @@ sub mtr_report_stats ($) {
# When trying to set lower_case_table_names = 2
# on a case sensitive file system. Bug#37402.
- /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive. Now setting lower_case_table_names to 0 to avoid future problems./
- )
+ /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive. Now setting lower_case_table_names to 0 to avoid future problems./ or
+
+ # maria-recovery.test has warning about missing log file
+ /File '.*maria_log.000.*' not found \(Errcode: 2\)/ or
+ # and about marked-corrupted table
+ /Table '..mysqltest.t_corrupted1' is crashed, skipping it. Please repair it with maria_chk -r/ or
+ # maria-recover.test corrupts tables on purpose
+ /Checking table: '..mysqltest.t_corrupted2'/ or
+ /Recovering table: '..mysqltest.t_corrupted2'/ or
+ /Table '..mysqltest.t_corrupted2' is marked as crashed and should be repaired/ or
+ /Incorrect key file for table '..mysqltest.t_corrupted2.MAI'; try to repair it/
+ )
{
next; # Skip these lines
}
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index 4e4f09981cc..e4743c73d6b 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -134,8 +134,9 @@ our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
our $default_vardir;
our $opt_usage;
+our $opt_list_options;
our $opt_suites;
-our $opt_suites_default= "main,binlog,rpl,rpl_ndb,ndb"; # Default suites to run
+our $opt_suites_default= "main,binlog,rpl,rpl_ndb,ndb,maria"; # Default suites to run
our $opt_script_debug= 0; # Script debugging, enable with --script-debug
our $opt_verbose= 0; # Verbose output, enable with --verbose
@@ -171,6 +172,7 @@ our @opt_combinations;
our $opt_skip_combination;
our @opt_extra_mysqld_opt;
+our @opt_extra_mysqltest_opt;
our $opt_compress;
our $opt_ssl;
@@ -430,7 +432,7 @@ sub main () {
my $tests= collect_test_cases($opt_suites);
# Turn off NDB and other similar options if no tests use it
- my ($need_ndbcluster,$need_im);
+ my ($need_ndbcluster,$need_im, $need_debug);
foreach my $test (@$tests)
{
next if $test->{skip};
@@ -438,6 +440,7 @@ sub main () {
if (!$opt_extern)
{
$need_ndbcluster||= $test->{ndb_test};
+ $need_debug||=$test->{need_debug};
$need_im||= $test->{component_id} eq 'im';
# Count max number of slaves used by a test case
@@ -463,6 +466,11 @@ sub main () {
$opt_skip_ndbcluster_slave= 1;
}
+ if ( !$need_debug && !$opt_debug)
+ {
+ $opt_debug=0;
+ }
+
# Check if slave cluster can be skipped
if ($max_slave_num == 0)
{
@@ -547,7 +555,7 @@ sub command_line_setup () {
);
Getopt::Long::Configure("pass_through");
- GetOptions(
+ my %options=(
# Control what engine/variation to run
'embedded-server' => \$opt_embedded_server,
'ps-protocol' => \$opt_ps_protocol,
@@ -599,6 +607,9 @@ sub command_line_setup () {
# Extra options used when starting mysqld
'mysqld=s' => \@opt_extra_mysqld_opt,
+ # Extra options used when starting mysqld
+ 'mysqltest=s' => \@opt_extra_mysqltest_opt,
+
# Run test on running server
'extern' => \$opt_extern,
'ndb-connectstring=s' => \$opt_ndbconnectstring,
@@ -682,9 +693,13 @@ sub command_line_setup () {
(map { $_ => \&warn_about_removed_option } @removed_options),
'help|h' => \$opt_usage,
- ) or usage("Can't read options");
+ 'list-options' => \$opt_list_options,
+ );
+
+ GetOptions(%options) or usage("Can't read options");
usage("") if $opt_usage;
+ list_options(\%options) if $opt_list_options;
$glob_scriptname= basename($0);
@@ -990,7 +1005,7 @@ sub command_line_setup () {
# --------------------------------------------------------------------------
if ($opt_extern)
{
- mtr_report("Disable instance manager when running with extern mysqld");
+ # mtr_report("Disable instance manager when running with extern mysqld");
$opt_skip_im= 1;
}
elsif ( $mysql_version_id < 50000 )
@@ -1365,19 +1380,6 @@ sub command_line_setup () {
$path_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log";
$path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/";
-
- 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
- foreach my $mysqld (@{$master}, @{$slave})
- {
- my $sidx= $mysqld->{idx} ? "$mysqld->{idx}" : "";
- $mysqld->{path_myerr}=
- "$opt_vardir/log/" . $mysqld->{type} . "$sidx.trace";
- }
- }
}
#
@@ -2136,7 +2138,10 @@ sub environment_setup () {
$ENV{'MYSQL_UPGRADE'}= mysql_upgrade_arguments();
}
- $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables;
+ if ( !$opt_extern )
+ {
+ $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables;
+ }
# ----------------------------------------------------
# Setup env so childs can execute my_print_defaults
@@ -2153,6 +2158,7 @@ sub environment_setup () {
# ----------------------------------------------------
$ENV{'MY_PERROR'}= mtr_native_path($exe_perror);
+#warning remove the below
# ----------------------------------------------------
# Add the path where mysqld will find udf_example.so
# ----------------------------------------------------
@@ -2186,6 +2192,22 @@ sub environment_setup () {
"$glob_bindir/myisam/myisampack"));
# ----------------------------------------------------
+ # Setup env so childs can execute aria_pack and aria_chk
+ # ----------------------------------------------------
+ $ENV{'ARIA_CHK'}= mtr_native_path(mtr_exe_maybe_exists(
+ vs_config_dirs('storage/maria', 'aria_chk'),
+ vs_config_dirs('maria', 'aria_chk'),
+ "$path_client_bindir/aria_chk",
+ "$glob_basedir/storage/maria/aria_chk",
+ "$glob_basedir/maria/aria_chk"));
+ $ENV{'ARIA_PACK'}= mtr_native_path(mtr_exe_maybe_exists(
+ vs_config_dirs('storage/maria', 'aria_pack'),
+ vs_config_dirs('maria', 'aria_pack'),
+ "$path_client_bindir/aria_pack",
+ "$glob_basedir/storage/maria/aria_pack",
+ "$glob_basedir/maria/aria_pack"));
+
+ # ----------------------------------------------------
# We are nice and report a bit about our settings
# ----------------------------------------------------
if (!$opt_extern)
@@ -2430,6 +2452,25 @@ sub setup_vardir() {
{
unlink($name);
}
+ 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
+ foreach my $mysqld (@{$master}, @{$slave})
+ {
+ my $sidx= $mysqld->{idx} ? "$mysqld->{idx}" : "";
+ my $trace_name= "$opt_vardir/log/" . $mysqld->{type} . "$sidx.trace";
+ open(LOG, ">$mysqld->{path_myerr}") or die "Can't create $mysqld->{path_myerr}\n";
+ print LOG "
+NOTE: When running with --valgrind --debug the output from the .err file is
+stored together with the trace file to make it easier to find the exact
+position for valgrind errors.
+See trace file $trace_name.\n";
+ close(LOG);
+ $mysqld->{path_myerr}= $trace_name;
+ }
+ }
}
@@ -2882,7 +2923,7 @@ sub run_benchmarks ($) {
if ( ! $benchmark )
{
- mtr_add_arg($args, "--log");
+ mtr_add_arg($args, "--general-log");
mtr_run("$glob_mysql_bench_dir/run-all-tests", $args, "", "", "", "");
# FIXME check result code?!
}
@@ -3106,17 +3147,26 @@ sub install_db ($$) {
mtr_report("Installing \u$type Database");
-
my $args;
+ my $cmd_args;
mtr_init_args(\$args);
mtr_add_arg($args, "--no-defaults");
mtr_add_arg($args, "--bootstrap");
mtr_add_arg($args, "--basedir=%s", $path_my_basedir);
mtr_add_arg($args, "--datadir=%s", $data_dir);
mtr_add_arg($args, "--loose-skip-ndbcluster");
+ mtr_add_arg($args, "--loose-skip-aria");
+ mtr_add_arg($args, "--disable-sync-frm");
+ mtr_add_arg($args, "--loose-disable-debug");
mtr_add_arg($args, "--tmpdir=.");
mtr_add_arg($args, "--core-file");
+ #
+ # Setup args for bootstrap.test
+ #
+ mtr_init_args(\$cmd_args);
+ mtr_add_arg($cmd_args, "--loose-skip-aria");
+
if ( $opt_debug )
{
mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap_%s.trace",
@@ -3145,7 +3195,8 @@ sub install_db ($$) {
# ----------------------------------------------------------------------
# export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args>
# ----------------------------------------------------------------------
- $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args);
+ $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args) .
+ " " . join(" ", @$cmd_args);
# ----------------------------------------------------------------------
# Create the bootstrap.sql file
@@ -3323,6 +3374,24 @@ sub run_testcase_check_skip_test($)
my ($tinfo)= @_;
# ----------------------------------------------------------------------
+ # Skip some tests silently
+ # ----------------------------------------------------------------------
+
+ if ( $::opt_start_from )
+ {
+ if ($tinfo->{'name'} eq $::opt_start_from )
+ {
+ ## Found parting test. Run this test and all tests after this one
+ $::opt_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
@@ -3904,17 +3973,22 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$mysqld->{'path_myddir'});
+ mtr_add_arg($args, "%s--disable-sync-frm", $prefix); # Faster test
- if ( $mysql_version_id >= 50106 )
+ if (!$opt_extern and $mysql_version_id >= 50106 )
{
# Turn on logging to bothe tables and file
mtr_add_arg($args, "%s--log-output=table,file", $prefix);
}
my $log_base_path= "$opt_vardir/log/$mysqld->{'type'}$sidx";
- mtr_add_arg($args, "%s--log=%s.log", $prefix, $log_base_path);
+ mtr_add_arg($args, "%s--general-log-file=%s.log",
+ $prefix, $log_base_path);
+ mtr_add_arg($args, "%s--general-log", $prefix);
mtr_add_arg($args,
- "%s--log-slow-queries=%s-slow.log", $prefix, $log_base_path);
+ "%s--slow-query-log-file=%s-slow.log",
+ $prefix, $log_base_path);
+ mtr_add_arg($args, "%s--slow-query-log", $prefix);
# Check if "extra_opt" contains --skip-log-bin
my $skip_binlog= grep(/^--skip-log-bin/, @$extra_opt, @opt_extra_mysqld_opt);
@@ -4038,10 +4112,17 @@ sub mysqld_arguments ($$$$) {
} # end slave
- if ( $opt_debug )
+ if ( $debug_compiled_binaries && defined $opt_debug )
{
- mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/%s%s.trace",
- $prefix, $path_vardir_trace, $mysqld->{'type'}, $sidx);
+ if ( $opt_debug )
+ {
+ mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/%s%s.trace",
+ $prefix, $path_vardir_trace, $mysqld->{'type'}, $sidx);
+ }
+ else
+ {
+ mtr_add_arg($args, "--disable-debug");
+ }
}
mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix);
@@ -4894,6 +4975,11 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "--skip-ssl");
}
+ foreach my $arg ( @opt_extra_mysqltest_opt )
+ {
+ mtr_add_arg($args, "%s", $arg);
+ }
+
# ----------------------------------------------------------------------
# If embedded server, we create server args to give mysqltest to pass on
# ----------------------------------------------------------------------
@@ -5009,13 +5095,9 @@ sub gdb_arguments {
else
{
# write init file for mysqld
- mtr_tofile($gdb_init_file,
- "set args $str\n" .
- "break mysql_parse\n" .
- "commands 1\n" .
- "disable 1\n" .
- "end\n" .
- "run");
+ mtr_tofile($gdb_init_file, <<EOGDB );
+set args $str
+EOGDB
}
if ( $opt_manual_gdb )
@@ -5075,11 +5157,7 @@ sub ddd_arguments {
# write init file for mysqld
mtr_tofile($gdb_init_file,
"file $$exe\n" .
- "set args $str\n" .
- "break mysql_parse\n" .
- "commands 1\n" .
- "disable 1\n" .
- "end");
+ "set args $str\n");
}
if ( $opt_manual_ddd )
@@ -5367,3 +5445,16 @@ HERE
mtr_exit(1);
}
+
+sub list_options ($) {
+ my $hash= shift;
+
+ for (keys %$hash) {
+ s/(=.*|!)$//;
+ s/\|/\n--/g;
+ print "--$_\n";
+ }
+
+ mtr_exit(1);
+}
+