From ba900fe30252bd7568a589036205581c0a2b5a91 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Thu, 24 Apr 2008 13:02:53 +0200 Subject: [PATCH 01/38] Add support for running in parallel --- mysql-test/lib/My/Options.pm | 3 + mysql-test/lib/My/SafeProcess.pm | 6 +- mysql-test/lib/My/Test.pm | 122 +++++++ mysql-test/lib/mtr_cases.pm | 103 ++---- mysql-test/lib/mtr_report.pm | 126 ++++++- mysql-test/mysql-test-run.pl | 576 ++++++++++++++++++++++--------- 6 files changed, 678 insertions(+), 258 deletions(-) create mode 100644 mysql-test/lib/My/Test.pm diff --git a/mysql-test/lib/My/Options.pm b/mysql-test/lib/My/Options.pm index f0fc4ba75b5..40f05c41d1c 100644 --- a/mysql-test/lib/My/Options.pm +++ b/mysql-test/lib/My/Options.pm @@ -61,6 +61,9 @@ sub _split_option { elsif ($option=~ /^--(.*)$/){ return ($1, undef) } + elsif ($option=~ /^\$(.*)$/){ # $VAR + return ($1, undef) + } elsif ($option=~ /^(.*)=(.*)$/){ return ($1, $2) } diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index 4d703d73b9a..eccc0fcdeed 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -65,7 +65,7 @@ END { # Kill any children still running for my $proc (values %running){ if ( $proc->is_child($$) ){ - print "Killing: $proc\n"; + #print "Killing: $proc\n"; $proc->kill(); } } @@ -461,8 +461,8 @@ sub wait_one { return 1; } - warn "wait_one: expected pid $pid but got $retpid" - unless( $retpid == $pid ); + #warn "wait_one: expected pid $pid but got $retpid" + # unless( $retpid == $pid ); $self->_collect(); return 0; diff --git a/mysql-test/lib/My/Test.pm b/mysql-test/lib/My/Test.pm new file mode 100644 index 00000000000..890ae76b282 --- /dev/null +++ b/mysql-test/lib/My/Test.pm @@ -0,0 +1,122 @@ +# -*- cperl -*- + + +# +# One test +# +package My::Test; + +use strict; +use warnings; +use Carp; + + +sub new { + my $class= shift; + my $self= bless { + @_, + }, $class; + return $self; +} + + +# +# Return a unique key that can be used to +# identify this test in a hash +# +sub key { + my ($self)= @_; + my $key= $self->{name}; + $key.= "+".$self->{combination} if $self->{combination}; + return $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}; + croak "'is_failed' can't be called until test has been run!" + unless defined $result; + + return ($result eq 'MTR_RES_FAILED'); +} + + +sub write_test { + my ($test, $sock, $header)= @_; + + 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"; +} + + +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); + } + } + 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 0f8329f2f31..4e10066c176 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -40,7 +40,7 @@ our $default_storage_engine; our $opt_with_ndbcluster_only; our $defaults_file; our $defaults_extra_file; -our $reorder; +our $reorder= 1; sub collect_option { my ($opt, $value)= @_; @@ -55,6 +55,7 @@ use File::Basename; use IO::File(); use My::Config; use My::Platform; +use My::Test; use My::Find; require "mtr_misc.pl"; @@ -135,52 +136,16 @@ sub collect_test_cases ($$) { { my @criteria = (); - # Look for tests that must be run in a defined order - that is - # defined by test having the same name except for the ending digit + # + # Append the criteria for sorting, in order of importance. + # + push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "A" : "B")); + # Group test with equal options together. + # Ending with "~" makes empty sort later than filled + my $opts= $tinfo->{'master_opt'} ? $tinfo->{'master_opt'} : []; + push(@criteria, join("!", sort @{$opts}) . "~"); - # Put variables into hash - my $test_name= $tinfo->{'name'}; - my $depend_on_test_name; - if ( $test_name =~ /^([\D]+)([0-9]{1})$/ ) - { - my $base_name= $1; - my $idx= $2; - mtr_verbose("$test_name => $base_name idx=$idx"); - if ( $idx > 1 ) - { - $idx-= 1; - $base_name= "$base_name$idx"; - mtr_verbose("New basename $base_name"); - } - - foreach my $tinfo2 (@$cases) - { - if ( $tinfo2->{'name'} eq $base_name ) - { - mtr_verbose("found dependent test $tinfo2->{'name'}"); - $depend_on_test_name=$base_name; - } - } - } - - if ( defined $depend_on_test_name ) - { - mtr_verbose("Giving $test_name same critera as $depend_on_test_name"); - $sort_criteria{$test_name} = $sort_criteria{$depend_on_test_name}; - } - else - { - # - # Append the criteria for sorting, in order of importance. - # - push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); - # Group test with equal options together. - # Ending with "~" makes empty sort later than filled - my $opts= $tinfo->{'master_opt'} ? $tinfo->{'master_opt'} : []; - push(@criteria, join("!", sort @{$opts}) . "~"); - - $sort_criteria{$test_name} = join(" ", @criteria); - } + $sort_criteria{$tinfo->{name}} = join(" ", @criteria); } @$cases = sort { @@ -454,7 +419,7 @@ sub collect_one_suite($) } # Copy test options - my $new_test= {}; + my $new_test= My::Test->new(); while (my ($key, $value) = each(%$test)) { if (ref $value eq "ARRAY") { push(@{$new_test->{$key}}, @$value); @@ -682,13 +647,16 @@ sub collect_one_test_case { # ---------------------------------------------------------------------- # Set defaults # ---------------------------------------------------------------------- - my $tinfo= {}; - $tinfo->{'name'}= $suitename . ".$tname"; - $tinfo->{'path'}= "$testdir/$filename"; + my $tinfo= My::Test->new + ( + name => "$suitename.$tname", + path => "$testdir/$filename", - # TODO allow nonexistsing result file - # in that case .test must issue "exit" otherwise test should fail by default - $tinfo->{'result_file'}= "$resdir/$tname.result"; + # TODO allow nonexistsing result file + # in that case .test must issue "exit" otherwise test + # should fail by default + result_file => "$resdir/$tname.result", + ); # ---------------------------------------------------------------------- # Skip some tests but include in list, just mark them as skipped @@ -1034,19 +1002,6 @@ sub unspace { } - -sub envsubst { - my $string= shift; - - if ( ! defined $ENV{$string} ) - { - mtr_error(".opt file references '$string' which is not set"); - } - - return $ENV{$string}; -} - - sub opts_from_file ($) { my $file= shift; @@ -1083,10 +1038,6 @@ sub opts_from_file ($) { or $arg =~ s/^([^\'\"]*)\"(.*)\"([^\'\"]*)$/$1$2$3/; $arg =~ s/\\\\/\\/g; - # Expand environment variables - $arg =~ s/\$\{(\w+)\}/envsubst($1)/ge; - $arg =~ s/\$(\w+)/envsubst($1)/ge; - # Do not pass empty string since my_getopt is not capable to handle it. if (length($arg)) { push(@args, $arg); @@ -1102,17 +1053,7 @@ sub print_testcases { print "=" x 60, "\n"; foreach my $test (@cases){ - print "[", $test->{name}, "]", "\n"; - while ((my ($key, $value)) = each(%$test)) { - print " ", $key, "= "; - if (ref $value eq "ARRAY") { - print "[", join(", ", @$value), "]"; - } else { - print $value; - } - print "\n"; - } - print "\n"; + $test->print_test(); } print "=" x 60, "\n"; } diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index a3c0f26c8fd..f749168c64a 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -27,7 +27,7 @@ our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line mtr_warning mtr_error mtr_debug mtr_verbose mtr_verbose_restart mtr_report_test_passed mtr_report_test_failed mtr_report_test_skipped - mtr_report_stats); + mtr_report_stats mtr_report_test); use mtr_match; require "mtr_io.pl"; @@ -35,6 +35,10 @@ require "mtr_io.pl"; my $tot_real_time= 0; our $timestamp= 0; +our $name; +our $verbose; +our $verbose_restart= 0; + sub report_option { my ($opt, $value)= @_; @@ -43,6 +47,8 @@ sub report_option { $opt =~ s/-/_/; no strict 'refs'; ${$opt}= $value; + + #print $name, " setting $opt to ", (defined $value? $value : "undef") ,"\n"; } sub SHOW_SUITE_NAME() { return 1; }; @@ -51,6 +57,8 @@ sub _mtr_report_test_name ($) { my $tinfo= shift; my $tname= $tinfo->{name}; + return unless defined $verbose; + # Remove suite part of name $tname =~ s/.*\.// unless SHOW_SUITE_NAME; @@ -58,7 +66,7 @@ sub _mtr_report_test_name ($) { $tname.= " '$tinfo->{combination}'" if defined $tinfo->{combination}; - print _timestamp(); + print $name, _timestamp(); printf "%-30s ", $tname; } @@ -100,12 +108,19 @@ sub mtr_report_test_passed ($$) { $timer= mtr_fromfile("$::opt_vardir/log/timer"); $tot_real_time += ($timer/1000); $timer= sprintf "%12s", $timer; + $tinfo->{timer}= $timer; } # Set as passed unless already set if ( not defined $tinfo->{'result'} ){ $tinfo->{'result'}= 'MTR_RES_PASSED'; } mtr_report("[ pass ] $timer"); + + # Show any problems check-testcase found + if ( defined $tinfo->{'check'} ) + { + mtr_report($tinfo->{'check'}); + } } @@ -143,9 +158,7 @@ sub mtr_report_test_failed ($$) { { # Test failure was detected by test tool and its report # about what failed has been saved to file. Display the report. - print "\n"; - mtr_printfile($logfile); - print "\n"; + $tinfo->{logfile}= mtr_fromfile($logfile); } else { @@ -156,6 +169,83 @@ sub mtr_report_test_failed ($$) { } +sub mtr_report_test ($) { + my ($tinfo)= @_; + _mtr_report_test_name($tinfo); + + if ($tinfo->{'result'} eq 'MTR_RES_FAILED'){ + + #my $test_failures= $tinfo->{'failures'} || 0; + #$tinfo->{'failures'}= $test_failures + 1; + if ( defined $tinfo->{'warnings'} ) + { + mtr_report("[ fail ] Found warnings in server log file!"); + mtr_report($tinfo->{'warnings'}); + return; + } + if ( defined $tinfo->{'timeout'} ) + { + mtr_report("[ fail ] timeout"); + return; + } + else + { + mtr_report("[ fail ]"); + } + + if ( $tinfo->{'comment'} ) + { + # The test failure has been detected by mysql-test-run.pl + # when starting the servers or due to other error, the reason for + # failing the test is saved in "comment" + mtr_report("\nERROR: $tinfo->{'comment'}"); + } + elsif ( $tinfo->{logfile} ) + { + # Test failure was detected by test tool and its report + # about what failed has been saved to file. Display the report. + mtr_report("\n"); + mtr_report($tinfo->{logfile}, "\n"); + + } + else + { + # Neither this script or the test tool has recorded info + # about why the test has failed. Should be debugged. + mtr_report("\nUnexpected termination, probably when starting mysqld");; + } + } + elsif ($tinfo->{'result'} eq 'MTR_RES_SKIPPED') + { + if ( $tinfo->{'disable'} ) + { + mtr_report("[ disabled ] $tinfo->{'comment'}"); + } + elsif ( $tinfo->{'comment'} ) + { + if ( $tinfo->{skip_detected_by_test} ) + { + mtr_report("[ skip ]. $tinfo->{'comment'}"); + } + else + { + mtr_report("[ skip ] $tinfo->{'comment'}"); + } + } + else + { + mtr_report("[ skip ]"); + } + } + elsif ($tinfo->{'result'} eq 'MTR_RES_PASSED') + { + my $timer= $tinfo->{timer} || ""; + mtr_report("[ pass ] $timer"); + } + +} + + sub mtr_report_stats ($) { my $tests= shift; @@ -342,35 +432,42 @@ sub _timestamp { # Print message to screen sub mtr_report (@) { - print join(" ", @_), "\n"; + if (defined $verbose) + { + print join(" ", @_), "\n"; + } } # Print warning to screen sub mtr_warning (@) { - print STDERR _timestamp(), "mysql-test-run: WARNING: ", join(" ", @_), "\n"; + print STDERR $name, _timestamp(), + "mysql-test-run: WARNING: ", join(" ", @_), "\n"; } # Print error to screen and then exit sub mtr_error (@) { - print STDERR _timestamp(), "mysql-test-run: *** ERROR: ", join(" ", @_), "\n"; + print STDERR $name, _timestamp(), + "mysql-test-run: *** ERROR: ", join(" ", @_), "\n"; exit(1); } sub mtr_debug (@) { - if ( $::opt_verbose > 1 ) + if ( $verbose > 2 ) { - print STDERR _timestamp(), "####: ", join(" ", @_), "\n"; + print STDERR $name, + _timestamp(), "####: ", join(" ", @_), "\n"; } } sub mtr_verbose (@) { - if ( $::opt_verbose ) + if ( $verbose ) { - print STDERR _timestamp(), "> ",join(" ", @_),"\n"; + print STDERR $name, _timestamp(), + "> ",join(" ", @_),"\n"; } } @@ -378,9 +475,10 @@ sub mtr_verbose (@) { sub mtr_verbose_restart (@) { my ($server, @args)= @_; my $proc= $server->{proc}; - if ( $::opt_verbose_restart ) + if ( $verbose_restart ) { - print STDERR _timestamp(), "> Restart $proc - ",join(" ", @args),"\n"; + print STDERR $name,_timestamp(), + "> Restart $proc - ",join(" ", @args),"\n"; } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index cf23d63ee13..3b252b9dde3 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -51,6 +51,8 @@ use My::Find; use mtr_cases; use mtr_report; use mtr_match; +use IO::Socket::INET; +use IO::Select; require "lib/mtr_process.pl"; require "lib/mtr_io.pl"; @@ -88,7 +90,6 @@ my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb"; my $opt_suites; our $opt_verbose= 0; # Verbose output, enable with --verbose -our $opt_verbose_restart= 0; # Verbose output for restarts our $exe_mysql; our $exe_mysqladmin; @@ -141,7 +142,7 @@ my $config; # The currently running config my $current_config_name; # The currently running config file template my $opt_baseport; -my $opt_mtr_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto"; +my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto"; my $opt_record; my $opt_report_features; @@ -161,6 +162,8 @@ my $opt_repeat= 1; my $opt_retry= 3; my $opt_retry_failure= 2; +my $opt_parallel= 1; + my $opt_strace_client; our $opt_timer= 1; @@ -203,25 +206,46 @@ main(); sub main { - command_line_setup(); + # This is needed for test log evaluation in "gen-build-status-page" + # in all cases where the calling tool does not log the commands + # directly before it executes them, like "make test-force-pl" in RPM builds. + mtr_report("Logging: $0 ", join(" ", @ARGV)); - mtr_report("Checking supported features..."); + Getopt::Long::Configure("pass_through"); + GetOptions('parallel=i' => \$opt_parallel) or usage("Can't read options"); - check_ndbcluster_support(\%mysqld_variables); - check_ssl_support(\%mysqld_variables); - check_debug_support(\%mysqld_variables); + # Create server socket on any free port + my $server = new IO::Socket::INET + ( + LocalAddr => 'localhost', + Proto => 'tcp', + Listen => $opt_parallel, + ); + mtr_error("Could not create testcase server port: $!") unless $server; + my $server_port = $server->sockport(); + mtr_report("Using server port $server_port"); - executable_setup(); + # Create child processes + my %children; + for my $child_num (1..$opt_parallel){ + my $child_pid= My::SafeProcess::Base::_safe_fork(); + if ($child_pid == 0){ + $server= undef; # Close the server port in child + run_worker($server_port, $child_num); + exit(1); + } - environment_setup(); + mtr_report("Started worker, pid: $child_pid"); + $children{$child_pid}= 1; + } - if ( $opt_gcov ) - { + command_line_setup(0); + + if ( $opt_gcov ) { gcov_prepare(); } - if (!$opt_suites) - { + if (!$opt_suites) { $opt_suites= $DEFAULT_SUITES; # Check for any extra suites to enable based on the path name @@ -235,10 +259,9 @@ sub main { "mysql-6.0-ndb" => "ndb_team", ); - foreach my $dir ( reverse splitdir($basedir) ) - { + foreach my $dir ( reverse splitdir($basedir) ) { my $extra_suite= $extra_suites{$dir}; - if (defined $extra_suite){ + if (defined $extra_suite) { mtr_report("Found extra suite: $extra_suite"); $opt_suites= "$extra_suite,$opt_suites"; last; @@ -249,26 +272,289 @@ sub main { mtr_report("Collecting tests..."); my $tests= collect_test_cases($opt_suites, \@opt_cases); - initialize_servers(); - if ( $opt_report_features ) { # Put "report features" as the first test to run - my $tinfo = {}; - $tinfo->{'name'} = 'report_features'; - $tinfo->{'result_file'} = undef; # Prints result - $tinfo->{'path'} = 'include/report-features.test'; - $tinfo->{'master_opt'} = []; - $tinfo->{'slave_opt'} = []; + my $tinfo = My::Test->new + ( + name => 'report_features', + result_file => undef, # Prints result + path => 'include/report-features.test'. + master_opt => [], + slave_opt => [], + ); unshift(@$tests, $tinfo); } + initialize_servers(); + + mtr_report(); + mtr_print_thick_line(); + mtr_print_header(); + + my $completed= run_test_server($server, $tests, $opt_parallel); + + # Send Ctrl-C to any children still running + kill("INT", keys(%children)); + + # Wait for childs to exit + foreach my $pid (keys %children) + { + my $ret_pid= waitpid($pid, 0); + if ($ret_pid != $pid){ + mtr_report("Unknown process $ret_pid exited"); + } + else { + delete $children{$ret_pid}; + } + } + + mtr_verbose("Server exit\n"); + + mtr_print_line(); + + mtr_report_stats($completed); + + exit(0); +} + + +sub run_test_server { + my ($server, $tests, $childs) = @_; + + # Scheduler variables + my $max_ndb= $opt_parallel / 2; + $max_ndb = 4 if $max_ndb > 4; + $max_ndb = 1 if $max_ndb < 1; + my $num_ndb_tests= 0; + + my $completed= []; + my %running; + my $result; + + my $s= IO::Select->new(); + $s->add($server); + while (1) { + my @ready = $s->can_read(1); # Wake up once every second + foreach my $sock (@ready) { + if ($sock == $server) { + # New client connected + my $child= $sock->accept(); + mtr_verbose("Client connected"); + $s->add($child); + print $child "HELLO\n"; + } + else { + my $line= <$sock>; + if (!defined $line) { + # Client disconnected + mtr_verbose("Child closed socket"); + $s->remove($sock); + if (--$childs == 0){ + return $completed; + } + next; + } + chomp($line); + + if ($line eq 'TESTRESULT'){ + $result= My::Test::read_test($sock); + # $result->print_test(); + + # Report test status + mtr_report_test($result); + + if ($result->is_failed() and !$opt_force){ + # Test has failed, force is off + push(@$completed, $result); + return $completed; + } + + # Retry test run after test failure + my $retries= $result->{retries} || 1; + my $test_has_failed= $result->{failures} || 0; + if ($test_has_failed and $retries < $opt_retry){ + # Test should be run one more time unless it has failed + # too many times already + my $failures= $result->{failures}; + if ($opt_retry > 1 and $failures >= $opt_retry_failure){ + mtr_report("Test has failed $failures times,", + "no more retries!\n"); + } + else { + mtr_report("\nRetrying test, attempt($retries/$opt_retry)...\n"); + $result->{retries}= $retries+1; + $result->write_test($sock, 'TESTCASE'); + next; + } + } + + # Repeat test $opt_repeat number of times + my $repeat= $result->{repeat} || 1; + if ($repeat < $opt_repeat) + { + $result->{retries}= 0; + $result->{failures}= 0; + + $result->{repeat}= $repeat+1; + $result->write_test($sock, 'TESTCASE'); + next; + } + + # Remove from list of running + mtr_error("'", $result->{name},"' is not known to be running") + unless delete $running{$result->key()}; + + # Update scheduler variables + $num_ndb_tests-- if ($result->{ndb_test}); + + # Save result in completed list + push(@$completed, $result); + + } + elsif ($line eq 'START'){ + ; # Send first test + } + else { + mtr_error("Unknown response: '$line' from client"); + } + + # Find next test to schedule + # - Try to use same configuration as worker used last time + # - Limit number of parallel ndb tests + + my $next; + my $second_best; + for(my $i= 0; $i <= $#$tests; $i++) + { + my $t= $tests->[$i]; + + if (run_testcase_check_skip_test($t)){ + # Move the test to completed list + #mtr_report("skip - Moving test $i to completed"); + push(@$completed, splice(@$tests, $i, 1)); + redo; # Start over again + } + + # Limit number of parallell NDB tests + if ($t->{ndb_test} and $num_ndb_tests >= $max_ndb){ + #mtr_report("Skipping, num ndb is already at max, $num_ndb_tests"); + next; + } + + # Prefer same configuration + if (defined $result and + $result->{template_path} eq $t->{template_path}) + { + #mtr_report("Test uses same config => good match"); + # Test uses same config => good match + $next= splice(@$tests, $i, 1); + last; + } + + # Second best choice is the first that does not fulfill + # any of the above conditions + if (!defined $second_best){ + #mtr_report("Setting second_best to $i"); + $second_best= $i; + } + } + + # Use second best choice if no other test has been found + if (!$next and defined $second_best){ + #mtr_report("Take second best choice $second_best"); + mtr_error("Internal error, second best too large") + if $second_best > $#$tests; + $next= splice(@$tests, $second_best, 1); + } + + if ($next) { + #$next->print_test(); + $next->write_test($sock, 'TESTCASE'); + $running{$next->key()}= $next; + $num_ndb_tests++ if ($next->{ndb_test}); + } + else { + # No more test, tell child to exit + #mtr_report("Saying BYE to child"); + print $sock "BYE\n"; + } + } + } + } +} + + +sub run_worker ($) { + my ($server_port, $thread_num)= @_; + + $SIG{INT}= sub { exit(1); }; + + report_option('name',"worker[$thread_num]"); + + # Connect to server + my $server = new IO::Socket::INET + ( + PeerAddr => 'localhost', + PeerPort => $server_port, + Proto => 'tcp' + ); + mtr_error("Could not connect to server at port $server_port: $!") + unless $server; + + # Read hello from server which it will send when shared + # resources have been setup + my $hello= <$server>; + + command_line_setup($thread_num); + + if ( $opt_gcov ) + { + gcov_prepare(); + } + + setup_vardir(); + mysql_install_db($thread_num); + if ( using_extern() ) { create_config_file_for_extern(%opts_extern); } - run_tests($tests); + # Ask server for first test + print $server "START\n"; - exit(0); + while(my $line= <$server>){ + chomp($line); + if ($line eq 'TESTCASE'){ + my $test= My::Test::read_test($server); + #$test->print_test(); + run_testcase($test); + #$test->{result}= 'MTR_RES_PASSED'; + # Send it back, now with results set + #$test->print_test(); + $test->write_test($server, 'TESTRESULT'); + } + elsif ($line eq 'BYE'){ + mtr_report("Server said BYE"); + exit(0); + } + else { + mtr_error("Could not understand server, '$line'"); + } + } + + stop_all_servers(); + + if ( $opt_gcov ) + { + gcov_collect(); # collect coverage information + } + + if ( $opt_gcov ) + { + gcov_collect(); # collect coverage information + } + + exit(1); } @@ -278,14 +564,11 @@ sub ignore_option { } sub command_line_setup { + my ($thread_num)= @_; + my $opt_comment; my $opt_usage; - # This is needed for test log evaluation in "gen-build-status-page" - # in all cases where the calling tool does not log the commands - # directly before it executes them, like "make test-force-pl" in RPM builds. - mtr_report("Logging: $0 ", join(" ", @ARGV)); - # Read the command line options # Note: Keep list, and the order, in sync with usage at end of this file Getopt::Long::Configure("pass_through"); @@ -325,7 +608,7 @@ sub command_line_setup { 'skip-im' => \&ignore_option, # Specify ports - 'build-thread|mtr-build-thread=i' => \$opt_mtr_build_thread, + 'build-thread|mtr-build-thread=i' => \$opt_build_thread, # Test case authoring 'record' => \$opt_record, @@ -383,10 +666,10 @@ sub command_line_setup { 'report-features' => \$opt_report_features, 'comment=s' => \$opt_comment, 'fast' => \$opt_fast, - 'reorder' => \&collect_option, + 'reorder!' => \&collect_option, 'enable-disabled' => \&collect_option, 'verbose+' => \$opt_verbose, - 'verbose-restart' => \$opt_verbose_restart, + 'verbose-restart' => \&report_option, 'sleep=i' => \$opt_sleep, 'start-dirty' => \$opt_start_dirty, 'start' => \$opt_start, @@ -408,9 +691,21 @@ sub command_line_setup { usage("") if $opt_usage; # -------------------------------------------------------------------------- - # Check mtr_build_thread and calculate baseport + # Setup verbosity # -------------------------------------------------------------------------- - set_mtr_build_thread_ports($opt_mtr_build_thread); + if ($thread_num == 0){ + # The server should by default have verbose on + report_option('verbose', $opt_verbose ? $opt_verbose : 0); + } else { + # Worker should by default have verbose off + report_option('verbose', $opt_verbose ? $opt_verbose : undef); + } + + # -------------------------------------------------------------------------- + # Check build_thread and calculate baseport + # Use auto build thread in all but first worker + # -------------------------------------------------------------------------- + set_build_thread_ports($thread_num > 1 ? 'auto' : $opt_build_thread); if ( -d "../sql" ) { @@ -537,8 +832,9 @@ sub command_line_setup { # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs + # - Dont check in workers # -------------------------------------------------------------------------- - if ( defined $opt_mem ) + if ( defined $opt_mem and $thread_num == 0) { mtr_error("Can't use --mem and --vardir at the same time ") if $opt_vardir; @@ -554,7 +850,7 @@ sub command_line_setup { { if ( -d $fs ) { - my $template= "var_${opt_mtr_build_thread}_XXXX"; + my $template= "var_${opt_build_thread}_XXXX"; $opt_mem= tempdir( $template, DIR => $fs, CLEANUP => 0); last; } @@ -569,21 +865,11 @@ sub command_line_setup { { $opt_vardir= $default_vardir; } - elsif ( $mysql_version_id < 50000 and - $opt_vardir ne $default_vardir) - { - # Version 4.1 and --vardir was specified - # Only supported as a symlink from var/ - # by setting up $opt_mem that symlink will be created - if ( ! IS_WINDOWS ) - { - # Only platforms that have native symlinks can use the vardir trick - $opt_mem= $opt_vardir; - mtr_report("Using 4.1 vardir trick"); - } - $opt_vardir= $default_vardir; - } + # If more than one parallel run, use a subdir of the selected var + if ($thread_num && $opt_parallel > 1) { + $opt_vardir.= "/".$thread_num; + } $path_vardir_trace= $opt_vardir; # Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/... @@ -738,6 +1024,16 @@ sub command_line_setup { $path_testlog= "$opt_vardir/log/mysqltest.log"; $path_current_testlog= "$opt_vardir/log/current_test"; + mtr_report("Checking supported features..."); + + check_ndbcluster_support(\%mysqld_variables); + check_ssl_support(\%mysqld_variables); + check_debug_support(\%mysqld_variables); + + executable_setup(); + + environment_setup(); + } @@ -756,19 +1052,20 @@ sub command_line_setup { # http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html # But a fairly safe range seems to be 5001 - 32767 # -sub set_mtr_build_thread_ports($) { - my $mtr_build_thread= shift || 0; +sub set_build_thread_ports($) { + my $build_thread= shift || 0; - if ( lc($mtr_build_thread) eq 'auto' ) { - print "Requesting build thread... "; - $mtr_build_thread= + if ( lc($build_thread) eq 'auto' ) { + mtr_report("Requesting build thread... "); + $build_thread= mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299); - print "got ".$mtr_build_thread."\n"; + mtr_report(" - got $build_thread"); } - $ENV{MTR_BUILD_THREAD}= $mtr_build_thread; + $ENV{MTR_BUILD_THREAD}= $build_thread; + $opt_build_thread= $build_thread; # Calculate baseport - $opt_baseport= $mtr_build_thread * 10 + 10000; + $opt_baseport= $build_thread * 10 + 10000; if ( $opt_baseport < 5001 or $opt_baseport + 9 >= 32767 ) { mtr_error("MTR_BUILD_THREAD number results in a port", @@ -776,7 +1073,7 @@ sub set_mtr_build_thread_ports($) { "($opt_baseport - $opt_baseport + 9)"); } - mtr_report("Using MR_BUILD_THREAD $mtr_build_thread,", + mtr_report("Using MTR_BUILD_THREAD $build_thread,", "with reserved ports $opt_baseport..".($opt_baseport+9)); } @@ -1383,7 +1680,7 @@ sub remove_stale_vardir () { # Create var and the directories needed in var # sub setup_vardir() { - mtr_report("Creating var directory..."); + mtr_report("Creating var directory '$opt_vardir'..."); if ( $opt_vardir eq $default_vardir ) { @@ -1773,76 +2070,6 @@ sub ndbcluster_start ($) { } -# -# Run the collected tests -# -my $suite_timeout_proc; -sub run_tests { - my ($tests)= @_; - - mtr_report(); - mtr_print_thick_line(); - mtr_print_header(); - - $suite_timeout_proc= My::SafeProcess->timer($opt_suite_timeout* 60); - foreach my $tinfo ( @$tests ) - { - if (run_testcase_check_skip_test($tinfo)) - { - next; - } - - for my $repeat (1..$opt_repeat){ - - if (run_testcase($tinfo)) - { - # Testcase failed, enter retry mode - my $retries= 1; - while ($retries < $opt_retry){ - mtr_report("\nRetrying, attempt($retries/$opt_retry)...\n"); - - if (run_testcase($tinfo) <= 0) - { - # Testcase suceeded - - my $test_has_failed= $tinfo->{failures} || 0; - if (!$test_has_failed){ - last; - } - } - else - { - # Testcase failed - - # Limit number of test failures - my $failures= $tinfo->{failures}; - if ($opt_retry > 1 and $failures >= $opt_retry_failure){ - mtr_report("Test has failed $failures times, no more retries!\n"); - last; - } - } - $retries++; - } - } - } - } - # Kill the test suite timer - $suite_timeout_proc->kill(); - - mtr_print_line(); - - stop_all_servers(); - - if ( $opt_gcov ) - { - gcov_collect(); # collect coverage information - } - - mtr_report_stats($tests); - -} - - sub create_config_file_for_extern { my %opts= ( @@ -1990,7 +2217,7 @@ sub initialize_servers { remove_stale_vardir(); setup_vardir(); - mysql_install_db(); + mysql_install_db(0); } } check_running_as_root(); @@ -2044,6 +2271,7 @@ sub sql_to_bootstrap { sub mysql_install_db { + my ($thread_num)= @_; my $data_dir= "$opt_vardir/install.db"; mtr_report("Installing system database..."); @@ -2080,6 +2308,8 @@ sub mysql_install_db { # ---------------------------------------------------------------------- $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args); + return if $thread_num > 0; # Only generate MYSQLD_BOOTSTRAP_CMD in workers + # ---------------------------------------------------------------------- # Create the bootstrap.sql file # ---------------------------------------------------------------------- @@ -2387,7 +2617,7 @@ sub run_testcase ($) { # ---------------------------------------------------------------------- if ( $opt_start or $opt_start_dirty ) { - $suite_timeout_proc->kill(); +# MASV $suite_timeout_proc->kill(); mtr_report("\nStarted", started(all_servers())); mtr_report("Waiting for server(s) to exit..."); my $proc= My::SafeProcess->wait_any(); @@ -2538,11 +2768,12 @@ sub run_testcase ($) { # ---------------------------------------------------- # Check if test suite timer expired # ---------------------------------------------------- - if ( $proc eq $suite_timeout_proc ) - { - mtr_report("Test suite timeout! Terminating..."); - exit(1); - } +# MASV +# if ( $proc eq $suite_timeout_proc ) +# { +# mtr_report("Test suite timeout! Terminating..."); +# exit(1); +# } mtr_error("Unhandled process $proc exited"); } @@ -2617,7 +2848,7 @@ sub check_warnings ($) { my $res= 0; # Clear previous warnings - $tinfo->{warnings}= undef; + delete($tinfo->{warnings}); # Parallell( mysqlds(), run_check_warning, check_warning_failed); foreach my $mysqld ( mysqlds() ) @@ -2727,18 +2958,14 @@ sub report_failure_and_restart ($) { my $tinfo= shift; mtr_report_test_failed($tinfo, $path_current_testlog); - print "\n"; - if ( $opt_force ) - { - # Stop all servers that are known to be running - stop_all_servers(); - after_test_failure($tinfo->{'name'}); - mtr_report("Resuming tests...\n"); - return; - } - mtr_error("Test '$tinfo->{'name'}' failed.", - "To continue, re-run with '--force'"); + # Stop all servers that are known to be running + stop_all_servers(); + + # Collect and clean files + after_test_failure($tinfo->{'name'}); + + mtr_report("Resuming tests...\n"); } @@ -3118,12 +3345,32 @@ 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 { my ($mysqld, $tinfo)= @_; - return + my $opts= $mysqld->option("#!use-slave-opt") ? $tinfo->{slave_opt} : $tinfo->{master_opt}; + + # Expand environment variables + foreach my $opt ( @$opts ) + { + $opt =~ s/\$\{(\w+)\}/envsubst($1)/ge; + $opt =~ s/\$(\w+)/envsubst($1)/ge; + } + return $opts; } @@ -3227,7 +3474,12 @@ sub start_servers($) { } # Copy datadir from installed system db - copytree("$opt_vardir/install.db", $datadir) + 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; # Write start of testcase to log file @@ -3332,16 +3584,20 @@ sub run_check_testcase ($$$) { if ( $mode eq "after" and $res == 1 ) { - mtr_report("\nThe check of testcase '$tname' failed, this is the\n", - "diff between before and after:\n"); - # Test failed, display the report mysqltest has created - mtr_printfile($errfile); + # Test failed, grab the report mysqltest has created + my $report= mtr_grab_file($errfile); + $tinfo->{check}.= + "\nThe check of testcase '$tname' failed, this is the\n". + "diff between before and after:\n"; + $tinfo->{check}.= $report; + } elsif ( $res ) { - mtr_report("\nCould not execute 'check-testcase' $mode testcase '$tname':"); - mtr_printfile($errfile); - mtr_report(); + my $report= mtr_grab_file($errfile); + $tinfo->{'check'}.= + "\nCould not execute 'check-testcase' $mode testcase '$tname':\n"; + $tinfo->{check}.= $report; } return $res; } From 5681c996457d1cd8df58f5d5321a3c393ce3a567 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Thu, 24 Apr 2008 20:24:24 +0200 Subject: [PATCH 02/38] Print name(of thread) also in mtr_report, testserver does not set name so it will still look the same, but makes debugging much easier --- mysql-test/lib/mtr_report.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index f749168c64a..2dcf483dce0 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -434,7 +434,7 @@ sub _timestamp { sub mtr_report (@) { if (defined $verbose) { - print join(" ", @_), "\n"; + print $name, join(" ", @_), "\n"; } } From 13461e33d590fefa3bb3cb911a225276e1cb37cf Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Thu, 24 Apr 2008 20:25:00 +0200 Subject: [PATCH 03/38] If more than one parallel run, use a subdir of the selected tmpdir --- mysql-test/mysql-test-run.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index cb9b7970c9f..16335153140 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -892,6 +892,11 @@ sub command_line_setup { $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir; $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any + # If more than one parallel run, use a subdir of the selected tmpdir + if ($thread_num && $opt_parallel > 1) { + $opt_tmpdir.= "/".$thread_num; + } + # -------------------------------------------------------------------------- # fast option # -------------------------------------------------------------------------- From b1d7f68443629e4b8585d947770048447f51cc18 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Fri, 25 Apr 2008 10:31:13 +0200 Subject: [PATCH 04/38] Don't print stats when test run is abort because of test failure --- mysql-test/mysql-test-run.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c2e9bd7cf65..c1fca25c477 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -291,6 +291,7 @@ sub main { mtr_print_thick_line(); mtr_print_header(); + my $num_tests= @$tests; my $completed= run_test_server($server, $tests, $opt_parallel); # Send Ctrl-C to any children still running @@ -308,6 +309,12 @@ sub main { } } + if ( @$completed != $num_tests){ + # Not all tests completed, failure + mtr_error("Test failed.", + "To continue, re-run with '--force'"); + } + mtr_verbose("Server exit\n"); mtr_print_line(); From 425ceb2a65b99f080e8795867a260cbea63b5c2e Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Fri, 25 Apr 2008 14:38:46 +0200 Subject: [PATCH 05/38] Add lib/my/Test.pm --- mysql-test/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 31804714900..02dea1a4466 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -38,6 +38,7 @@ nobase_test_DATA = lib/mtr_cases.pm \ lib/My/Config.pm \ lib/My/Find.pm \ lib/My/Options.pm \ + lib/My/Test.pm \ lib/My/Platform.pm \ lib/My/SafeProcess.pm \ lib/My/File/Path.pm \ From fa5d32de711b003c3b11a62179eea95f24305854 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sat, 26 Apr 2008 09:35:04 +0200 Subject: [PATCH 06/38] Don't use empty string instead of --plugin-dir when plugins are not found --- mysql-test/mysql-test-run.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c1fca25c477..b033166513a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1404,8 +1404,8 @@ sub environment_setup { $ENV{'UDF_EXAMPLE_LIB'}= ($lib_udf_example ? basename($lib_udf_example) : ""); - $ENV{'UDF_EXAMPLE_LIB_OPT'}= - ($lib_udf_example ? "--plugin_dir=" . dirname($lib_udf_example) : ""); + $ENV{'UDF_EXAMPLE_LIB_OPT'}= "--plugin-dir=". + ($lib_udf_example ? dirname($lib_udf_example) : ""); # -------------------------------------------------------------------------- # Add the path where mysqld will find ha_example.so @@ -1416,9 +1416,9 @@ sub environment_setup { "$basedir/storage/example/.libs/ha_example.so",); $ENV{'EXAMPLE_PLUGIN'}= ($lib_example_plugin ? basename($lib_example_plugin) : ""); - $ENV{'EXAMPLE_PLUGIN_OPT'}= - ($lib_example_plugin ? - "--plugin_dir=" . dirname($lib_example_plugin) : ""); + $ENV{'EXAMPLE_PLUGIN_OPT'}= "--plugin-dir=". + ($lib_example_plugin ? dirname($lib_example_plugin) : ""); + } # -------------------------------------------------------------------------- From d0d79913adf741865891279e69c039591399bf74 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sat, 26 Apr 2008 22:16:20 +0200 Subject: [PATCH 07/38] Use parallel=4 as default --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b033166513a..b7fd4974754 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -162,7 +162,7 @@ my $opt_repeat= 1; my $opt_retry= 3; my $opt_retry_failure= 2; -my $opt_parallel= 1; +my $opt_parallel= 4; my $opt_strace_client; From 17158847523f8c2d11a0387c47ff9e1138a72c2c Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 27 Apr 2008 16:16:50 +0200 Subject: [PATCH 08/38] Increase start timeout when running parallell Fix comments --- mysql-test/mysql-test-run.pl | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3de7f730af3..d2b5422e068 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -151,10 +151,10 @@ my $opt_mark_progress; my $opt_sleep; -my $opt_testcase_timeout= 15; # 15 minutes -my $opt_suite_timeout = 180; # 3 hours -my $opt_shutdown_timeout= 10; # 10 seconds -my $opt_start_timeout = 30; # 30 seconds +my $opt_testcase_timeout= 15; # minutes +my $opt_suite_timeout = 180; # minutes +my $opt_shutdown_timeout= 10; # seconds +my $opt_start_timeout = 30; # seconds my $opt_start; my $opt_start_dirty; @@ -162,7 +162,7 @@ my $opt_repeat= 1; my $opt_retry= 3; my $opt_retry_failure= 2; -my $opt_parallel= 4; +my $opt_parallel; my $opt_strace_client; @@ -217,6 +217,10 @@ sub main { Getopt::Long::Configure("pass_through"); GetOptions('parallel=i' => \$opt_parallel) or usage("Can't read options"); + if ( not defined $opt_parallel ){ + $opt_parallel= 4; # Default + } + # Create server socket on any free port my $server = new IO::Socket::INET ( @@ -985,6 +989,11 @@ sub command_line_setup { } # -------------------------------------------------------------------------- + # Set timeout values + # -------------------------------------------------------------------------- + $opt_start_timeout*= $opt_parallel; + + # # Check valgrind arguments # -------------------------------------------------------------------------- if ( $opt_valgrind or $opt_valgrind_path or @valgrind_args) From b18a64979a64664b912076bb9b43b28510348831 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 27 Apr 2008 21:31:32 +0200 Subject: [PATCH 09/38] Run all check-warning and check-testcase in parallel, this also give the oportunity to check if any other process fails during this. Add possiblitiy to store "user_data" in a Safeprocess Add function to get pid from a SafeProcess --- mysql-test/lib/My/SafeProcess.pm | 14 ++ mysql-test/lib/mtr_report.pm | 6 + mysql-test/mysql-test-run.pl | 244 ++++++++++++++++++++++--------- 3 files changed, 196 insertions(+), 68 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index eccc0fcdeed..7762441496c 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -128,6 +128,7 @@ sub new { my $verbose = delete($opts{'verbose'}); my $host = delete($opts{'host'}); my $shutdown = delete($opts{'shutdown'}); + my $user_data= delete($opts{'user_data'}); # if (defined $host) { # $safe_script= "lib/My/SafeProcess/safe_process_cpcd.pl"; @@ -173,6 +174,7 @@ sub new { SAFE_NAME => $name, SAFE_SHUTDOWN => $shutdown, PARENT => $$, + SAFE_USER_DATA => $user_data, }, $class); # Put the new process in list of running @@ -546,4 +548,16 @@ sub _verbose { print STDERR " ## ", @_, "\n"; } + +sub pid { + my ($self)= @_; + return $self->{SAFE_PID}; +} + +sub user_data { + my ($self)= @_; + return $self->{SAFE_USER_DATA}; +} + + 1; diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index fcb4c614653..18c752d018d 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -242,6 +242,12 @@ sub mtr_report_test ($) { { my $timer= $tinfo->{timer} || ""; mtr_report("[ pass ] $timer"); + + # Show any problems check-testcase found + if ( defined $tinfo->{'check'} ) + { + mtr_report($tinfo->{'check'}); + } } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 9742be9a00f..5ef452318c5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2482,25 +2482,90 @@ sub do_before_run_mysqltest($) } +# +# Check all server for sideffects +# +# RETURN VALUE +# 0 ok +# 1 Check failed +# >1 Fatal errro + sub check_testcase($$) { my ($tinfo, $mode)= @_; - my $result; + my $tname= $tinfo->{name}; - # Parallell( mysqlds(), run_check_testcase, check_testcase_failed ); + # Start the mysqltest processes in parallel to save time + # also makes it possible to wait for any process to exit during the check + my %started; foreach my $mysqld ( mysqlds() ) { if ( defined $mysqld->{'proc'} ) { - if (run_check_testcase($tinfo, $mode, $mysqld)) - { - # Check failed, mark the test case with that info - $tinfo->{'check_testcase_failed'}= 1; - $result= 1; - } + my $proc= start_check_testcase($tinfo, $mode, $mysqld); + $started{$proc->pid()}= $proc; } } - return $result; + + while (1){ + my $result; + my $proc= My::SafeProcess->wait_any(); + mtr_report("Got $proc"); + + if ( delete $started{$proc->pid()} ) { + # One check testcase process returned + my $res= $proc->exit_status(); + + if ( $res == 0){ + # Check completed without problem + + if ( keys(%started) == 0){ + # All checks completed + return 0; + } + # Wait for next process to exit + next; + } + else + { + if ( $mode eq "after" and $res == 1 ) + { + # Test failed, grab the report mysqltest has created + my $report= mtr_grab_file($proc->user_data()); + $tinfo->{check}.= + "\nThe check of testcase '$tname' failed, this is the\n". + "diff between before and after:\n"; + $tinfo->{check}.= $report; + + # Check failed, mark the test case with that info + $tinfo->{'check_testcase_failed'}= 1; + $result= 1; + } + elsif ( $res ) + { + my $report= mtr_grab_file($proc->user_data()); + $tinfo->{comment}.= + "Could not execute 'check-testcase' $mode testcase '$tname':\n"; + $tinfo->{comment}.= $report; + + $result= 2; + } + + } + } + else { + # Unknown process returned, most likley a crash, abort everything + $tinfo->{comment}= + "Unexpected process $proc returned during ". + "check testcase $mode test"; + $result= 3; + } + + # Kill any check processes still running + map($_->kill(), values(%started)); + + return $result; + } } @@ -2668,9 +2733,10 @@ sub run_testcase ($) { do_before_run_mysqltest($tinfo); - if ( $opt_check_testcases ) - { - check_testcase($tinfo, "before") + if ( $opt_check_testcases and check_testcase($tinfo, "before") ){ + # Failed to record state of server or server crashed + report_failure_and_restart($tinfo); + return 1; } my $test= start_mysqltest($tinfo); @@ -2707,12 +2773,21 @@ sub run_testcase ($) { mtr_report_test_passed($tinfo, $opt_timer); } - if ( $opt_check_testcases and check_testcase($tinfo, "after")) + my $check_res; + if ( $opt_check_testcases and + $check_res= check_testcase($tinfo, "after")) { - # Stop all servers that are known to be running - stop_all_servers(); - clean_datadir(); - mtr_report("Resuming tests...\n"); + if ($check_res == 1) { + # Test case had sideeffects, not fatal error, just continue + stop_all_servers(); + clean_datadir(); + mtr_report("Resuming tests...\n"); + } + else { + # Test case check failed fatally, probably a server crashed + report_failure_and_restart($tinfo); + return 1; + } } } elsif ( $res == 62 ) @@ -2818,7 +2893,7 @@ sub run_testcase ($) { # 0 OK # 1 Check failed # -sub run_check_warnings ($$) { +sub start_check_warnings ($$) { my $tinfo= shift; my $mysqld= shift; @@ -2836,37 +2911,17 @@ sub run_check_warnings ($$) { mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test"); my $errfile= "$opt_vardir/tmp/$name.err"; - my $res= My::SafeProcess->run + my $proc= My::SafeProcess->new ( name => $name, path => $exe_mysqltest, error => $errfile, output => $errfile, args => \$args, + user_data => $errfile, ); - - if ( $res == 0 ) - { - my $report= mtr_grab_file($errfile); - # Log to var/log/warnings file - mtr_tofile("$opt_vardir/log/warnings", - $tname."\n", - $report); - - $res= 1; - $tinfo->{'warnings'}.= $report; - } - elsif ( $res == 62 ) { - # Test case was ok and called "skip" - $res= 0; - } - elsif ( $res ) - { - mtr_report("\nCould not execute 'check-warnings' for testcase '$tname':"); - mtr_printfile($errfile); - $res= 0; # Ignore error - } - return $res; + mtr_verbose("Started $proc"); + return $proc; } @@ -2878,17 +2933,86 @@ sub check_warnings ($) { my ($tinfo)= @_; my $res= 0; + my $tname= $tinfo->{name}; + # Clear previous warnings delete($tinfo->{warnings}); - # Parallell( mysqlds(), run_check_warning, check_warning_failed); + # Start the mysqltest processes in parallel to save time + # also makes it possible to wait for any process to exit during the check + my %started; foreach my $mysqld ( mysqlds() ) { - if (run_check_warnings($tinfo, $mysqld)){ - $res= 1; - mtr_report(); + if ( defined $mysqld->{'proc'} ) + { + my $proc= start_check_warnings($tinfo, $mysqld); + $started{$proc->pid()}= $proc; } } + + while (1){ + my $result= 0; + my $proc= My::SafeProcess->wait_any(); + mtr_report("Got $proc"); + + if ( delete $started{$proc->pid()} ) { + # One check warning process returned + my $res= $proc->exit_status(); + + if ( $res == 0 or $res == 62 ){ + + if ( $res == 0 ) { + # Check completed with problem + my $report= mtr_grab_file($proc->user_data()); + # Log to var/log/warnings file + mtr_tofile("$opt_vardir/log/warnings", + $tname."\n".$report); + + $tinfo->{'warnings'}.= $report; + $result= 1; + } + + if ( $res == 62 ) { + # Test case was ok and called "skip" + ; + } + + if ( keys(%started) == 0){ + # All checks completed + return $result; + } + # Wait for next process to exit + next; + } + else + { + my $report= mtr_grab_file($proc->user_data()); + $tinfo->{comment}.= + "Could not execute 'check-warnings' for testcase '$tname':"; + $tinfo->{comment}.= $report; + + $result= 2; + } + } + else { + # Unknown process returned, most likley a crash, abort everything + $tinfo->{comment}= + "Unexpected process $proc returned during ". + "check warnings"; + $result= 3; + } + + # Kill any check processes still running + map($_->kill(), values(%started)); + + return $result; + } + + + + + return $res; + return $res; } @@ -3632,10 +3756,9 @@ sub start_servers($) { # After testcase, run and compare with the recorded file, they should be equal! # # RETURN VALUE -# 0 OK -# 1 Check failed +# The newly started process # -sub run_check_testcase ($$$) { +sub start_check_testcase ($$$) { my $tinfo= shift; my $mode= shift; my $mysqld= shift; @@ -3660,32 +3783,17 @@ sub run_check_testcase ($$$) { mtr_add_arg($args, "--record"); } my $errfile= "$opt_vardir/tmp/$name.err"; - my $res= My::SafeProcess->run + my $proc= My::SafeProcess->new ( name => $name, path => $exe_mysqltest, error => $errfile, args => \$args, + user_data => $errfile, ); - if ( $mode eq "after" and $res == 1 ) - { - # Test failed, grab the report mysqltest has created - my $report= mtr_grab_file($errfile); - $tinfo->{check}.= - "\nThe check of testcase '$tname' failed, this is the\n". - "diff between before and after:\n"; - $tinfo->{check}.= $report; - - } - elsif ( $res ) - { - my $report= mtr_grab_file($errfile); - $tinfo->{'check'}.= - "\nCould not execute 'check-testcase' $mode testcase '$tname':\n"; - $tinfo->{check}.= $report; - } - return $res; + mtr_report("Started $proc"); + return $proc; } From 4f9409c8353aec715ec9ebd51951207c5d55cc4d Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 27 Apr 2008 23:35:38 +0200 Subject: [PATCH 10/38] Move code that saves datadirs to test server Remove mtr_report_test_failed --- mysql-test/lib/mtr_report.pm | 47 +----------- mysql-test/mysql-test-run.pl | 139 +++++++++++++++++++++-------------- 2 files changed, 83 insertions(+), 103 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 18c752d018d..9e8e26459fe 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -26,7 +26,7 @@ our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line mtr_print_header mtr_report mtr_report_stats mtr_warning mtr_error mtr_debug mtr_verbose mtr_verbose_restart mtr_report_test_passed - mtr_report_test_failed mtr_report_test_skipped + mtr_report_test_skipped mtr_report_test); use mtr_match; @@ -125,51 +125,6 @@ sub mtr_report_test_passed ($$) { } -sub mtr_report_test_failed ($$) { - my ($tinfo, $logfile)= @_; - _mtr_report_test_name($tinfo); - - $tinfo->{'result'}= 'MTR_RES_FAILED'; - my $test_failures= $tinfo->{'failures'} || 0; - $tinfo->{'failures'}= $test_failures + 1; - if ( defined $tinfo->{'warnings'} ) - { - mtr_report("[ fail ] Found warnings in server log file!"); - mtr_report($tinfo->{'warnings'}); - return; - } - elsif ( defined $tinfo->{'timeout'} ) - { - mtr_report("[ fail ] timeout"); - return; - } - else - { - mtr_report("[ fail ]"); - } - - if ( $tinfo->{'comment'} ) - { - # The test failure has been detected by mysql-test-run.pl - # when starting the servers or due to other error, the reason for - # failing the test is saved in "comment" - mtr_report("\nERROR: $tinfo->{'comment'}"); - } - elsif ( defined $logfile and -f $logfile ) - { - # Test failure was detected by test tool and its report - # about what failed has been saved to file. Display the report. - $tinfo->{logfile}= mtr_fromfile($logfile); - } - else - { - # Neither this script or the test tool has recorded info - # about why the test has failed. Should be debugged. - mtr_report("\nUnexpected termination, probably when starting mysqld");; - } -} - - sub mtr_report_test ($) { my ($tinfo)= @_; _mtr_report_test_name($tinfo); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5ef452318c5..9dac8b6c488 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -41,6 +41,7 @@ use Getopt::Long; use My::File::Path; # Patched version of File::Path use File::Basename; use File::Copy; +use File::Find; use File::Temp qw / tempdir /; use File::Spec::Functions qw / splitdir /; use My::Platform; @@ -197,10 +198,7 @@ our %mysqld_variables; my $source_dist= 0; my $opt_max_save_core= $ENV{MTR_MAX_SAVE_CORE} || 5; -my $num_saved_cores= 0; # Number of core files saved in vardir/log/ so far. - my $opt_max_save_datadir= $ENV{MTR_MAX_SAVE_DATADIR} || 20; -my $num_saved_datadir= 0; # Number of datadirs saved in vardir/log/ so far. select(STDOUT); $| = 1; # Automatically flush STDOUT @@ -335,6 +333,9 @@ sub main { sub run_test_server { my ($server, $tests, $childs) = @_; + 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. + # Scheduler variables my $max_ndb= $opt_parallel / 2; $max_ndb = 4 if $max_ndb > 4; @@ -377,10 +378,54 @@ sub run_test_server { # Report test status mtr_report_test($result); - if ($result->is_failed() and !$opt_force){ - # Test has failed, force is off - push(@$completed, $result); - return $completed; + if ( $result->is_failed() ) { + + # Save the workers "savedir" in var/log + my $worker_savedir= $result->{savedir}; + my $worker_savename= basename($worker_savedir); + my $savedir= "$opt_vardir/log/$worker_savename"; + + if ($opt_max_save_datadir > 0 && + $num_saved_datadir >= $opt_max_save_datadir) + { + mtr_report(" - skipping '$worker_savedir/'"); + rmtree($worker_savedir); + } + else { + mtr_report(" - saving '$worker_savedir/' to '$savedir/'"); + rename($worker_savedir, $savedir); + } + $num_saved_datadir++; + + if ($opt_max_save_core > 0) { + # Limit number of core files saved + find({ no_chdir => 1, + wanted => sub { + my $core_file= $File::Find::name; + my $core_name= basename($core_file); + + if ($core_name =~ "core*"){ + if ($num_saved_cores >= $opt_max_save_core) { + mtr_report(" - deleting '$core_name'", + "($num_saved_cores/$opt_max_save_core)"); + unlink("$core_file"); + } + else { + mtr_report(" - found '$core_name'", + "($num_saved_cores/$opt_max_save_core)"); + } + ++$num_saved_cores; + } + } + }, + $savedir); + } + + if ( !$opt_force ) { + # Test has failed, force is off + push(@$completed, $result); + return $completed; + } } # Retry test run after test failure @@ -3079,46 +3124,15 @@ sub clean_datadir { } -# -# Limit number of core files saved -# -sub limit_cores_after_failure ($) { - my ($datadir)= @_; - - # Look for core files - foreach my $core_file ( glob("$datadir/core*") ) - { - my $core_name= basename($core_file); - if ($opt_max_save_core > 0 && $num_saved_cores >= $opt_max_save_core) { - # Delete file to avoid saving it when the datadir is later saved - mtr_report(" - deleting '$core_name'", - "($num_saved_cores/$opt_max_save_core)"); - unlink("$core_file"); - } - else { - mtr_report(" - found '$core_name'", - "($num_saved_cores/$opt_max_save_core)"); - } - ++$num_saved_cores; - } -} - # # Save datadir before it's removed # sub save_datadir_after_failure($$) { my ($dir, $savedir)= @_; - if ($opt_max_save_datadir > 0 && - $num_saved_datadir >= $opt_max_save_datadir) - { - mtr_report(" - skipping '$dir'"); - } - else { - mtr_report(" - saving '$dir'"); - my $dir_name= basename($dir); - rename("$dir", "$savedir/$dir_name"); - } + mtr_report(" - saving '$dir'"); + my $dir_name= basename($dir); + rename("$dir", "$savedir/$dir_name"); } @@ -3133,6 +3147,9 @@ sub after_failure ($) { $save_dir.= "-$tinfo->{combination}" if defined $tinfo->{combination}; + # Save savedir path for server + $tinfo->{savedir}= $save_dir; + mkpath($save_dir) if ! -d $save_dir; # Save the used my.cnf file @@ -3140,12 +3157,6 @@ sub after_failure ($) { if ( clusters() ) { foreach my $cluster ( clusters() ) { - - foreach my $server ( ndbds($cluster), ndb_mgmds($cluster) ) { - my $data_dir= $server->value('DataDir'); - limit_cores_after_failure($data_dir); - } - my $cluster_dir= "$opt_vardir/".$cluster->{name}; save_datadir_after_failure($cluster_dir, $save_dir); } @@ -3153,29 +3164,43 @@ sub after_failure ($) { else { foreach my $mysqld ( mysqlds() ) { my $data_dir= $mysqld->value('datadir'); - limit_cores_after_failure($data_dir); save_datadir_after_failure(dirname($data_dir), $save_dir); } } - - $num_saved_datadir++; - - clean_datadir(); } sub report_failure_and_restart ($) { my $tinfo= shift; - mtr_report_test_failed($tinfo, $path_current_testlog); - - # Stop all servers that are known to be running stop_all_servers(); - # Collect and clean files + $tinfo->{'result'}= 'MTR_RES_FAILED'; + + my $test_failures= $tinfo->{'failures'} || 0; + $tinfo->{'failures'}= $test_failures + 1; + + + my $logfile= $path_current_testlog; + if ( $tinfo->{comment} ) + { + # The test failure has been detected by mysql-test-run.pl + # when starting the servers or due to other error, the reason for + # failing the test is saved in "comment" + ; + } + elsif ( defined $logfile and -f $logfile ) + { + # Test failure was detected by test tool and its report + # about what failed has been saved to file. Save the report + # in tinfo + $tinfo->{logfile}= mtr_fromfile($logfile); + } + after_failure($tinfo); - mtr_report("Resuming tests...\n"); + mtr_report_test($tinfo); + } From 6400538a901625873bd08aef168268fba89b35ce Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 08:17:23 +0200 Subject: [PATCH 11/38] Stop the test case time if "check_testcase" before test fails --- mysql-test/mysql-test-run.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 9dac8b6c488..44dc51b5e95 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2781,6 +2781,10 @@ sub run_testcase ($) { if ( $opt_check_testcases and check_testcase($tinfo, "before") ){ # Failed to record state of server or server crashed report_failure_and_restart($tinfo); + + # Stop the test case timer + $test_timeout_proc->kill(); + return 1; } From 9da80dac200a90add678952eb5ef8c3a46afc6af Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 08:23:00 +0200 Subject: [PATCH 12/38] Print number of test completed at failure --- mysql-test/mysql-test-run.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 44dc51b5e95..881e540b2da 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -316,6 +316,8 @@ sub main { if ( @$completed != $num_tests){ # Not all tests completed, failure + mtr_report(); + mtr_report("After @$completed of $num_tests."); mtr_error("Test failed.", "To continue, re-run with '--force'"); } From 9e3c23c089bd817733d5b6ccf793e8d57f643dfe Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 08:26:04 +0200 Subject: [PATCH 13/38] Add printout of all tests in case number of completed differs number of test and force is on --- mysql-test/mysql-test-run.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 881e540b2da..8271eacb636 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -315,6 +315,14 @@ sub main { } if ( @$completed != $num_tests){ + + if ($opt_force){ + # All test should have been run, print the completed list + foreach my $test ( @completed ){ + $test->print_test(); + } + } + # Not all tests completed, failure mtr_report(); mtr_report("After @$completed of $num_tests."); From f201478cb7f10973acc193a0833a78c720ef1e18 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 08:28:06 +0200 Subject: [PATCH 14/38] Only run the "saved core limit" if the datadir was saved --- mysql-test/mysql-test-run.pl | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 8271eacb636..543789a3f5b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -404,33 +404,33 @@ sub run_test_server { else { mtr_report(" - saving '$worker_savedir/' to '$savedir/'"); rename($worker_savedir, $savedir); + + if ($opt_max_save_core > 0) { + # Limit number of core files saved + find({ no_chdir => 1, + wanted => sub { + my $core_file= $File::Find::name; + my $core_name= basename($core_file); + + if ($core_name =~ "core*"){ + if ($num_saved_cores >= $opt_max_save_core) { + mtr_report(" - deleting '$core_name'", + "($num_saved_cores/$opt_max_save_core)"); + unlink("$core_file"); + } + else { + mtr_report(" - found '$core_name'", + "($num_saved_cores/$opt_max_save_core)"); + } + ++$num_saved_cores; + } + } + }, + $savedir); + } } $num_saved_datadir++; - if ($opt_max_save_core > 0) { - # Limit number of core files saved - find({ no_chdir => 1, - wanted => sub { - my $core_file= $File::Find::name; - my $core_name= basename($core_file); - - if ($core_name =~ "core*"){ - if ($num_saved_cores >= $opt_max_save_core) { - mtr_report(" - deleting '$core_name'", - "($num_saved_cores/$opt_max_save_core)"); - unlink("$core_file"); - } - else { - mtr_report(" - found '$core_name'", - "($num_saved_cores/$opt_max_save_core)"); - } - ++$num_saved_cores; - } - } - }, - $savedir); - } - if ( !$opt_force ) { # Test has failed, force is off push(@$completed, $result); From aa635c20efb65b41dac406404ad36a355fcb47b1 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 08:38:07 +0200 Subject: [PATCH 15/38] Reenable suite timeout detection --- mysql-test/mysql-test-run.pl | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 543789a3f5b..be14b235249 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -314,11 +314,15 @@ sub main { } } + if ( not defined @$completed ) { + mtr_error("Test suite aborted"); + } + if ( @$completed != $num_tests){ if ($opt_force){ # All test should have been run, print the completed list - foreach my $test ( @completed ){ + foreach my $test ( @$completed ){ $test->print_test(); } } @@ -330,8 +334,6 @@ sub main { "To continue, re-run with '--force'"); } - mtr_verbose("Server exit\n"); - mtr_print_line(); mtr_report_stats($completed); @@ -356,6 +358,8 @@ sub run_test_server { my %running; my $result; + my $suite_timeout_proc= My::SafeProcess->timer($opt_suite_timeout * 60); + my $s= IO::Select->new(); $s->add($server); while (1) { @@ -375,6 +379,7 @@ sub run_test_server { mtr_verbose("Child closed socket"); $s->remove($sock); if (--$childs == 0){ + $suite_timeout_proc->kill(); return $completed; } next; @@ -433,6 +438,7 @@ sub run_test_server { if ( !$opt_force ) { # Test has failed, force is off + $suite_timeout_proc->kill(); push(@$completed, $result); return $completed; } @@ -549,6 +555,15 @@ sub run_test_server { } } } + + # ---------------------------------------------------- + # Check if test suite timer expired + # ---------------------------------------------------- + if ( ! $suite_timeout_proc->wait_one(0) ) + { + mtr_report("Test suite timeout! Terminating..."); + return undef; + } } } @@ -2771,7 +2786,6 @@ sub run_testcase ($) { # ---------------------------------------------------------------------- if ( $opt_start or $opt_start_dirty ) { -# MASV $suite_timeout_proc->kill(); mtr_report("\nStarted", started(all_servers())); mtr_report("Waiting for server(s) to exit..."); my $proc= My::SafeProcess->wait_any(); @@ -2930,16 +2944,6 @@ sub run_testcase ($) { return 1; } - # ---------------------------------------------------- - # Check if test suite timer expired - # ---------------------------------------------------- -# MASV -# if ( $proc eq $suite_timeout_proc ) -# { -# mtr_report("Test suite timeout! Terminating..."); -# exit(1); -# } - mtr_error("Unhandled process $proc exited"); } mtr_error("Should never come here"); From 2aae18545dd792b7bf01fe4a40a02c96f2bb4f0b Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 09:24:30 +0200 Subject: [PATCH 16/38] Limit number of test failures before aborting --- mysql-test/mysql-test-run.pl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index be14b235249..ed2d3f6625b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -199,6 +199,7 @@ my $source_dist= 0; my $opt_max_save_core= $ENV{MTR_MAX_SAVE_CORE} || 5; my $opt_max_save_datadir= $ENV{MTR_MAX_SAVE_DATADIR} || 20; +my $opt_max_test_fail= $ENV{MTR_MAX_TEST_FAIL} || 10; select(STDOUT); $| = 1; # Automatically flush STDOUT @@ -347,6 +348,7 @@ 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 # Scheduler variables my $max_ndb= $opt_parallel / 2; @@ -442,6 +444,14 @@ sub run_test_server { push(@$completed, $result); return $completed; } + elsif ($num_failed_test > 0 and + $num_failed_test >= $opt_max_test_fail) { + $suite_timeout_proc->kill(); + mtr_report("Too many tests($num_failed_test) failed!", + "Terminating..."); + return undef; + } + $num_failed_test++; } # Retry test run after test failure @@ -719,6 +729,7 @@ sub command_line_setup { 'strace-client:s' => \$opt_strace_client, '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, @@ -4340,6 +4351,10 @@ Options for debugging the product 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 + 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 + it's default with MTR_MAX_TEST_FAIL Options for valgrind From 91cc80ad57fad65c3588c5a3d153a338ed41ea70 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 12:20:42 +0200 Subject: [PATCH 17/38] Return immediately from 'check-testcase' and 'check_warnings' if no check processes has been started --- mysql-test/mysql-test-run.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ed2d3f6625b..e5199614d86 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2588,6 +2588,9 @@ sub check_testcase($$) } } + # Return immediately if no check proceess was started + return 0 unless ( keys %started ); + while (1){ my $result; my $proc= My::SafeProcess->wait_any(); @@ -3024,6 +3027,9 @@ sub check_warnings ($) { } } + # Return immediately if no check proceess was started + return 0 unless ( keys %started ); + while (1){ my $result= 0; my $proc= My::SafeProcess->wait_any(); From 5d3d99c365d526b0d5c4b9e894818cda9579e78b Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 14:37:40 +0200 Subject: [PATCH 18/38] Save files in var/tmp/ after failure --- mysql-test/mysql-test-run.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e5199614d86..64738492258 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3190,6 +3190,9 @@ sub after_failure ($) { # Save the used my.cnf file copy($path_config_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}; From a0f393d66024335e50507ff39a7883d541e92086 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 28 Apr 2008 15:03:30 +0200 Subject: [PATCH 19/38] Don't append thread num to $opt_tmpdir is var/tmp Remove .err and .result files produced by check-testcase and check-warnings --- mysql-test/mysql-test-run.pl | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 64738492258..50348053bdf 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -989,7 +989,7 @@ sub command_line_setup { $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any # If more than one parallel run, use a subdir of the selected tmpdir - if ($thread_num && $opt_parallel > 1) { + if ($thread_num && $opt_parallel > 1 and $opt_tmpdir ne "$opt_vardir/tmp") { $opt_tmpdir.= "/".$thread_num; } @@ -2597,12 +2597,20 @@ sub check_testcase($$) mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { + + my $err_file= $proc->user_data(); + my $base_file= mtr_match_extension($err_file, "err"); # Trim extension + unlink("$base_file.result"); + # One check testcase process returned my $res= $proc->exit_status(); if ( $res == 0){ # Check completed without problem + # Remove the .err file the check generated + unlink($err_file); + if ( keys(%started) == 0){ # All checks completed return 0; @@ -2615,7 +2623,7 @@ sub check_testcase($$) if ( $mode eq "after" and $res == 1 ) { # Test failed, grab the report mysqltest has created - my $report= mtr_grab_file($proc->user_data()); + my $report= mtr_grab_file($err_file); $tinfo->{check}.= "\nThe check of testcase '$tname' failed, this is the\n". "diff between before and after:\n"; @@ -2627,7 +2635,7 @@ sub check_testcase($$) } elsif ( $res ) { - my $report= mtr_grab_file($proc->user_data()); + my $report= mtr_grab_file($err_file); $tinfo->{comment}.= "Could not execute 'check-testcase' $mode testcase '$tname':\n"; $tinfo->{comment}.= $report; @@ -2635,6 +2643,9 @@ sub check_testcase($$) $result= 2; } + # Remove the .err file the check generated + unlink($err_file); + } } else { @@ -3038,12 +3049,13 @@ sub check_warnings ($) { if ( delete $started{$proc->pid()} ) { # One check warning process returned my $res= $proc->exit_status(); + my $err_file= $proc->user_data(); if ( $res == 0 or $res == 62 ){ if ( $res == 0 ) { # Check completed with problem - my $report= mtr_grab_file($proc->user_data()); + my $report= mtr_grab_file($err_file); # Log to var/log/warnings file mtr_tofile("$opt_vardir/log/warnings", $tname."\n".$report); @@ -3056,6 +3068,8 @@ sub check_warnings ($) { # Test case was ok and called "skip" ; } + # Remove the .err file the check generated + unlink($err_file); if ( keys(%started) == 0){ # All checks completed @@ -3066,13 +3080,15 @@ sub check_warnings ($) { } else { - my $report= mtr_grab_file($proc->user_data()); + my $report= mtr_grab_file($err_file); $tinfo->{comment}.= "Could not execute 'check-warnings' for testcase '$tname':"; $tinfo->{comment}.= $report; $result= 2; } + # Remove the .err file the check generated + unlink($err_file); } else { # Unknown process returned, most likley a crash, abort everything From 8c97dc80ca0f1060dba183c95e29ed326ee7407b Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Fri, 2 May 2008 12:11:04 +0200 Subject: [PATCH 20/38] Print tests that has been run but shouldn't and vice versa Use opt_start_timeout also for ndb Remove the .result files generated by 'check_testcase' --- mysql-test/lib/mtr_report.pm | 12 +++++++++--- mysql-test/mysql-test-run.pl | 36 +++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 9e8e26459fe..cf884b41d55 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -131,8 +131,6 @@ sub mtr_report_test ($) { if ($tinfo->{'result'} eq 'MTR_RES_FAILED'){ - #my $test_failures= $tinfo->{'failures'} || 0; - #$tinfo->{'failures'}= $test_failures + 1; if ( defined $tinfo->{'warnings'} ) { mtr_report("[ fail ] Found warnings in server log file!"); @@ -233,7 +231,7 @@ sub mtr_report_stats ($) { $tot_tests++; $tot_passed++; } - elsif ( $tinfo->{'result'} eq 'MTR_RES_FAILED' ) + elsif ( $tinfo->{failures} ) { $tot_tests++; $tot_failed++; @@ -301,6 +299,14 @@ sub mtr_report_stats ($) { # Print a list of testcases that failed if ( $tot_failed != 0 ) { + + # Print each failed test, again + #foreach my $test ( @$tests ){ + # if ( $test->{result} eq 'MTR_RES_FAILED' ) { + # mtr_report_test($test); + # } + #} + my $ratio= $tot_passed * 100 / $tot_tests; print "Failed $tot_failed/$tot_tests tests, "; printf("%.2f", $ratio); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 50348053bdf..4838ddefe54 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -322,15 +322,29 @@ sub main { if ( @$completed != $num_tests){ if ($opt_force){ - # All test should have been run, print the completed list - foreach my $test ( @$completed ){ - $test->print_test(); + # All test should have been run, print the ones that differs + my %tests= (); + foreach my $t (@$tests) { $tests{$t->key()}= 1; }; + foreach my $done ( @$completed ){ + if ($tests{$done->key()}) { + mtr_report("Found one extra completed"); + $done->print_test(); + } } + %tests= (); + foreach my $t (@$completed) { $tests{$t->key()}= 1; }; + foreach my $done ( @$tests ){ + if ($tests{$done->key()}) { + mtr_report("Found one test not run"); + $done->print_test(); + } + } + } # Not all tests completed, failure mtr_report(); - mtr_report("After @$completed of $num_tests."); + mtr_report(@$completed, " of $num_tests completed."); mtr_error("Test failed.", "To continue, re-run with '--force'"); } @@ -467,6 +481,7 @@ sub run_test_server { } else { mtr_report("\nRetrying test, attempt($retries/$opt_retry)...\n"); + delete($result->{result}); $result->{retries}= $retries+1; $result->write_test($sock, 'TESTCASE'); next; @@ -479,7 +494,7 @@ sub run_test_server { { $result->{retries}= 0; $result->{failures}= 0; - + delete($result->{result}); $result->{repeat}= $repeat+1; $result->write_test($sock, 'TESTCASE'); next; @@ -1983,7 +1998,7 @@ sub ndbcluster_wait_started($$){ mtr_init_args(\$args); mtr_add_arg($args, "--defaults-file=%s", $path_config_file); mtr_add_arg($args, "--defaults-group-suffix=%s", $cluster->suffix()); - mtr_add_arg($args, "--timeout=60"); + mtr_add_arg($args, "--timeout=%d", $opt_start_timeout); if ($ndb_waiter_extra_opt) { @@ -2600,7 +2615,6 @@ sub check_testcase($$) my $err_file= $proc->user_data(); my $base_file= mtr_match_extension($err_file, "err"); # Trim extension - unlink("$base_file.result"); # One check testcase process returned my $res= $proc->exit_status(); @@ -2611,6 +2625,11 @@ sub check_testcase($$) # Remove the .err file the check generated unlink($err_file); + # Remove the .result file the check generated + if ( $mode eq 'after' ){ + unlink("$base_file.result"); + } + if ( keys(%started) == 0){ # All checks completed return 0; @@ -2646,6 +2665,9 @@ sub check_testcase($$) # Remove the .err file the check generated unlink($err_file); + # Remove the .result file the check generated + unlink("$base_file.result"); + } } else { From c9a37bec4be5f966418212705d5e0d72d6c9aaec Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Fri, 2 May 2008 13:00:04 +0200 Subject: [PATCH 21/38] Change the "diff tool" detection algoritm to use "diff -u", "diff -c" and then just "diff" --- client/mysqltest.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index bc00d78c205..0bca63b6e81 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1345,23 +1345,21 @@ void show_diff(DYNAMIC_STRING* ds, if (init_dynamic_string(&ds_tmp, "", 256, 256)) die("Out of memory"); - /* First try with diff --help to see if the command exists at all */ + /* First try with unified diff */ if (run_tool("diff", &ds_tmp, /* Get output from diff in ds_tmp */ - "--help", + "-u", + filename1, + filename2, "2>&1", - NULL) != 0) /* Most "diff --help" tools return 0 */ - { - diff_failed= "You don't appear to have diff installed"; - } - else + NULL) > 1) /* Most "diff" tools return >1 if error */ { dynstr_set(&ds_tmp, ""); - /* First try with unified diff */ + /* Fallback to context diff with "diff -c" */ if (run_tool("diff", &ds_tmp, /* Get output from diff in ds_tmp */ - "-u", + "-c", filename1, filename2, "2>&1", @@ -1369,17 +1367,17 @@ void show_diff(DYNAMIC_STRING* ds, { dynstr_set(&ds_tmp, ""); - /* Fallback to context diff with "diff -c" */ + /* Fallback to plain "diff" */ if (run_tool("diff", &ds_tmp, /* Get output from diff in ds_tmp */ - "-c", filename1, filename2, "2>&1", NULL) > 1) /* Most "diff" tools return >1 if error */ { dynstr_set(&ds_tmp, ""); - diff_failed= "Could not execute 'diff -u' or 'diff -c'"; + + diff_failed= "Could not execute 'diff -u', 'diff -c' or 'diff'"; } } } From 8ece58b87e94a63402164e5fdae3057561229ff3 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sat, 3 May 2008 16:10:23 +0200 Subject: [PATCH 22/38] mysql-test-run.pl: Print the scalar value of $completed, not the array values --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4838ddefe54..eb251a93049 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -344,7 +344,7 @@ sub main { # Not all tests completed, failure mtr_report(); - mtr_report(@$completed, " of $num_tests completed."); + mtr_report(int(@$completed), " of $num_tests completed."); mtr_error("Test failed.", "To continue, re-run with '--force'"); } From e088f111e931eb084f123b65ccc314cd593b1309 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.(none)" <> Date: Sun, 4 May 2008 13:31:40 +0200 Subject: [PATCH 23/38] Use SysInfo.pm to find a suitable value for number of workers when --parallel hasn't been specified Add lib/My/SysInfo.pm --- mysql-test/Makefile.am | 1 + mysql-test/lib/My/SysInfo.pm | 181 +++++++++++++++++++++++++++++++++++ mysql-test/mysql-test-run.pl | 17 +++- 3 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 mysql-test/lib/My/SysInfo.pm diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 02dea1a4466..c37e808faf2 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -42,6 +42,7 @@ nobase_test_DATA = lib/mtr_cases.pm \ lib/My/Platform.pm \ lib/My/SafeProcess.pm \ lib/My/File/Path.pm \ + lib/My/SysInfo.pm \ lib/My/SafeProcess/Base.pm \ lib/My/SafeProcess/safe_process.pl diff --git a/mysql-test/lib/My/SysInfo.pm b/mysql-test/lib/My/SysInfo.pm new file mode 100644 index 00000000000..b764b4548f7 --- /dev/null +++ b/mysql-test/lib/My/SysInfo.pm @@ -0,0 +1,181 @@ +# -*- cperl -*- +# Copyright (C) 2004-2006 MySQL 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 +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +package My::SysInfo; + +use strict; +use Carp; +use My::Platform; + + + +sub _cpuinfo { + my ($self)= @_; + print "_cpuinfo\n"; + + my $info_file= "/proc/cpuinfo"; + if ( !( -e $info_file and -f $info_file) ) { + return undef; + } + + my $F= IO::File->new($info_file) or return undef; + + # Set input separator to blank line + local $/ = ''; + + while ( my $cpu_chunk= <$F>) { + chomp($cpu_chunk); + + my $cpuinfo = {}; + + foreach my $cpuline ( split(/\n/, $cpu_chunk) ) { + my ( $attribute, $value ) = split(/\s*:\s*/, $cpuline); + + $attribute =~ s/\s+/_/; + $attribute = lc($attribute); + + if ( $value =~ /^(no|not available|yes)$/ ) { + $value = $value eq 'yes' ? 1 : 0; + } + + if ( $attribute eq 'flags' ) { + @{ $cpuinfo->{flags} } = split / /, $value; + } else { + $cpuinfo->{$attribute} = $value; + } + } + + push(@{$self->{cpus}}, $cpuinfo); + } + $F= undef; # Close file + return $self; +} + + +sub _kstat { + my ($self)= @_; + while (1){ + my $instance_num= $self->{cpus} ? @{$self->{cpus}} : 0; + my $list= `kstat -p -m cpu_info -i $instance_num`; + my @lines= split('\n', $list) or return undef; + + my $cpuinfo= {}; + foreach my $line (@lines) + { + my ($module, $instance, $name, $statistic, $value)= + $line=~ /(\w*):(\w*):(\w*):(\w*)\t(.*)/; + + $cpuinfo->{$statistic}= $value; + } + + # Default value, the actual cpu values can be used to decrease it + # on slower cpus + $cpuinfo->{bogomips}= 2000; + + push(@{$self->{cpus}}, $cpuinfo); + } + + return $self; +} + + +sub _unamex { + my ($self)= @_; + # TODO + return undef; +} + + +sub new { + my ($class)= @_; + + + my $self= bless { + cpus => (), + }, $class; + + my @info_methods = + ( + \&_cpuinfo, + \&_kstat, + \&_unamex, + ); + + foreach my $method (@info_methods){ + if ($method->($self)){ + return $self; + } + } + + # Push a dummy cpu + push(@{$self->{cpus}}, {bogomips => 2000, model_name => "unknown"}); + + return $self; +} + + +# Return the list of cpus found +sub cpus { + my ($self)= @_; + return @{$self->{cpus}} or + confess "INTERNAL ERROR: No cpus in list"; +} + + +# Return the number of cpus found +sub num_cpus { + my ($self)= @_; + return int(@{$self->{cpus}}) or + confess "INTERNAL ERROR: No cpus in list"; +} + + +# Return the smallest bogomips value amongst the processors +sub min_bogomips { + my ($self)= @_; + + my $bogomips; + + foreach my $cpu (@{$self->{cpus}}) { + if (!defined $bogomips or $bogomips > $cpu->{bogomips}) { + $bogomips= $cpu->{bogomips}; + } + } + + return $bogomips; +} + + +# Prit the cpuinfo +sub print_info { + my ($self)= @_; + + foreach my $cpu (@{$self->{cpus}}) { + while ((my ($key, $value)) = each(%$cpu)) { + print " ", $key, "= "; + if (ref $value eq "ARRAY") { + print "[", join(", ", @$value), "]"; + } else { + print $value; + } + print "\n"; + } + print "\n"; + } +} + +1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index eb251a93049..40fec215b34 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -49,6 +49,7 @@ use My::SafeProcess; use My::ConfigFactory; use My::Options; use My::Find; +use My::SysInfo; use mtr_cases; use mtr_report; use mtr_match; @@ -206,7 +207,9 @@ $| = 1; # Automatically flush STDOUT main(); + sub main { + report_option('verbose', 0); # This is needed for test log evaluation in "gen-build-status-page" # in all cases where the calling tool does not log the commands @@ -216,8 +219,17 @@ sub main { Getopt::Long::Configure("pass_through"); GetOptions('parallel=i' => \$opt_parallel) or usage("Can't read options"); - if ( not defined $opt_parallel ){ - $opt_parallel= 4; # Default + if ( not defined $opt_parallel ) { + # Try to find a suitable value for number of workers + my $sys_info= My::SysInfo->new(); + $sys_info->print_info(); + + $opt_parallel= $sys_info->num_cpus(); + for my $limit (2000, 1500, 1000, 500){ + $opt_parallel-- if ($sys_info->min_bogomips() < $limit); + } + $opt_parallel= 1 if ($opt_parallel < 1); + mtr_report("Using parallel: $opt_parallel"); } # Create server socket on any free port @@ -241,7 +253,6 @@ sub main { exit(1); } - mtr_report("Started worker, pid: $child_pid"); $children{$child_pid}= 1; } From 6cef6279c25ea6bfd4ed937d65daf1da6c107fb8 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.(none)" <> Date: Sun, 4 May 2008 16:35:16 +0200 Subject: [PATCH 24/38] Always set bogomips unless already set Return undef only in case kstat works Cpus reported once, but with 'cpu_count' set to the actual number --- mysql-test/lib/My/SysInfo.pm | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/mysql-test/lib/My/SysInfo.pm b/mysql-test/lib/My/SysInfo.pm index b764b4548f7..87f768f4866 100644 --- a/mysql-test/lib/My/SysInfo.pm +++ b/mysql-test/lib/My/SysInfo.pm @@ -21,7 +21,7 @@ use strict; use Carp; use My::Platform; - +use constant DEFAULT_BOGO_MIPS => 2000; sub _cpuinfo { my ($self)= @_; @@ -59,7 +59,14 @@ sub _cpuinfo { } } - push(@{$self->{cpus}}, $cpuinfo); + # Make sure bogomips is set to some value + $cpuinfo->{bogomips} |= DEFAULT_BOGO_MIPS; + + # Cpus reported once, but with 'cpu_count' set to the actual number + my $cpu_count= $cpuinfo->{cpu_count} || 1; + for(1..$cpu_count){ + push(@{$self->{cpus}}, $cpuinfo); + } } $F= undef; # Close file return $self; @@ -71,7 +78,7 @@ sub _kstat { while (1){ my $instance_num= $self->{cpus} ? @{$self->{cpus}} : 0; my $list= `kstat -p -m cpu_info -i $instance_num`; - my @lines= split('\n', $list) or return undef; + my @lines= split('\n', $list) or last; # Break loop my $cpuinfo= {}; foreach my $line (@lines) @@ -82,14 +89,19 @@ sub _kstat { $cpuinfo->{$statistic}= $value; } - # Default value, the actual cpu values can be used to decrease it + # Default value, the actual cpu values can be used to decrease this # on slower cpus - $cpuinfo->{bogomips}= 2000; + $cpuinfo->{bogomips}= DEFAULT_BOGO_MIPS; push(@{$self->{cpus}}, $cpuinfo); } - return $self; + # At least one cpu should have been found + # if this method worked + if ( $self->{cpus} ) { + return $self; + } + return undef; } @@ -122,7 +134,11 @@ sub new { } # Push a dummy cpu - push(@{$self->{cpus}}, {bogomips => 2000, model_name => "unknown"}); + push(@{$self->{cpus}}, + { + bogomips => DEFAULT_BOGO_MIPS, + model_name => "unknown", + }); return $self; } From b4b0fcee26dc9a9ae30a98c37e999d0beb9d1275 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 20:59:51 +0200 Subject: [PATCH 25/38] Debug printouts for not all tests completed --- mysql-test/mysql-test-run.pl | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 40fec215b34..74b895a5c40 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -333,31 +333,16 @@ sub main { if ( @$completed != $num_tests){ if ($opt_force){ - # All test should have been run, print the ones that differs - my %tests= (); - foreach my $t (@$tests) { $tests{$t->key()}= 1; }; - foreach my $done ( @$completed ){ - if ($tests{$done->key()}) { - mtr_report("Found one extra completed"); - $done->print_test(); - } + # All test should have been run, print any that are still in $tests + foreach my $test ( @$tests ){ + $test->print_test(); } - %tests= (); - foreach my $t (@$completed) { $tests{$t->key()}= 1; }; - foreach my $done ( @$tests ){ - if ($tests{$done->key()}) { - mtr_report("Found one test not run"); - $done->print_test(); - } - } - } # Not all tests completed, failure mtr_report(); - mtr_report(int(@$completed), " of $num_tests completed."); - mtr_error("Test failed.", - "To continue, re-run with '--force'"); + mtr_report("Only ", int(@$completed), " of $num_tests completed."); + mtr_error("Not all tests completed"); } mtr_print_line(); From 86ac70f774dc554768bf819f75bb1c4dc05a9e2e Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 21:20:25 +0200 Subject: [PATCH 26/38] Improve retry logic --- mysql-test/mysql-test-run.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 74b895a5c40..e4e51a5bcf0 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -465,14 +465,14 @@ sub run_test_server { } # Retry test run after test failure - my $retries= $result->{retries} || 1; + my $retries= $result->{retries} || 2; my $test_has_failed= $result->{failures} || 0; - if ($test_has_failed and $retries < $opt_retry){ + if ($test_has_failed and $retries <= $opt_retry){ # Test should be run one more time unless it has failed # too many times already my $failures= $result->{failures}; if ($opt_retry > 1 and $failures >= $opt_retry_failure){ - mtr_report("Test has failed $failures times,", + mtr_report("\nTest has failed $failures times,", "no more retries!\n"); } else { From b9a810dd25550aa79978fcbfbbc5596b7366bb6c Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 21:21:11 +0200 Subject: [PATCH 27/38] Correctly calculate failed tests --- mysql-test/lib/mtr_report.pm | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index cf884b41d55..026d5e9776e 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -222,22 +222,27 @@ sub mtr_report_stats ($) { foreach my $tinfo (@$tests) { - if ( $tinfo->{'result'} eq 'MTR_RES_SKIPPED' ) + if ( $tinfo->{failures} ) { + # Test has failed at least one time + $tot_tests++; + $tot_failed++; + } + elsif ( $tinfo->{'result'} eq 'MTR_RES_SKIPPED' ) + { + # Test was skipped $tot_skiped++; } elsif ( $tinfo->{'result'} eq 'MTR_RES_PASSED' ) { + # Test passed $tot_tests++; $tot_passed++; } - elsif ( $tinfo->{failures} ) - { - $tot_tests++; - $tot_failed++; - } + if ( $tinfo->{'restarted'} ) { + # Servers was restarted $tot_restarts++; } @@ -302,7 +307,7 @@ sub mtr_report_stats ($) { # Print each failed test, again #foreach my $test ( @$tests ){ - # if ( $test->{result} eq 'MTR_RES_FAILED' ) { + # if ( $test->{failures} ) { # mtr_report_test($test); # } #} @@ -320,7 +325,7 @@ sub mtr_report_stats ($) { foreach my $tinfo (@$tests) { my $tname= $tinfo->{'name'}; - if ( $tinfo->{'result'} eq 'MTR_RES_FAILED' and ! $seen{$tname}) + if ( $tinfo->{failures} and ! $seen{$tname}) { print " $tname"; $seen{$tname}= 1; From ec03ad0591a5849279ac020574ccdac6cbb00e86 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 21:40:40 +0200 Subject: [PATCH 28/38] Move opt_timer to mtr_report.pm --- mysql-test/lib/mtr_report.pm | 28 ++++++++++++++-------------- mysql-test/mysql-test-run.pl | 11 +++-------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 026d5e9776e..aa7d763629e 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -39,7 +39,7 @@ our $timediff= 1; our $name; our $verbose; our $verbose_restart= 0; - +our $timer= 1; sub report_option { my ($opt, $value)= @_; @@ -99,23 +99,22 @@ sub mtr_report_test_skipped ($) { } -sub mtr_report_test_passed ($$) { - my ($tinfo, $use_timer)= @_; +sub mtr_report_test_passed ($) { + my ($tinfo)= @_; _mtr_report_test_name($tinfo); - my $timer= ""; - if ( $use_timer and -f "$::opt_vardir/log/timer" ) + my $timer_str= ""; + if ( $timer and -f "$::opt_vardir/log/timer" ) { - $timer= mtr_fromfile("$::opt_vardir/log/timer"); - $tot_real_time += ($timer/1000); - $timer= sprintf "%12s", $timer; - $tinfo->{timer}= $timer; + $timer_str= mtr_fromfile("$::opt_vardir/log/timer"); + $tinfo->{timer}= $timer_str; } # Set as passed unless already set if ( not defined $tinfo->{'result'} ){ $tinfo->{'result'}= 'MTR_RES_PASSED'; } - mtr_report("[ pass ] $timer"); + + mtr_report("[ pass ] ", sprintf("%12s", $timer_str)); # Show any problems check-testcase found if ( defined $tinfo->{'check'} ) @@ -193,8 +192,9 @@ sub mtr_report_test ($) { } elsif ($tinfo->{'result'} eq 'MTR_RES_PASSED') { - my $timer= $tinfo->{timer} || ""; - mtr_report("[ pass ] $timer"); + my $timer_str= $tinfo->{timer} || ""; + $tot_real_time += ($timer_str/1000); + mtr_report("[ pass ] ", sprintf("%12s", $timer_str)); # Show any problems check-testcase found if ( defined $tinfo->{'check'} ) @@ -262,7 +262,7 @@ sub mtr_report_stats ($) { # ---------------------------------------------------------------------- print "The servers were restarted $tot_restarts times\n"; - if ( $::opt_timer ) + if ( $timer ) { use English; @@ -343,7 +343,7 @@ sub mtr_report_stats ($) { } else { - print "All $tot_tests tests were successful.\n"; + print "All $tot_tests tests were successful.\n\n"; } if ( $tot_failed != 0 || $found_problems) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e4e51a5bcf0..0fc5ed6aeee 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -168,8 +168,6 @@ my $opt_parallel; my $opt_strace_client; -our $opt_timer= 1; - our $opt_user; my $opt_valgrind= 0; @@ -784,7 +782,7 @@ sub command_line_setup { 'repeat=i' => \$opt_repeat, 'retry=i' => \$opt_retry, 'retry-failure=i' => \$opt_retry_failure, - 'timer!' => \$opt_timer, + 'timer!' => \&report_option, 'user=s' => \$opt_user, 'testcase-timeout=i' => \$opt_testcase_timeout, 'suite-timeout=i' => \$opt_suite_timeout, @@ -2886,7 +2884,7 @@ sub run_testcase ($) { } else { - mtr_report_test_passed($tinfo, $opt_timer); + mtr_report_test_passed($tinfo); } my $check_res; @@ -3948,10 +3946,7 @@ sub start_mysqltest ($) { mtr_add_arg($args, "$exe_mysqltest"); } - if ( $opt_timer ) - { - mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir); - } + mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir); if ( $opt_compress ) { From fb88bd04a6b6900cf4fc974c9734d2b1eb0ac07e Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 21:43:49 +0200 Subject: [PATCH 29/38] Set "timediff" to off by default --- mysql-test/lib/mtr_report.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index aa7d763629e..349a1205d44 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -35,7 +35,7 @@ require "mtr_io.pl"; my $tot_real_time= 0; our $timestamp= 0; -our $timediff= 1; +our $timediff= 0; our $name; our $verbose; our $verbose_restart= 0; From 63a0cdb59d90d3f34a830c9d2bdc58641ed953da Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 21:45:38 +0200 Subject: [PATCH 30/38] Make timediff an option --- mysql-test/mysql-test-run.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0fc5ed6aeee..a50bd6be8d0 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -789,6 +789,7 @@ sub command_line_setup { 'shutdown-timeout=i' => \$opt_shutdown_timeout, 'warnings!' => \$opt_warnings, 'timestamp' => \&report_option, + 'timediff' => \&report_option, 'help|h' => \$opt_usage, ) or usage("Can't read options"); From 9d6d039cf1d452062137b0b7b87911e0a0f2f448 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Sun, 4 May 2008 23:22:41 +0200 Subject: [PATCH 31/38] Tune reporting --- mysql-test/lib/mtr_report.pm | 60 +++++++++--------------------------- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 349a1205d44..4a321e5d847 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -52,7 +52,6 @@ sub report_option { #print $name, " setting $opt to ", (defined $value? $value : "undef") ,"\n"; } -sub SHOW_SUITE_NAME() { return 1; }; sub _mtr_report_test_name ($) { my $tinfo= shift; @@ -60,67 +59,40 @@ sub _mtr_report_test_name ($) { return unless defined $verbose; - # Remove suite part of name - $tname =~ s/.*\.// unless SHOW_SUITE_NAME; - # Add combination name if any $tname.= " '$tinfo->{combination}'" if defined $tinfo->{combination}; print $name, _timestamp(); - printf "%-30s ", $tname; + printf "%-40s ", $tname; } sub mtr_report_test_skipped ($) { - my $tinfo= shift; - _mtr_report_test_name($tinfo); - + my ($tinfo)= @_; $tinfo->{'result'}= 'MTR_RES_SKIPPED'; - if ( $tinfo->{'disable'} ) - { - mtr_report("[ disabled ] $tinfo->{'comment'}"); - } - elsif ( $tinfo->{'comment'} ) - { - if ( $tinfo->{skip_detected_by_test} ) - { - mtr_report("[ skip ]. $tinfo->{'comment'}"); - } - else - { - mtr_report("[ skip ] $tinfo->{'comment'}"); - } - } - else - { - mtr_report("[ skip ]"); - } + + mtr_report_test($tinfo); } sub mtr_report_test_passed ($) { my ($tinfo)= @_; - _mtr_report_test_name($tinfo); + # Save the timer value my $timer_str= ""; if ( $timer and -f "$::opt_vardir/log/timer" ) { $timer_str= mtr_fromfile("$::opt_vardir/log/timer"); $tinfo->{timer}= $timer_str; } + # Set as passed unless already set if ( not defined $tinfo->{'result'} ){ $tinfo->{'result'}= 'MTR_RES_PASSED'; } - mtr_report("[ pass ] ", sprintf("%12s", $timer_str)); - - # Show any problems check-testcase found - if ( defined $tinfo->{'check'} ) - { - mtr_report($tinfo->{'check'}); - } + mtr_report_test($tinfo); } @@ -178,7 +150,7 @@ sub mtr_report_test ($) { { if ( $tinfo->{skip_detected_by_test} ) { - mtr_report("[ skip ]. $tinfo->{'comment'}"); + mtr_report("[ skip ]. $tinfo->{'comment'}"); } else { @@ -194,7 +166,7 @@ sub mtr_report_test ($) { { my $timer_str= $tinfo->{timer} || ""; $tot_real_time += ($timer_str/1000); - mtr_report("[ pass ] ", sprintf("%12s", $timer_str)); + mtr_report("[ pass ] ", sprintf("%5s", $timer_str)); # Show any problems check-testcase found if ( defined $tinfo->{'check'} ) @@ -202,7 +174,6 @@ sub mtr_report_test ($) { mtr_report($tinfo->{'check'}); } } - } @@ -372,14 +343,11 @@ sub mtr_print_thick_line { sub mtr_print_header () { print "\n"; - if ( $::opt_timer ) - { - print "TEST RESULT TIME (ms)\n"; - } - else - { - print "TEST RESULT\n"; - } + printf "TEST"; + print " " x 38; + print "RESULT "; + print "TIME (ms)" if $timer; + print "\n"; mtr_print_line(); print "\n"; } From be295c87cc347fc467ea5956dbf83e075b47423e Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 5 May 2008 00:21:12 +0200 Subject: [PATCH 32/38] Change rmtree+mkpath to use clean_dir --- mysql-test/mysql-test-run.pl | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a50bd6be8d0..7b1573366c0 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3161,6 +3161,30 @@ sub check_expected_crash_and_restart { } +# Remove all files and subdirectories of a directory +sub clean_dir { + my ($dir)= @_; + finddepth( + { no_chdir => 1, + wanted => sub { + if (-d $_){ + # A dir + if ($_ eq $dir){ + # The dir to clean + return; + } else { + rmdir($_) or mtr_warning("rmdir failed: $!"); + } + } else { + # Hopefully a file + unlink($_) or mtr_warning("unlink failed: $!"); + } + } + }, + $dir); +} + + sub clean_datadir { mtr_verbose("Cleaning datadirs..."); @@ -3183,11 +3207,9 @@ sub clean_datadir { } # Remove all files in tmp and var/tmp - rmtree("$opt_vardir/tmp"); - mkpath("$opt_vardir/tmp"); + clean_dir("$opt_vardir/tmp"); if ($opt_tmpdir ne "$opt_vardir/tmp"){ - rmtree($opt_tmpdir); - mkpath($opt_tmpdir); + clean_dir($opt_tmpdir); } } From 76905924dbd4a6dc9730a061cf9668ce00e8d751 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 5 May 2008 13:47:43 +0200 Subject: [PATCH 33/38] Add temporary printouts --- mysql-test/mysql-test-run.pl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7b1573366c0..2227a8c77f6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3164,6 +3164,7 @@ sub check_expected_crash_and_restart { # Remove all files and subdirectories of a directory sub clean_dir { my ($dir)= @_; + print "clean_dir: $dir\n"; finddepth( { no_chdir => 1, wanted => sub { @@ -3173,11 +3174,13 @@ sub clean_dir { # The dir to clean return; } else { - rmdir($_) or mtr_warning("rmdir failed: $!"); + print "rmdir: '$_'\n"; + rmdir($_) or mtr_warning("rmdir($_) failed: $!"); } } else { # Hopefully a file - unlink($_) or mtr_warning("unlink failed: $!"); + print "unlink: '$_'\n"; + unlink($_) or mtr_warning("unlink($_) failed: $!"); } } }, From 39e11a1ddb4f02a4b55971d1800cdc006fb2ec41 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.mysql.com" <> Date: Mon, 5 May 2008 22:55:47 +0200 Subject: [PATCH 34/38] Add printouts --- mysql-test/lib/mtr_report.pm | 9 +++++++-- mysql-test/mysql-test-run.pl | 17 ++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 4a321e5d847..1a8a5e3e0ec 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -26,7 +26,7 @@ our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line mtr_print_header mtr_report mtr_report_stats mtr_warning mtr_error mtr_debug mtr_verbose mtr_verbose_restart mtr_report_test_passed - mtr_report_test_skipped + mtr_report_test_skipped mtr_print mtr_report_test); use mtr_match; @@ -386,8 +386,13 @@ sub _timestamp { $tm->hour, $tm->min, $tm->sec, $diff); } +# Always print message to screen +sub mtr_print (@) { + print $name, join(" ", @_), "\n"; +} -# Print message to screen + +# Print message to screen if verbose is defined sub mtr_report (@) { if (defined $verbose) { diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2227a8c77f6..d3febb6a5c1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2895,7 +2895,6 @@ sub run_testcase ($) { if ($check_res == 1) { # Test case had sideeffects, not fatal error, just continue stop_all_servers(); - clean_datadir(); mtr_report("Resuming tests...\n"); } else { @@ -3164,7 +3163,7 @@ sub check_expected_crash_and_restart { # Remove all files and subdirectories of a directory sub clean_dir { my ($dir)= @_; - print "clean_dir: $dir\n"; + mtr_print("clean_dir: $dir"); finddepth( { no_chdir => 1, wanted => sub { @@ -3174,12 +3173,12 @@ sub clean_dir { # The dir to clean return; } else { - print "rmdir: '$_'\n"; + mtr_print("rmdir: '$_'"); rmdir($_) or mtr_warning("rmdir($_) failed: $!"); } } else { # Hopefully a file - print "unlink: '$_'\n"; + mtr_print("unlink: '$_'"); unlink($_) or mtr_warning("unlink($_) failed: $!"); } } @@ -3192,10 +3191,14 @@ 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'"); + mtr_print(" - removing '$cluster_dir'"); rmtree($cluster_dir); } @@ -3204,7 +3207,7 @@ sub clean_datadir { { my $mysqld_dir= dirname($mysqld->value('datadir')); if (-d $mysqld_dir ) { - mtr_verbose(" - removing '$mysqld_dir'"); + mtr_print(" - removing '$mysqld_dir'"); rmtree($mysqld_dir); } } @@ -3509,7 +3512,7 @@ sub mysqld_start ($$) { sub stop_all_servers () { - mtr_report("Stopping all servers..."); + mtr_print("Stopping all servers..."); # Kill all started servers My::SafeProcess::shutdown(0, # shutdown timeout 0 => kill From c45e9ff746701fac7f7de5dbc8b1eff3c2961367 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Tue, 6 May 2008 17:11:09 +0200 Subject: [PATCH 35/38] Generate a unique tmpdir for each server to avoid that they delete each others temporary files at start up - see 'mysql_rm_tmp_tables' --- mysql-test/lib/My/ConfigFactory.pm | 10 ++++++++-- mysql-test/mysql-test-run.pl | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index 69bb969d7b8..824267c8cc0 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -104,10 +104,16 @@ sub fix_server_id { sub fix_socket { my ($self, $config, $group_name, $group)= @_; # Put socket file in tmpdir - my $dir= $group->value('tmpdir'); + my $dir= $self->{ARGS}->{tmpdir}; return "$dir/$group_name.sock"; } +sub fix_tmpdir { + my ($self, $config, $group_name, $group)= @_; + my $dir= $self->{ARGS}->{tmpdir}; + return "$dir/$group_name"; +} + sub fix_log_error { my ($self, $config, $group_name, $group)= @_; my $dir= dirname($group->value('datadir')); @@ -182,7 +188,7 @@ sub fix_ssl_client_key { my @mysqld_rules= ( { 'basedir' => sub { return shift->{ARGS}->{basedir}; } }, - { 'tmpdir' => sub { return shift->{ARGS}->{tmpdir}; } }, + { 'tmpdir' => \&fix_tmpdir }, { 'character-sets-dir' => \&fix_charset_dir }, { 'language' => \&fix_language }, { 'datadir' => \&fix_datadir }, diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index d3febb6a5c1..3e186b5ec46 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3816,6 +3816,10 @@ sub start_servers($) { mtr_error("Failed to copy 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); From 447916b9e6e29cb2c97be4280c98e12b242d0136 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.(none)" <> Date: Fri, 9 May 2008 11:50:36 +0200 Subject: [PATCH 36/38] Make printout of $name nicer Remove debug printouts --- mysql-test/lib/mtr_report.pm | 19 +++++++++++-------- mysql-test/mysql-test-run.pl | 21 ++++++++++----------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 1a8a5e3e0ec..b5c868cb20a 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -52,6 +52,9 @@ sub report_option { #print $name, " setting $opt to ", (defined $value? $value : "undef") ,"\n"; } +sub _name { + return $name ? $name." " : undef; +} sub _mtr_report_test_name ($) { my $tinfo= shift; @@ -63,7 +66,7 @@ sub _mtr_report_test_name ($) { $tname.= " '$tinfo->{combination}'" if defined $tinfo->{combination}; - print $name, _timestamp(); + print _name(), _timestamp(); printf "%-40s ", $tname; } @@ -388,7 +391,7 @@ sub _timestamp { # Always print message to screen sub mtr_print (@) { - print $name, join(" ", @_), "\n"; + print _name(), join(" ", @_), "\n"; } @@ -396,21 +399,21 @@ sub mtr_print (@) { sub mtr_report (@) { if (defined $verbose) { - print $name, join(" ", @_), "\n"; + print _name(), join(" ", @_), "\n"; } } # Print warning to screen sub mtr_warning (@) { - print STDERR $name, _timestamp(), + print STDERR _name(), _timestamp(), "mysql-test-run: WARNING: ", join(" ", @_), "\n"; } # Print error to screen and then exit sub mtr_error (@) { - print STDERR $name, _timestamp(), + print STDERR _name(), _timestamp(), "mysql-test-run: *** ERROR: ", join(" ", @_), "\n"; exit(1); } @@ -419,7 +422,7 @@ sub mtr_error (@) { sub mtr_debug (@) { if ( $verbose > 2 ) { - print STDERR $name, + print STDERR _name(), _timestamp(), "####: ", join(" ", @_), "\n"; } } @@ -428,7 +431,7 @@ sub mtr_debug (@) { sub mtr_verbose (@) { if ( $verbose ) { - print STDERR $name, _timestamp(), + print STDERR _name(), _timestamp(), "> ",join(" ", @_),"\n"; } } @@ -439,7 +442,7 @@ sub mtr_verbose_restart (@) { my $proc= $server->{proc}; if ( $verbose_restart ) { - print STDERR $name,_timestamp(), + print STDERR _name(),_timestamp(), "> Restart $proc - ",join(" ", @args),"\n"; } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index d3febb6a5c1..adf207d6473 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -220,7 +220,6 @@ sub main { if ( not defined $opt_parallel ) { # Try to find a suitable value for number of workers my $sys_info= My::SysInfo->new(); - $sys_info->print_info(); $opt_parallel= $sys_info->num_cpus(); for my $limit (2000, 1500, 1000, 500){ @@ -2828,15 +2827,15 @@ sub run_testcase ($) { # ---------------------------------------------------------------------- if ( $opt_start or $opt_start_dirty ) { - mtr_report("\nStarted", started(all_servers())); - mtr_report("Waiting for server(s) to exit..."); + mtr_print("\nStarted", started(all_servers())); + mtr_print("Waiting for server(s) to exit..."); my $proc= My::SafeProcess->wait_any(); if ( grep($proc eq $_, started(all_servers())) ) { - mtr_report("Server $proc died"); + mtr_print("Server $proc died"); exit(1); } - mtr_report("Unknown process $proc died"); + mtr_print("Unknown process $proc died"); exit(1); } @@ -3163,7 +3162,7 @@ sub check_expected_crash_and_restart { # Remove all files and subdirectories of a directory sub clean_dir { my ($dir)= @_; - mtr_print("clean_dir: $dir"); + mtr_verbose("clean_dir: $dir"); finddepth( { no_chdir => 1, wanted => sub { @@ -3173,12 +3172,12 @@ sub clean_dir { # The dir to clean return; } else { - mtr_print("rmdir: '$_'"); + mtr_verbose("rmdir: '$_'"); rmdir($_) or mtr_warning("rmdir($_) failed: $!"); } } else { # Hopefully a file - mtr_print("unlink: '$_'"); + mtr_verbose("unlink: '$_'"); unlink($_) or mtr_warning("unlink($_) failed: $!"); } } @@ -3198,7 +3197,7 @@ sub clean_datadir { foreach my $cluster ( clusters() ) { my $cluster_dir= "$opt_vardir/".$cluster->{name}; - mtr_print(" - removing '$cluster_dir'"); + mtr_verbose(" - removing '$cluster_dir'"); rmtree($cluster_dir); } @@ -3207,7 +3206,7 @@ sub clean_datadir { { my $mysqld_dir= dirname($mysqld->value('datadir')); if (-d $mysqld_dir ) { - mtr_print(" - removing '$mysqld_dir'"); + mtr_verbose(" - removing '$mysqld_dir'"); rmtree($mysqld_dir); } } @@ -3512,7 +3511,7 @@ sub mysqld_start ($$) { sub stop_all_servers () { - mtr_print("Stopping all servers..."); + mtr_verbose("Stopping all servers..."); # Kill all started servers My::SafeProcess::shutdown(0, # shutdown timeout 0 => kill From 10348f0f3882e936ed497196f1bfcd9cb7acbfba Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.(none)" <> Date: Tue, 20 May 2008 11:48:52 +0200 Subject: [PATCH 37/38] (temporarily)Turn on timestamp by default --- mysql-test/lib/mtr_report.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index b5c868cb20a..786e73f0680 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -34,7 +34,7 @@ require "mtr_io.pl"; my $tot_real_time= 0; -our $timestamp= 0; +our $timestamp= 1; our $timediff= 0; our $name; our $verbose; From ce4b99857bf432da85a55fb456eea1cda9cbd452 Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Thu, 19 Jun 2008 10:07:55 +0200 Subject: [PATCH 38/38] Instruct mysql_upgrade what tmpdir to use --- mysql-test/lib/My/ConfigFactory.pm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index 824267c8cc0..31927f5e8d5 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -300,6 +300,16 @@ my @mysqlbinlog_rules= ); +# +# Rules to run for [mysql_upgrade] section +# - will be run in order listed here +# +my @mysql_upgrade_rules= +( + { 'tmpdir' => sub { return shift->{ARGS}->{tmpdir}; } }, +); + + # # Generate a [client.] group to be # used for connecting to [mysqld.] @@ -606,6 +616,11 @@ sub new_config { $config->insert('mysqlbinlog'), @mysqlbinlog_rules); + # [mysql_upgrade] need additional settings + $self->run_rules_for_group($config, + $config->insert('mysql_upgrade'), + @mysql_upgrade_rules); + # Additional rules required for [client] $self->run_rules_for_group($config, $config->insert('client'),