I am writing a script that reads connection information from a config
file, and based, on what it finds, connects to multiple mysql servers
and performs tasks.  To test this script, I need to set up test
servers, but getting them running without causing the tests to be
rerun when they stop is a bit..tricky.  I cannot say that I'm proud of
it, but here is how I did it:

tc_my_script_spec.rb:
require 'my_script'
...

def setup_test_servers
  teardown_test_servers(:kill)
...
  pids = []
...
  pid = fork {`nohup mysqld_safe --no-defaults #{server_options * ' '}
&`}
  raise "mysqld_safe fork failed" if $? != 0
  if pid
    pids << pid
  else
    exit!
  end
...
  pids.each{|pid| Process.kill(9,pid)}

  Spec::Runner.configure do |config|
    config.after(:suite)
      at_exit(teardown_test_servers(nil)
    end
  end
end

def teardown_test_servers(kill)
  @servers.each do |server, data|
    connection_options = {
      :host => data[:host],
      :port => data[:port],
      :user => 'shutdown',
    }
  connection_string = '--no-defaults ' + connect_options.map{|opt,
val| "--#{opt}=#{val}"} * ' '
  if doit_status("mysqladmin #{connect_string} ping 2>&1") == 0
    doit("mysqladmin #{connect_string} shutdown")
  end
  doit("rm -rf #{datadir}") if kill or !File.exists? "#{datadir}/keep"
end

def doit(command)
  response = core_do(command)
  $? != 0 and raise "Command: #{command}\nExit code :#{'%x' % $?}.\n#
{response}"
  response
end

def doit_status(command)
  core_do(command)
  $? >> 8
end

def core_do(command)
  response = `#{command}`
  signal = $? & 0x7f
  kill(signal, 0) if signal != 0
  response
end

...

describe ...

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to