← Back to team overview

maria-developers team mailing list archive

wl#127 - changes to mtr for sphinx

 

Hi,

Kristian, I've done the changes - would you mind to review the patch ?

Somehow bzr didn't send the email automatically - could not connect to
the server, so I'll attach the output of bzr bundle to this email.

If you dont have time to review it (or don't want to :),
please remove yourself from a "reviewer" field in WL#127.

Thanks!

Regards,
Sergei

P.S. there are three patches attached - three bundles.

the first one fixes ndb. as ndb is hacked in mtr and is all over the
place, I could not change mtr without touching ndb related pieces,
and I need to make sure that I didn't break them. I found out that ndb
doesn't even build - without my changes, so I fixed that. I think we
need to build ndb at on some buildbot slaves, just to make sure we don't
break it. Or remove it completely - as it's clearly not used, and not
expected to be used, ndb users should use telco trees.

the second contain mtr changes.

the third adds sphinx suite.

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: sergii@xxxxxxxxx-20100802202047-rm609k322sd83e8e
# target_branch: lp:maria/5.2
# testament_sha1: 18b7a266ec9b4152c909e7596672c3cc78b6aa97
# timestamp: 2010-08-02 23:22:52 +0300
# base_revision_id: igor@xxxxxxxxxxxx-20100726173415-tkk3534ie8bzeleb
# 
# Begin patch
=== modified file 'BUILD/SETUP.sh'
--- BUILD/SETUP.sh	2010-03-30 16:16:57 +0000
+++ BUILD/SETUP.sh	2010-08-02 20:20:47 +0000
@@ -91,8 +91,8 @@
 get_make_parallel_flag
 
 # SSL library to use.--with-ssl will select our bundled yaSSL
-# implementation of SSL. To use openSSl you will nee too point out
-# the location of openSSL headers and lbs on your system.
+# implementation of SSL. To use OpenSSL you will need to specify
+# the location of OpenSSL headers and libs on your system.
 # Ex --with-ssl=/usr
 SSL_LIBRARY=--with-ssl
 
@@ -178,8 +178,7 @@
 max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache"
 max_no_ndb_configs="$SSL_LIBRARY --with-plugins=max-no-ndb --with-embedded-server --with-libevent"
 max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent"
-# Disable NDB in maria max builds
-max_configs=$max_no_ndb_configs
+all_configs="$SSL_LIBRARY --with-plugins=max --with-plugin-ndbcluster --with-embedded-server --with-libevent"
 
 #
 # CPU and platform specific compilation flags.

=== added file 'BUILD/compile-amd64-debug-all'
--- BUILD/compile-amd64-debug-all	1970-01-01 00:00:00 +0000
+++ BUILD/compile-amd64-debug-all	2010-08-02 20:20:47 +0000
@@ -0,0 +1,7 @@
+#! /bin/sh
+path=`dirname $0`
+. "$path/SETUP.sh"
+extra_flags="$amd64_cflags $debug_cflags"
+extra_configs="$amd64_configs $debug_configs $all_configs"
+
+. "$path/FINISH.sh"

=== added file 'BUILD/compile-pentium-debug-all'
--- BUILD/compile-pentium-debug-all	1970-01-01 00:00:00 +0000
+++ BUILD/compile-pentium-debug-all	2010-08-02 20:20:47 +0000
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+path=`dirname $0`
+set -- "$@" --with-debug=full
+. "$path/SETUP.sh"
+
+extra_flags="$pentium_cflags $debug_cflags"
+extra_configs="$pentium_configs $debug_configs $all_configs $error_inject --with-experimental-collations"
+
+. "$path/FINISH.sh"

=== added file 'BUILD/compile-pentium64-debug-all'
--- BUILD/compile-pentium64-debug-all	1970-01-01 00:00:00 +0000
+++ BUILD/compile-pentium64-debug-all	2010-08-02 20:20:47 +0000
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+path=`dirname $0`
+set -- "$@" --with-debug=full
+. "$path/SETUP.sh"
+
+extra_flags="$pentium64_cflags $debug_cflags"
+extra_configs="$pentium_configs $debug_configs $all_configs"
+
+extra_configs="$extra_configs "
+CC="$CC --pipe"
+. "$path/FINISH.sh"

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- storage/ndb/include/ndbapi/NdbDictionary.hpp	2007-12-07 10:05:19 +0000
+++ storage/ndb/include/ndbapi/NdbDictionary.hpp	2010-08-02 20:20:47 +0000
@@ -20,7 +20,7 @@
 
 class Ndb;
 struct charset_info_st;
-typedef struct charset_info_st CHARSET_INFO;
+typedef const struct charset_info_st CHARSET_INFO;
 
 /**
  * @class NdbDictionary

=== modified file 'storage/ndb/include/util/NdbSqlUtil.hpp'
--- storage/ndb/include/util/NdbSqlUtil.hpp	2006-12-23 19:20:40 +0000
+++ storage/ndb/include/util/NdbSqlUtil.hpp	2010-08-02 20:20:47 +0000
@@ -20,7 +20,7 @@
 #include <kernel/ndb_limits.h>
 
 struct charset_info_st;
-typedef struct charset_info_st CHARSET_INFO;
+typedef const struct charset_info_st CHARSET_INFO;
 
 class NdbSqlUtil {
 public:

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2008-02-06 12:06:05 +0000
+++ storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2010-08-02 20:20:47 +0000
@@ -2249,7 +2249,7 @@
 	Uint32 TattrDesc1 = tableDescriptor[TattrDescrIndex].tabDescr;
 	Uint32 TattrDesc2 = tableDescriptor[TattrDescrIndex+1].tabDescr;
 	Uint32 typeId = AttributeDescriptor::getType(TattrDesc1);
-	void * cs = 0;
+	const void * cs = 0;
 	if(AttributeOffset::getCharsetFlag(TattrDesc2))
 	{
 	  Uint32 pos = AttributeOffset::getCharsetPos(TattrDesc2);

# Begin bundle
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
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: sergii@xxxxxxxxx-20100802203334-9vg7c158cx13cy3q
# target_branch: lp:maria/5.2
# testament_sha1: 871f207021dbec51f99b1b378d3497b58241d4b3
# timestamp: 2010-08-02 23:34:10 +0300
# base_revision_id: sergii@xxxxxxxxx-20100802202047-rm609k322sd83e8e
# 
# Begin patch
=== modified file 'mysql-test/lib/My/Config.pm'
--- mysql-test/lib/My/Config.pm	2008-09-05 13:31:09 +0000
+++ mysql-test/lib/My/Config.pm	2010-08-02 20:33:34 +0000
@@ -61,7 +61,7 @@
     $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 @@
 # 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 @@
       $self->insert($group_name, $magic, undef);
     }
 
-    # Comments
-    elsif ( $line =~ /^#/ || $line =~ /^;/) {
-      # Skip comment
-      next;
-    }
-
     # Empty lines
     elsif ( $line =~ /^$/ ) {
       # Skip empty lines
@@ -236,7 +235,7 @@
     }
 
     # <option>
-    elsif ( $line =~ /^([\@\w-]+)\s*$/ ) {
+    elsif ( $line =~ /^([#\@\w-]+)\s*$/ ) {
       my $option= $1;
 
       croak "Found option '$option' outside of group"
@@ -247,7 +246,7 @@
     }
 
     # <option>=<value>
-    elsif ( $line =~ /^([\@\w-]+)\s*=\s*(.*?)\s*$/ ) {
+    elsif ( $line =~ /^([#\@\w-]+)\s*=\s*(.*?)\s*$/ ) {
       my $option= $1;
       my $value= $2;
 
@@ -256,10 +255,17 @@
 
       #print "$option=$value\n";
       $self->insert($group_name, $option, $value);
-    } else {
+    }
+
+    # Comments
+    elsif ( $line =~ /^#/ || $line =~ /^;/) {
+      # Skip comment
+      next;
+    }
+    
+    else {
       croak "Unexpected line '$line' found in '$path'";
     }
-
   }
   undef $F;			# Close the file
 
@@ -437,44 +443,4 @@
   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'
--- mysql-test/lib/My/ConfigFactory.pm	2010-04-28 12:52:24 +0000
+++ mysql-test/lib/My/ConfigFactory.pm	2010-08-02 20:33:34 +0000
@@ -57,16 +57,12 @@
 
 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 @@
 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 @@
 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,29 @@
 
 sub resolve_at_variable {
   my ($self, $config, $group, $option)= @_;
-
-  # 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'";
-
-  my $from= $from_group->value($option_name);
-  $config->insert($group->name(), $option->name(), $from)
+  local $_ = $option->value();
+  my ($res, $after);
+
+  while (m/(.*?)\@((?:\w+\.)+)(#?[-\w]+)/gi) {
+    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;
+  }
+  m/\G.*/;
+  $res .= $after;
+
+  $config->insert($group->name(), $option->name(), $res)
 }
 
 
