mongo 1.5.2 → 1.6.0
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/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)
|