Toward automated rs tests

This commit is contained in:
Kyle Banker 2010-12-13 16:25:23 -05:00
parent d69b0df717
commit 0a47b76fca
3 changed files with 52 additions and 35 deletions

View File

@ -1,7 +1,7 @@
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'mongo' require 'mongo'
require 'test/unit' require 'test/unit'
require './test/test_helper' require './test/replica_sets/rs_test_helper'
# NOTE: This test expects a replica set of three nodes to be running # NOTE: This test expects a replica set of three nodes to be running
# on the local host. # on the local host.
@ -9,19 +9,22 @@ class ReplicaSetCountTest < Test::Unit::TestCase
include Mongo include Mongo
def setup def setup
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]], [RS.host, RS.ports[2]])
[TEST_HOST, TEST_PORT + 2])
@db = @conn.db(MONGO_TEST_DB) @db = @conn.db(MONGO_TEST_DB)
@db.drop_collection("test-sets") @db.drop_collection("test-sets")
@coll = @db.collection("test-sets") @coll = @db.collection("test-sets")
end end
def teardown
RS.start(@node)
end
def test_correct_count_after_insertion_reconnect def test_correct_count_after_insertion_reconnect
@coll.insert({:a => 20})#, :safe => {:w => 3, :wtimeout => 10000}) @coll.insert({:a => 20})#, :safe => {:w => 3, :wtimeout => 10000})
assert_equal 1, @coll.count assert_equal 1, @coll.count
puts "Please disconnect the current master." # Disconnecting the current master node
gets @node = RS.kill_primary
rescue_connection_failure do rescue_connection_failure do
@coll.insert({:a => 30}, :safe => true) @coll.insert({:a => 30}, :safe => true)

View File

@ -69,21 +69,7 @@ class Test::Unit::TestCase
self.class.mongo_port self.class.mongo_port
end end
# Generic code for rescuing connection failures and retrying operations.
# This could be combined with some timeout functionality.
def rescue_connection_failure
success = false
while !success
begin
yield
success = true
rescue Mongo::ConnectionFailure
puts "Rescuing"
sleep(1)
end
end
end
def assert_raise_error(klass, message) def assert_raise_error(klass, message)
begin begin
yield yield

View File

@ -1,12 +1,18 @@
#!/usr/bin/ruby #!/usr/bin/ruby
require 'rubygems' STDOUT.sync = true
require 'mongo'
unless defined? Mongo
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
end
class ReplSetManager class ReplSetManager
attr_accessor :host, :start_port, :ports
def initialize(opts={}) def initialize(opts={})
@start_port = opts[:start_port] || 30000 @start_port = opts[:start_port] || 30000
@ports = []
@name = opts[:name] || 'replica-set-foo' @name = opts[:name] || 'replica-set-foo'
@count = opts[:count] || 3 @count = opts[:count] || 3
@host = opts[:host] || 'localhost' @host = opts[:host] || 'localhost'
@ -21,14 +27,17 @@ class ReplSetManager
puts "Starting a replica set with #{@count} nodes" puts "Starting a replica set with #{@count} nodes"
system("killall mongod") system("killall mongod")
@count.times do |n| @count.times do |n|
@mongods[n] ||= {} @mongods[n] ||= {}
@mongods[n]['db_path'] = get_path("rs-#{n}") port = @start_port + n
@mongods[n]['log_path'] = get_path("log-#{n}") @ports << port
@mongods[n]['port'] = port
@mongods[n]['db_path'] = get_path("rs-#{port}")
@mongods[n]['log_path'] = get_path("log-#{port}")
system("rm -rf #{@mongods[n]['db_path']}") system("rm -rf #{@mongods[n]['db_path']}")
system("mkdir -p #{@mongods[n]['db_path']}") system("mkdir -p #{@mongods[n]['db_path']}")
@mongods[n]['port'] = @start_port + n
@mongods[n]['start'] = "mongod --replSet #{@name} --logpath '#{@mongods[n]['log_path']}' " + @mongods[n]['start'] = "mongod --replSet #{@name} --logpath '#{@mongods[n]['log_path']}' " +
" --dbpath #{@mongods[n]['db_path']} --port #{@mongods[n]['port']} --fork" " --dbpath #{@mongods[n]['db_path']} --port #{@mongods[n]['port']} --fork"
@ -43,7 +52,6 @@ class ReplSetManager
@config['members'] << member @config['members'] << member
end end
p @mongods
init init
ensure_up ensure_up
end end
@ -54,6 +62,18 @@ class ReplSetManager
sleep(1) sleep(1)
end end
def kill_primary
node = get_node_with_state(1)
kill(node)
return node
end
def kill_secondary
node = get_node_with_state(2)
kill(node)
return node
end
def start(node) def start(node)
system(@mongods[node]['start']) system(@mongods[node]['start'])
@mongods[node]['up'] = true @mongods[node]['up'] = true
@ -63,15 +83,15 @@ class ReplSetManager
alias :restart :start alias :restart :start
def ensure_up def ensure_up
print "Ensuring members are up..."
@con = get_connection @con = get_connection
p @con
attempt(Mongo::OperationFailure) do attempt(Mongo::OperationFailure) do
status = @con['admin'].command({'replSetGetStatus' => 1}) status = @con['admin'].command({'replSetGetStatus' => 1})
p status print "."
if status['members'].all? { |m| [1, 2, 7].include?(m['state']) } if status['members'].all? { |m| [1, 2, 7].include?(m['state']) }
puts "All members up!" puts "All members up!"
return return status
else else
raise Mongo::OperationFailure raise Mongo::OperationFailure
end end
@ -88,11 +108,22 @@ class ReplSetManager
end end
end end
def get_node_with_state(state)
status = ensure_up
node = status['members'].detect {|m| m['state'] == state}
if node
host_port = node['name'].split(':')
port = host_port[1] ? host_port[1].to_i : 27017
key = @mongods.keys.detect {|key| @mongods[key]['port'] == port}
return key
else
return false
end
end
def get_connection def get_connection
attempt(Mongo::ConnectionFailure) do attempt(Mongo::ConnectionFailure) do
node = @mongods.keys.detect {|key| !@mongods[key]['arbiter'] && @mongods[key]['up'] } node = @mongods.keys.detect {|key| !@mongods[key]['arbiter'] && @mongods[key]['up'] }
p @mongods[node]['port']
p node
@con = Mongo::Connection.new(@host, @mongods[node]['port'], :slave_ok => true) @con = Mongo::Connection.new(@host, @mongods[node]['port'], :slave_ok => true)
end end
@ -100,10 +131,7 @@ class ReplSetManager
end end
def get_path(name) def get_path(name)
p @path File.join(@path, name)
j = File.join(@path, name)
p j
j
end end
def attempt(exception) def attempt(exception)