@@ -453,7 +459,7 @@
       next unless defined $option->value();
 
       $self->resolve_at_variable($config, $group, $option)
-	if ($option->value() =~ /^\@/);
+	if ($option->value() =~ /\@/);
     }
   }
 }
@@ -595,25 +601,12 @@
     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'
--- mysql-test/lib/My/SafeProcess.pm	2010-04-28 12:52:24 +0000
+++ mysql-test/lib/My/SafeProcess.pm	2010-08-02 20:33:34 +0000
@@ -120,7 +120,7 @@
   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 @@
 
   # 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'
--- mysql-test/lib/My/Suite.pm	1970-01-01 00:00:00 +0000
+++ mysql-test/lib/My/Suite.pm	2010-08-02 20:33:34 +0000
@@ -0,0 +1,7 @@
+package My::Suite;
+
+sub config_files { () }
+sub servers { () }
+
+bless { };
+

=== modified file 'mysql-test/lib/mtr_cases.pm'
--- mysql-test/lib/mtr_cases.pm	2010-06-14 16:58:52 +0000
+++ mysql-test/lib/mtr_cases.pm	2010-08-02 20:33:34 +0000
@@ -39,7 +39,6 @@
 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 @@
 # 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 @@
   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 @@
      name          => "$suitename.$tname",
      shortname     => $tname,
      path          => "$testdir/$filename",
