[Commits] Rev 2834: wl#127 - mtr changes to support per-suite extensions in http://bazaar.launchpad.net/~maria-captains/maria/5.2/

At http://bazaar.launchpad.net/~maria-captains/maria/5.2/ ------------------------------------------------------------ revno: 2834 revision-id: sergii@pisem.net-20100806130745-mc2jc1941bgazpg6 parent: sergii@pisem.net-20100802202047-rm609k322sd83e8e committer: Sergei Golubchik <sergii@pisem.net> branch nick: 5.2 timestamp: Fri 2010-08-06 17:07:45 +0400 message: wl#127 - mtr changes to support per-suite extensions === modified file 'mysql-test/lib/My/Config.pm' --- a/mysql-test/lib/My/Config.pm 2008-09-05 13:31:09 +0000 +++ b/mysql-test/lib/My/Config.pm 2010-08-06 13:07:45 +0000 @@ -61,7 +61,7 @@ sub insert { $option->{value}= $value; } else { - my $option= My::Config::Option->new($option_name, $value); + $option= My::Config::Option->new($option_name, $value); # Insert option in list push(@{$self->{options}}, $option); # Insert option in hash @@ -141,9 +141,14 @@ sub option { # Return value for an option in the group, fail if it does not exist # sub value { - my ($self, $option_name)= @_; + my ($self, $option_name, %create)= @_; my $option= $self->option($option_name); + if (! defined($option) and $create{$option_name}) { + my $value= &{$create{$option_name}}; + $option = $self->insert($option_name, $value); + } + croak "No option named '$option_name' in group '$self->{name}'" if ! defined($option); @@ -208,12 +213,6 @@ sub new { $self->insert($group_name, $magic, undef); } - # Comments - elsif ( $line =~ /^#/ || $line =~ /^;/) { - # Skip comment - next; - } - # Empty lines elsif ( $line =~ /^$/ ) { # Skip empty lines @@ -236,7 +235,7 @@ sub new { } # <option> - elsif ( $line =~ /^([\@\w-]+)\s*$/ ) { + elsif ( $line =~ /^(#?[\w-]+)\s*$/ ) { my $option= $1; croak "Found option '$option' outside of group" @@ -247,7 +246,7 @@ sub new { } # <option>=<value> - elsif ( $line =~ /^([\@\w-]+)\s*=\s*(.*?)\s*$/ ) { + elsif ( $line =~ /^(#?[\w-]+)\s*=\s*(.*?)\s*$/ ) { my $option= $1; my $value= $2; @@ -256,10 +255,17 @@ sub new { #print "$option=$value\n"; $self->insert($group_name, $option, $value); - } else { - croak "Unexpected line '$line' found in '$path'"; } + # Comments + elsif ( $line =~ /^#/ || $line =~ /^;/) { + # Skip comment + next; + } + + else { + croak "Unexpected line '$line' found in '$path'"; + } } undef $F; # Close the file @@ -437,44 +443,4 @@ sub exists { return defined($option); } - -# Overload "to string"-operator with 'stringify' -use overload - '""' => \&stringify; - -# -# Return the config as a string in my.cnf file format -# -sub stringify { - my ($self)= @_; - my $res; - - foreach my $group ($self->groups()) { - $res .= "[$group->{name}]\n"; - - foreach my $option ($group->options()) { - $res .= $option->name(); - my $value= $option->value(); - if (defined $value) { - $res .= "=$value"; - } - $res .= "\n"; - } - $res .= "\n"; - } - return $res; -} - - -# -# Save the config to named file -# -sub save { - my ($self, $path)= @_; - my $F= IO::File->new($path, ">") - or croak "Could not open '$path': $!"; - print $F $self; - undef $F; # Close the file -} - 1; === modified file 'mysql-test/lib/My/ConfigFactory.pm' --- a/mysql-test/lib/My/ConfigFactory.pm 2010-04-28 12:52:24 +0000 +++ b/mysql-test/lib/My/ConfigFactory.pm 2010-08-06 13:07:45 +0000 @@ -57,16 +57,12 @@ sub fix_pidfile { sub fix_port { my ($self, $config, $group_name, $group)= @_; - my $hostname= $group->value('#host'); - return $self->{HOSTS}->{$hostname}++; + return $self->{PORT}++; } sub fix_host { my ($self)= @_; - # Get next host from HOSTS array - my @hosts= keys(%{$self->{HOSTS}});; - my $host_no= $self->{NEXT_HOST}++ % @hosts; - return $hosts[$host_no]; + 'localhost' } sub is_unique { @@ -195,6 +191,7 @@ sub fix_ssl_client_key { my @mysqld_rules= ( { 'basedir' => sub { return shift->{ARGS}->{basedir}; } }, + { '#vardir' => sub { return shift->{ARGS}->{vardir}; } }, { 'tmpdir' => \&fix_tmpdir }, { 'character-sets-dir' => \&fix_charset_dir }, { 'language' => \&fix_language }, @@ -229,7 +226,7 @@ if (IS_WINDOWS) sub fix_ndb_mgmd_port { my ($self, $config, $group_name, $group)= @_; my $hostname= $group->value('HostName'); - return $self->{HOSTS}->{$hostname}++; + return $self->{PORT}++; } @@ -428,20 +425,28 @@ sub post_check_embedded_group { sub resolve_at_variable { my ($self, $config, $group, $option)= @_; + local $_ = $option->value(); + my ($res, $after); - # Split the options value on last . - my @parts= split(/\./, $option->value()); - my $option_name= pop(@parts); - my $group_name= join('.', @parts); - - $group_name =~ s/^\@//; # Remove at - - my $from_group= $config->group($group_name) - or croak "There is no group named '$group_name' that ", - "can be used to resolve '$option_name'"; + while (m/(.*?)\@((?:\w+\.)+)(#?[-\w]+)/g) { + my ($before, $group_name, $option_name)= ($1, $2, $3); + $after = $'; + chop($group_name); + + my $from_group= $config->group($group_name) + or croak "There is no group named '$group_name' that ", + "can be used to resolve '$option_name'"; + + my @auto_options = ( + 'port' => sub { fix_port($self, $config, $group_name, $group) }, + '#port' => sub { fix_port($self, $config, $group_name, $group) }, + ); + my $value= $from_group->value($option_name, @auto_options); + $res .= $before.$value; + } + $res .= $after; - my $from= $from_group->value($option_name); - $config->insert($group->name(), $option->name(), $from) + $config->insert($group->name(), $option->name(), $res) } @@ -453,7 +458,7 @@ sub post_fix_resolve_at_variables { next unless defined $option->value(); $self->resolve_at_variable($config, $group, $option) - if ($option->value() =~ /^\@/); + if ($option->value() =~ /\@/); } } } @@ -595,25 +600,12 @@ sub new_config { croak "you must pass '$required'" unless defined $args->{$required}; } - # Fill in hosts/port hash - my $hosts= {}; - my $baseport= $args->{baseport}; - $args->{hosts}= [ 'localhost' ] unless exists($args->{hosts}); - foreach my $host ( @{$args->{hosts}} ) { - $hosts->{$host}= $baseport; - } - # Open the config template my $config= My::Config->new($args->{'template_path'}); - my $extra_template_path= $args->{'extra_template_path'}; - if ($extra_template_path){ - $config->append(My::Config->new($extra_template_path)); - } my $self= bless { CONFIG => $config, ARGS => $args, - HOSTS => $hosts, - NEXT_HOST => 0, + PORT => $args->{baseport}, SERVER_ID => 1, }, $class; === modified file 'mysql-test/lib/My/Handles.pm' (properties changed: +x to -x) === modified file 'mysql-test/lib/My/SafeProcess.pm' --- a/mysql-test/lib/My/SafeProcess.pm 2010-04-28 12:52:24 +0000 +++ b/mysql-test/lib/My/SafeProcess.pm 2010-08-06 13:07:45 +0000 @@ -120,7 +120,7 @@ sub new { my $input = delete($opts{'input'}); my $output = delete($opts{'output'}); my $error = delete($opts{'error'}); - my $verbose = delete($opts{'verbose'}); + my $verbose = delete($opts{'verbose'}) || $::opt_verbose; my $nocore = delete($opts{'nocore'}); my $host = delete($opts{'host'}); my $shutdown = delete($opts{'shutdown'}); @@ -200,7 +200,7 @@ sub shutdown { # Call shutdown function if process has one, else # use kill - foreach my $proc (@processes){ + foreach my $proc (@processes) { _verbose(" proc: $proc"); my $shutdown= $proc->{SAFE_SHUTDOWN}; if ($shutdown_timeout > 0 and defined $shutdown){ === added file 'mysql-test/lib/My/Suite.pm' --- a/mysql-test/lib/My/Suite.pm 1970-01-01 00:00:00 +0000 +++ b/mysql-test/lib/My/Suite.pm 2010-08-06 13:07:45 +0000 @@ -0,0 +1,41 @@ +# +# A default suite class that is used for all suites without their owns suite.pm +# +# The suite.pm needs to have @ISA=qw(My::Suite) and it must end +# with bless {}; - that is it must return an object of that class. +# +# A suite class can define config_files() and servers() methods. +# +# A config_files method returns a list of additional config files (besides +# my.cnf), that this suite needs to be created. For every file it specifies +# a function that will create it, when given a My::Config object. For example: +# +# sub config_files { ( 'config.ini' => \&write_ini, +# 'new.conf' => \&do_new_conf ) } +# +# A servers method returns a list of processes that needs to be started for +# this suite. A process is specified as a pair (regex, hash). A regex must +# match a section in the my.cnf template (for example, qr/mysqld\./ corresponds +# to all mysqld processes), a hash contains these options: +# SORT => a number, processes are started in the order of increasing SORT +# values (and stopped in the reverse order). mysqld has number 300. +# START => a function to start a process. It takes two arguments, +# My::Config::Group and My::Test. If START is undefined the process +# will not be started. +# WAIT => a function waits for the process to be started. It takes +# My::Config::Group as an argument. Internallys mtr first invokes +# START for all processes, then WAIT for all started processes. +# +# example: sub servers { ( qr/^foo$/ => { SORT => 200, +# START => \&start_foo, +# WAIT => \&wait_foo } ) } +# +# See suite/sphinx/suite.pm for a working example. +# +package My::Suite; + +sub config_files { () } +sub servers { () } + +bless { }; + === modified file 'mysql-test/lib/mtr_cases.pm' --- a/mysql-test/lib/mtr_cases.pm 2010-06-14 16:58:52 +0000 +++ b/mysql-test/lib/mtr_cases.pm 2010-08-06 13:07:45 +0000 @@ -39,7 +39,6 @@ our $enable_disabled; our $default_storage_engine; our $opt_with_ndbcluster_only; our $defaults_file; -our $defaults_extra_file; our $quick_collect; sub collect_option { @@ -71,6 +70,8 @@ my $skip_test_reg; # If "Quick collect", set to 1 once a test to run has been found. my $some_test_found; +my $default_suite_object = do 'My/Suite.pm'; + sub init_pattern { my ($from, $what)= @_; return undef unless defined $from; @@ -295,6 +296,17 @@ sub collect_one_suite mtr_verbose("testdir: $testdir"); mtr_verbose("resdir: $resdir"); + # + # Load the Suite object + # + unless ($::suites{$suite}) { + if (-f "$suitedir/suite.pm") { + $::suites{$suite} = do "$suitedir/suite.pm"; + } else { + $::suites{$suite} = $default_suite_object; + } + } + # ---------------------------------------------------------------------- # Build a hash of disabled testcases for this suite # ---------------------------------------------------------------------- @@ -743,7 +755,7 @@ sub collect_one_test_case { name => "$suitename.$tname", shortname => $tname, path => "$testdir/$filename", - + suite => $suitename, ); my $result_file= "$resdir/$tname.result"; @@ -1086,12 +1098,6 @@ sub collect_one_test_case { } } - - # Set extra config file to use - if (defined $defaults_extra_file) { - $tinfo->{extra_template_path}= $defaults_extra_file; - } - # ---------------------------------------------------------------------- # Append mysqld extra options to both master and slave # ---------------------------------------------------------------------- === modified file 'mysql-test/mysql-test-run.pl' --- a/mysql-test/mysql-test-run.pl 2010-06-14 17:01:20 +0000 +++ b/mysql-test/mysql-test-run.pl 2010-08-06 13:07:45 +0000 @@ -130,7 +130,7 @@ my $path_config_file; # The ge # executables will be used by the test suite. our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; -my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,innodb,vcol,oqgraph"; +my $DEFAULT_SUITES= "main,binlog,federated,rpl,maria,parts,innodb,vcol,oqgraph,ndb"; my $opt_suites; our $opt_verbose= 0; # Verbose output, enable with --verbose @@ -255,6 +255,8 @@ our $debug_compiled_binaries; our %mysqld_variables; +our %suites; + my $source_dist= 0; my $opt_max_save_core= env_or_val(MTR_MAX_SAVE_CORE => 5); @@ -805,7 +807,7 @@ sub run_worker ($) { # We need to gracefully shut down the servers to see any # Valgrind memory leak errors etc. since last server restart. if ($opt_warnings) { - stop_servers(all_servers()); + stop_servers(reverse servers()); if(check_warnings_post_shutdown($server)) { # Warnings appeared in log file(s) during final server shutdown. exit(1); @@ -1583,7 +1585,7 @@ sub collect_mysqld_features { my $cmd= join(" ", $exe_mysqld, @$args); my $list= `$cmd`; - print "cmd: $cmd\n"; + mtr_verbose("cmd: $cmd"); foreach my $line (split('\n', $list)) { @@ -2471,7 +2473,7 @@ sub check_ndbcluster_support ($) { } -sub ndbcluster_wait_started($$){ +sub ndbcluster_wait_started { my $cluster= shift; my $ndb_waiter_extra_opt= shift; my $path_waitlog= join('/', $opt_vardir, $cluster->name(), "ndb_waiter.log"); @@ -2639,7 +2641,7 @@ sub ndbd_start { sub ndbcluster_start ($) { - my $cluster= shift; + my ($cluster) = @_; mtr_verbose("ndbcluster_start '".$cluster->name()."'"); @@ -2659,6 +2661,109 @@ sub ndbcluster_start ($) { } +sub mysql_server_start($) { + my ($mysqld, $tinfo) = @_; + + if ( $mysqld->{proc} ) + { + # Already started + + # Write start of testcase to log file + mark_log($mysqld->value('#log-error'), $tinfo); + + return; + } + + my $datadir= $mysqld->value('datadir'); + if (not $opt_start_dirty) + { + + my @options= ('log-bin', 'relay-log'); + foreach my $option_name ( @options ) { + next unless $mysqld->option($option_name); + + my $file_name= $mysqld->value($option_name); + next unless + defined $file_name and + -e $file_name; + + mtr_debug(" -removing '$file_name'"); + unlink($file_name) or die ("unable to remove file '$file_name'"); + } + + if (-d $datadir ) { + preserve_error_log($mysqld); + mtr_verbose(" - removing '$datadir'"); + rmtree($datadir); + } + } + + my $mysqld_basedir= $mysqld->value('basedir'); + if ( $basedir eq $mysqld_basedir ) + { + if (! $opt_start_dirty) # If dirty, keep possibly grown system db + { + # Copy datadir from installed system db + for my $path ( "$opt_vardir", "$opt_vardir/..") { + my $install_db= "$path/install.db"; + copytree($install_db, $datadir) + if -d $install_db; + } + mtr_error("Failed to copy system db to '$datadir'") + unless -d $datadir; + } + } + else + { + mysql_install_db($mysqld); # For versional testing + + mtr_error("Failed to install system db to '$datadir'") + unless -d $datadir; + + } + restore_error_log($mysqld); + + # Create the servers tmpdir + my $tmpdir= $mysqld->value('tmpdir'); + mkpath($tmpdir) unless -d $tmpdir; + + # Write start of testcase to log file + mark_log($mysqld->value('#log-error'), $tinfo); + + # Run <tname>-master.sh + if ($mysqld->option('#!run-master-sh') and + run_sh_script($tinfo->{master_sh}) ) + { + $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'"; + return 1; + } + + # Run <tname>-slave.sh + if ($mysqld->option('#!run-slave-sh') and + run_sh_script($tinfo->{slave_sh})) + { + $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'"; + return 1; + } + + if (!$opt_embedded_server) + { + my $extra_opts= get_extra_opts($mysqld, $tinfo); + mysqld_start($mysqld,$extra_opts); + + # Save this test case information, so next can examine it + $mysqld->{'started_tinfo'}= $tinfo; + } +} + +sub mysql_server_wait { + my ($mysqld) = @_; + + return not sleep_until_file_created($mysqld->value('pid-file'), + $opt_start_timeout, + $mysqld->{'proc'}); +} + sub create_config_file_for_extern { my %opts= ( @@ -3436,6 +3541,75 @@ sub timezone { return $tinfo->{timezone} || "DEFAULT"; } +sub mycnf_create { + my ($config) = @_; + my $res; + + foreach my $group ($config->groups()) { + $res .= "[$group->{name}]\n"; + + foreach my $option ($group->options()) { + $res .= $option->name(); + my $value= $option->value(); + if (defined $value) { + $res .= "=$value"; + } + $res .= "\n"; + } + $res .= "\n"; + } + $res; +} + +sub config_files($) { + my ($tinfo) = @_; + ( + 'my.cnf' => \&mycnf_create, + $suites{$tinfo->{suite}}->config_files() + ); +} + +sub _like { return $config ? $config->like($_[0]) : (); } +sub mysqlds { return _like('mysqld\.'); } +sub ndbds { return _like('cluster_config\.ndbd\.');} +sub ndb_mgmds { return _like('cluster_config\.ndb_mgmd\.'); } + +sub fix_servers($) { + my ($tinfo) = @_; + return () unless $config; + my %servers = ( + qr/mysqld\./ => { + SORT => 300, + START => \&mysql_server_start, + WAIT => \&mysql_server_wait, + }, + qr/mysql_cluster\./ => { + SORT => 200, + START => \&ndbcluster_start, + WAIT => \&ndbcluster_wait_started, + }, + qr/cluster_config\.ndb_mgmd\./ => { + SORT => 210, + START => undef, + }, + qr/cluster_config\.ndbd\./ => { + SORT => 220, + START => undef, + }, + $suites{$tinfo->{suite}}->servers() + ); + for ($config->groups()) { + while (my ($re,$prop) = each %servers) { + @$_{keys %$prop} = values %$prop if $_->{name} =~ /^$re/; + } + } +} + +sub servers { + return unless $config; + ( sort { $a->{SORT} <=> $b->{SORT} } + grep { defined $_->{SORT} } $config->groups() ); +} # Storage for changed environment variables my %old_env; @@ -3478,13 +3652,13 @@ sub run_testcase ($$) { if ( @restart != 0) { # Remember that we restarted for this test case (count restarts) $tinfo->{'restarted'}= 1; - stop_servers(@restart ); + stop_servers(reverse @restart); if ($opt_warnings) { check_warnings_post_shutdown($server_socket); } } - if ( started(all_servers()) == 0 ) + if (started(servers()) == 0) { # Remove old datadirs @@ -3514,7 +3688,6 @@ sub run_testcase ($$) { vardir => $opt_vardir, tmpdir => $opt_tmpdir, baseport => $baseport, - #hosts => [ 'host1', 'host2' ], user => $opt_user, password => '', ssl => $opt_ssl_supported, @@ -3522,8 +3695,16 @@ sub run_testcase ($$) { } ); - # Write the new my.cnf - $config->save($path_config_file); + fix_servers($tinfo); + + # Write config files: + my %config_files = config_files($tinfo); + while (my ($file, $generate) = each %config_files) { + my ($path) = "$opt_vardir/$file"; + open (F, '>', $path) or die "Could not open '$path': $!"; + print F &$generate($config); + close F; + } # Remember current config so a restart can occur when a test need # to use a different one @@ -3561,7 +3742,7 @@ sub run_testcase ($$) { if ( $start_only ) { - mtr_print("\nStarted", started(all_servers())); + mtr_print("\nStarted", started(servers())); mtr_print("Using config for test", $tinfo->{name}); mtr_print("Port and socket path for server(s):"); foreach my $mysqld ( mysqlds() ) @@ -3577,7 +3758,7 @@ sub run_testcase ($$) { } else { my $proc= My::SafeProcess->wait_any(); - if ( grep($proc eq $_, started(all_servers())) ) + if ( grep($proc eq $_, started(servers())) ) { mtr_print("Server $proc died"); exit(1); @@ -3666,7 +3847,7 @@ sub run_testcase ($$) { if ($opt_warnings) { # Checking error logs for warnings, so need to stop server # gracefully so that memory leaks etc. can be properly detected. - stop_servers(all_servers()); + stop_servers(reverse servers()); check_warnings_post_shutdown($server_socket); # Even if we got warnings here, we should not fail this # particular test, as the warnings may be caused by an earlier @@ -3712,7 +3893,7 @@ sub run_testcase ($$) { # Wait a bit and see if a server died, if so report that instead mtr_milli_sleep(100); my $srvproc= My::SafeProcess::check_any(); - if ($srvproc && grep($srvproc eq $_, started(all_servers()))) { + if ($srvproc && grep($srvproc eq $_, started(servers()))) { $proc= $srvproc; goto SRVDIED; } @@ -3760,7 +3941,7 @@ sub run_testcase ($$) { # ---------------------------------------------------- # Check if it was a server that died # ---------------------------------------------------- - if ( grep($proc eq $_, started(all_servers())) ) + if ( grep($proc eq $_, started(servers())) ) { # Server failed, probably crashed $tinfo->{comment}= @@ -3777,7 +3958,7 @@ sub run_testcase ($$) { } # Try to dump core for mysqltest and all servers - foreach my $proc ($test, started(all_servers())) + foreach my $proc ($test, started(servers())) { mtr_print("Trying to dump core for $proc"); if ($proc->dump_core()) @@ -3824,7 +4005,8 @@ sub run_testcase ($$) { # valuable debugging information even if there is no test failure recorded. sub _preserve_error_log_names { my ($mysqld)= @_; - my $error_log_file= $mysqld->value('#log-error'); + my $error_log_file= $mysqld->if_exist('#log-error'); + return unless $error_log_file and -r $error_log_file; my $error_log_dir= dirname($error_log_file); my $save_name= $error_log_dir ."/../". $mysqld->name() .".error.log"; return ($error_log_file, $save_name); @@ -3833,14 +4015,14 @@ sub _preserve_error_log_names { sub preserve_error_log { my ($mysqld)= @_; my ($error_log_file, $save_name)= _preserve_error_log_names($mysqld); - my $res= rename($error_log_file, $save_name); + rename($error_log_file, $save_name) if $save_name; # Ignore any errors, as it's just a best-effort to keep the log if possible. } sub restore_error_log { my ($mysqld)= @_; my ($error_log_file, $save_name)= _preserve_error_log_names($mysqld); - my $res= rename($save_name, $error_log_file); + rename($save_name, $error_log_file) if $save_name; } # Keep track of last position in mysqld error log where we scanned for @@ -3884,6 +4066,8 @@ sub pre_write_errorlog { sub extract_server_log ($$) { my ($error_log, $tname) = @_; + + return unless $error_log; # Open the servers .err log file and read all lines # belonging to current test into @lines @@ -3926,9 +4110,9 @@ sub get_log_from_proc ($$) { my ($proc, $name)= @_; my $srv_log= ""; - foreach my $mysqld (mysqlds()) { + foreach my $mysqld (servers()) { if ($mysqld->{proc} eq $proc) { - my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name); + my @srv_lines= extract_server_log($mysqld->if_exist('#log-error'), $name); $srv_log= "\nServer log from this test:\n" . join ("", @srv_lines); last; } @@ -4007,6 +4191,7 @@ sub extract_warning_lines ($) { my @antipatterns = ( qr/error .*connecting to master/, + qr/Plugin 'ndbcluster' will be forced to shutdown/, qr/InnoDB: Error: in ALTER TABLE `test`.`t[12]`/, qr/InnoDB: Error: table `test`.`t[12]` does not exist in the InnoDB internal/, qr/Slave: Unknown table 't1' Error_code: 1051/, @@ -4323,29 +4508,18 @@ sub clean_dir { sub clean_datadir { - mtr_verbose("Cleaning datadirs..."); - if (started(all_servers()) != 0){ + if (started(servers()) != 0) { mtr_error("Trying to clean datadir before all servers stopped"); } - foreach my $cluster ( clusters() ) - { - my $cluster_dir= "$opt_vardir/".$cluster->{name}; - mtr_verbose(" - removing '$cluster_dir'"); - rmtree($cluster_dir); - - } - - foreach my $mysqld ( mysqlds() ) + for (servers()) { - my $mysqld_dir= dirname($mysqld->value('datadir')); - preserve_error_log($mysqld); - if (-d $mysqld_dir ) { - mtr_verbose(" - removing '$mysqld_dir'"); - rmtree($mysqld_dir); - } + preserve_error_log($_); # or at least, try to + my $dir= "$opt_vardir/".$_->{name}; + mtr_verbose(" - removing '$dir'"); + rmtree($dir); } # Remove all files in tmp and var/tmp @@ -4368,17 +4542,6 @@ sub save_datadir_after_failure($$) { } -sub remove_ndbfs_from_ndbd_datadir { - my ($ndbd_datadir)= @_; - # Remove the ndb_*_fs directory from ndbd.X/ dir - foreach my $ndbfs_dir ( glob("$ndbd_datadir/ndb_*_fs") ) - { - next unless -d $ndbfs_dir; # Skip if not a directory - rmtree($ndbfs_dir); - } -} - - sub after_failure ($) { my ($tinfo)= @_; @@ -4395,31 +4558,18 @@ sub after_failure ($) { mkpath($save_dir) if ! -d $save_dir; - # Save the used my.cnf file - copy($path_config_file, $save_dir); + # Save the used config files + my %config_files = config_files($tinfo); + while (my ($file, $generate) = each %config_files) { + copy("$opt_vardir/$file", $save_dir); + } # Copy the tmp dir copytree("$opt_vardir/tmp/", "$save_dir/tmp/"); - if ( clusters() ) { - foreach my $cluster ( clusters() ) { - my $cluster_dir= "$opt_vardir/".$cluster->{name}; - - # Remove the fileystem of each ndbd - foreach my $ndbd ( in_cluster($cluster, ndbds()) ) - { - my $ndbd_datadir= $ndbd->value("DataDir"); - remove_ndbfs_from_ndbd_datadir($ndbd_datadir); - } - - save_datadir_after_failure($cluster_dir, $save_dir); - } - } - else { - foreach my $mysqld ( mysqlds() ) { - my $data_dir= $mysqld->value('datadir'); - save_datadir_after_failure(dirname($data_dir), $save_dir); - } + foreach (servers()) { + my $dir= "$opt_vardir/".$_->{name}; + save_datadir_after_failure($dir, $save_dir); } } @@ -4738,17 +4888,17 @@ sub stop_all_servers () { # Kill all started servers My::SafeProcess::shutdown($shutdown_timeout, - started(all_servers())); + started(servers())); # Remove pidfiles - foreach my $server ( all_servers() ) + foreach my $server (servers()) { my $pid_file= $server->if_exist('pid-file'); unlink($pid_file) if defined $pid_file; } # Mark servers as stopped - map($_->{proc}= undef, all_servers()); + map($_->{proc}= undef, servers()); } @@ -4810,8 +4960,7 @@ sub server_need_restart { return 1; } - my $is_mysqld= grep ($server eq $_, mysqlds()); - if ($is_mysqld) + if ($server->name() =~ /^mysqld\./) { # Check that running process was started with same options @@ -4858,22 +5007,14 @@ sub server_need_restart { sub servers_need_restart($) { my ($tinfo)= @_; - return grep { server_need_restart($tinfo, $_); } all_servers(); + return grep { server_need_restart($tinfo, $_); } servers(); } -# -# Return list of specific servers -# - there is no servers in an empty config -# -sub _like { return $config ? $config->like($_[0]) : (); } -sub mysqlds { return _like('mysqld.'); } -sub ndbds { return _like('cluster_config.ndbd.');} -sub ndb_mgmds { return _like('cluster_config.ndb_mgmd.'); } -sub clusters { return _like('mysql_cluster.'); } -sub all_servers { return ( mysqlds(), ndb_mgmds(), ndbds() ); } +############################################ +############################################ # # Filter a list of servers and return only those that are part @@ -4927,28 +5068,10 @@ sub get_extra_opts { sub stop_servers($$) { my (@servers)= @_; - if ( join('|', @servers) eq join('|', all_servers()) ) - { - # All servers are going down, use some kind of order to - # avoid too many warnings in the log files + mtr_report("Restarting ", started(@servers)); - mtr_report("Restarting all servers"); - - # mysqld processes - My::SafeProcess::shutdown( $opt_shutdown_timeout, started(mysqlds()) ); - - # cluster processes - My::SafeProcess::shutdown( $opt_shutdown_timeout, - started(ndbds(), ndb_mgmds()) ); - } - else - { - mtr_report("Restarting ", started(@servers)); - - # Stop only some servers - My::SafeProcess::shutdown( $opt_shutdown_timeout, - started(@servers) ); - } + My::SafeProcess::shutdown($opt_shutdown_timeout, + started(@servers)); foreach my $server (@servers) { @@ -4975,145 +5098,14 @@ sub stop_servers($$) { sub start_servers($) { my ($tinfo)= @_; - # Start clusters - foreach my $cluster ( clusters() ) - { - ndbcluster_start($cluster); + for (servers()) { + $_->{START}->($_, $tinfo) if $_->{START}; } - # Start mysqlds - foreach my $mysqld ( mysqlds() ) - { - if ( $mysqld->{proc} ) - { - # Already started - - # Write start of testcase to log file - mark_log($mysqld->value('#log-error'), $tinfo); - - next; - } - - my $datadir= $mysqld->value('datadir'); - if ($opt_start_dirty) - { - # Don't delete anything if starting dirty - ; - } - else - { - - my @options= ('log-bin', 'relay-log'); - foreach my $option_name ( @options ) { - next unless $mysqld->option($option_name); - - my $file_name= $mysqld->value($option_name); - next unless - defined $file_name and - -e $file_name; - - mtr_debug(" -removing '$file_name'"); - unlink($file_name) or die ("unable to remove file '$file_name'"); - } - - if (-d $datadir ) { - preserve_error_log($mysqld); - mtr_verbose(" - removing '$datadir'"); - rmtree($datadir); - } - } - - my $mysqld_basedir= $mysqld->value('basedir'); - if ( $basedir eq $mysqld_basedir ) - { - if (! $opt_start_dirty) # If dirty, keep possibly grown system db - { - # Copy datadir from installed system db - for my $path ( "$opt_vardir", "$opt_vardir/..") { - my $install_db= "$path/install.db"; - copytree($install_db, $datadir) - if -d $install_db; - } - mtr_error("Failed to copy system db to '$datadir'") - unless -d $datadir; - } - } - else - { - mysql_install_db($mysqld); # For versional testing - - mtr_error("Failed to install system db to '$datadir'") - unless -d $datadir; - - } - restore_error_log($mysqld); - - # Create the servers tmpdir - my $tmpdir= $mysqld->value('tmpdir'); - mkpath($tmpdir) unless -d $tmpdir; - - # Write start of testcase to log file - mark_log($mysqld->value('#log-error'), $tinfo); - - # Run <tname>-master.sh - if ($mysqld->option('#!run-master-sh') and - run_sh_script($tinfo->{master_sh}) ) - { - $tinfo->{'comment'}= "Failed to execute '$tinfo->{master_sh}'"; - return 1; - } - - # Run <tname>-slave.sh - if ($mysqld->option('#!run-slave-sh') and - run_sh_script($tinfo->{slave_sh})) - { - $tinfo->{'comment'}= "Failed to execute '$tinfo->{slave_sh}'"; - return 1; - } - - if (!$opt_embedded_server) - { - my $extra_opts= get_extra_opts($mysqld, $tinfo); - mysqld_start($mysqld,$extra_opts); - - # Save this test case information, so next can examine it - $mysqld->{'started_tinfo'}= $tinfo; - } - - } - - # Wait for clusters to start - foreach my $cluster ( clusters() ) - { - if (ndbcluster_wait_started($cluster, "")) - { - # failed to start - $tinfo->{'comment'}= "Start of '".$cluster->name()."' cluster failed"; - return 1; - } - } - - # Wait for mysqlds to start - foreach my $mysqld ( mysqlds() ) - { - next if !started($mysqld); - - if (sleep_until_file_created($mysqld->value('pid-file'), - $opt_start_timeout, - $mysqld->{'proc'}) == 0) { - $tinfo->{comment}= - "Failed to start ".$mysqld->name(); - - my $logfile= $mysqld->value('#log-error'); - if ( defined $logfile and -f $logfile ) - { - my @srv_lines= extract_server_log($logfile, $tinfo->{name}); - $tinfo->{logfile}= "Server log is:\n" . join ("", @srv_lines); - } - else - { - $tinfo->{logfile}= "Could not open server logfile: '$logfile'"; - } + for (servers()) { + next unless $_->{WAIT} and started($_); + if ($_->{WAIT}->($_)) { + $tinfo->{comment}= "Failed to start ".$_->name(); return 1; } }
participants (1)
-
serg@askmonty.org