mongo 1.6.4 → 1.7.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +13 -13
- data/Rakefile +7 -10
- data/docs/{GridFS.md → GRID_FS.md} +0 -0
- data/docs/HISTORY.md +16 -0
- data/docs/READ_PREFERENCE.md +70 -10
- data/docs/TUTORIAL.md +2 -2
- data/lib/mongo.rb +2 -0
- data/lib/mongo/collection.rb +62 -11
- data/lib/mongo/connection.rb +31 -41
- data/lib/mongo/cursor.rb +42 -86
- data/lib/mongo/db.rb +10 -8
- data/lib/mongo/networking.rb +30 -65
- data/lib/mongo/repl_set_connection.rb +91 -170
- data/lib/mongo/sharded_connection.rb +221 -0
- data/lib/mongo/util/node.rb +29 -36
- data/lib/mongo/util/pool.rb +10 -3
- data/lib/mongo/util/pool_manager.rb +77 -90
- data/lib/mongo/util/sharding_pool_manager.rb +143 -0
- data/lib/mongo/util/support.rb +22 -2
- data/lib/mongo/util/tcp_socket.rb +10 -15
- data/lib/mongo/util/uri_parser.rb +17 -10
- data/lib/mongo/version.rb +1 -1
- data/test/collection_test.rb +133 -1
- data/test/connection_test.rb +50 -4
- data/test/db_api_test.rb +3 -3
- data/test/db_test.rb +6 -1
- data/test/replica_sets/basic_test.rb +3 -6
- data/test/replica_sets/complex_connect_test.rb +14 -2
- data/test/replica_sets/complex_read_preference_test.rb +237 -0
- data/test/replica_sets/connect_test.rb +47 -67
- data/test/replica_sets/count_test.rb +1 -1
- data/test/replica_sets/cursor_test.rb +70 -0
- data/test/replica_sets/read_preference_test.rb +171 -118
- data/test/replica_sets/refresh_test.rb +3 -3
- data/test/replica_sets/refresh_with_threads_test.rb +2 -2
- data/test/replica_sets/rs_test_helper.rb +2 -2
- data/test/sharded_cluster/basic_test.rb +112 -0
- data/test/sharded_cluster/mongo_config_test.rb +126 -0
- data/test/sharded_cluster/sc_test_helper.rb +39 -0
- data/test/test_helper.rb +3 -3
- data/test/threading/threading_with_large_pool_test.rb +1 -1
- data/test/tools/mongo_config.rb +307 -0
- data/test/tools/repl_set_manager.rb +12 -12
- data/test/unit/collection_test.rb +1 -1
- data/test/unit/cursor_test.rb +11 -6
- data/test/unit/db_test.rb +4 -0
- data/test/unit/grid_test.rb +2 -0
- data/test/unit/read_test.rb +39 -8
- data/test/uri_test.rb +4 -8
- metadata +144 -127
data/test/connection_test.rb
CHANGED
@@ -58,6 +58,12 @@ class TestConnection < Test::Unit::TestCase
|
|
58
58
|
assert_equal mongo_port, con.primary_pool.port
|
59
59
|
end
|
60
60
|
|
61
|
+
def test_uri_with_extra_opts
|
62
|
+
con = Connection.from_uri("mongodb://#{host_port}", :pool_size => 10, :slave_ok => true)
|
63
|
+
assert_equal 10, con.pool_size
|
64
|
+
assert_true con.slave_ok?
|
65
|
+
end
|
66
|
+
|
61
67
|
def test_env_mongodb_uri
|
62
68
|
begin
|
63
69
|
old_mongodb_uri = ENV['MONGODB_URI']
|
@@ -82,6 +88,46 @@ class TestConnection < Test::Unit::TestCase
|
|
82
88
|
end
|
83
89
|
end
|
84
90
|
|
91
|
+
def test_db_from_uri_exists_no_options
|
92
|
+
begin
|
93
|
+
db_name = "_database"
|
94
|
+
|
95
|
+
old_mongodb_uri = ENV['MONGODB_URI']
|
96
|
+
ENV['MONGODB_URI'] = "mongodb://#{host_port}/#{db_name}"
|
97
|
+
con = Connection.from_uri
|
98
|
+
db = con.db
|
99
|
+
assert_equal db.name, db_name
|
100
|
+
ensure
|
101
|
+
ENV['MONGODB_URI'] = old_mongodb_uri
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_db_from_uri_exists_options
|
106
|
+
begin
|
107
|
+
db_name = "_database"
|
108
|
+
|
109
|
+
old_mongodb_uri = ENV['MONGODB_URI']
|
110
|
+
ENV['MONGODB_URI'] = "mongodb://#{host_port}/#{db_name}?"
|
111
|
+
con = Connection.from_uri
|
112
|
+
db = con.db
|
113
|
+
assert_equal db.name, db_name
|
114
|
+
ensure
|
115
|
+
ENV['MONGODB_URI'] = old_mongodb_uri
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_db_from_uri_exists_no_db_name
|
120
|
+
begin
|
121
|
+
old_mongodb_uri = ENV['MONGODB_URI']
|
122
|
+
ENV['MONGODB_URI'] = "mongodb://#{host_port}/"
|
123
|
+
con = Connection.from_uri
|
124
|
+
db = con.db
|
125
|
+
assert_equal db.name, Mongo::Connection::DEFAULT_DB_NAME
|
126
|
+
ensure
|
127
|
+
ENV['MONGODB_URI'] = old_mongodb_uri
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
85
131
|
def test_server_version
|
86
132
|
assert_match(/\d\.\d+(\.\d+)?/, @conn.server_version.to_s)
|
87
133
|
end
|
@@ -207,7 +253,7 @@ class TestConnection < Test::Unit::TestCase
|
|
207
253
|
assert !@conn.locked?
|
208
254
|
@conn.lock!
|
209
255
|
assert @conn.locked?
|
210
|
-
|
256
|
+
assert [1, true].include?(@conn['admin']['$cmd.sys.inprog'].find_one['fsyncLock'])
|
211
257
|
assert_match(/unlock/, @conn.unlock!['info'])
|
212
258
|
unlocked = false
|
213
259
|
counter = 0
|
@@ -339,7 +385,7 @@ class TestConnection < Test::Unit::TestCase
|
|
339
385
|
end
|
340
386
|
|
341
387
|
should "close the connection on receive_message for major exceptions" do
|
342
|
-
@con.expects(:
|
388
|
+
@con.expects(:checkout_reader).raises(SystemStackError)
|
343
389
|
@con.expects(:close)
|
344
390
|
begin
|
345
391
|
@coll.find.next
|
@@ -375,11 +421,11 @@ class TestConnection < Test::Unit::TestCase
|
|
375
421
|
|
376
422
|
should "release connection if an exception is raised on receive_message" do
|
377
423
|
@con.stubs(:receive).raises(ConnectionFailure)
|
378
|
-
assert_equal 0, @con.
|
424
|
+
assert_equal 0, @con.read_pool.checked_out.size
|
379
425
|
assert_raise ConnectionFailure do
|
380
426
|
@coll.find.to_a
|
381
427
|
end
|
382
|
-
assert_equal 0, @con.
|
428
|
+
assert_equal 0, @con.read_pool.checked_out.size
|
383
429
|
end
|
384
430
|
|
385
431
|
should "show a proper exception message if an IOError is raised while closing a socket" do
|
data/test/db_api_test.rb
CHANGED
@@ -429,9 +429,9 @@ class DBAPITest < Test::Unit::TestCase
|
|
429
429
|
end
|
430
430
|
|
431
431
|
def test_array
|
432
|
-
@@coll.remove
|
433
|
-
@@coll.insert({'b' => [1, 2, 3]})
|
434
|
-
@@coll.insert({'b' => [1, 2, 3]})
|
432
|
+
@@coll.remove({'$atomic' => true}, :safe => true)
|
433
|
+
@@coll.insert({'b' => [1, 2, 3]}, :safe => true)
|
434
|
+
@@coll.insert({'b' => [1, 2, 3]}, :safe => true)
|
435
435
|
rows = @@coll.find({}, {:fields => ['b']}).to_a
|
436
436
|
assert_equal 2, rows.length
|
437
437
|
assert_equal [1, 2, 3], rows[1]['b']
|
data/test/db_test.rb
CHANGED
@@ -221,7 +221,12 @@ class DBTest < Test::Unit::TestCase
|
|
221
221
|
assert ex.message.include?("forced error"),
|
222
222
|
"error message does not contain 'forced error'"
|
223
223
|
assert_equal 10038, ex.error_code
|
224
|
-
|
224
|
+
|
225
|
+
if @@version >= "2.1.0"
|
226
|
+
assert_equal 10038, ex.result['code']
|
227
|
+
else
|
228
|
+
assert_equal 10038, ex.result['assertionCode']
|
229
|
+
end
|
225
230
|
ensure
|
226
231
|
assert raised, "No assertion raised!"
|
227
232
|
end
|
@@ -47,21 +47,18 @@ class BasicTest < Test::Unit::TestCase
|
|
47
47
|
seeds = build_seeds(3)
|
48
48
|
args = {:name => @rs.name}
|
49
49
|
@conn = ReplSetConnection.new(seeds, args)
|
50
|
-
@major_version = @rs.version.first
|
51
50
|
|
52
51
|
assert_equal @conn.host, @rs.primary[0]
|
53
52
|
assert_equal @conn.port, @rs.primary[1]
|
54
53
|
assert_equal @conn.host, @conn.primary_pool.host
|
55
54
|
assert_equal @conn.port, @conn.primary_pool.port
|
56
|
-
#assert_equal @conn.nodes.sort, @conn.seeds.sort
|
57
55
|
assert_equal 2, @conn.secondaries.length
|
58
56
|
assert_equal 0, @conn.arbiters.length
|
59
57
|
assert_equal 2, @conn.secondary_pools.length
|
60
58
|
assert_equal @rs.name, @conn.replica_set_name
|
61
|
-
assert @conn.secondary_pools.include?(@conn.read_pool)
|
59
|
+
assert @conn.secondary_pools.include?(@conn.read_pool(:secondary))
|
62
60
|
assert_equal 90, @conn.refresh_interval
|
63
61
|
assert_equal @conn.refresh_mode, false
|
64
|
-
assert_equal 5, @conn.tag_map.keys.length unless @major_version < 2
|
65
62
|
end
|
66
63
|
|
67
64
|
context "Socket pools" do
|
@@ -92,10 +89,10 @@ class BasicTest < Test::Unit::TestCase
|
|
92
89
|
end
|
93
90
|
|
94
91
|
should "close the connection on receive_message for major exceptions" do
|
95
|
-
@con.expects(:
|
92
|
+
@con.expects(:checkout_reader).raises(SystemStackError)
|
96
93
|
@con.expects(:close)
|
97
94
|
begin
|
98
|
-
@coll.find.next
|
95
|
+
@coll.find({}, :read => :primary).next
|
99
96
|
rescue SystemStackError
|
100
97
|
end
|
101
98
|
end
|
@@ -21,6 +21,8 @@ class ComplexConnectTest < Test::Unit::TestCase
|
|
21
21
|
"#{@rs.host}:#{@rs.ports[0]}",
|
22
22
|
])
|
23
23
|
|
24
|
+
version = @conn.server_version
|
25
|
+
|
24
26
|
@conn['test']['foo'].insert({:a => 1})
|
25
27
|
assert @conn['test']['foo'].find_one
|
26
28
|
|
@@ -34,11 +36,21 @@ class ComplexConnectTest < Test::Unit::TestCase
|
|
34
36
|
primary['admin'].command({:replSetReconfig => config})
|
35
37
|
end
|
36
38
|
@rs.ensure_up
|
39
|
+
|
40
|
+
force_stepdown = BSON::OrderedHash.new
|
41
|
+
force_stepdown[:replSetStepDown] = 1
|
42
|
+
force_stepdown[:force] = true
|
43
|
+
|
37
44
|
assert_raise ConnectionFailure do
|
38
|
-
primary['admin'].command(
|
45
|
+
primary['admin'].command(force_stepdown)
|
39
46
|
end
|
40
47
|
|
41
|
-
|
48
|
+
# isMaster is currently broken in 2.1+ when called on removed nodes
|
49
|
+
if version < "2.1"
|
50
|
+
rescue_connection_failure do
|
51
|
+
assert @conn['test']['foo'].find_one
|
52
|
+
end
|
53
|
+
|
42
54
|
assert @conn['test']['foo'].find_one
|
43
55
|
end
|
44
56
|
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require './test/replica_sets/rs_test_helper'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
# Tags for members:
|
6
|
+
# 0 => {"dc" => "ny", "rack" => "a", "db" => "main"}
|
7
|
+
# 1 => {"dc" => "ny", "rack" => "b", "db" => "main"}
|
8
|
+
# 2 => {"dc" => "sf", "rack" => "a", "db" => "main"}
|
9
|
+
|
10
|
+
class ComplexReadPreferenceTest < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
ensure_rs
|
13
|
+
|
14
|
+
# Insert data
|
15
|
+
conn = Connection.new(@rs.host, @rs.primary[1])
|
16
|
+
db = conn.db(MONGO_TEST_DB)
|
17
|
+
coll = db.collection("test-sets")
|
18
|
+
coll.save({:a => 20}, :safe => {:w => 2})
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_primary_with_tags
|
22
|
+
# Test specifying a tag set with default read preference of primary throws and error
|
23
|
+
conn = make_connection({:tag_sets => {"rack" => "a"}})
|
24
|
+
assert_raise_error MongoArgumentError, "Read preferecy :primary cannot be combined with tags" do
|
25
|
+
conn.read_pool
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_tags
|
30
|
+
return true if @rs.version < "2.1"
|
31
|
+
|
32
|
+
assert_read_pool(:primary, {}, 0)
|
33
|
+
assert_read_pool(:primary_preferred, {}, 0)
|
34
|
+
assert_read_pool(:secondary, {}, [1,2])
|
35
|
+
assert_read_pool(:secondary_preferred, {}, [1,2])
|
36
|
+
|
37
|
+
# Test tag_sets are ignored on primary
|
38
|
+
assert_read_pool(:primary_preferred,
|
39
|
+
{"rack" => "b"}, 0)
|
40
|
+
|
41
|
+
# Test single tag
|
42
|
+
assert_read_pool(:secondary,
|
43
|
+
{"rack" => "a"}, 2)
|
44
|
+
assert_read_pool(:secondary,
|
45
|
+
{"rack" => "b"}, 1)
|
46
|
+
assert_read_pool(:secondary,
|
47
|
+
{"db" => "main"}, [1, 2])
|
48
|
+
|
49
|
+
# Test multiple tags
|
50
|
+
assert_read_pool(:secondary,
|
51
|
+
{"db" => "main", "rack" => "a"}, 2)
|
52
|
+
assert_read_pool(:secondary,
|
53
|
+
{"dc" => "ny", "rack" => "b", "db" => "main"}, 1)
|
54
|
+
|
55
|
+
# Test multiple tags failing
|
56
|
+
assert_fail_pool(:secondary,
|
57
|
+
{"dc" => "ny", "rack" => "a"})
|
58
|
+
assert_fail_pool(:secondary,
|
59
|
+
{"dc" => "ny", "rack" => "b", "db" => "main", "xtra" => "?"})
|
60
|
+
|
61
|
+
# Test symbol is converted to string for key
|
62
|
+
assert_read_pool(:secondary,
|
63
|
+
{:db => "main", "rack" => "b"}, 1)
|
64
|
+
assert_read_pool(:secondary,
|
65
|
+
{:db => "main", :rack => "b"}, 1)
|
66
|
+
assert_read_pool(:secondary,
|
67
|
+
{"db" => "main", :rack => "b"}, 1)
|
68
|
+
|
69
|
+
# Test secondary_preferred
|
70
|
+
assert_read_pool(:secondary_preferred,
|
71
|
+
{"dc" => "ny"}, 1)
|
72
|
+
assert_read_pool(:secondary_preferred,
|
73
|
+
{"dc" => "sf"}, 2)
|
74
|
+
assert_read_pool(:secondary_preferred,
|
75
|
+
{"dc" => "china"}, 0)
|
76
|
+
|
77
|
+
# Test secondary_preferred with no matching member
|
78
|
+
assert_read_pool(:secondary_preferred,
|
79
|
+
{"dc" => "bad"}, 0)
|
80
|
+
assert_read_pool(:secondary_preferred,
|
81
|
+
{"db" => "main", "dc" => "china"}, 0)
|
82
|
+
assert_read_pool(:secondary_preferred,
|
83
|
+
{"db" => "ny", "rack" => "a"}, 0)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_tag_sets
|
87
|
+
return true if @rs.version < "2.1"
|
88
|
+
|
89
|
+
# Test primary_preferred overrides any tags when primary is available
|
90
|
+
assert_read_pool(:primary_preferred, [
|
91
|
+
{"dc" => "sf"}
|
92
|
+
], 0)
|
93
|
+
|
94
|
+
# Test first tag_set takes priority over the second
|
95
|
+
assert_read_pool(:secondary, [
|
96
|
+
{"dc" => "sf"},
|
97
|
+
{"dc" => "ny"}
|
98
|
+
], 2)
|
99
|
+
assert_read_pool(:secondary, [
|
100
|
+
{"dc" => "ny"},
|
101
|
+
{"dc" => "sf"}
|
102
|
+
], 1)
|
103
|
+
assert_read_pool(:secondary_preferred, [
|
104
|
+
{"dc" => "sf"},
|
105
|
+
{"dc" => "ny"}
|
106
|
+
], 2)
|
107
|
+
assert_read_pool(:secondary_preferred, [
|
108
|
+
{"dc" => "ny"},
|
109
|
+
{"dc" => "sf"}
|
110
|
+
], 1)
|
111
|
+
|
112
|
+
# Test tags not matching any member throw an error
|
113
|
+
assert_fail_pool(:secondary, [
|
114
|
+
{"dc" => "ny", "rack" => "a"},
|
115
|
+
{"dc" => "sf", "rack" => "b"},
|
116
|
+
])
|
117
|
+
|
118
|
+
# Test bad tags get skipped over
|
119
|
+
assert_read_pool(:secondary_preferred, [
|
120
|
+
{"bad" => "tag"},
|
121
|
+
{"dc" => "sf"}
|
122
|
+
], 2)
|
123
|
+
|
124
|
+
# Test less selective tags
|
125
|
+
assert_read_pool(:secondary, [
|
126
|
+
{"dc" => "ny", "rack" => "b", "db" => "alt"},
|
127
|
+
{"dc" => "ny", "rack" => "a"},
|
128
|
+
{"dc" => "sf"}
|
129
|
+
], 2)
|
130
|
+
assert_read_pool(:secondary_preferred, [
|
131
|
+
{"dc" => "ny", "rack" => "b", "db" => "alt"},
|
132
|
+
{"dc" => "ny", "rack" => "a"},
|
133
|
+
{"dc" => "sf"}
|
134
|
+
], 2)
|
135
|
+
assert_read_pool(:secondary_preferred, [
|
136
|
+
{"dc" => "ny", "rack" => "a"},
|
137
|
+
{"dc" => "sf", "rack" => "b"},
|
138
|
+
{"db" => "main"}
|
139
|
+
], [1,2])
|
140
|
+
|
141
|
+
# Test secondary preferred gives primary if no tags match
|
142
|
+
assert_read_pool(:secondary_preferred, [
|
143
|
+
{"dc" => "ny", "rack" => "a"},
|
144
|
+
{"dc" => "sf", "rack" => "b"}
|
145
|
+
], 0)
|
146
|
+
assert_read_pool(:secondary_preferred, [
|
147
|
+
{"dc" => "ny", "rack" => "a"},
|
148
|
+
{"dc" => "sf", "rack" => "b"},
|
149
|
+
{"dc" => "ny", "rack" => "b"},
|
150
|
+
], 1)
|
151
|
+
|
152
|
+
# Basic nearest test
|
153
|
+
assert_read_pool(:nearest, [
|
154
|
+
{"dc" => "ny", "rack" => "a"},
|
155
|
+
{"dc" => "sf", "rack" => "b"},
|
156
|
+
{"db" => "main"}
|
157
|
+
], [0,1,2])
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_nearest
|
161
|
+
# Test refresh happens on connection after interval has passed
|
162
|
+
conn = make_connection(
|
163
|
+
:read => :secondary_preferred,
|
164
|
+
:refresh_mode => :sync,
|
165
|
+
:refresh_interval => 1,
|
166
|
+
:secondary_acceptable_latency_ms => 10
|
167
|
+
)
|
168
|
+
pools = conn.manager.pools
|
169
|
+
|
170
|
+
# Connection should select node with 110 ping every time
|
171
|
+
set_pings(pools, [100,110,130])
|
172
|
+
sleep(2)
|
173
|
+
|
174
|
+
assert conn.read_pool == pools[1]
|
175
|
+
|
176
|
+
# Connection should select node with 100 ping every time
|
177
|
+
set_pings(pools, [100,120,100])
|
178
|
+
sleep(2)
|
179
|
+
|
180
|
+
assert conn.read_pool == pools[2]
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_tags_and_nearest
|
184
|
+
return true if @rs.version < "2.1"
|
185
|
+
|
186
|
+
# Test connection's read pool matches tags
|
187
|
+
assert_read_pool(:secondary_preferred, {"dc" => "sf"}, 2, [100,110,130])
|
188
|
+
|
189
|
+
# Test connection's read pool picks near pool (both match tags)
|
190
|
+
assert_read_pool(:secondary_preferred, {"db" => "main"}, 1, [100,110,130])
|
191
|
+
assert_read_pool(:secondary_preferred, {"db" => "main"}, 2, [100,130,110])
|
192
|
+
assert_read_pool(:secondary_preferred, {"db" => "fake"}, 0, [100,130,110])
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def set_pings(pools, pings)
|
198
|
+
pools.sort! { |a,b| a.port <=> b.port }
|
199
|
+
pools.each_with_index do |pool, index|
|
200
|
+
pool.stubs(:ping_time).returns(pings[index])
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def make_connection(opts = {})
|
205
|
+
ReplSetConnection.new(build_seeds(3), opts)
|
206
|
+
end
|
207
|
+
|
208
|
+
def assert_read_pool(mode=:primary, tags=[], node_nums=[0], pings=[], latency=10)
|
209
|
+
if pings.empty?
|
210
|
+
conn = make_connection({:read => mode, :tag_sets => tags})
|
211
|
+
else
|
212
|
+
conn = make_connection({
|
213
|
+
:read => mode,
|
214
|
+
:tag_sets => tags,
|
215
|
+
:refresh_mode => :sync,
|
216
|
+
:refresh_interval => 1,
|
217
|
+
:secondary_acceptable_latency_ms => latency
|
218
|
+
})
|
219
|
+
|
220
|
+
set_pings(conn.manager.pools, pings)
|
221
|
+
sleep(2)
|
222
|
+
end
|
223
|
+
|
224
|
+
assert conn[MONGO_TEST_DB]['test-sets'].find_one
|
225
|
+
|
226
|
+
target_ports = [*node_nums].collect {|num| @rs.ports[num]}
|
227
|
+
|
228
|
+
assert target_ports.member?(conn.read_pool.port)
|
229
|
+
end
|
230
|
+
|
231
|
+
def assert_fail_pool(mode=:primary, tags={})
|
232
|
+
assert_raise_error ConnectionFailure, "No replica set member available for query " +
|
233
|
+
"with read preference matching mode #{mode} and tags matching #{tags}." do
|
234
|
+
make_connection({:read => mode, :tag_sets => tags}).read_pool
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -3,12 +3,22 @@ require './test/replica_sets/rs_test_helper'
|
|
3
3
|
|
4
4
|
class ConnectTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
+
@old_mongodb_uri = ENV['MONGODB_URI']
|
6
7
|
ensure_rs
|
7
8
|
end
|
8
9
|
|
9
10
|
def teardown
|
10
11
|
@rs.restart_killed_nodes
|
11
12
|
@conn.close if defined?(@conn) && @conn
|
13
|
+
ENV['MONGODB_URI'] = @old_mongodb_uri
|
14
|
+
end
|
15
|
+
|
16
|
+
def step_down_command
|
17
|
+
# Adding force=true to avoid 'no secondaries within 10 seconds of my optime' errors
|
18
|
+
step_down_command = BSON::OrderedHash.new
|
19
|
+
step_down_command[:replSetStepDown] = 60
|
20
|
+
step_down_command[:force] = true
|
21
|
+
step_down_command
|
12
22
|
end
|
13
23
|
|
14
24
|
# TODO: test connect timeout.
|
@@ -27,21 +37,6 @@ class ConnectTest < Test::Unit::TestCase
|
|
27
37
|
end
|
28
38
|
end
|
29
39
|
|
30
|
-
def test_connect_with_primary_node_killed
|
31
|
-
@rs.kill_primary
|
32
|
-
|
33
|
-
# Becuase we're killing the primary and trying to connect right away,
|
34
|
-
# this is going to fail right away.
|
35
|
-
assert_raise_error(ConnectionFailure, "Failed to connect to primary node") do
|
36
|
-
@conn = ReplSetConnection.new build_seeds(3)
|
37
|
-
end
|
38
|
-
|
39
|
-
# This allows the secondary to come up as a primary
|
40
|
-
rescue_connection_failure do
|
41
|
-
@conn = ReplSetConnection.new build_seeds(3)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
40
|
def test_connect_with_secondary_node_killed
|
46
41
|
@rs.kill_secondary
|
47
42
|
|
@@ -67,13 +62,9 @@ class ConnectTest < Test::Unit::TestCase
|
|
67
62
|
|
68
63
|
primary = Mongo::Connection.new(@conn.primary_pool.host, @conn.primary_pool.port)
|
69
64
|
assert_raise Mongo::ConnectionFailure do
|
70
|
-
primary['admin'].command(
|
65
|
+
primary['admin'].command(step_down_command)
|
71
66
|
end
|
72
67
|
assert @conn.connected?
|
73
|
-
assert_raise Mongo::ConnectionFailure do
|
74
|
-
@conn[MONGO_TEST_DB]['bar'].find_one
|
75
|
-
end
|
76
|
-
assert !@conn.connected?
|
77
68
|
|
78
69
|
rescue_connection_failure do
|
79
70
|
@conn[MONGO_TEST_DB]['bar'].find_one
|
@@ -84,11 +75,6 @@ class ConnectTest < Test::Unit::TestCase
|
|
84
75
|
@conn = ReplSetConnection.new build_seeds(3)
|
85
76
|
|
86
77
|
primary = Mongo::Connection.new(@conn.primary_pool.host, @conn.primary_pool.port)
|
87
|
-
|
88
|
-
# Adding force=true to avoid 'no secondaries within 10 seconds of my optime' errors
|
89
|
-
step_down_command = BSON::OrderedHash.new
|
90
|
-
step_down_command[:replSetStepDown] = 60
|
91
|
-
step_down_command[:force] = true
|
92
78
|
assert_raise Mongo::ConnectionFailure do
|
93
79
|
primary['admin'].command(step_down_command)
|
94
80
|
end
|
@@ -99,39 +85,34 @@ class ConnectTest < Test::Unit::TestCase
|
|
99
85
|
end
|
100
86
|
|
101
87
|
def test_connect_with_connection_string
|
102
|
-
|
103
|
-
@conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name}")
|
104
|
-
end
|
88
|
+
@conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name}")
|
105
89
|
assert @conn.is_a?(ReplSetConnection)
|
106
90
|
assert @conn.connected?
|
107
91
|
end
|
108
92
|
|
109
93
|
def test_connect_with_connection_string_in_env_var
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
ENV['MONGODB_URI'] = old_mongodb_uri
|
120
|
-
end
|
94
|
+
ENV['MONGODB_URI'] = "mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name}"
|
95
|
+
@conn = ReplSetConnection.new
|
96
|
+
assert @conn.is_a?(ReplSetConnection)
|
97
|
+
assert_equal 2, @conn.seeds.length
|
98
|
+
assert_equal @rs.host, @conn.seeds[0][0]
|
99
|
+
assert_equal @rs.host, @conn.seeds[1][0]
|
100
|
+
assert_equal @rs.ports[0], @conn.seeds[0][1]
|
101
|
+
assert_equal @rs.ports[1], @conn.seeds[1][1]
|
102
|
+
assert @conn.connected?
|
121
103
|
end
|
122
104
|
|
123
105
|
def test_connect_with_connection_string_in_implicit_mongodb_uri
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
end
|
106
|
+
ENV['MONGODB_URI'] = "mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name}"
|
107
|
+
@conn = Connection.from_uri
|
108
|
+
assert @conn.is_a?(ReplSetConnection)
|
109
|
+
assert_equal 2, @conn.seeds.length
|
110
|
+
assert_equal @rs.host, @conn.seeds[0][0]
|
111
|
+
assert_equal @rs.host, @conn.seeds[1][0]
|
112
|
+
assert_equal @rs.ports[0], @conn.seeds[0][1]
|
113
|
+
assert_equal @rs.ports[1], @conn.seeds[1][1]
|
114
|
+
assert_equal @rs.name, @conn.replica_set_name
|
115
|
+
assert @conn.connected?
|
135
116
|
end
|
136
117
|
|
137
118
|
def test_connect_with_new_seed_format
|
@@ -147,9 +128,7 @@ class ConnectTest < Test::Unit::TestCase
|
|
147
128
|
end
|
148
129
|
|
149
130
|
def test_connect_with_full_connection_string
|
150
|
-
|
151
|
-
@conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name};safe=true;w=2;fsync=true;slaveok=true")
|
152
|
-
end
|
131
|
+
@conn = Connection.from_uri("mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name};safe=true;w=2;fsync=true;slaveok=true")
|
153
132
|
assert @conn.is_a?(ReplSetConnection)
|
154
133
|
assert @conn.connected?
|
155
134
|
assert_equal 2, @conn.safe[:w]
|
@@ -158,19 +137,20 @@ class ConnectTest < Test::Unit::TestCase
|
|
158
137
|
end
|
159
138
|
|
160
139
|
def test_connect_with_full_connection_string_in_env_var
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
140
|
+
ENV['MONGODB_URI'] = "mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name};safe=true;w=2;fsync=true;slaveok=true"
|
141
|
+
@conn = ReplSetConnection.new
|
142
|
+
assert @conn.is_a?(ReplSetConnection)
|
143
|
+
assert @conn.connected?
|
144
|
+
assert_equal 2, @conn.safe[:w]
|
145
|
+
assert @conn.safe[:fsync]
|
146
|
+
assert @conn.read_pool
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_connect_options_override_env_var
|
150
|
+
ENV['MONGODB_URI'] = "mongodb://#{@rs.host}:#{@rs.ports[0]},#{@rs.host}:#{@rs.ports[1]}?replicaset=#{@rs.name};safe=true;w=2;fsync=true;slaveok=true"
|
151
|
+
@conn = ReplSetConnection.new({:safe => false})
|
152
|
+
assert @conn.is_a?(ReplSetConnection)
|
153
|
+
assert @conn.connected?
|
154
|
+
assert_equal @conn.safe, false
|
175
155
|
end
|
176
156
|
end
|