-
+     suite         => $suitename,
     );
 
   my $result_file= "$resdir/$tname.result";
@@ -1086,12 +1098,6 @@
     }
   }
 
-
-  # 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'
--- mysql-test/mysql-test-run.pl	2010-06-14 17:01:20 +0000
+++ mysql-test/mysql-test-run.pl	2010-08-02 20:33:34 +0000
@@ -130,7 +130,7 @@
 # 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 %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 @@
       # 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 @@
   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 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 ndbcluster_start ($) {
-  my $cluster= shift;
+  my ($cluster) = @_;
 
   mtr_verbose("ndbcluster_start '".$cluster->name()."'");
 
@@ -2659,6 +2661,109 @@
 }
 
 
+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');
+  unless ($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=
     (
@@ -3082,7 +3187,7 @@
      path          => $exe_mysql,
      args          => \$args,
      output        => '/dev/null',
-     error         => '/dev/null'
+     error         => '/dev/null',
     );
 
   return $res
@@ -3436,6 +3541,75 @@
   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 = (
+    'mysqld.' => {
+      SORT => 300,
+      START => \&mysql_server_start,
+      WAIT => \&mysql_server_wait,
+    },
+    'mysql_cluster.' => {
+      SORT => 200,
+      START => \&ndbcluster_start,
+      WAIT => \&ndbcluster_wait_started,
+    },
+    'cluster_config.ndb_mgmd.' => {
+      SORT => 210,
+      START => undef,
+    },
+    'cluster_config.ndbd.' => {
+      SORT => 220,
+      START => undef,
+    },
+    $suites{$tinfo->{suite}}->servers()
+  );
+  for ($config->groups()) {
+    while (my ($re,$prop) = each %servers) {
+      @$_{'SORT','START'} = @$prop{'SORT','START'} 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 @@
     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 @@
 	   vardir          => $opt_vardir,
 	   tmpdir          => $opt_tmpdir,
 	   baseport        => $baseport,
-	   #hosts          => [ 'host1', 'host2' ],
 	   user            => $opt_user,
 	   password        => '',
 	   ssl             => $opt_ssl_supported,
@@ -3522,8 +3695,16 @@
 	  }
 	);
 
-      # 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 @@
 
   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 @@
     }
     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 @@
             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 @@
 	# 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 @@
     # ----------------------------------------------------
     # 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 @@
     }
 
     # 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 @@
 # 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 {
   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 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 @@
   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 @@
   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_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() )
