MDEV-25857 MTR should report at least last test that was executed in case of shutdown and not-completed

* return a success/failure value from mysqld_start()
  and don't error out / exit in mysqld_start(), the caller will do
* pass the correct $mysqld object into check_expected_crash_and_restart()
  instead of searching for it inside. Search in the caller
* so that when a failed restart changes $mysqld->{proc}, mtr would
  still detect it as a failed mysqld (by updating $proc to match)

also: log the server command line into the server error log
This commit is contained in:
Sergei Golubchik 2021-07-05 22:02:23 +02:00
parent 22e4baaa5d
commit 6a466db00a

View file

@ -2820,7 +2820,9 @@ sub mysql_server_start($) {
if (!$opt_embedded_server)
{
mysqld_start($mysqld,$extra_opts);
mysqld_start($mysqld, $extra_opts) or
mtr_error("Failed to start mysqld ".$mysqld->name()." with command "
. $ENV{MYSQLD_LAST_CMD});
# Save this test case information, so next can examine it
$mysqld->{'started_tinfo'}= $tinfo;
@ -4135,9 +4137,12 @@ sub run_testcase ($$) {
# ----------------------------------------------------
# Check if it was an expected crash
# ----------------------------------------------------
my $check_crash = check_expected_crash_and_restart($wait_for_proc);
my @mysqld = grep($wait_for_proc eq $_->{proc}, mysqlds());
goto SRVDIED unless @mysqld;
my $check_crash = check_expected_crash_and_restart($mysqld[0]);
if ($check_crash == 0) # unexpected exit/crash of $wait_for_proc
{
$proc= $mysqld[0]->{proc};
goto SRVDIED;
}
elsif ($check_crash == 1) # $wait_for_proc was started again by check_expected_crash_and_restart()
@ -4695,61 +4700,52 @@ sub check_warnings_post_shutdown {
}
#
# Loop through our list of processes and look for and entry
# with the provided pid, if found check for the file indicating
# expected crash and restart it.
# Check for the file indicating expected crash and restart it.
#
sub check_expected_crash_and_restart {
my ($proc)= @_;
my $mysqld = shift;
foreach my $mysqld ( mysqlds() )
# Check if crash expected by looking at the .expect file
# in var/tmp
my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
if ( -f $expect_file )
{
next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc );
mtr_verbose("Crash was expected, file '$expect_file' exists");
# Check if crash expected by looking at the .expect file
# in var/tmp
my $expect_file= "$opt_vardir/tmp/".$mysqld->name().".expect";
if ( -f $expect_file )
for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++)
{
mtr_verbose("Crash was expected, file '$expect_file' exists");
for (my $waits = 0; $waits < 50; mtr_milli_sleep(100), $waits++)
# Race condition seen on Windows: try again until file not empty
next if -z $expect_file;
# If last line in expect file starts with "wait"
# sleep a little and try again, thus allowing the
# test script to control when the server should start
# up again. Keep trying for up to 5s at a time.
my $last_line= mtr_lastlinesfromfile($expect_file, 1);
if ($last_line =~ /^wait/ )
{
# Race condition seen on Windows: try again until file not empty
next if -z $expect_file;
# If last line in expect file starts with "wait"
# sleep a little and try again, thus allowing the
# test script to control when the server should start
# up again. Keep trying for up to 5s at a time.
my $last_line= mtr_lastlinesfromfile($expect_file, 1);
if ($last_line =~ /^wait/ )
{
mtr_verbose("Test says wait before restart") if $waits == 0;
next;
}
# Ignore any partial or unknown command
next unless $last_line =~ /^restart/;
# If last line begins "restart:", the rest of the line is read as
# extra command line options to add to the restarted mysqld.
# Anything other than 'wait' or 'restart:' (with a colon) will
# result in a restart with original mysqld options.
if ($last_line =~ /restart:(.+)/) {
my @rest_opt= split(' ', $1);
$mysqld->{'restart_opts'}= \@rest_opt;
} else {
delete $mysqld->{'restart_opts'};
}
unlink($expect_file);
# Start server with same settings as last time
mysqld_start($mysqld, $mysqld->{'started_opts'});
return 1;
mtr_verbose("Test says wait before restart") if $waits == 0;
next;
}
# Loop ran through: we should keep waiting after a re-check
return 2;
# Ignore any partial or unknown command
next unless $last_line =~ /^restart/;
# If last line begins "restart:", the rest of the line is read as
# extra command line options to add to the restarted mysqld.
# Anything other than 'wait' or 'restart:' (with a colon) will
# result in a restart with original mysqld options.
if ($last_line =~ /restart:(.+)/) {
my @rest_opt= split(' ', $1);
$mysqld->{'restart_opts'}= \@rest_opt;
} else {
delete $mysqld->{'restart_opts'};
}
unlink($expect_file);
# Start server with same settings as last time
return mysqld_start($mysqld, $mysqld->{'started_opts'});
}
# Loop ran through: we should keep waiting after a re-check
return 2;
}
# Not an expected crash
@ -5106,6 +5102,7 @@ sub mysqld_start ($$) {
if ( defined $exe )
{
mtr_tofile($output, "\$ $exe @$args\n");
pre_write_errorlog($output);
$mysqld->{'proc'}= My::SafeProcess->new
(
@ -5124,17 +5121,10 @@ sub mysqld_start ($$) {
mtr_verbose("Started $mysqld->{proc}");
}
if (!sleep_until_file_created($mysqld->value('pid-file'),
$opt_start_timeout, $mysqld->{'proc'}, $warn_seconds))
{
my $mname= $mysqld->name();
mtr_error("Failed to start mysqld $mname with command $exe");
}
# Remember options used when starting
$mysqld->{'started_opts'}= $extra_opts;
return;
return sleep_until_file_created($mysqld->value('pid-file'),
$opt_start_timeout, $mysqld->{'proc'}, $warn_seconds);
}