mongo 1.3.0 → 1.12.5
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +122 -271
- data/Rakefile +25 -209
- data/VERSION +1 -0
- data/bin/mongo_console +31 -9
- data/lib/mongo/bulk_write_collection_view.rb +387 -0
- data/lib/mongo/collection.rb +576 -269
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/connection/node.rb +249 -0
- data/lib/mongo/connection/pool.rb +340 -0
- data/lib/mongo/connection/pool_manager.rb +320 -0
- data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection.rb +7 -875
- data/lib/mongo/cursor.rb +403 -117
- data/lib/mongo/db.rb +444 -243
- data/lib/mongo/exception.rb +145 -0
- data/lib/mongo/functional/authentication.rb +455 -0
- data/lib/mongo/functional/logging.rb +85 -0
- data/lib/mongo/functional/read_preference.rb +183 -0
- data/lib/mongo/functional/scram.rb +556 -0
- data/lib/mongo/functional/uri_parser.rb +409 -0
- data/lib/mongo/functional/write_concern.rb +66 -0
- data/lib/mongo/functional.rb +20 -0
- data/lib/mongo/gridfs/grid.rb +30 -24
- data/lib/mongo/gridfs/grid_ext.rb +6 -10
- data/lib/mongo/gridfs/grid_file_system.rb +38 -20
- data/lib/mongo/gridfs/grid_io.rb +84 -75
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/legacy.rb +140 -0
- data/lib/mongo/mongo_client.rb +697 -0
- data/lib/mongo/mongo_replica_set_client.rb +535 -0
- data/lib/mongo/mongo_sharded_client.rb +159 -0
- data/lib/mongo/networking.rb +372 -0
- data/lib/mongo/{util → utils}/conversions.rb +29 -8
- data/lib/mongo/{util → utils}/core_ext.rb +28 -18
- data/lib/mongo/{util → utils}/server_version.rb +4 -6
- data/lib/mongo/{util → utils}/support.rb +29 -31
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo.rb +51 -50
- data/mongo.gemspec +29 -32
- data/test/functional/authentication_test.rb +39 -0
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1198 -0
- data/test/functional/client_test.rb +627 -0
- data/test/functional/collection_test.rb +2175 -0
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
- data/test/functional/cursor_fail_test.rb +57 -0
- data/test/functional/cursor_message_test.rb +56 -0
- data/test/functional/cursor_test.rb +683 -0
- data/test/functional/db_api_test.rb +835 -0
- data/test/functional/db_connection_test.rb +25 -0
- data/test/functional/db_test.rb +348 -0
- data/test/functional/grid_file_system_test.rb +285 -0
- data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
- data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
- data/test/functional/pool_test.rb +136 -0
- data/test/functional/safe_test.rb +98 -0
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +62 -0
- data/test/functional/timeout_test.rb +60 -0
- data/test/functional/uri_test.rb +446 -0
- data/test/functional/write_concern_test.rb +118 -0
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +476 -0
- data/test/replica_set/authentication_test.rb +37 -0
- data/test/replica_set/basic_test.rb +189 -0
- data/test/replica_set/client_test.rb +393 -0
- data/test/replica_set/connection_test.rb +138 -0
- data/test/replica_set/count_test.rb +66 -0
- data/test/replica_set/cursor_test.rb +220 -0
- data/test/replica_set/insert_test.rb +157 -0
- data/test/replica_set/max_values_test.rb +151 -0
- data/test/replica_set/pinning_test.rb +105 -0
- data/test/replica_set/query_test.rb +73 -0
- data/test/replica_set/read_preference_test.rb +219 -0
- data/test/replica_set/refresh_test.rb +211 -0
- data/test/replica_set/replication_ack_test.rb +95 -0
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +203 -0
- data/test/shared/authentication/basic_auth_shared.rb +260 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
- data/test/shared/authentication/gssapi_shared.rb +176 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/authentication/scram_shared.rb +92 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +53 -94
- data/test/threading/basic_test.rb +120 -0
- data/test/tools/mongo_config.rb +708 -0
- data/test/tools/mongo_config_test.rb +160 -0
- data/test/unit/client_test.rb +381 -0
- data/test/unit/collection_test.rb +89 -53
- data/test/unit/connection_test.rb +282 -32
- data/test/unit/cursor_test.rb +206 -8
- data/test/unit/db_test.rb +55 -13
- data/test/unit/grid_test.rb +43 -16
- data/test/unit/mongo_sharded_client_test.rb +48 -0
- data/test/unit/node_test.rb +93 -0
- data/test/unit/pool_manager_test.rb +111 -0
- data/test/unit/read_pref_test.rb +406 -0
- data/test/unit/read_test.rb +159 -0
- data/test/unit/safe_test.rb +69 -36
- data/test/unit/sharding_pool_manager_test.rb +84 -0
- data/test/unit/write_concern_test.rb +175 -0
- data.tar.gz.sig +3 -0
- metadata +227 -216
- metadata.gz.sig +0 -0
- data/docs/CREDITS.md +0 -123
- data/docs/FAQ.md +0 -116
- data/docs/GridFS.md +0 -158
- data/docs/HISTORY.md +0 -244
- data/docs/RELEASES.md +0 -33
- data/docs/REPLICA_SETS.md +0 -72
- data/docs/TUTORIAL.md +0 -247
- data/docs/WRITE_CONCERN.md +0 -28
- data/lib/mongo/exceptions.rb +0 -71
- data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
- data/lib/mongo/repl_set_connection.rb +0 -342
- data/lib/mongo/test.rb +0 -20
- data/lib/mongo/util/pool.rb +0 -177
- data/lib/mongo/util/uri_parser.rb +0 -185
- data/test/async/collection_test.rb +0 -224
- data/test/async/connection_test.rb +0 -24
- data/test/async/cursor_test.rb +0 -162
- data/test/async/worker_pool_test.rb +0 -99
- data/test/auxillary/1.4_features.rb +0 -166
- data/test/auxillary/authentication_test.rb +0 -68
- data/test/auxillary/autoreconnect_test.rb +0 -41
- data/test/auxillary/fork_test.rb +0 -30
- data/test/auxillary/repl_set_auth_test.rb +0 -58
- data/test/auxillary/slave_connection_test.rb +0 -36
- data/test/auxillary/threaded_authentication_test.rb +0 -101
- data/test/bson/binary_test.rb +0 -15
- data/test/bson/bson_test.rb +0 -649
- data/test/bson/byte_buffer_test.rb +0 -208
- data/test/bson/hash_with_indifferent_access_test.rb +0 -38
- data/test/bson/json_test.rb +0 -17
- data/test/bson/object_id_test.rb +0 -154
- data/test/bson/ordered_hash_test.rb +0 -204
- data/test/bson/timestamp_test.rb +0 -24
- data/test/collection_test.rb +0 -910
- data/test/connection_test.rb +0 -309
- data/test/cursor_fail_test.rb +0 -75
- data/test/cursor_message_test.rb +0 -43
- data/test/cursor_test.rb +0 -483
- data/test/db_api_test.rb +0 -726
- data/test/db_connection_test.rb +0 -15
- data/test/db_test.rb +0 -287
- data/test/grid_file_system_test.rb +0 -243
- data/test/load/resque/load.rb +0 -21
- data/test/load/resque/processor.rb +0 -26
- data/test/load/thin/load.rb +0 -24
- data/test/load/unicorn/load.rb +0 -23
- data/test/load/unicorn/unicorn.rb +0 -29
- data/test/replica_sets/connect_test.rb +0 -94
- data/test/replica_sets/connection_string_test.rb +0 -32
- data/test/replica_sets/count_test.rb +0 -35
- data/test/replica_sets/insert_test.rb +0 -53
- data/test/replica_sets/pooled_insert_test.rb +0 -55
- data/test/replica_sets/query_secondaries.rb +0 -96
- data/test/replica_sets/query_test.rb +0 -51
- data/test/replica_sets/replication_ack_test.rb +0 -66
- data/test/replica_sets/rs_test_helper.rb +0 -27
- data/test/safe_test.rb +0 -68
- data/test/support/hash_with_indifferent_access.rb +0 -186
- data/test/support/keys.rb +0 -45
- data/test/support_test.rb +0 -18
- data/test/threading/threading_with_large_pool_test.rb +0 -90
- data/test/threading_test.rb +0 -87
- data/test/tools/auth_repl_set_manager.rb +0 -14
- data/test/tools/load.rb +0 -58
- data/test/tools/repl_set_manager.rb +0 -266
- data/test/tools/sharding_manager.rb +0 -202
- data/test/tools/test.rb +0 -4
- data/test/unit/pool_test.rb +0 -9
- data/test/unit/repl_set_connection_test.rb +0 -59
- data/test/uri_test.rb +0 -91
@@ -0,0 +1,627 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
require 'logger'
|
17
|
+
|
18
|
+
class ClientTest < Test::Unit::TestCase
|
19
|
+
|
20
|
+
include Mongo
|
21
|
+
include BSON
|
22
|
+
|
23
|
+
def setup
|
24
|
+
@client = standard_connection
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
@client.close
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_connection_failure
|
32
|
+
assert_raise Mongo::ConnectionFailure do
|
33
|
+
MongoClient.new('localhost', 27347)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_host_port_accessors
|
38
|
+
assert_equal @client.host, TEST_HOST
|
39
|
+
assert_equal @client.port, TEST_PORT
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_server_info
|
43
|
+
server_info = @client.server_info
|
44
|
+
assert server_info.keys.include?("version")
|
45
|
+
assert Mongo::Support.ok?(server_info)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_ping
|
49
|
+
ping = @client.ping
|
50
|
+
assert ping['ok']
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_ipv6
|
54
|
+
with_ipv6_enabled(@client) do
|
55
|
+
assert client = MongoClient.new('[::1]')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_ipv6_uri_no_opts
|
60
|
+
with_ipv6_enabled(@client) do
|
61
|
+
uri = 'mongodb://[::1]:27017'
|
62
|
+
with_preserved_env_uri(uri) do
|
63
|
+
assert MongoClient.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_ipv6_uri_opts
|
69
|
+
with_ipv6_enabled(@client) do
|
70
|
+
uri = 'mongodb://[::1]:27017/?slaveOk=true'
|
71
|
+
with_preserved_env_uri(uri) do
|
72
|
+
assert MongoClient.new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_unix_sock
|
78
|
+
# There's an issue with unix sockets on JRuby with 32-bit libc
|
79
|
+
# https://jira.codehaus.org/browse/JRUBY-7183
|
80
|
+
return if RUBY_PLATFORM =~ /java/
|
81
|
+
begin
|
82
|
+
assert MongoClient.new("/tmp/mongodb-#{TEST_PORT}.sock")
|
83
|
+
rescue Errno::EAFNOSUPPORT
|
84
|
+
# System doesn't support UNIX sockets
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_initialize_with_auths
|
89
|
+
auth = { :username => TEST_USER,
|
90
|
+
:password => TEST_USER_PWD,
|
91
|
+
:db_name => TEST_DB,
|
92
|
+
:source => TEST_DB}
|
93
|
+
|
94
|
+
client = MongoClient.new(:auths => Set.new([auth]))
|
95
|
+
assert client['test']['test'].find.to_a
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_connection_uri
|
99
|
+
con = MongoClient.from_uri("mongodb://#{host_port}")
|
100
|
+
assert_equal mongo_host, con.primary_pool.host
|
101
|
+
assert_equal mongo_port, con.primary_pool.port
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_uri_with_extra_opts
|
105
|
+
con = MongoClient.from_uri("mongodb://#{host_port}", :pool_size => 10, :slave_ok => true)
|
106
|
+
assert_equal 10, con.pool_size
|
107
|
+
assert con.slave_ok?
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_env_mongodb_uri
|
111
|
+
uri = "mongodb://#{host_port}"
|
112
|
+
with_preserved_env_uri(uri) do
|
113
|
+
con = MongoClient.new
|
114
|
+
assert_equal mongo_host, con.primary_pool.host
|
115
|
+
assert_equal mongo_port, con.primary_pool.port
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_from_uri_implicit_mongodb_uri
|
120
|
+
uri = "mongodb://#{host_port}"
|
121
|
+
with_preserved_env_uri(uri) do
|
122
|
+
con = MongoClient.from_uri
|
123
|
+
assert_equal mongo_host, con.primary_pool.host
|
124
|
+
assert_equal mongo_port, con.primary_pool.port
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_db_from_uri_exists_no_options
|
129
|
+
db_name = "_database"
|
130
|
+
uri = "mongodb://#{host_port}/#{db_name}"
|
131
|
+
with_preserved_env_uri(uri) do
|
132
|
+
con = MongoClient.from_uri
|
133
|
+
db = con.db
|
134
|
+
assert_equal db.name, db_name
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_db_from_uri_exists_options
|
139
|
+
db_name = "_database"
|
140
|
+
uri = "mongodb://#{host_port}/#{db_name}?"
|
141
|
+
with_preserved_env_uri(uri) do
|
142
|
+
con = MongoClient.from_uri
|
143
|
+
db = con.db
|
144
|
+
assert_equal db.name, db_name
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_db_from_uri_exists_no_db_name
|
149
|
+
uri = "mongodb://#{host_port}/"
|
150
|
+
with_preserved_env_uri(uri) do
|
151
|
+
con = MongoClient.from_uri
|
152
|
+
db = con.db
|
153
|
+
assert_equal db.name, MongoClient::DEFAULT_DB_NAME
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_db_from_uri_from_string_param
|
158
|
+
db_name = "_database"
|
159
|
+
db = MongoClient.from_uri("mongodb://#{host_port}/#{db_name}").db
|
160
|
+
assert_equal db.name, db_name
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_db_from_uri_from_string_param_no_db_name
|
164
|
+
db = MongoClient.from_uri("mongodb://#{host_port}").db
|
165
|
+
assert_equal db.name, MongoClient::DEFAULT_DB_NAME
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_from_uri_write_concern
|
169
|
+
con = MongoClient.from_uri(TEST_URI)
|
170
|
+
db = con.db
|
171
|
+
coll = db.collection('from-uri-test')
|
172
|
+
assert_equal BSON::ObjectId, coll.insert({'a' => 1}).class
|
173
|
+
[con, db, coll].each do |component|
|
174
|
+
component.write_concern.each do |key,value|
|
175
|
+
assert_not_nil(value, "component #{component.class.inspect} should not have write concern #{key.inspect} field with nil value")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
assert_equal({:w => 1}, con.write_concern, "write concern should not have extra pairs that were not specified by the user")
|
179
|
+
assert_equal({:w => 1}, db.write_concern, "write concern should not have extra pairs that were not specified by the user")
|
180
|
+
assert_equal({:w => 1}, coll.write_concern, "write concern should not have extra pairs that were not specified by the user")
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_server_version
|
184
|
+
assert_match(/\d\.\d+(\.\d+)?/, @client.server_version.to_s)
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_invalid_database_names
|
188
|
+
assert_raise TypeError do @client.db(4) end
|
189
|
+
|
190
|
+
assert_raise Mongo::InvalidNSName do @client.db('') end
|
191
|
+
assert_raise Mongo::InvalidNSName do @client.db('te$t') end
|
192
|
+
assert_raise Mongo::InvalidNSName do @client.db('te.t') end
|
193
|
+
assert_raise Mongo::InvalidNSName do @client.db('te\\t') end
|
194
|
+
assert_raise Mongo::InvalidNSName do @client.db('te/t') end
|
195
|
+
assert_raise Mongo::InvalidNSName do @client.db('te st') end
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_options_passed_to_db
|
199
|
+
@pk_mock = Object.new
|
200
|
+
db = @client.db('test', :pk => @pk_mock, :strict => true)
|
201
|
+
assert_equal @pk_mock, db.pk_factory
|
202
|
+
assert db.strict?
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_database_info
|
206
|
+
db_name = 'ruby_test'
|
207
|
+
@client.drop_database(db_name)
|
208
|
+
@client.db(db_name).collection('info-test').insert('a' => 1)
|
209
|
+
|
210
|
+
info = @client.database_info
|
211
|
+
assert_not_nil info
|
212
|
+
assert_kind_of Hash, info
|
213
|
+
assert_not_nil info[db_name]
|
214
|
+
assert info[db_name] > 0
|
215
|
+
|
216
|
+
@client.drop_database(db_name)
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_copy_database
|
220
|
+
return unless @client.server_version >= '2.5' ||
|
221
|
+
@client.server_version < '2.4'
|
222
|
+
old_db = @client['ruby-test-old']
|
223
|
+
new_db = @client['ruby-test-new']
|
224
|
+
coll = 'copy-test'
|
225
|
+
|
226
|
+
old_db[coll].insert('a' => 1)
|
227
|
+
@client.drop_database(new_db.name)
|
228
|
+
silently { old_db.add_user('chevy', 'chase') }
|
229
|
+
@client.copy_database(old_db.name, new_db.name, host_port, 'chevy', 'chase')
|
230
|
+
old_db.remove_user('chevy')
|
231
|
+
assert_equal old_db[coll].find_one, new_db[coll].find_one
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_database_names
|
235
|
+
@client.db(TEST_DB).collection('info-test').remove({})
|
236
|
+
@client.db(TEST_DB).collection('info-test').insert('a' => 1)
|
237
|
+
|
238
|
+
names = @client.database_names
|
239
|
+
assert_not_nil names
|
240
|
+
assert_kind_of Array, names
|
241
|
+
assert names.length >= 1
|
242
|
+
assert names.include?(TEST_DB)
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_logging
|
246
|
+
output = StringIO.new
|
247
|
+
logger = Logger.new(output)
|
248
|
+
logger.level = Logger::DEBUG
|
249
|
+
standard_connection(:logger => logger).db(TEST_DB)
|
250
|
+
assert output.string.include?("admin['$cmd'].find")
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_logging_duration
|
254
|
+
output = StringIO.new
|
255
|
+
logger = Logger.new(output)
|
256
|
+
logger.level = Logger::DEBUG
|
257
|
+
standard_connection(:logger => logger).db(TEST_DB)
|
258
|
+
assert_match(/\(\d+.\d{1}ms\)/, output.string)
|
259
|
+
assert output.string.include?("admin['$cmd'].find")
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_connection_logger
|
263
|
+
output = StringIO.new
|
264
|
+
logger = Logger.new(output)
|
265
|
+
logger.level = Logger::DEBUG
|
266
|
+
connection = standard_connection(:logger => logger)
|
267
|
+
assert_equal logger, connection.logger
|
268
|
+
|
269
|
+
connection.logger.debug 'testing'
|
270
|
+
assert output.string.include?('testing')
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_drop_database
|
274
|
+
db = @client.db(TEST_DB + '_drop_test')
|
275
|
+
coll = db.collection('temp')
|
276
|
+
coll.remove
|
277
|
+
coll.insert(:name => 'temp')
|
278
|
+
assert_equal 1, coll.count()
|
279
|
+
assert @client.database_names.include?(TEST_DB + '_drop_test')
|
280
|
+
|
281
|
+
@client.drop_database(TEST_DB + '_drop_test')
|
282
|
+
assert !@client.database_names.include?(TEST_DB + '_drop_test')
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_nodes
|
286
|
+
silently do
|
287
|
+
@client = MongoClient.multi([['foo', 27017], ['bar', 27018]], :connect => false)
|
288
|
+
end
|
289
|
+
seeds = @client.seeds
|
290
|
+
assert_equal 2, seeds.length
|
291
|
+
assert_equal ['foo', 27017], seeds[0]
|
292
|
+
assert_equal ['bar', 27018], seeds[1]
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_fsync_lock
|
296
|
+
assert !@client.locked?
|
297
|
+
@client.lock!
|
298
|
+
assert @client.locked?
|
299
|
+
assert [1, true].include?(@client['admin']['$cmd.sys.inprog'].find_one['fsyncLock'])
|
300
|
+
assert_match(/unlock/, @client.unlock!['info'])
|
301
|
+
unlocked = false
|
302
|
+
counter = 0
|
303
|
+
while counter < 100
|
304
|
+
if @client['admin']['$cmd.sys.inprog'].find_one['fsyncLock'].nil?
|
305
|
+
unlocked = true
|
306
|
+
break
|
307
|
+
else
|
308
|
+
counter += 1
|
309
|
+
end
|
310
|
+
end
|
311
|
+
assert !@client.locked?
|
312
|
+
assert unlocked, "mongod failed to unlock"
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_max_bson_size_value
|
316
|
+
conn = standard_connection(:connect => false)
|
317
|
+
|
318
|
+
admin_db = Object.new
|
319
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxBsonObjectSize' => 15_000_000})
|
320
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
321
|
+
conn.connect
|
322
|
+
assert_equal 15_000_000, conn.max_bson_size
|
323
|
+
|
324
|
+
conn = standard_connection
|
325
|
+
if conn.server_version > "1.7.2"
|
326
|
+
assert_equal conn['admin'].command({:ismaster => 1})['maxBsonObjectSize'], conn.max_bson_size
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_max_message_size_value
|
331
|
+
conn = standard_connection(:connect => false)
|
332
|
+
|
333
|
+
admin_db = Object.new
|
334
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxMessageSizeBytes' => 20_000_000})
|
335
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
336
|
+
conn.connect
|
337
|
+
|
338
|
+
assert_equal 20_000_000, conn.max_message_size
|
339
|
+
|
340
|
+
conn = standard_connection
|
341
|
+
maxMessageSizeBytes = conn['admin'].command({:ismaster => 1})['maxMessageSizeBytes']
|
342
|
+
if conn.server_version.to_s[/([^-]+)/,1] >= "2.4.0"
|
343
|
+
assert_equal 48_000_000, maxMessageSizeBytes
|
344
|
+
elsif conn.server_version > "2.3.2"
|
345
|
+
assert_equal conn.max_bson_size, maxMessageSizeBytes
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_max_bson_size_with_no_reported_max_size
|
350
|
+
conn = standard_connection(:connect => false)
|
351
|
+
|
352
|
+
admin_db = Object.new
|
353
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
354
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
355
|
+
|
356
|
+
conn.connect
|
357
|
+
assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, conn.max_bson_size
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_max_message_size_with_no_reported_max_size
|
361
|
+
conn = standard_connection(:connect => false)
|
362
|
+
|
363
|
+
admin_db = Object.new
|
364
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
365
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
366
|
+
|
367
|
+
conn.connect
|
368
|
+
assert_equal Mongo::DEFAULT_MAX_BSON_SIZE * Mongo::MESSAGE_SIZE_FACTOR, conn.max_message_size
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_max_wire_version_and_min_wire_version_values
|
372
|
+
conn = standard_connection(:connect => false)
|
373
|
+
|
374
|
+
admin_db = Object.new
|
375
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxWireVersion' => 1, 'minWireVersion' => 1, 'maxWriteBatchSize' => 999})
|
376
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
377
|
+
conn.connect
|
378
|
+
|
379
|
+
assert_equal 1, conn.max_wire_version
|
380
|
+
assert_equal 1, conn.min_wire_version
|
381
|
+
assert_equal 999, conn.max_write_batch_size
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_max_wire_version_and_min_wire_version_values_with_no_reported_values
|
385
|
+
conn = standard_connection(:connect => false)
|
386
|
+
|
387
|
+
admin_db = Object.new
|
388
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
389
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
390
|
+
conn.connect
|
391
|
+
|
392
|
+
assert_equal 0, conn.max_wire_version
|
393
|
+
assert_equal 0, conn.min_wire_version
|
394
|
+
assert_equal Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE, conn.max_write_batch_size
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_wire_version_feature
|
398
|
+
conn = standard_connection(:connect => false)
|
399
|
+
conn.stubs(:min_wire_version).returns(0)
|
400
|
+
conn.stubs(:max_wire_version).returns(1)
|
401
|
+
assert_true conn.wire_version_feature?(0)
|
402
|
+
assert_true conn.wire_version_feature?(1)
|
403
|
+
assert_false conn.wire_version_feature?(2)
|
404
|
+
assert_false conn.wire_version_feature?(-1)
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_wire_version_not_in_range
|
408
|
+
[
|
409
|
+
[Mongo::MongoClient::MAX_WIRE_VERSION+1, Mongo::MongoClient::MAX_WIRE_VERSION+1],
|
410
|
+
[Mongo::MongoClient::MIN_WIRE_VERSION-1, Mongo::MongoClient::MIN_WIRE_VERSION-1]
|
411
|
+
].each do |min_wire_version, max_wire_version|
|
412
|
+
conn = standard_connection(:connect => false)
|
413
|
+
admin_db = Object.new
|
414
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version})
|
415
|
+
conn.expects(:[]).with('admin').returns(admin_db)
|
416
|
+
assert_raises Mongo::ConnectionFailure do
|
417
|
+
conn.connect
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_use_write_command
|
423
|
+
with_write_commands(@client) do
|
424
|
+
assert_true @client.use_write_command?({:w => 1})
|
425
|
+
assert_false @client.use_write_command?({:w => 0})
|
426
|
+
end
|
427
|
+
with_write_operations(@client) do
|
428
|
+
assert_false @client.use_write_command?({:w => 1})
|
429
|
+
assert_false @client.use_write_command?({:w => 0})
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_connection_activity
|
434
|
+
conn = standard_connection
|
435
|
+
assert conn.active?
|
436
|
+
|
437
|
+
conn.primary_pool.close
|
438
|
+
assert !conn.active?
|
439
|
+
|
440
|
+
# Simulate a dropped connection.
|
441
|
+
dropped_socket = mock('dropped_socket')
|
442
|
+
dropped_socket.stubs(:read).raises(Errno::ECONNRESET)
|
443
|
+
dropped_socket.stubs(:send).raises(Errno::ECONNRESET)
|
444
|
+
dropped_socket.stub_everything
|
445
|
+
|
446
|
+
conn.primary_pool.host = 'localhost'
|
447
|
+
conn.primary_pool.port = Mongo::MongoClient::DEFAULT_PORT
|
448
|
+
conn.primary_pool.instance_variable_set("@pids", {dropped_socket => Process.pid})
|
449
|
+
conn.primary_pool.instance_variable_set("@sockets", [dropped_socket])
|
450
|
+
|
451
|
+
assert !conn.active?
|
452
|
+
end
|
453
|
+
|
454
|
+
def test_operation_timeout_with_active
|
455
|
+
conn = MongoClient.new
|
456
|
+
authenticate_client(conn)
|
457
|
+
assert conn.active?
|
458
|
+
assert_equal Mongo::MongoClient::DEFAULT_OP_TIMEOUT, conn.op_timeout
|
459
|
+
|
460
|
+
pool = conn.primary_pool
|
461
|
+
socket = pool.instance_variable_get(:@thread_ids_to_sockets)[Thread.current.object_id]
|
462
|
+
|
463
|
+
socket.stubs(:read).raises(Mongo::OperationTimeout)
|
464
|
+
assert_equal false, conn.active?
|
465
|
+
end
|
466
|
+
|
467
|
+
context "Saved authentications" do
|
468
|
+
setup do
|
469
|
+
@client = Mongo::MongoClient.new
|
470
|
+
|
471
|
+
@auth = {
|
472
|
+
:db_name => TEST_DB,
|
473
|
+
:username => TEST_USER,
|
474
|
+
:password => TEST_USER_PWD,
|
475
|
+
:source => TEST_DB,
|
476
|
+
:mechanism => 'MONGODB-CR'
|
477
|
+
}
|
478
|
+
|
479
|
+
@client.auths << @auth
|
480
|
+
end
|
481
|
+
|
482
|
+
should "save and validate the authentication" do
|
483
|
+
assert_equal Authentication.validate_credentials(@auth), @client.auths.first
|
484
|
+
end
|
485
|
+
|
486
|
+
should "not allow multiple authentications for the same db" do
|
487
|
+
auth = {
|
488
|
+
:db_name => TEST_DB,
|
489
|
+
:username => TEST_USER,
|
490
|
+
:password => TEST_USER_PWD,
|
491
|
+
:source => TEST_DB,
|
492
|
+
:mechanism => nil
|
493
|
+
}
|
494
|
+
|
495
|
+
assert_raise Mongo::MongoArgumentError do
|
496
|
+
@client.add_auth(
|
497
|
+
auth[:db_name],
|
498
|
+
auth[:username],
|
499
|
+
auth[:password],
|
500
|
+
auth[:source],
|
501
|
+
auth[:mechanism])
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
should "remove auths by database" do
|
506
|
+
@client.remove_auth('non-existent database')
|
507
|
+
assert_equal 1, @client.auths.length
|
508
|
+
|
509
|
+
@client.remove_auth(TEST_DB)
|
510
|
+
assert_equal 0, @client.auths.length
|
511
|
+
end
|
512
|
+
|
513
|
+
should "remove all auths" do
|
514
|
+
@client.clear_auths
|
515
|
+
assert_equal 0, @client.auths.length
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
context "Socket pools" do
|
520
|
+
context "checking out writers" do
|
521
|
+
setup do
|
522
|
+
@con = standard_connection(:pool_size => 10, :pool_timeout => 2)
|
523
|
+
@coll = @con[TEST_DB]['test-connection-exceptions']
|
524
|
+
end
|
525
|
+
|
526
|
+
should "close the connection on send_message for major exceptions" do
|
527
|
+
@con.stubs(:checkout_writer).raises(SystemStackError)
|
528
|
+
@con.stubs(:checkout_reader).raises(SystemStackError)
|
529
|
+
@con.expects(:close)
|
530
|
+
begin
|
531
|
+
@coll.insert({:foo => "bar"})
|
532
|
+
rescue SystemStackError
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
context "with GLE" do
|
537
|
+
setup do
|
538
|
+
# Force this connection to use send_message_with_gle for these tests
|
539
|
+
@con.stubs(:use_write_command?).returns(false)
|
540
|
+
end
|
541
|
+
|
542
|
+
should "close the connection on send_message_with_gle for major exceptions" do
|
543
|
+
@con.stubs(:checkout_writer).raises(SystemStackError)
|
544
|
+
@con.stubs(:checkout_reader).raises(SystemStackError)
|
545
|
+
@con.expects(:close)
|
546
|
+
begin
|
547
|
+
@coll.insert({:foo => "bar"}, :w => 1)
|
548
|
+
rescue SystemStackError
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
should "release the connection on send_message_with_gle for connection exceptions" do
|
553
|
+
mock_writer = mock(:close => true)
|
554
|
+
mock_writer.expects(:read).raises(ConnectionFailure)
|
555
|
+
@con.expects(:send_message_on_socket)
|
556
|
+
|
557
|
+
@con.stubs(:checkout_writer).returns(mock_writer)
|
558
|
+
@con.expects(:checkin).with(mock_writer)
|
559
|
+
@coll.insert({:foo => "bar"}, :w => 1) rescue nil
|
560
|
+
end
|
561
|
+
|
562
|
+
should "release the connection on send_message_with_gle for all exceptions" do
|
563
|
+
mock_writer = mock()
|
564
|
+
mock_writer.expects(:read).raises(ArgumentError)
|
565
|
+
@con.expects(:send_message_on_socket)
|
566
|
+
@con.stubs(:checkout_writer).returns(mock_writer)
|
567
|
+
@con.expects(:checkin).with(mock_writer).once
|
568
|
+
begin
|
569
|
+
@coll.insert({:foo => "bar"}, :w => 1)
|
570
|
+
rescue ArgumentError
|
571
|
+
end
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
should "close the connection on receive_message for major exceptions" do
|
576
|
+
@con.expects(:checkout_reader).raises(SystemStackError)
|
577
|
+
@con.expects(:close)
|
578
|
+
begin
|
579
|
+
@coll.find.next
|
580
|
+
rescue SystemStackError
|
581
|
+
end
|
582
|
+
end
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
context "Connection exceptions" do
|
587
|
+
setup do
|
588
|
+
@con = MongoClient.new(TEST_HOST, TEST_PORT, :pool_size => 10, :pool_timeout => 10)
|
589
|
+
@coll = @con[TEST_DB]['test-connection-exceptions']
|
590
|
+
end
|
591
|
+
|
592
|
+
should "release connection if an exception is raised on send_message" do
|
593
|
+
@con.stubs(:send_message_on_socket).raises(ConnectionFailure)
|
594
|
+
assert_equal 0, @con.primary_pool.checked_out.size
|
595
|
+
assert_raise ConnectionFailure do
|
596
|
+
@coll.insert({:test => "insert"})
|
597
|
+
end
|
598
|
+
assert_equal 0, @con.primary_pool.checked_out.size
|
599
|
+
end
|
600
|
+
|
601
|
+
should "release connection if an exception is raised on write concern :w => 1" do
|
602
|
+
@con.stubs(:receive).raises(ConnectionFailure)
|
603
|
+
assert_equal 0, @con.primary_pool.checked_out.size
|
604
|
+
assert_raise ConnectionFailure do
|
605
|
+
@coll.insert({:test => "insert"}, :w => 1)
|
606
|
+
end
|
607
|
+
assert_equal 0, @con.primary_pool.checked_out.size
|
608
|
+
end
|
609
|
+
|
610
|
+
should "release connection if an exception is raised on receive_message" do
|
611
|
+
@con.stubs(:receive).raises(ConnectionFailure)
|
612
|
+
assert_equal 0, @con.read_pool.checked_out.size
|
613
|
+
assert_raise ConnectionFailure do
|
614
|
+
@coll.find.to_a
|
615
|
+
end
|
616
|
+
assert_equal 0, @con.read_pool.checked_out.size
|
617
|
+
end
|
618
|
+
|
619
|
+
should "show a proper exception message if an IOError is raised while closing a socket" do
|
620
|
+
TCPSocket.any_instance.stubs(:close).raises(IOError.new)
|
621
|
+
|
622
|
+
@con.primary_pool.checkout_new_socket
|
623
|
+
@con.primary_pool.expects(:warn)
|
624
|
+
assert @con.primary_pool.close
|
625
|
+
end
|
626
|
+
end
|
627
|
+
end
|