mongo 1.5.2 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +24 -8
- data/docs/HISTORY.md +15 -0
- data/docs/READ_PREFERENCE.md +1 -1
- data/docs/RELEASES.md +18 -4
- data/docs/REPLICA_SETS.md +5 -5
- data/docs/WRITE_CONCERN.md +1 -1
- data/lib/mongo/collection.rb +49 -10
- data/lib/mongo/connection.rb +7 -24
- data/lib/mongo/cursor.rb +3 -1
- data/lib/mongo/db.rb +5 -1
- data/lib/mongo/exceptions.rb +0 -3
- data/lib/mongo/gridfs/grid.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +11 -3
- data/lib/mongo/networking.rb +7 -3
- data/lib/mongo/repl_set_connection.rb +58 -82
- data/lib/mongo/util/logging.rb +26 -18
- data/lib/mongo/util/node.rb +11 -2
- data/lib/mongo/util/pool_manager.rb +7 -5
- data/lib/mongo/util/support.rb +2 -2
- data/lib/mongo/util/uri_parser.rb +74 -36
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -2
- data/test/auxillary/authentication_test.rb +8 -0
- data/test/auxillary/repl_set_auth_test.rb +1 -2
- data/test/bson/ordered_hash_test.rb +1 -1
- data/test/bson/test_helper.rb +2 -1
- data/test/collection_test.rb +71 -0
- data/test/connection_test.rb +9 -0
- data/test/db_test.rb +7 -0
- data/test/grid_file_system_test.rb +12 -0
- data/test/load/thin/load.rb +1 -1
- data/test/replica_sets/basic_test.rb +36 -26
- data/test/replica_sets/complex_connect_test.rb +44 -0
- data/test/replica_sets/connect_test.rb +48 -22
- data/test/replica_sets/count_test.rb +4 -6
- data/test/replica_sets/insert_test.rb +13 -14
- data/test/replica_sets/pooled_insert_test.rb +9 -10
- data/test/replica_sets/query_test.rb +4 -4
- data/test/replica_sets/read_preference_test.rb +48 -14
- data/test/replica_sets/refresh_test.rb +43 -42
- data/test/replica_sets/refresh_with_threads_test.rb +10 -9
- data/test/replica_sets/replication_ack_test.rb +3 -3
- data/test/replica_sets/rs_test_helper.rb +17 -11
- data/test/test_helper.rb +2 -1
- data/test/tools/repl_set_manager.rb +63 -39
- data/test/unit/collection_test.rb +2 -1
- data/test/unit/connection_test.rb +22 -0
- data/test/unit/cursor_test.rb +6 -3
- data/test/unit/read_test.rb +1 -1
- data/test/uri_test.rb +17 -2
- metadata +151 -167
data/lib/mongo/util/support.rb
CHANGED
@@ -59,11 +59,11 @@ module Mongo
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def validate_read_preference(value)
|
62
|
-
if [:primary, :secondary, nil].include?(value)
|
62
|
+
if [:primary, :secondary, :secondary_only, nil].include?(value)
|
63
63
|
return true
|
64
64
|
else
|
65
65
|
raise MongoArgumentError, "#{value} is not a valid read preference. " +
|
66
|
-
"Please specify either :primary or :secondary."
|
66
|
+
"Please specify either :primary or :secondary or :secondary_only."
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -20,39 +20,63 @@ module Mongo
|
|
20
20
|
class URIParser
|
21
21
|
|
22
22
|
DEFAULT_PORT = 27017
|
23
|
-
|
24
|
-
|
23
|
+
|
24
|
+
USER_REGEX = /([-.\w:]+)/
|
25
|
+
PASS_REGEX = /([^@,]+)/
|
26
|
+
AUTH_REGEX = /(#{USER_REGEX}:#{PASS_REGEX}@)?/
|
27
|
+
|
28
|
+
HOST_REGEX = /([-.\w]+)/
|
29
|
+
PORT_REGEX = /(?::(\w+))?/
|
30
|
+
NODE_REGEX = /((#{HOST_REGEX}#{PORT_REGEX},?)+)/
|
31
|
+
|
32
|
+
PATH_REGEX = /(?:\/([-\w]+))?/
|
33
|
+
|
34
|
+
MONGODB_URI_MATCHER = /#{AUTH_REGEX}#{NODE_REGEX}#{PATH_REGEX}/
|
35
|
+
MONGODB_URI_SPEC = "mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]"
|
36
|
+
|
25
37
|
SPEC_ATTRS = [:nodes, :auths]
|
26
|
-
OPT_ATTRS = [:connect, :replicaset, :slaveok, :safe, :w, :wtimeout, :fsync]
|
27
|
-
|
28
|
-
OPT_VALID = {:connect
|
29
|
-
:replicaset
|
30
|
-
:slaveok
|
31
|
-
:safe
|
32
|
-
:w
|
33
|
-
:wtimeout
|
34
|
-
:fsync
|
38
|
+
OPT_ATTRS = [:connect, :replicaset, :slaveok, :safe, :w, :wtimeout, :fsync, :journal, :connecttimeoutms, :sockettimeoutms, :wtimeoutms]
|
39
|
+
|
40
|
+
OPT_VALID = {:connect => lambda {|arg| ['direct', 'replicaset'].include?(arg)},
|
41
|
+
:replicaset => lambda {|arg| arg.length > 0},
|
42
|
+
:slaveok => lambda {|arg| ['true', 'false'].include?(arg)},
|
43
|
+
:safe => lambda {|arg| ['true', 'false'].include?(arg)},
|
44
|
+
:w => lambda {|arg| arg =~ /^\d+$/ },
|
45
|
+
:wtimeout => lambda {|arg| arg =~ /^\d+$/ },
|
46
|
+
:fsync => lambda {|arg| ['true', 'false'].include?(arg)},
|
47
|
+
:journal => lambda {|arg| ['true', 'false'].include?(arg)},
|
48
|
+
:connecttimeoutms => lambda {|arg| arg =~ /^\d+$/ },
|
49
|
+
:sockettimeoutms => lambda {|arg| arg =~ /^\d+$/ },
|
50
|
+
:wtimeoutms => lambda {|arg| arg =~ /^\d+$/ }
|
35
51
|
}
|
36
52
|
|
37
|
-
OPT_ERR = {:connect
|
38
|
-
:replicaset
|
39
|
-
:slaveok
|
40
|
-
:safe
|
41
|
-
:w
|
42
|
-
:wtimeout
|
43
|
-
:fsync
|
53
|
+
OPT_ERR = {:connect => "must be 'direct' or 'replicaset'",
|
54
|
+
:replicaset => "must be a string containing the name of the replica set to connect to",
|
55
|
+
:slaveok => "must be 'true' or 'false'",
|
56
|
+
:safe => "must be 'true' or 'false'",
|
57
|
+
:w => "must be an integer specifying number of nodes to replica to",
|
58
|
+
:wtimeout => "must be an integer specifying milliseconds",
|
59
|
+
:fsync => "must be 'true' or 'false'",
|
60
|
+
:journal => "must be 'true' or 'false'",
|
61
|
+
:connecttimeoutms => "must be an integer specifying milliseconds",
|
62
|
+
:sockettimeoutms => "must be an integer specifying milliseconds",
|
63
|
+
:wtimeoutms => "must be an integer specifying milliseconds"
|
44
64
|
}
|
45
65
|
|
46
|
-
OPT_CONV = {:connect
|
47
|
-
:replicaset
|
48
|
-
:slaveok
|
49
|
-
:safe
|
50
|
-
:w
|
51
|
-
:wtimeout
|
52
|
-
:fsync
|
66
|
+
OPT_CONV = {:connect => lambda {|arg| arg},
|
67
|
+
:replicaset => lambda {|arg| arg},
|
68
|
+
:slaveok => lambda {|arg| arg == 'true' ? true : false},
|
69
|
+
:safe => lambda {|arg| arg == 'true' ? true : false},
|
70
|
+
:w => lambda {|arg| arg.to_i},
|
71
|
+
:wtimeout => lambda {|arg| arg.to_i},
|
72
|
+
:fsync => lambda {|arg| arg == 'true' ? true : false},
|
73
|
+
:journal => lambda {|arg| arg == 'true' ? true : false},
|
74
|
+
:connecttimeoutms => lambda {|arg| arg.to_f / 1000 }, # stored as seconds
|
75
|
+
:sockettimeoutms => lambda {|arg| arg.to_f / 1000 }, # stored as seconds
|
76
|
+
:wtimeoutms => lambda {|arg| arg.to_i }
|
53
77
|
}
|
54
78
|
|
55
|
-
attr_reader :nodes, :auths, :connect, :replicaset, :slaveok, :safe, :w, :wtimeout, :fsync
|
79
|
+
attr_reader :nodes, :auths, :connect, :replicaset, :slaveok, :safe, :w, :wtimeout, :fsync, :journal, :connecttimeoutms, :sockettimeoutms, :wtimeoutms
|
56
80
|
|
57
81
|
# Parse a MongoDB URI. This method is used by Connection.from_uri.
|
58
82
|
# Returns an array of nodes and an array of db authorizations, if applicable.
|
@@ -76,15 +100,25 @@ module Mongo
|
|
76
100
|
def connection_options
|
77
101
|
opts = {}
|
78
102
|
|
79
|
-
if (@w || @wtimeout || @fsync) && !@safe
|
80
|
-
raise MongoArgumentError, "Safe must be true if w,
|
103
|
+
if (@w || @journal || @wtimeout || @fsync || @wtimeoutms) && !@safe
|
104
|
+
raise MongoArgumentError, "Safe must be true if w, journal, wtimeoutMS, or fsync is specified"
|
81
105
|
end
|
82
106
|
|
83
107
|
if @safe
|
84
|
-
if @w || @wtimeout || @fsync
|
108
|
+
if @w || @journal || @wtimeout || @fsync || @wtimeoutms
|
85
109
|
safe_opts = {}
|
86
110
|
safe_opts[:w] = @w if @w
|
87
|
-
safe_opts[:
|
111
|
+
safe_opts[:j] = @journal if @journal
|
112
|
+
|
113
|
+
if @wtimeout
|
114
|
+
warn "Using wtimeout in a URI is deprecated, please use wtimeoutMS. It will be removed in v2.0."
|
115
|
+
safe_opts[:wtimeout] = @wtimeout
|
116
|
+
end
|
117
|
+
|
118
|
+
if @wtimeoutms
|
119
|
+
safe_opts[:wtimeout] = @wtimeoutms
|
120
|
+
end
|
121
|
+
|
88
122
|
safe_opts[:fsync] = @fsync if @fsync
|
89
123
|
else
|
90
124
|
safe_opts = true
|
@@ -92,6 +126,14 @@ module Mongo
|
|
92
126
|
|
93
127
|
opts[:safe] = safe_opts
|
94
128
|
end
|
129
|
+
|
130
|
+
if @connecttimeoutms
|
131
|
+
opts[:connect_timeout] = @connecttimeoutms
|
132
|
+
end
|
133
|
+
|
134
|
+
if @sockettimeoutms
|
135
|
+
opts[:op_timeout] = @sockettimeoutms
|
136
|
+
end
|
95
137
|
|
96
138
|
if @slaveok
|
97
139
|
if @connect == 'direct'
|
@@ -121,7 +163,7 @@ module Mongo
|
|
121
163
|
uname = matches[2]
|
122
164
|
pwd = matches[3]
|
123
165
|
hosturis = matches[4].split(',')
|
124
|
-
db = matches[
|
166
|
+
db = matches[8]
|
125
167
|
|
126
168
|
hosturis.each do |hosturi|
|
127
169
|
# If port is present, use it, otherwise use default port
|
@@ -158,7 +200,7 @@ module Mongo
|
|
158
200
|
separator = opts.include?('&') ? '&' : ';'
|
159
201
|
opts.split(separator).each do |attr|
|
160
202
|
key, value = attr.split('=')
|
161
|
-
key
|
203
|
+
key = key.downcase.to_sym
|
162
204
|
value = value.strip.downcase
|
163
205
|
if !OPT_ATTRS.include?(key)
|
164
206
|
raise MongoArgumentError, "Invalid Mongo URI option #{key}"
|
@@ -173,10 +215,6 @@ module Mongo
|
|
173
215
|
end
|
174
216
|
|
175
217
|
def configure_connect
|
176
|
-
if @nodes.length > 1 && !@connect
|
177
|
-
@connect = 'replicaset'
|
178
|
-
end
|
179
|
-
|
180
218
|
if !@connect
|
181
219
|
if @nodes.length > 1
|
182
220
|
@connect = 'replicaset'
|
data/lib/mongo/version.rb
CHANGED
data/mongo.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.version = Mongo::VERSION
|
7
7
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.summary = 'Ruby driver for
|
9
|
+
s.summary = 'Ruby driver for MongoDB'
|
10
10
|
s.description = 'A Ruby driver for MongoDB. For more information about Mongo, see http://www.mongodb.org.'
|
11
11
|
|
12
12
|
s.require_paths = ['lib']
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.rdoc_options = ['--main', 'README.md', '--inline-source']
|
27
27
|
s.extra_rdoc_files = ['README.md']
|
28
28
|
|
29
|
-
s.authors = ['Jim Menard', 'Mike Dirolf', 'Kyle Banker']
|
29
|
+
s.authors = ['Jim Menard', 'Mike Dirolf', 'Kyle Banker', 'Tyler Brock']
|
30
30
|
s.email = 'mongodb-dev@googlegroups.com'
|
31
31
|
s.homepage = 'http://www.mongodb.org'
|
32
32
|
|
@@ -26,6 +26,7 @@ class AuthenticationTest < Test::Unit::TestCase
|
|
26
26
|
@admin.authenticate('bob', 'secret')
|
27
27
|
@db1.add_user('user1', 'secret')
|
28
28
|
@db2.add_user('user2', 'secret')
|
29
|
+
@db2.add_user('userRO', 'secret', true) # read-only
|
29
30
|
@admin.logout
|
30
31
|
|
31
32
|
assert_raise Mongo::OperationFailure do
|
@@ -53,6 +54,7 @@ class AuthenticationTest < Test::Unit::TestCase
|
|
53
54
|
|
54
55
|
assert @db1['stuff'].insert({:a => 2}, :safe => true)
|
55
56
|
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
57
|
+
assert @db2['stuff'].find(:safe => true)
|
56
58
|
|
57
59
|
@db1.logout
|
58
60
|
assert_raise Mongo::OperationFailure do
|
@@ -63,6 +65,12 @@ class AuthenticationTest < Test::Unit::TestCase
|
|
63
65
|
assert_raise Mongo::OperationFailure do
|
64
66
|
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
65
67
|
end
|
68
|
+
|
69
|
+
@db2.authenticate('userRO', 'secret')
|
70
|
+
assert @db2['stuff'].find(:safe => true)
|
71
|
+
assert_raise Mongo::OperationFailure do
|
72
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
73
|
+
end
|
66
74
|
end
|
67
75
|
|
68
76
|
end
|
@@ -15,8 +15,7 @@ class AuthTest < Test::Unit::TestCase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_repl_set_auth
|
18
|
-
@conn = ReplSetConnection.new(
|
19
|
-
[@manager.host, @manager.ports[2]], :name => @manager.name)
|
18
|
+
@conn = ReplSetConnection.new(build_seeds(3), :name => @manager.name)
|
20
19
|
|
21
20
|
# Add an admin user
|
22
21
|
@conn['admin'].add_user("me", "secret")
|
data/test/bson/test_helper.rb
CHANGED
data/test/collection_test.rb
CHANGED
@@ -151,6 +151,17 @@ class TestCollection < Test::Unit::TestCase
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
+
def test_bulk_insert
|
155
|
+
docs = []
|
156
|
+
docs << {:foo => 1}
|
157
|
+
docs << {:foo => 2}
|
158
|
+
docs << {:foo => 3}
|
159
|
+
response = @@test.insert(docs)
|
160
|
+
assert_equal 3, response.length
|
161
|
+
assert response.all? {|id| id.is_a?(BSON::ObjectId)}
|
162
|
+
assert_equal 3, @@test.count
|
163
|
+
end
|
164
|
+
|
154
165
|
def test_bulk_insert_with_continue_on_error
|
155
166
|
if @@version >= "2.0"
|
156
167
|
@@test.create_index([["foo", 1]], :unique => true)
|
@@ -180,6 +191,50 @@ class TestCollection < Test::Unit::TestCase
|
|
180
191
|
end
|
181
192
|
end
|
182
193
|
|
194
|
+
def test_bson_valid_with_collect_on_error
|
195
|
+
docs = []
|
196
|
+
docs << {:foo => 1}
|
197
|
+
docs << {:bar => 1}
|
198
|
+
doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
|
199
|
+
assert_equal 2, @@test.count
|
200
|
+
assert_equal error_docs, []
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_bson_invalid_key_serialize_error_with_collect_on_error
|
204
|
+
docs = []
|
205
|
+
docs << {:foo => 1}
|
206
|
+
docs << {:bar => 1}
|
207
|
+
invalid_docs = []
|
208
|
+
invalid_docs << {'$invalid-key' => 1}
|
209
|
+
invalid_docs << {'invalid.key' => 1}
|
210
|
+
docs += invalid_docs
|
211
|
+
assert_raise BSON::InvalidKeyName do
|
212
|
+
@@test.insert(docs, :collect_on_error => false)
|
213
|
+
end
|
214
|
+
assert_equal 0, @@test.count
|
215
|
+
|
216
|
+
doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
|
217
|
+
assert_equal 2, @@test.count
|
218
|
+
assert_equal error_docs, invalid_docs
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_bson_invalid_encoding_serialize_error_with_collect_on_error
|
222
|
+
docs = []
|
223
|
+
docs << {:foo => 1}
|
224
|
+
docs << {:bar => 1}
|
225
|
+
invalid_docs = []
|
226
|
+
invalid_docs << {"\223\372\226{" => 1} # non utf8 encoding
|
227
|
+
docs += invalid_docs
|
228
|
+
assert_raise BSON::InvalidStringEncoding do
|
229
|
+
@@test.insert(docs, :collect_on_error => false)
|
230
|
+
end
|
231
|
+
assert_equal 0, @@test.count
|
232
|
+
|
233
|
+
doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
|
234
|
+
assert_equal 2, @@test.count
|
235
|
+
assert_equal error_docs, invalid_docs
|
236
|
+
end
|
237
|
+
|
183
238
|
def test_maximum_insert_size
|
184
239
|
docs = []
|
185
240
|
16.times do
|
@@ -546,6 +601,22 @@ class TestCollection < Test::Unit::TestCase
|
|
546
601
|
@@test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
|
547
602
|
assert res["results"]
|
548
603
|
end
|
604
|
+
|
605
|
+
def test_map_reduce_with_collection_output_to_other_db
|
606
|
+
@@test << {:user_id => 1}
|
607
|
+
@@test << {:user_id => 2}
|
608
|
+
|
609
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
610
|
+
r = Code.new("function(k,vals) { return 1; }")
|
611
|
+
oh = BSON::OrderedHash.new
|
612
|
+
oh[:replace] = 'foo'
|
613
|
+
oh[:db] = 'somedb'
|
614
|
+
res = @@test.map_reduce(m, r, :out => (oh))
|
615
|
+
assert res["result"]
|
616
|
+
assert res["counts"]
|
617
|
+
assert res["timeMillis"]
|
618
|
+
assert res.find.to_a.any? {|doc| doc["_id"] == 2 && doc["value"] == 1}
|
619
|
+
end
|
549
620
|
end
|
550
621
|
end
|
551
622
|
|
data/test/connection_test.rb
CHANGED
@@ -137,6 +137,15 @@ class TestConnection < Test::Unit::TestCase
|
|
137
137
|
assert output.string.include?("admin['$cmd'].find")
|
138
138
|
end
|
139
139
|
|
140
|
+
def test_logging_duration
|
141
|
+
output = StringIO.new
|
142
|
+
logger = Logger.new(output)
|
143
|
+
logger.level = Logger::DEBUG
|
144
|
+
connection = standard_connection(:logger => logger).db(MONGO_TEST_DB)
|
145
|
+
assert_match /\(\d+ms\)/, output.string
|
146
|
+
assert output.string.include?("admin['$cmd'].find")
|
147
|
+
end
|
148
|
+
|
140
149
|
def test_connection_logger
|
141
150
|
output = StringIO.new
|
142
151
|
logger = Logger.new(output)
|
data/test/db_test.rb
CHANGED
@@ -151,6 +151,13 @@ class DBTest < Test::Unit::TestCase
|
|
151
151
|
@@db.remove_user('foo:bar')
|
152
152
|
end
|
153
153
|
|
154
|
+
def test_authenticate_read_only
|
155
|
+
@@db.add_user('joebob', 'user', true) # read-only user
|
156
|
+
assert @@db.authenticate('joebob', 'user')
|
157
|
+
@@db.logout
|
158
|
+
@@db.remove_user('joebob')
|
159
|
+
end
|
160
|
+
|
154
161
|
def test_authenticate_with_connection_uri
|
155
162
|
@@db.add_user('spongebob', 'squarepants')
|
156
163
|
assert Mongo::Connection.from_uri("mongodb://spongebob:squarepants@#{host_port}/#{@@db.name}")
|
@@ -165,6 +165,18 @@ class GridFileSystemTest < Test::Unit::TestCase
|
|
165
165
|
assert_equal 0, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
|
166
166
|
end
|
167
167
|
|
168
|
+
should "delete all versions which exceed the number of versions to keep specified by the option :versions" do
|
169
|
+
@versions = 1 + rand(4-1)
|
170
|
+
@grid.open('sample', 'w', :versions => @versions) do |f|
|
171
|
+
f.write @new_data
|
172
|
+
end
|
173
|
+
@new_ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
|
174
|
+
assert_equal @versions, @new_ids.length
|
175
|
+
id = @new_ids.first
|
176
|
+
assert !@ids.include?(id)
|
177
|
+
assert_equal @versions, @db['fs.files'].find({'filename' => 'sample'}).count
|
178
|
+
end
|
179
|
+
|
168
180
|
should "delete old versions on write with :delete_old is passed in" do
|
169
181
|
@grid.open('sample', 'w', :delete_old => true) do |f|
|
170
182
|
f.write @new_data
|
data/test/load/thin/load.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'mongo')
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
-
$con = Mongo::ReplSetConnection.new(['localhost',
|
4
|
+
$con = Mongo::ReplSetConnection.new(['localhost:30000', 'localhost:30001'], :read => :secondary, :refresh_mode => :sync, :refresh_interval => 30)
|
5
5
|
$db = $con['foo']
|
6
6
|
|
7
7
|
class Load < Sinatra::Base
|
@@ -2,63 +2,64 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
2
|
require './test/replica_sets/rs_test_helper'
|
3
3
|
|
4
4
|
class BasicTest < Test::Unit::TestCase
|
5
|
-
|
5
|
+
|
6
|
+
def setup
|
7
|
+
ensure_rs
|
8
|
+
end
|
6
9
|
|
7
10
|
def teardown
|
8
|
-
|
11
|
+
@rs.restart_killed_nodes
|
9
12
|
@conn.close if defined?(@conn) && @conn
|
10
13
|
end
|
11
14
|
|
12
15
|
def test_connect
|
13
|
-
@conn = ReplSetConnection.new(
|
14
|
-
[self.rs.host, self.rs.ports[2]], :name => self.rs.name)
|
16
|
+
@conn = ReplSetConnection.new(build_seeds(3), :name => @rs.name)
|
15
17
|
assert @conn.connected?
|
16
18
|
|
17
|
-
assert_equal
|
18
|
-
assert_equal
|
19
|
-
assert_equal
|
19
|
+
assert_equal @rs.primary, @conn.primary
|
20
|
+
assert_equal @rs.secondaries.sort, @conn.secondaries.sort
|
21
|
+
assert_equal @rs.arbiters.sort, @conn.arbiters.sort
|
20
22
|
|
21
|
-
@conn = ReplSetConnection.new([
|
22
|
-
:name =>
|
23
|
+
@conn = ReplSetConnection.new(["#{@rs.host}:#{@rs.ports[1]}","#{@rs.host}:#{@rs.ports[0]}"],
|
24
|
+
:name => @rs.name)
|
23
25
|
assert @conn.connected?
|
24
26
|
end
|
25
27
|
|
26
28
|
def test_cache_original_seed_nodes
|
27
|
-
|
28
|
-
|
29
|
+
seeds = build_seeds(3) << "#{@rs.host}:19356"
|
30
|
+
@conn = ReplSetConnection.new(seeds, :name => @rs.name)
|
29
31
|
assert @conn.connected?
|
30
|
-
assert @conn.seeds.include?([
|
31
|
-
assert_equal [
|
32
|
+
assert @conn.seeds.include?([@rs.host, 19356]), "Original seed nodes not cached!"
|
33
|
+
assert_equal [@rs.host, 19356], @conn.seeds.last, "Original seed nodes not cached!"
|
32
34
|
end
|
33
35
|
|
34
36
|
def test_accessors
|
35
|
-
seeds =
|
36
|
-
|
37
|
-
|
38
|
-
@
|
37
|
+
seeds = build_seeds(3)
|
38
|
+
args = {:name => @rs.name}
|
39
|
+
@conn = ReplSetConnection.new(seeds, args)
|
40
|
+
@major_version = @rs.version.first
|
39
41
|
|
40
|
-
assert_equal @conn.host,
|
41
|
-
assert_equal @conn.port,
|
42
|
+
assert_equal @conn.host, @rs.primary[0]
|
43
|
+
assert_equal @conn.port, @rs.primary[1]
|
42
44
|
assert_equal @conn.host, @conn.primary_pool.host
|
43
45
|
assert_equal @conn.port, @conn.primary_pool.port
|
44
46
|
assert_equal @conn.nodes.sort, @conn.seeds.sort
|
45
47
|
assert_equal 2, @conn.secondaries.length
|
46
48
|
assert_equal 0, @conn.arbiters.length
|
47
49
|
assert_equal 2, @conn.secondary_pools.length
|
48
|
-
assert_equal
|
50
|
+
assert_equal @rs.name, @conn.replica_set_name
|
49
51
|
assert @conn.secondary_pools.include?(@conn.read_pool)
|
50
|
-
assert_equal 5, @conn.tag_map.keys.length
|
51
52
|
assert_equal 90, @conn.refresh_interval
|
52
53
|
assert_equal @conn.refresh_mode, false
|
54
|
+
assert_equal 5, @conn.tag_map.keys.length unless @major_version < 2
|
53
55
|
end
|
54
56
|
|
55
57
|
context "Socket pools" do
|
56
58
|
context "checking out writers" do
|
57
59
|
setup do
|
58
|
-
seeds =
|
59
|
-
|
60
|
-
|
61
|
-
@con = ReplSetConnection.new(*args)
|
60
|
+
seeds = build_seeds(3)
|
61
|
+
args = {:name => @rs.name}
|
62
|
+
@con = ReplSetConnection.new(seeds, args)
|
62
63
|
@coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
|
63
64
|
end
|
64
65
|
|
@@ -88,7 +89,16 @@ class BasicTest < Test::Unit::TestCase
|
|
88
89
|
rescue SystemStackError
|
89
90
|
end
|
90
91
|
end
|
91
|
-
|
92
|
+
end
|
93
|
+
|
94
|
+
context "checking out readers" do
|
95
|
+
setup do
|
96
|
+
seeds = build_seeds(3)
|
97
|
+
args = {:name => @rs.name}
|
98
|
+
@con = ReplSetConnection.new(seeds, args)
|
99
|
+
@coll = @con[MONGO_TEST_DB]['test-connection-exceptions']
|
100
|
+
end
|
101
|
+
|
92
102
|
should "close the connection on receive_message for major exceptions" do
|
93
103
|
@con.expects(:checkout_reader).raises(SystemStackError)
|
94
104
|
@con.expects(:close)
|