diff --git a/mysql-test/include/check-warnings.test b/mysql-test/include/check-warnings.test index 9f404201ab8..154de4be290 100644 --- a/mysql-test/include/check-warnings.test +++ b/mysql-test/include/check-warnings.test @@ -1,9 +1,43 @@ - # # This test is executed once after each test to check the servers # for unexpected warnings found in the servers error log # +# NOTE! mysql-test-run.pl has already done a rough filtering +# of the file and written any suspicious lines +# to $error_log.warnings file +# --disable_query_log + +# Don't write these queries to binlog +set SQL_LOG_BIN=0; + +# Turn off any debug crashes, allow the variable to be +# non existent in release builds +--error 0,1193 +set debug=""; + +use mtr; + +create temporary table error_log ( + row int auto_increment primary key, + suspicious int default 1, + file_name varchar(255), + line varchar(1024) default null +) engine=myisam; + +# Get the name of servers error log +let $log_error= query_get_value(show variables like 'log_error', Value, 1); +let $log_warning= $log_error.warnings; + +# Load the warnings into a temporary table +eval load data infile '$log_warning' into table error_log + fields terminated by 'xykls37' + ignore 1 lines + (line) + set file_name='$log_error'; + +# Call check_warnings to filter out any warning in +# the error_log table call mtr.check_warnings(@result); if (`select @result = 0`){ skip OK; diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index 3da64fbd791..73287900f3c 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -2,44 +2,6 @@ delimiter ||; use mtr|| --- --- Load table with the patterns that are considered --- as suspicious and should be examined further --- -CREATE TABLE suspicious_patterns ( - pattern VARCHAR(255) -) ENGINE=MyISAM|| - - --- --- Declare a trigger that makes sure --- no invalid patterns can be inserted --- into suspicious_patterns --- -/*!50002 -CREATE DEFINER=root@localhost TRIGGER sp_insert -BEFORE INSERT ON suspicious_patterns -FOR EACH ROW BEGIN - DECLARE dummy INT; - SELECT "" REGEXP NEW.pattern INTO dummy; -END -*/|| - - --- --- Insert patterns for the lines we should check --- -INSERT INTO suspicious_patterns VALUES - ("^Warning:|mysqld: Warning|\\[Warning\\]"), - ("^Error:|\\[ERROR\\]"), - ("^==.* at 0x"), - ("InnoDB: Warning"), - ("^safe_mutex:|allocated at line"), - ("missing DBUG_RETURN"), - ("Attempting backtrace"), - ("Assertion .* failed")|| - - -- -- Create table where testcases can insert patterns to -- be suppressed @@ -219,71 +181,34 @@ INSERT INTO global_suppressions VALUES -- CREATE DEFINER=root@localhost PROCEDURE check_warnings(OUT result INT) BEGIN - DECLARE `text` mediumtext charset utf8; DECLARE `pos` bigint unsigned; -- Don't write these queries to binlog SET SQL_LOG_BIN=0; - -- - -- Load the server .err file into "error_log" table - -- - CREATE TEMPORARY TABLE error_log ( - row INT AUTO_INCREMENT PRIMARY KEY, - line mediumtext NULL - ) ENGINE=MyISAM; - - SELECT variable_value INTO @log_error - FROM information_schema.global_variables - WHERE variable_name='LOG_ERROR'; - - SET @old_max_allowed_packet= @@global.max_allowed_packet; - SET @@global.max_allowed_packet= 1024*1024*1024; - SET text= load_file(@log_error); - SET @@global.max_allowed_packet= @old_max_allowed_packet; - -- select text; - - SET pos= LOCATE('\n', text); - WHILE pos DO - INSERT error_log (line) - VALUES ( - SUBSTR(text, 1, pos-1) - ); - SET text= SUBSTR(text FROM pos+1); - SET pos= LOCATE('\n', text); - END WHILE; - - -- select * from error_log; -- - -- Remove all lines belonging to previous tests + -- Remove mark from lines that are suppressed by global suppressions -- - SELECT COALESCE(MAX(row),0) INTO @max_row - FROM error_log - WHERE line REGEXP "^CURRENT_TEST:"; - DELETE FROM error_log WHERE row < @max_row; + UPDATE error_log el, global_suppressions gs + SET suspicious=0 + WHERE el.suspicious=1 AND el.line REGEXP gs.pattern; - CREATE TEMPORARY TABLE suspect_lines ENGINE=MyISAM AS - SELECT DISTINCT el.line, 0 as "suppressed" - FROM error_log el, suspicious_patterns ep - WHERE el.line REGEXP ep.pattern; + -- + -- Remove mark from lines that are suppressed by test specific suppressions + -- + UPDATE error_log el, test_suppressions ts + SET suspicious=0 + WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; - -- Mark lines that are suppressed by global suppressions - UPDATE suspect_lines sl, global_suppressions gs - SET suppressed=1 - WHERE sl.line REGEXP gs.pattern; - - -- Mark lines that are suppressed by test specific suppressions - UPDATE suspect_lines sl, test_suppressions ts - SET suppressed=2 - WHERE sl.line REGEXP ts.pattern; - - SELECT COUNT(*) INTO @num_warnings FROM suspect_lines - WHERE suppressed=0; + -- + -- Get the number of marked lines and return result + -- + SELECT COUNT(*) INTO @num_warnings FROM error_log + WHERE suspicious=1; IF @num_warnings > 0 THEN - SELECT @log_error; - SELECT line as log_error - FROM suspect_lines WHERE suppressed=0; + SELECT file_name, line + FROM error_log WHERE suspicious=1; --SELECT * FROM test_suppressions; -- Return 2 -> check failed SELECT 2 INTO result; @@ -294,7 +219,7 @@ BEGIN -- Cleanup for next test TRUNCATE test_suppressions; - DROP TABLE error_log, suspect_lines; + DROP TABLE error_log; END|| diff --git a/mysql-test/lib/My/File/Path.pm b/mysql-test/lib/My/File/Path.pm index 7c0004ef526..99edeecdaf7 100644 --- a/mysql-test/lib/My/File/Path.pm +++ b/mysql-test/lib/My/File/Path.pm @@ -59,6 +59,43 @@ sub rmtree { }; +use File::Basename; +sub _mkpath_debug { + my ($message, $path, $dir, $err)= @_; + + print "=" x 40, "\n"; + print $message, "\n"; + print "err: '$err'\n"; + print "path: '$path'\n"; + print "dir: '$dir'\n"; + + print "-" x 40, "\n"; + my $dirname= dirname($path); + print "ls -l $dirname\n"; + print `ls -l $dirname`, "\n"; + print "-" x 40, "\n"; + print "dir $dirname\n"; + print `dir $dirname`, "\n"; + print "-" x 40, "\n"; + my $dirname2= dirname($dirname); + print "ls -l $dirname2\n"; + print `ls -l $dirname2`, "\n"; + print "-" x 40, "\n"; + print "dir $dirname2\n"; + print `dir $dirname2`, "\n"; + print "-" x 40, "\n"; + print "file exists\n" if (-e $path); + print "file is a plain file\n" if (-f $path); + print "file is a directory\n" if (-d $path); + print "-" x 40, "\n"; + print "showing handles for $path\n"; + My::Handles::show_handles($path); + + print "=" x 40, "\n"; + +} + + sub mkpath { my $path; @@ -78,15 +115,20 @@ sub mkpath { next if -d $path; # Path already exists and is a directory croak("File already exists but is not a directory: '$path'") if -e $path; next if mkdir($path); + _mkpath_debug("mkdir failed", $path, $dir, $!); # mkdir failed, try one more time next if mkdir($path); + _mkpath_debug("mkdir failed, second time", $path, $dir, $!); # mkdir failed again, try two more time after sleep(s) sleep(1); next if mkdir($path); + _mkpath_debug("mkdir failed, third time", $path, $dir, $!); + sleep(1); next if mkdir($path); + _mkpath_debug("mkdir failed, fourth time", $path, $dir, $!); # Report failure and die croak("Couldn't create directory '$path' ", diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 31359c08493..ce29f9a42ad 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -91,11 +91,14 @@ sub mtr_report_test_passed ($) { $tinfo->{timer}= $timer_str; } - # Set as passed unless already set - if ( not defined $tinfo->{'result'} ){ - $tinfo->{'result'}= 'MTR_RES_PASSED'; + # Big warning if status already set + if ( $tinfo->{'result'} ){ + mtr_warning("mtr_report_test_passed: Test result", + "already set to '", $tinfo->{'result'}, ","); } + $tinfo->{'result'}= 'MTR_RES_PASSED'; + mtr_report_test($tinfo); } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 53e87e30f29..ab3887c6cd4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -371,9 +371,9 @@ sub main { if ($opt_force){ # All test should have been run, print any that are still in $tests - foreach my $test ( @$tests ){ - $test->print_test(); - } + #foreach my $test ( @$tests ){ + # $test->print_test(); + #} } # Not all tests completed, failure @@ -697,6 +697,12 @@ sub run_worker ($) { if ($line eq 'TESTCASE'){ my $test= My::Test::read_test($server); #$test->print_test(); + + # Clear comment and logfile, to avoid + # reusing them from previous test + delete($test->{'comment'}); + delete($test->{'logfile'}); + run_testcase($test); #$test->{result}= 'MTR_RES_PASSED'; # Send it back, now with results set @@ -2915,6 +2921,7 @@ sub start_run_one ($$) { output => $errfile, args => \$args, user_data => $errfile, + verbose => $opt_verbose, ); mtr_verbose("Started $proc"); return $proc; @@ -3362,6 +3369,85 @@ sub run_testcase ($) { } +# +# Perform a rough examination of the servers +# error log and write all lines that look +# suspicious into $error_log.warnings +# +sub extract_warning_lines ($) { + my ($error_log) = @_; + + # Open the servers .err log file and read all lines + # belonging to current tets into @lines + my $Ferr = IO::File->new($error_log) + or mtr_error("Could not open file '$error_log' for reading: $!"); + + my @lines; + while ( my $line = <$Ferr> ) + { + if ( $line =~ /"^CURRENT_TEST:"/ ) + { + # Throw away lines from previous tests + @lines = (); + } + push(@lines, $line); + } + $Ferr = undef; # Close error log file + + # mysql_client_test.test sends a COM_DEBUG packet to the server + # to provoke a SAFEMALLOC leak report, ignore any warnings + # between "Begin/end safemalloc memory dump" + if ( grep(/Begin safemalloc memory dump:/, @lines) > 0) + { + my $discard_lines= 1; + foreach my $line ( @lines ) + { + if ($line =~ /Begin safemalloc memory dump:/){ + $discard_lines = 1; + } elsif ($line =~ /End safemalloc memory dump./){ + $discard_lines = 0; + } + + if ($discard_lines){ + $line = "ignored"; + } + } + } + + # Write all suspicious lines to $error_log.warnings file + my $warning_log = "$error_log.warnings"; + my $Fwarn = IO::File->new($warning_log, "w") + or die("Could not open file '$warning_log' for writing: $!"); + print $Fwarn "Suspicious lines from $error_log\n"; + + my @patterns = + ( + qr/^Warning:|mysqld: Warning|\\[Warning\\]/, + qr/^Error:|\\[ERROR\\]/, + qr/^==.* at 0x/, + qr/InnoDB: Warning|InnoDB: Error/, + qr/^safe_mutex:|allocated at line/, + qr/missing DBUG_RETURN/, + qr/Attempting backtrace/, + qr/Assertion .* failed/, + ); + + foreach my $line ( @lines ) + { + foreach my $pat ( @patterns ) + { + if ( $line =~ /$pat/ ) + { + print $Fwarn $line; + last; + } + } + } + $Fwarn = undef; # Close file + +} + + # Run include/check-warnings.test # # RETURN VALUE @@ -3374,6 +3460,8 @@ sub start_check_warnings ($$) { my $name= "warnings-".$mysqld->name(); + extract_warning_lines($mysqld->value('log-error')); + my $args; mtr_init_args(\$args); @@ -3409,6 +3497,7 @@ sub start_check_warnings ($$) { output => $errfile, args => \$args, user_data => $errfile, + verbose => $opt_verbose, ); mtr_verbose("Started $proc"); return $proc; @@ -3645,6 +3734,17 @@ sub save_datadir_after_failure($$) { } +sub remove_ndbfs_from_ndbd_datadir { + my ($ndbd_datadir)= @_; + # Remove the ndb_*_fs directory from ndbd.X/ dir + foreach my $ndbfs_dir ( glob("$ndbd_datadir/ndb_*_fs") ) + { + next unless -d $ndbfs_dir; # Skip if not a directory + rmtree($ndbfs_dir); + } +} + + sub after_failure ($) { my ($tinfo)= @_; @@ -3670,6 +3770,14 @@ sub after_failure ($) { if ( clusters() ) { foreach my $cluster ( clusters() ) { my $cluster_dir= "$opt_vardir/".$cluster->{name}; + + # Remove the fileystem of each ndbd + foreach my $ndbd ( in_cluster($cluster, ndbds()) ) + { + my $ndbd_datadir= $ndbd->value("DataDir"); + remove_ndbfs_from_ndbd_datadir($ndbd_datadir); + } + save_datadir_after_failure($cluster_dir, $save_dir); } } diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index be14e282f2a..384442f8c31 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -1,6 +1,5 @@ Run mysql_upgrade once mtr.global_suppressions OK -mtr.suspicious_patterns OK mtr.test_suppressions OK mysql.columns_priv OK mysql.db OK @@ -33,7 +32,6 @@ Run it again - should say already completed This installation of MySQL is already upgraded to VERSION, use --force if you still need to run mysql_upgrade Force should run it regardless of wether it's been run before mtr.global_suppressions OK -mtr.suspicious_patterns OK mtr.test_suppressions OK mysql.columns_priv OK mysql.db OK @@ -66,7 +64,6 @@ CREATE USER mysqltest1@'%' IDENTIFIED by 'sakila'; GRANT ALL ON *.* TO mysqltest1@'%'; Run mysql_upgrade with password protected account mtr.global_suppressions OK -mtr.suspicious_patterns OK mtr.test_suppressions OK mysql.columns_priv OK mysql.db OK @@ -101,7 +98,6 @@ mysqlcheck: Got error: 2005: Unknown MySQL server host 'not_existing_host' (errn FATAL ERROR: Upgrade failed set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE'; mtr.global_suppressions OK -mtr.suspicious_patterns OK mtr.test_suppressions OK mysql.columns_priv OK mysql.db OK diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index ac582930a6e..6f7fcb7efde 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -2,7 +2,6 @@ DROP TABLE IF EXISTS t1, `t``1`, `t 1`; drop view if exists v1; drop database if exists client_test_db; mtr.global_suppressions OK -mtr.suspicious_patterns OK mtr.test_suppressions OK mysql.columns_priv OK mysql.db OK diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 01363714484..78932396efe 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -513,7 +513,7 @@ Next alarm time: %lu\n", fprintf(stdout,"\nBegin safemalloc memory dump:\n"); // tag needed for test suite TERMINATE(stdout, 1); // Write malloc information fprintf(stdout,"\nEnd safemalloc memory dump.\n"); - + fflush(stdout); #ifdef HAVE_MALLINFO struct mallinfo info= mallinfo(); printf("\nMemory status:\n\