-  {
-    my $mysqld_dir= dirname($mysqld->value('datadir'));
-    preserve_error_log($mysqld);
-    if (-d $mysqld_dir ) {
-      mtr_verbose(" - removing '$mysqld_dir'");
-      rmtree($mysqld_dir);
-    }
+  for (servers())
+  {
+    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 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 @@
 
   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 @@
 
   # 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 @@
     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 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 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 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) );
-  }
+  mtr_report("Restarting ", started(@servers));
+
+  My::SafeProcess::shutdown($opt_shutdown_timeout,
+                             started(@servers));
 
   foreach my $server (@servers)
   {
@@ -4975,145 +5098,14 @@
 sub start_servers($) {
   my ($tinfo)= @_;
 
-  # Start clusters
-  foreach my $cluster ( clusters() )
-  {
-    ndbcluster_start($cluster);
-  }
-
-  # 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()) {
+    $_->{START}->($_, $tinfo) if $_->{START};
+  }
+
+  for (servers()) {
+    next unless $_->{WAIT} and started($_);
+    if ($_->{WAIT}->($_, $tinfo)) {
+      $tinfo->{comment}= "Failed to start ".$_->name();
       return 1;
     }
   }

# Begin bundle
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
9E/8XckU4UJBFngnuA==
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: sergii@xxxxxxxxx-20100802203541-tzdflh1grtz1uecx
# target_branch: lp:maria/5.2
# testament_sha1: 09a1d2d0c655570924c74723c6074f92f27a2d1e
# timestamp: 2010-08-02 23:35:55 +0300
# base_revision_id: sergii@xxxxxxxxx-20100802203334-9vg7c158cx13cy3q
# 
# Begin patch
=== added directory 'mysql-test/suite/sphinx'
=== added file 'mysql-test/suite/sphinx/my.cnf'
--- mysql-test/suite/sphinx/my.cnf	1970-01-01 00:00:00 +0000
+++ mysql-test/suite/sphinx/my.cnf	2010-08-02 20:35:41 +0000
@@ -0,0 +1,29 @@
+!include include/default_my.cnf
+
+[source src1]
+type = xmlpipe2
+xmlpipe_command = cat suite/sphinx/testdata.xml
+
+[index test1]
+source = src1
+docinfo = extern
+charset_type = utf-8
+path = @mysqld.1.#vardir/searchd/test1
+
+[indexer]
+mem_limit = 32M
+
+[searchd]
+read_timeout = 5
+max_children = 30
+max_matches = 1000
+seamless_rotate = 1
+preopen_indexes = 0
+unlink_old = 1
+log = @mysqld.1.#vardir/searchd/sphinx-searchd.log
+query_log = @mysqld.1.#vardir/searchd/sphinx-query.log
+#log-error = @mysqld.1.#vardir/searchd/sphinx.log
+pid_file = @mysqld.1.#vardir/run/searchd.pid
+
+[ENV]
+SPHINXSEARCH_PORT = @searchd.port

=== added file 'mysql-test/suite/sphinx/sphinx.result'
--- mysql-test/suite/sphinx/sphinx.result	1970-01-01 00:00:00 +0000
+++ mysql-test/suite/sphinx/sphinx.result	2010-08-02 20:35:41 +0000
@@ -0,0 +1,39 @@
+create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/*";
+select * from ts where q='test';
+id	w	q
+1	2	test
+2	2	test
+4	1	test
+drop table ts;
+create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/*";
+select * from ts where q='test;filter=gid,1;mode=extended';
+id	w	q
+1	2421	test;filter=gid,1;mode=extended
+2	2421	test;filter=gid,1;mode=extended
+select * from ts where q='test|one;mode=extended';
+id	w	q
+1	3595	test|one;mode=extended
+2	2460	test|one;mode=extended
+4	1471	test|one;mode=extended
+select * from ts where q='test;offset=1;limit=1';
+id	w	q
+2	2	test;offset=1;limit=1
+alter table ts connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/test1";
+select id, w from ts where q='one';
+id	w
+1	2
+drop table ts;
+create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, gid int not null, _sph_count int not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:SPHINXSEARCH_PORT/test1";
+select * from ts;
+id	w	q	gid	_sph_count
+select * from ts where q='';
+id	w	q	gid	_sph_count
+1	1		1	0
+2	1		1	0
+3	1		2	0
+4	1		2	0
+select * from ts where q=';groupby=attr:gid';
+id	w	q	gid	_sph_count
+3	1	;groupby=attr:gid	2	2
+1	1	;groupby=attr:gid	1	2
+drop table ts;

=== added file 'mysql-test/suite/sphinx/sphinx.test'
--- mysql-test/suite/sphinx/sphinx.test	1970-01-01 00:00:00 +0000
+++ mysql-test/suite/sphinx/sphinx.test	2010-08-02 20:35:41 +0000
@@ -0,0 +1,25 @@
+if (`SELECT "$HAVE_SPHINX" < "0000.0009.0009"`) {
+   skip Need Sphinx version 0.9.9 or later;
+}
+
+--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT
+eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/*";
+select * from ts where q='test';
+drop table ts;
+
+--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT
+eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/*";
+select * from ts where q='test;filter=gid,1;mode=extended';
+select * from ts where q='test|one;mode=extended';
+select * from ts where q='test;offset=1;limit=1';
+--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT
+eval alter table ts connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/test1";
+select id, w from ts where q='one';
+drop table ts;
+
+--replace_result $SPHINXSEARCH_PORT SPHINXSEARCH_PORT
+eval create table ts ( id bigint unsigned not null, w int not null, q varchar(255) not null, gid int not null, _sph_count int not null, index(q) ) engine=sphinx connection="sphinx://127.0.0.1:$SPHINXSEARCH_PORT/test1";
+select * from ts;
+select * from ts where q='';
+select * from ts where q=';groupby=attr:gid';
+drop table ts;

=== added file 'mysql-test/suite/sphinx/suite.opt'
--- mysql-test/suite/sphinx/suite.opt	1970-01-01 00:00:00 +0000
+++ mysql-test/suite/sphinx/suite.opt	2010-08-02 20:35:41 +0000
@@ -0,0 +1,1 @@
+--plugin-load=$HA_SPHINX_SO
\ No newline at end of file

=== added file 'mysql-test/suite/sphinx/suite.pm'
--- mysql-test/suite/sphinx/suite.pm	1970-01-01 00:00:00 +0000
+++ mysql-test/suite/sphinx/suite.pm	2010-08-02 20:35:41 +0000
@@ -0,0 +1,116 @@
+package My::Suite_A;
+
+use My::SafeProcess;
+use My::File::Path;
+use mtr_report;
+
+@ISA = qw(My::Suite);
+
+use Carp;
+$Carp::Verbose=1;
+
+############# initialization ######################
+sub locate_sphinx_binary {
+  my ($name)= @_;
+  my $res;
+  my @list= map "$_/bin/$name", qw(/usr /usr/local /usr/local/sphinx);
+  my $env_override= $ENV{"SPHINXSEARCH_\U$name"};
+  @list= ($env_override) if $env_override;
+  for (@list) { return $_ if -x $_; }
+}
+
+# Look for Sphinx binaries.
+my $exe_sphinx_indexer = &locate_sphinx_binary('indexer');
+my $exe_sphinx_searchd = &locate_sphinx_binary('searchd');
+
+if ($exe_sphinx_indexer and $exe_sphinx_searchd)
+{
+  local $_ = `"$exe_sphinx_searchd" --help`;
+  $ENV{HAVE_SPHINX}= sprintf "%04d.%04d.%04d", (/([0-9]+)\.([0-9]+)\.([0-9]+)/);
+}
+
+############# action methods ######################
+
+sub write_sphinx_conf {
+  my ($config) = @_; # My::Config
+  my $res;
+
+  foreach my $group ($config->groups()) {
+    my $name= $group->{name};
+    # Only the ones relevant to Sphinx search.
+    next unless ($name eq 'indexer' or $name eq 'searchd' or
+                 $name =~ /^(source|index) \w+$/);
+    $res .= "$name\n{\n";
+    foreach my $option ($group->options()) {
+      $res .= $option->name();
+      my $value= $option->value();
+      if (defined $value) {
+	$res .= "=$value";
+      }
+      $res .= "\n";
+    }
+    $res .= "}\n\n";
+  }
+  $res;
+}
+
+sub searchd_start {
+  my ($sphinx, $test) = @_; # My::Config::Group, My::Test
+
+  return unless $exe_sphinx_indexer and $exe_sphinx_searchd;
+
+  # First we must run the indexer to create the data.
+  my $sphinx_data_dir= "$::opt_vardir/" . $sphinx->name();
+  mkpath($sphinx_data_dir);
+  my $sphinx_log= $sphinx->value('#log-error');
+  my $sphinx_config= "$::opt_vardir/my_sphinx.conf";
+  my $cmd= "\"$exe_sphinx_indexer\" --config \"$sphinx_config\" test1 > \"$sphinx_log\" 2>&1";
+  &::mtr_verbose("cmd: $cmd");
+  system $cmd;
+
+  # Then start the searchd daemon.
+  my $args;
+  &::mtr_init_args(\$args);
+  &::mtr_add_arg($args, "--config");
+  &::mtr_add_arg($args, $sphinx_config);
+  &::mtr_add_arg($args, "--console");
+  &::mtr_add_arg($args, "--pidfile");
+
+  $sphinx->{'proc'}= My::SafeProcess->new
+    (
+     name         => 'sphinx-' . $sphinx->name(),
+     path         => $exe_sphinx_searchd,
+     args         => \$args,
+     output       => $sphinx_log,
+     error        => $sphinx_log,
+     append       => 1,
+     nocore       => 1,
+    );
+  &::mtr_verbose("Started $sphinx->{proc}");
+}
+
+sub searchd_wait {
+  my ($sphinx) = @_; # My::Config::Group
+
+  return not &::sleep_until_file_created($sphinx->value('pid_file'), 20,
+                                         $sphinx->{'proc'})
+}
+
+############# declaration methods ######################
+
+sub config_files() {
+  ( 'my_sphinx.conf' => \&write_sphinx_conf )
+}
+
+sub servers {
+  ( 'searchd' => {
+      SORT => 400,
+      START => \&searchd_start,
+      WAIT => \&searchd_wait,
+    }
+  )
+}
+
+############# return an object ######################
+bless { };
+

=== added file 'mysql-test/suite/sphinx/testdata.xml'
--- mysql-test/suite/sphinx/testdata.xml	1970-01-01 00:00:00 +0000
+++ mysql-test/suite/sphinx/testdata.xml	2010-08-02 20:35:41 +0000
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sphinx:docset>
+
+<sphinx:schema>
+<sphinx:field name="title"/> 
+<sphinx:field name="content"/>
+<sphinx:attr name="gid" type="int"/>
+</sphinx:schema>
+
+<sphinx:document id="1">
+<title>test one</title>
+<content>this is my test document number one. also checking search within phrases.</content>
+<gid>1</gid>
+</sphinx:document>
+
+<sphinx:document id="2">
+<title>test two</title>
+<content>this is my test document number two</content>
+<gid>1</gid>
+</sphinx:document>
+
+<sphinx:document id="3">
+<title>another doc</title>
+<content>this is another group</content>
+<gid>2</gid>
+</sphinx:document>
+
+<sphinx:document id="4">
+<title>doc number four</title>
+<content>this is to test groups</content>
+<gid>2</gid>
+</sphinx:document>
+
+</sphinx:docset>
+

# Begin bundle
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
FOFCQg+j/IA=

Follow ups