ReplSetConnection updates
This commit is contained in:
parent
08b7cddc81
commit
27b410f869
|
@ -92,47 +92,18 @@ module Mongo
|
||||||
#
|
#
|
||||||
# @core connections
|
# @core connections
|
||||||
def initialize(host=nil, port=nil, options={})
|
def initialize(host=nil, port=nil, options={})
|
||||||
@auths = options.fetch(:auths, [])
|
|
||||||
|
|
||||||
@host_to_try = format_pair(host, port)
|
@host_to_try = format_pair(host, port)
|
||||||
|
|
||||||
# Host and port of current master.
|
# Host and port of current master.
|
||||||
@host = @port = nil
|
@host = @port = nil
|
||||||
|
|
||||||
# Lock for request ids.
|
|
||||||
@id_lock = Mutex.new
|
|
||||||
|
|
||||||
# Pool size and timeout.
|
|
||||||
@pool_size = options[:pool_size] || 1
|
|
||||||
@timeout = options[:timeout] || 5.0
|
|
||||||
|
|
||||||
# Mutex for synchronizing pool access
|
|
||||||
@connection_mutex = Mutex.new
|
|
||||||
|
|
||||||
# Global safe option. This is false by default.
|
|
||||||
@safe = options[:safe] || false
|
|
||||||
|
|
||||||
# Create a mutex when a new key, in this case a socket,
|
|
||||||
# is added to the hash.
|
|
||||||
@safe_mutexes = Hash.new { |h, k| h[k] = Mutex.new }
|
|
||||||
|
|
||||||
# Condition variable for signal and wait
|
|
||||||
@queue = ConditionVariable.new
|
|
||||||
|
|
||||||
# slave_ok can be true only if one node is specified
|
# slave_ok can be true only if one node is specified
|
||||||
@slave_ok = options[:slave_ok]
|
@slave_ok = options[:slave_ok]
|
||||||
|
|
||||||
@primary = nil
|
setup(options)
|
||||||
|
|
||||||
# Connection pool for primay node
|
|
||||||
@primary_pool = nil
|
|
||||||
|
|
||||||
@logger = options[:logger] || nil
|
|
||||||
|
|
||||||
should_connect = options.fetch(:connect, true)
|
|
||||||
connect if should_connect
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# DEPRECATED
|
# DEPRECATED
|
||||||
#
|
#
|
||||||
# Initialize a connection to a MongoDB replica set using an array of seed nodes.
|
# Initialize a connection to a MongoDB replica set using an array of seed nodes.
|
||||||
|
@ -160,19 +131,10 @@ module Mongo
|
||||||
#
|
#
|
||||||
# @deprecated
|
# @deprecated
|
||||||
def self.multi(nodes, opts={})
|
def self.multi(nodes, opts={})
|
||||||
unless nodes.length > 0 && nodes.all? {|n| n.is_a? Array}
|
warn "Connection.multi is now deprecated. Please use ReplSetConnection.new instead."
|
||||||
raise MongoArgumentError, "Connection.multi requires at least one node to be specified."
|
|
||||||
end
|
|
||||||
|
|
||||||
# Block returns an array, the first element being an array of nodes and the second an array
|
nodes << opts
|
||||||
# of authorizations for the database.
|
ReplSetConnection.new(*nodes)
|
||||||
new(nil, nil, opts) do |con|
|
|
||||||
nodes.map do |node|
|
|
||||||
con.instance_variable_set(:@replica_set, true)
|
|
||||||
con.instance_variable_set(:@read_secondary, true) if opts[:read_secondary]
|
|
||||||
con.pair_val_to_connection(node)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Initialize a connection to MongoDB using the MongoDB URI spec:
|
# Initialize a connection to MongoDB using the MongoDB URI spec:
|
||||||
|
@ -191,6 +153,8 @@ module Mongo
|
||||||
elsif nodes.length > 1
|
elsif nodes.length > 1
|
||||||
nodes << opts
|
nodes << opts
|
||||||
ReplSetConnection.new(*nodes)
|
ReplSetConnection.new(*nodes)
|
||||||
|
else
|
||||||
|
raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -500,40 +464,8 @@ module Mongo
|
||||||
@primary_pool = nil
|
@primary_pool = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
## Configuration helper methods
|
|
||||||
|
|
||||||
# Returns a host-port pair.
|
# Checkout a socket for reading (i.e., a secondary node).
|
||||||
#
|
|
||||||
# @return [Array]
|
|
||||||
#
|
|
||||||
# @private
|
|
||||||
def format_pair(host, port)
|
|
||||||
case host
|
|
||||||
when String
|
|
||||||
[host, port ? port.to_i : DEFAULT_PORT]
|
|
||||||
when nil
|
|
||||||
['localhost', DEFAULT_PORT]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Convert an argument containing a host name string and a
|
|
||||||
# port number integer into a [host, port] pair array.
|
|
||||||
#
|
|
||||||
# @private
|
|
||||||
def pair_val_to_connection(a)
|
|
||||||
case a
|
|
||||||
when nil
|
|
||||||
['localhost', DEFAULT_PORT]
|
|
||||||
when String
|
|
||||||
[a, DEFAULT_PORT]
|
|
||||||
when Integer
|
|
||||||
['localhost', a]
|
|
||||||
when Array
|
|
||||||
a
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checkout a socket for reading (i.e., a secondary node).
|
|
||||||
def checkout_reader
|
def checkout_reader
|
||||||
connect unless connected?
|
connect unless connected?
|
||||||
|
|
||||||
|
@ -567,6 +499,77 @@ module Mongo
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# Generic initialization code.
|
||||||
|
# @protected
|
||||||
|
def setup(options)
|
||||||
|
# Authentication objects
|
||||||
|
@auths = options.fetch(:auths, [])
|
||||||
|
|
||||||
|
# Lock for request ids.
|
||||||
|
@id_lock = Mutex.new
|
||||||
|
|
||||||
|
# Pool size and timeout.
|
||||||
|
@pool_size = options[:pool_size] || 1
|
||||||
|
@timeout = options[:timeout] || 5.0
|
||||||
|
|
||||||
|
# Mutex for synchronizing pool access
|
||||||
|
@connection_mutex = Mutex.new
|
||||||
|
|
||||||
|
# Global safe option. This is false by default.
|
||||||
|
@safe = options[:safe] || false
|
||||||
|
|
||||||
|
# Create a mutex when a new key, in this case a socket,
|
||||||
|
# is added to the hash.
|
||||||
|
@safe_mutexes = Hash.new { |h, k| h[k] = Mutex.new }
|
||||||
|
|
||||||
|
# Condition variable for signal and wait
|
||||||
|
@queue = ConditionVariable.new
|
||||||
|
|
||||||
|
# Connection pool for primay node
|
||||||
|
@primary = nil
|
||||||
|
@primary_pool = nil
|
||||||
|
|
||||||
|
@logger = options[:logger] || nil
|
||||||
|
|
||||||
|
should_connect = options.fetch(:connect, true)
|
||||||
|
connect if should_connect
|
||||||
|
end
|
||||||
|
|
||||||
|
## Configuration helper methods
|
||||||
|
|
||||||
|
# Returns a host-port pair.
|
||||||
|
#
|
||||||
|
# @return [Array]
|
||||||
|
#
|
||||||
|
# @private
|
||||||
|
def format_pair(host, port)
|
||||||
|
case host
|
||||||
|
when String
|
||||||
|
[host, port ? port.to_i : DEFAULT_PORT]
|
||||||
|
when nil
|
||||||
|
['localhost', DEFAULT_PORT]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convert an argument containing a host name string and a
|
||||||
|
# port number integer into a [host, port] pair array.
|
||||||
|
#
|
||||||
|
# @private
|
||||||
|
def pair_val_to_connection(a)
|
||||||
|
case a
|
||||||
|
when nil
|
||||||
|
['localhost', DEFAULT_PORT]
|
||||||
|
when String
|
||||||
|
[a, DEFAULT_PORT]
|
||||||
|
when Integer
|
||||||
|
['localhost', a]
|
||||||
|
when Array
|
||||||
|
a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# If a ConnectionFailure is raised, this method will be called
|
# If a ConnectionFailure is raised, this method will be called
|
||||||
|
@ -584,7 +587,7 @@ module Mongo
|
||||||
# apply any saved authentication.
|
# apply any saved authentication.
|
||||||
# TODO: simplify
|
# TODO: simplify
|
||||||
def is_primary?(config)
|
def is_primary?(config)
|
||||||
config && (config['ismaster'] == 1 || config['ismaster'] == true) || !@replica_set && @slave_ok
|
config && (config['ismaster'] == 1 || config['ismaster'] == true) || @slave_ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_is_master(node)
|
def check_is_master(node)
|
||||||
|
|
|
@ -19,19 +19,25 @@
|
||||||
module Mongo
|
module Mongo
|
||||||
|
|
||||||
# Instantiates and manages connections to MongoDB.
|
# Instantiates and manages connections to MongoDB.
|
||||||
class ReplSetConnection
|
class ReplSetConnection < Connection
|
||||||
attr_reader :nodes, :secondaries, :arbiters, :read_pool, :secondary_pools
|
attr_reader :nodes, :secondaries, :arbiters, :read_pool, :secondary_pools
|
||||||
|
|
||||||
def initialize(*args)
|
def initialize(*args)
|
||||||
|
|
||||||
if args.last.is_a?(Hash)
|
if args.last.is_a?(Hash)
|
||||||
options = args.pop
|
opts = args.pop
|
||||||
|
else
|
||||||
|
opts = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless args.length > 0
|
||||||
|
raise MongoArgumentError, "A ReplSetConnection requires at least one node."
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get seed nodes
|
||||||
@nodes = args
|
@nodes = args
|
||||||
|
|
||||||
# Replica set name
|
# Replica set name
|
||||||
@replica_set_name = options[:rs_name]
|
@replica_set = opts[:rs_name]
|
||||||
|
|
||||||
# Cache the various node types when connecting to a replica set.
|
# Cache the various node types when connecting to a replica set.
|
||||||
@secondaries = []
|
@secondaries = []
|
||||||
|
@ -41,7 +47,10 @@ module Mongo
|
||||||
@secondary_pools = []
|
@secondary_pools = []
|
||||||
@read_pool = nil
|
@read_pool = nil
|
||||||
|
|
||||||
super
|
# Are we allowing reads from secondaries?
|
||||||
|
@read_secondary = opts.fetch(:read_secondary, false)
|
||||||
|
|
||||||
|
setup(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a new socket and attempt to connect to master.
|
# Create a new socket and attempt to connect to master.
|
||||||
|
@ -86,13 +95,14 @@ module Mongo
|
||||||
|
|
||||||
# If a ConnectionFailure is raised, this method will be called
|
# If a ConnectionFailure is raised, this method will be called
|
||||||
# to close the connection and reset connection values.
|
# to close the connection and reset connection values.
|
||||||
|
# TODO: what's the point of this method?
|
||||||
def reset_connection
|
def reset_connection
|
||||||
super
|
super
|
||||||
@secondaries = []
|
@secondaries = []
|
||||||
@secondary_pools = []
|
@secondary_pools = []
|
||||||
@arbiters = []
|
@arbiters = []
|
||||||
@nodes_tried = []
|
@nodes_tried = []
|
||||||
@nodes_to_try = []
|
@nodes_to_try = []
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -124,7 +134,12 @@ module Mongo
|
||||||
config
|
config
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Primary, when connecting to a replica can, can only be a true primary node.
|
||||||
|
# (And not a slave, which is possible when connecting with the standard
|
||||||
|
# Connection class.
|
||||||
|
def is_primary?(config)
|
||||||
|
config && (config['ismaster'] == 1 || config['ismaster'] == true)
|
||||||
|
end
|
||||||
|
|
||||||
# Pick a node randomly from the set of possible secondaries.
|
# Pick a node randomly from the set of possible secondaries.
|
||||||
def pick_secondary_for_read
|
def pick_secondary_for_read
|
||||||
|
@ -135,15 +150,15 @@ module Mongo
|
||||||
|
|
||||||
# Make sure that we're connected to the expected replica set.
|
# Make sure that we're connected to the expected replica set.
|
||||||
def check_set_name(config, socket)
|
def check_set_name(config, socket)
|
||||||
if @replica_set_name
|
if @replica_set
|
||||||
config = self['admin'].command({:replSetGetStatus => 1},
|
config = self['admin'].command({:replSetGetStatus => 1},
|
||||||
:sock => socket, :check_response => false)
|
:sock => socket, :check_response => false)
|
||||||
|
|
||||||
if !Mongo::Support.ok?(config)
|
if !Mongo::Support.ok?(config)
|
||||||
raise ReplicaSetConnectionError, config['errmsg']
|
raise ReplicaSetConnectionError, config['errmsg']
|
||||||
elsif config['set'] != @replica_set_name
|
elsif config['set'] != @replica_set
|
||||||
raise ReplicaSetConnectionError,
|
raise ReplicaSetConnectionError,
|
||||||
"Attempting to connect to replica set '#{config['set']}' but expected '#{@replica_set_name}'"
|
"Attempting to connect to replica set '#{config['set']}' but expected '#{@replica_set}'"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,15 +9,15 @@ class ConnectTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def test_connect_bad_name
|
def test_connect_bad_name
|
||||||
assert_raise_error(ReplicaSetConnectionError, "expected 'wrong-repl-set-name'") do
|
assert_raise_error(ReplicaSetReplSetConnectionError, "expected 'wrong-repl-set-name'") do
|
||||||
Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]],
|
ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
:rs_name => "wrong-repl-set-name")
|
[TEST_HOST, TEST_PORT + 2], :rs_name => "wrong-repl-set-name")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_connect
|
def test_connect
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]],
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
:name => "foo")
|
[TEST_HOST, TEST_PORT + 2], :name => "foo")
|
||||||
assert @conn.connected?
|
assert @conn.connected?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ class ConnectTest < Test::Unit::TestCase
|
||||||
puts "Please kill the node at #{TEST_PORT}."
|
puts "Please kill the node at #{TEST_PORT}."
|
||||||
gets
|
gets
|
||||||
|
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[TEST_HOST, TEST_PORT + 2]])
|
||||||
assert @conn.connected?
|
assert @conn.connected?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -33,7 +34,8 @@ class ConnectTest < Test::Unit::TestCase
|
||||||
puts "Please kill the node at #{TEST_PORT + 1}."
|
puts "Please kill the node at #{TEST_PORT + 1}."
|
||||||
gets
|
gets
|
||||||
|
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[TEST_HOST, TEST_PORT + 2]])
|
||||||
assert @conn.connected?
|
assert @conn.connected?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +43,8 @@ class ConnectTest < Test::Unit::TestCase
|
||||||
puts "Please kill the node at #{TEST_PORT + 2}."
|
puts "Please kill the node at #{TEST_PORT + 2}."
|
||||||
gets
|
gets
|
||||||
|
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[TEST_HOST, TEST_PORT + 2]])
|
||||||
assert @conn.connected?
|
assert @conn.connected?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,8 @@ class ReplicaSetCountTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[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")
|
||||||
|
|
|
@ -9,7 +9,8 @@ class ReplicaSetInsertTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[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")
|
||||||
|
|
|
@ -9,7 +9,8 @@ class ReplicaSetNodeTypeTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[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")
|
||||||
|
|
|
@ -9,8 +9,8 @@ class ReplicaSetPooledInsertTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]],
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
:pool_size => 10, :timeout => 5)
|
[TEST_HOST, TEST_PORT + 2], :pool_size => 10, :timeout => 5)
|
||||||
@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")
|
||||||
|
|
|
@ -9,7 +9,7 @@ class ReplicaSetQuerySecondariesTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT]], :read_secondary => true)
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], :read_secondary => true)
|
||||||
@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", :safe => {:w => 2, :wtimeout => 100})
|
@coll = @db.collection("test-sets", :safe => {:w => 2, :wtimeout => 100})
|
||||||
|
|
|
@ -9,7 +9,8 @@ class ReplicaSetQueryTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[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")
|
||||||
|
|
|
@ -8,11 +8,13 @@ class ReplicaSetAckTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@conn = Mongo::Connection.multi([[TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1], [TEST_HOST, TEST_PORT + 2]])
|
@conn = ReplSetConnection.multi([TEST_HOST, TEST_PORT], [TEST_HOST, TEST_PORT + 1],
|
||||||
|
[TEST_HOST, TEST_PORT + 2])
|
||||||
|
|
||||||
master = [@conn.primary_pool.host, @conn.primary_pool.port]
|
master = [@conn.primary_pool.host, @conn.primary_pool.port]
|
||||||
|
|
||||||
@slave1 = Mongo::Connection.new(@conn.secondary_pools[0].host, @conn.secondary_pools[0].port, :slave_ok => true)
|
@slave1 = Connection.new(@conn.secondary_pools[0].host,
|
||||||
|
@conn.secondary_pools[0].port, :slave_ok => true)
|
||||||
|
|
||||||
@db = @conn.db(MONGO_TEST_DB)
|
@db = @conn.db(MONGO_TEST_DB)
|
||||||
@db.drop_collection("test-sets")
|
@db.drop_collection("test-sets")
|
||||||
|
@ -37,7 +39,6 @@ class ReplicaSetAckTest < Test::Unit::TestCase
|
||||||
assert @col.insert({:foo => "0" * 10000}, :safe => {:w => 2, :wtimeout => 1000})
|
assert @col.insert({:foo => "0" * 10000}, :safe => {:w => 2, :wtimeout => 1000})
|
||||||
assert_equal 2, @slave1[MONGO_TEST_DB]["test-sets"].count
|
assert_equal 2, @slave1[MONGO_TEST_DB]["test-sets"].count
|
||||||
|
|
||||||
|
|
||||||
assert @col.update({:baz => "bar"}, {:baz => "foo"}, :safe => {:w => 2, :wtimeout => 1000})
|
assert @col.update({:baz => "bar"}, {:baz => "foo"}, :safe => {:w => 2, :wtimeout => 1000})
|
||||||
assert @slave1[MONGO_TEST_DB]["test-sets"].find_one({:baz => "foo"})
|
assert @slave1[MONGO_TEST_DB]["test-sets"].find_one({:baz => "foo"})
|
||||||
|
|
||||||
|
|
|
@ -1,181 +1,82 @@
|
||||||
require './test/test_helper'
|
require './test/test_helper'
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
#class ConnectionTest < Test::Unit::TestCase
|
class ReplSetConnectionTest < Test::Unit::TestCase
|
||||||
# context "Initialization: " do
|
context "Initialization: " do
|
||||||
# setup do
|
setup do
|
||||||
# def new_mock_socket(host='localhost', port=27017)
|
def new_mock_socket(host='localhost', port=27017)
|
||||||
# socket = Object.new
|
socket = Object.new
|
||||||
# socket.stubs(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
socket.stubs(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
||||||
# socket.stubs(:close)
|
socket.stubs(:close)
|
||||||
# socket
|
socket
|
||||||
# end
|
end
|
||||||
#
|
|
||||||
# def new_mock_db
|
def new_mock_db
|
||||||
# db = Object.new
|
db = Object.new
|
||||||
# end
|
end
|
||||||
# end
|
end
|
||||||
#
|
|
||||||
# context "given a single node" do
|
context "connecting to a replica set" do
|
||||||
# setup do
|
setup do
|
||||||
# @conn = Connection.new('localhost', 27017, :connect => false)
|
TCPSocket.stubs(:new).returns(new_mock_socket('localhost', 27017))
|
||||||
# TCPSocket.stubs(:new).returns(new_mock_socket)
|
@conn = ReplSetConnection.new(['localhost', 27017], :connect => false, :read_secondary => true)
|
||||||
#
|
|
||||||
# admin_db = new_mock_db
|
admin_db = new_mock_db
|
||||||
# admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
@hosts = ['localhost:27018', 'localhost:27019', 'localhost:27020']
|
||||||
# @conn.expects(:[]).with('admin').returns(admin_db)
|
|
||||||
# @conn.connect
|
admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts}).
|
||||||
# end
|
then.returns({'ok' => 1, 'ismaster' => 0, 'hosts' => @hosts, 'secondary' => 1}).
|
||||||
#
|
then.returns({'ok' => 1, 'ismaster' => 0, 'hosts' => @hosts, 'secondary' => 1}).
|
||||||
# should "set localhost and port to master" do
|
then.returns({'ok' => 1, 'ismaster' => 0, 'arbiterOnly' => 1})
|
||||||
# assert_equal 'localhost', @conn.primary_pool.host
|
|
||||||
# assert_equal 27017, @conn.primary_pool.port
|
@conn.stubs(:[]).with('admin').returns(admin_db)
|
||||||
# end
|
@conn.connect
|
||||||
#
|
end
|
||||||
# should "set connection pool to 1" do
|
|
||||||
# assert_equal 1, @conn.primary_pool.size
|
should "store the hosts returned from the ismaster command" do
|
||||||
# end
|
assert_equal 'localhost', @conn.primary_pool.host
|
||||||
#
|
assert_equal 27017, @conn.primary_pool.port
|
||||||
# should "default slave_ok to false" do
|
|
||||||
# assert !@conn.slave_ok?
|
assert_equal 'localhost', @conn.secondary_pools[0].host
|
||||||
# end
|
assert_equal 27018, @conn.secondary_pools[0].port
|
||||||
# end
|
|
||||||
#
|
assert_equal 'localhost', @conn.secondary_pools[1].host
|
||||||
# context "connecting to a replica set" do
|
assert_equal 27019, @conn.secondary_pools[1].port
|
||||||
# setup do
|
|
||||||
# TCPSocket.stubs(:new).returns(new_mock_socket('localhost', 27017))
|
assert_equal 2, @conn.secondary_pools.length
|
||||||
# @conn = Connection.multi([['localhost', 27017]], :connect => false, :read_secondary => true)
|
end
|
||||||
#
|
end
|
||||||
# admin_db = new_mock_db
|
|
||||||
# @hosts = ['localhost:27018', 'localhost:27019', 'localhost:27020']
|
context "connecting to a replica set and providing seed nodes" do
|
||||||
#
|
setup do
|
||||||
# admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts}).
|
TCPSocket.stubs(:new).returns(new_mock_socket)
|
||||||
# then.returns({'ok' => 1, 'ismaster' => 0, 'hosts' => @hosts, 'secondary' => 1}).
|
@conn = ReplSetConnection.new(['localhost', 27017], ['localhost', 27019], :connect => false)
|
||||||
# then.returns({'ok' => 1, 'ismaster' => 0, 'hosts' => @hosts, 'secondary' => 1}).
|
|
||||||
# then.returns({'ok' => 1, 'ismaster' => 0, 'arbiterOnly' => 1})
|
admin_db = new_mock_db
|
||||||
#
|
@hosts = ['localhost:27017', 'localhost:27018', 'localhost:27019']
|
||||||
# @conn.stubs(:[]).with('admin').returns(admin_db)
|
admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts})
|
||||||
# @conn.connect
|
@conn.stubs(:[]).with('admin').returns(admin_db)
|
||||||
# end
|
@conn.connect
|
||||||
#
|
end
|
||||||
# should "store the hosts returned from the ismaster command" do
|
end
|
||||||
# assert_equal 'localhost', @conn.primary_pool.host
|
|
||||||
# assert_equal 27017, @conn.primary_pool.port
|
context "initializing with a mongodb uri" do
|
||||||
#
|
|
||||||
# assert_equal 'localhost', @conn.secondary_pools[0].host
|
should "parse a uri specifying multiple nodes" do
|
||||||
# assert_equal 27018, @conn.secondary_pools[0].port
|
@conn = Connection.from_uri("mongodb://localhost:27017,mydb.com:27018", :connect => false)
|
||||||
#
|
assert_equal ['localhost', 27017], @conn.nodes[0]
|
||||||
# assert_equal 'localhost', @conn.secondary_pools[1].host
|
assert_equal ['mydb.com', 27018], @conn.nodes[1]
|
||||||
# assert_equal 27019, @conn.secondary_pools[1].port
|
end
|
||||||
#
|
|
||||||
# assert_equal 2, @conn.secondary_pools.length
|
should "parse a uri specifying multiple nodes with auth" do
|
||||||
# end
|
@conn = Connection.from_uri("mongodb://kyle:s3cr3t@localhost:27017/app,mickey:m0u5e@mydb.com:27018/dsny", :connect => false)
|
||||||
# end
|
assert_equal ['localhost', 27017], @conn.nodes[0]
|
||||||
#
|
assert_equal ['mydb.com', 27018], @conn.nodes[1]
|
||||||
# context "connecting to a replica set and providing seed nodes" do
|
auth_hash = {'username' => 'kyle', 'password' => 's3cr3t', 'db_name' => 'app'}
|
||||||
# setup do
|
assert_equal auth_hash, @conn.auths[0]
|
||||||
# TCPSocket.stubs(:new).returns(new_mock_socket)
|
auth_hash = {'username' => 'mickey', 'password' => 'm0u5e', 'db_name' => 'dsny'}
|
||||||
# @conn = Connection.multi([['localhost', 27017], ['localhost', 27019]], :connect => false)
|
assert_equal auth_hash, @conn.auths[1]
|
||||||
#
|
end
|
||||||
# admin_db = new_mock_db
|
end
|
||||||
# @hosts = ['localhost:27017', 'localhost:27018', 'localhost:27019']
|
end
|
||||||
# admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts})
|
end
|
||||||
# @conn.stubs(:[]).with('admin').returns(admin_db)
|
|
||||||
# @conn.connect
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "not store any hosts redundantly" do
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# context "initializing a paired connection" do
|
|
||||||
# should "require left and right nodes" do
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.multi(['localhost', 27018], :connect => false)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.multi(['localhost', 27018], :connect => false)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "store both nodes" do
|
|
||||||
# @conn = Connection.multi([['localhost', 27017], ['localhost', 27018]], :connect => false)
|
|
||||||
#
|
|
||||||
# assert_equal ['localhost', 27017], @conn.nodes[0]
|
|
||||||
# assert_equal ['localhost', 27018], @conn.nodes[1]
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# context "initializing with a mongodb uri" do
|
|
||||||
# should "parse a simple uri" do
|
|
||||||
# @conn = Connection.from_uri("mongodb://localhost", :connect => false)
|
|
||||||
# assert_equal ['localhost', 27017], @conn.primary
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "allow a complex host names" do
|
|
||||||
# host_name = "foo.bar-12345.org"
|
|
||||||
# @conn = Connection.from_uri("mongodb://#{host_name}", :connect => false)
|
|
||||||
# assert_equal [host_name, 27017], @conn.primary
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "parse a uri specifying multiple nodes" do
|
|
||||||
# #@conn = Connection.from_uri("mongodb://localhost:27017,mydb.com:27018", :connect => false)
|
|
||||||
# #assert_equal ['localhost', 27017], @conn.nodes[0]
|
|
||||||
# #assert_equal ['mydb.com', 27018], @conn.nodes[1]
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "parse a uri specifying multiple nodes with auth" do
|
|
||||||
# #@conn = Connection.from_uri("mongodb://kyle:s3cr3t@localhost:27017/app,mickey:m0u5e@mydb.com:27018/dsny", :connect => false)
|
|
||||||
# #assert_equal ['localhost', 27017], @conn.nodes[0]
|
|
||||||
# #assert_equal ['mydb.com', 27018], @conn.nodes[1]
|
|
||||||
# #auth_hash = {'username' => 'kyle', 'password' => 's3cr3t', 'db_name' => 'app'}
|
|
||||||
# #assert_equal auth_hash, @conn.auths[0]
|
|
||||||
# #auth_hash = {'username' => 'mickey', 'password' => 'm0u5e', 'db_name' => 'dsny'}
|
|
||||||
# #assert_equal auth_hash, @conn.auths[1]
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "parse a uri with a hyphen & underscore in the username or password" do
|
|
||||||
# @conn = Connection.from_uri("mongodb://hyphen-user_name:p-s_s@localhost:27017/db", :connect => false)
|
|
||||||
# assert_equal ['localhost', 27017], @conn.nodes[0]
|
|
||||||
# auth_hash = { 'db_name' => 'db', 'username' => 'hyphen-user_name', "password" => 'p-s_s' }
|
|
||||||
# assert_equal auth_hash, @conn.auths[0]
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "attempt to connect" do
|
|
||||||
# TCPSocket.stubs(:new).returns(new_mock_socket)
|
|
||||||
# @conn = Connection.from_uri("mongodb://localhost", :connect => false)
|
|
||||||
#
|
|
||||||
# admin_db = new_mock_db
|
|
||||||
# admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
|
||||||
# @conn.expects(:[]).with('admin').returns(admin_db)
|
|
||||||
# @conn.expects(:apply_saved_authentication)
|
|
||||||
# @conn.connect
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "raise an error on invalid uris" do
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.from_uri("mongo://localhost", :connect => false)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.from_uri("mongodb://localhost:abc", :connect => false)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.from_uri("mongodb://localhost:27017, my.db.com:27018, ", :connect => false)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# should "require all of username, password, and database if any one is specified" do
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.from_uri("mongodb://localhost/db", :connect => false)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# assert_raise MongoArgumentError do
|
|
||||||
# Connection.from_uri("mongodb://kyle:password@localhost", :connect => false)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#end
|
|
||||||
|
|
Loading…
Reference in New Issue