mongo 1.10.0-java

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.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +190 -0
  5. data/README.md +149 -0
  6. data/Rakefile +31 -0
  7. data/VERSION +1 -0
  8. data/bin/mongo_console +43 -0
  9. data/ext/jsasl/target/jsasl.jar +0 -0
  10. data/lib/mongo.rb +90 -0
  11. data/lib/mongo/bulk_write_collection_view.rb +380 -0
  12. data/lib/mongo/collection.rb +1164 -0
  13. data/lib/mongo/collection_writer.rb +364 -0
  14. data/lib/mongo/connection.rb +19 -0
  15. data/lib/mongo/connection/node.rb +239 -0
  16. data/lib/mongo/connection/pool.rb +347 -0
  17. data/lib/mongo/connection/pool_manager.rb +325 -0
  18. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  21. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  22. data/lib/mongo/connection/socket/tcp_socket.rb +86 -0
  23. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  24. data/lib/mongo/cursor.rb +719 -0
  25. data/lib/mongo/db.rb +735 -0
  26. data/lib/mongo/exception.rb +88 -0
  27. data/lib/mongo/functional.rb +21 -0
  28. data/lib/mongo/functional/authentication.rb +318 -0
  29. data/lib/mongo/functional/logging.rb +85 -0
  30. data/lib/mongo/functional/read_preference.rb +174 -0
  31. data/lib/mongo/functional/sasl_java.rb +48 -0
  32. data/lib/mongo/functional/uri_parser.rb +374 -0
  33. data/lib/mongo/functional/write_concern.rb +66 -0
  34. data/lib/mongo/gridfs.rb +18 -0
  35. data/lib/mongo/gridfs/grid.rb +112 -0
  36. data/lib/mongo/gridfs/grid_ext.rb +53 -0
  37. data/lib/mongo/gridfs/grid_file_system.rb +163 -0
  38. data/lib/mongo/gridfs/grid_io.rb +484 -0
  39. data/lib/mongo/legacy.rb +140 -0
  40. data/lib/mongo/mongo_client.rb +702 -0
  41. data/lib/mongo/mongo_replica_set_client.rb +523 -0
  42. data/lib/mongo/mongo_sharded_client.rb +159 -0
  43. data/lib/mongo/networking.rb +370 -0
  44. data/lib/mongo/utils.rb +19 -0
  45. data/lib/mongo/utils/conversions.rb +110 -0
  46. data/lib/mongo/utils/core_ext.rb +70 -0
  47. data/lib/mongo/utils/server_version.rb +69 -0
  48. data/lib/mongo/utils/support.rb +80 -0
  49. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  50. data/mongo.gemspec +36 -0
  51. data/test/functional/authentication_test.rb +35 -0
  52. data/test/functional/bulk_api_stress_test.rb +133 -0
  53. data/test/functional/bulk_write_collection_view_test.rb +1129 -0
  54. data/test/functional/client_test.rb +565 -0
  55. data/test/functional/collection_test.rb +2073 -0
  56. data/test/functional/collection_writer_test.rb +83 -0
  57. data/test/functional/conversions_test.rb +163 -0
  58. data/test/functional/cursor_fail_test.rb +63 -0
  59. data/test/functional/cursor_message_test.rb +57 -0
  60. data/test/functional/cursor_test.rb +625 -0
  61. data/test/functional/db_api_test.rb +819 -0
  62. data/test/functional/db_connection_test.rb +27 -0
  63. data/test/functional/db_test.rb +344 -0
  64. data/test/functional/grid_file_system_test.rb +285 -0
  65. data/test/functional/grid_io_test.rb +252 -0
  66. data/test/functional/grid_test.rb +273 -0
  67. data/test/functional/pool_test.rb +62 -0
  68. data/test/functional/safe_test.rb +98 -0
  69. data/test/functional/ssl_test.rb +29 -0
  70. data/test/functional/support_test.rb +62 -0
  71. data/test/functional/timeout_test.rb +58 -0
  72. data/test/functional/uri_test.rb +330 -0
  73. data/test/functional/write_concern_test.rb +118 -0
  74. data/test/helpers/general.rb +50 -0
  75. data/test/helpers/test_unit.rb +317 -0
  76. data/test/replica_set/authentication_test.rb +35 -0
  77. data/test/replica_set/basic_test.rb +174 -0
  78. data/test/replica_set/client_test.rb +341 -0
  79. data/test/replica_set/complex_connect_test.rb +77 -0
  80. data/test/replica_set/connection_test.rb +138 -0
  81. data/test/replica_set/count_test.rb +64 -0
  82. data/test/replica_set/cursor_test.rb +212 -0
  83. data/test/replica_set/insert_test.rb +140 -0
  84. data/test/replica_set/max_values_test.rb +145 -0
  85. data/test/replica_set/pinning_test.rb +55 -0
  86. data/test/replica_set/query_test.rb +73 -0
  87. data/test/replica_set/read_preference_test.rb +214 -0
  88. data/test/replica_set/refresh_test.rb +175 -0
  89. data/test/replica_set/replication_ack_test.rb +94 -0
  90. data/test/replica_set/ssl_test.rb +32 -0
  91. data/test/sharded_cluster/basic_test.rb +197 -0
  92. data/test/shared/authentication/basic_auth_shared.rb +286 -0
  93. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  94. data/test/shared/authentication/gssapi_shared.rb +164 -0
  95. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  96. data/test/shared/ssl_shared.rb +235 -0
  97. data/test/test_helper.rb +56 -0
  98. data/test/threading/basic_test.rb +120 -0
  99. data/test/tools/mongo_config.rb +608 -0
  100. data/test/tools/mongo_config_test.rb +160 -0
  101. data/test/unit/client_test.rb +347 -0
  102. data/test/unit/collection_test.rb +166 -0
  103. data/test/unit/connection_test.rb +325 -0
  104. data/test/unit/cursor_test.rb +299 -0
  105. data/test/unit/db_test.rb +136 -0
  106. data/test/unit/grid_test.rb +76 -0
  107. data/test/unit/mongo_sharded_client_test.rb +48 -0
  108. data/test/unit/node_test.rb +93 -0
  109. data/test/unit/pool_manager_test.rb +142 -0
  110. data/test/unit/read_pref_test.rb +115 -0
  111. data/test/unit/read_test.rb +159 -0
  112. data/test/unit/safe_test.rb +158 -0
  113. data/test/unit/sharding_pool_manager_test.rb +84 -0
  114. data/test/unit/write_concern_test.rb +175 -0
  115. metadata +260 -0
  116. metadata.gz.sig +0 -0
@@ -0,0 +1,565 @@
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_connection_uri
78
+ con = MongoClient.from_uri("mongodb://#{host_port}")
79
+ assert_equal mongo_host, con.primary_pool.host
80
+ assert_equal mongo_port, con.primary_pool.port
81
+ end
82
+
83
+ def test_uri_with_extra_opts
84
+ con = MongoClient.from_uri("mongodb://#{host_port}", :pool_size => 10, :slave_ok => true)
85
+ assert_equal 10, con.pool_size
86
+ assert con.slave_ok?
87
+ end
88
+
89
+ def test_env_mongodb_uri
90
+ uri = "mongodb://#{host_port}"
91
+ with_preserved_env_uri(uri) do
92
+ con = MongoClient.new
93
+ assert_equal mongo_host, con.primary_pool.host
94
+ assert_equal mongo_port, con.primary_pool.port
95
+ end
96
+ end
97
+
98
+ def test_from_uri_implicit_mongodb_uri
99
+ uri = "mongodb://#{host_port}"
100
+ with_preserved_env_uri(uri) do
101
+ con = MongoClient.from_uri
102
+ assert_equal mongo_host, con.primary_pool.host
103
+ assert_equal mongo_port, con.primary_pool.port
104
+ end
105
+ end
106
+
107
+ def test_db_from_uri_exists_no_options
108
+ db_name = "_database"
109
+ uri = "mongodb://#{host_port}/#{db_name}"
110
+ with_preserved_env_uri(uri) do
111
+ con = MongoClient.from_uri
112
+ db = con.db
113
+ assert_equal db.name, db_name
114
+ end
115
+ end
116
+
117
+ def test_db_from_uri_exists_options
118
+ db_name = "_database"
119
+ uri = "mongodb://#{host_port}/#{db_name}?"
120
+ with_preserved_env_uri(uri) do
121
+ con = MongoClient.from_uri
122
+ db = con.db
123
+ assert_equal db.name, db_name
124
+ end
125
+ end
126
+
127
+ def test_db_from_uri_exists_no_db_name
128
+ uri = "mongodb://#{host_port}/"
129
+ with_preserved_env_uri(uri) do
130
+ con = MongoClient.from_uri
131
+ db = con.db
132
+ assert_equal db.name, MongoClient::DEFAULT_DB_NAME
133
+ end
134
+ end
135
+
136
+ def test_db_from_uri_from_string_param
137
+ db_name = "_database"
138
+ db = MongoClient.from_uri("mongodb://#{host_port}/#{db_name}").db
139
+ assert_equal db.name, db_name
140
+ end
141
+
142
+ def test_db_from_uri_from_string_param_no_db_name
143
+ db = MongoClient.from_uri("mongodb://#{host_port}").db
144
+ assert_equal db.name, MongoClient::DEFAULT_DB_NAME
145
+ end
146
+
147
+ def test_from_uri_write_concern
148
+ con = MongoClient.from_uri("mongodb://#{host_port}")
149
+ db = con.db
150
+ coll = db.collection('from-uri-test')
151
+ assert_equal BSON::ObjectId, coll.insert({'a' => 1}).class
152
+ [con, db, coll].each do |component|
153
+ component.write_concern.each do |key,value|
154
+ assert_not_nil(value, "component #{component.class.inspect} should not have write concern #{key.inspect} field with nil value")
155
+ end
156
+ end
157
+ assert_equal({:w => 1}, con.write_concern, "write concern should not have extra pairs that were not specified by the user")
158
+ assert_equal({:w => 1}, db.write_concern, "write concern should not have extra pairs that were not specified by the user")
159
+ assert_equal({:w => 1}, coll.write_concern, "write concern should not have extra pairs that were not specified by the user")
160
+ end
161
+
162
+ def test_server_version
163
+ assert_match(/\d\.\d+(\.\d+)?/, @client.server_version.to_s)
164
+ end
165
+
166
+ def test_invalid_database_names
167
+ assert_raise TypeError do @client.db(4) end
168
+
169
+ assert_raise Mongo::InvalidNSName do @client.db('') end
170
+ assert_raise Mongo::InvalidNSName do @client.db('te$t') end
171
+ assert_raise Mongo::InvalidNSName do @client.db('te.t') end
172
+ assert_raise Mongo::InvalidNSName do @client.db('te\\t') end
173
+ assert_raise Mongo::InvalidNSName do @client.db('te/t') end
174
+ assert_raise Mongo::InvalidNSName do @client.db('te st') end
175
+ end
176
+
177
+ def test_options_passed_to_db
178
+ @pk_mock = Object.new
179
+ db = @client.db('test', :pk => @pk_mock, :strict => true)
180
+ assert_equal @pk_mock, db.pk_factory
181
+ assert db.strict?
182
+ end
183
+
184
+ def test_database_info
185
+ @client.drop_database(TEST_DB)
186
+ @client.db(TEST_DB).collection('info-test').insert('a' => 1)
187
+
188
+ info = @client.database_info
189
+ assert_not_nil info
190
+ assert_kind_of Hash, info
191
+ assert_not_nil info[TEST_DB]
192
+ assert info[TEST_DB] > 0
193
+
194
+ @client.drop_database(TEST_DB)
195
+ end
196
+
197
+ def test_copy_database
198
+ old_name = TEST_DB + '_old'
199
+ new_name = TEST_DB + '_new'
200
+
201
+ @client.drop_database(new_name)
202
+ @client.db(old_name).collection('copy-test').insert('a' => 1)
203
+ @client.copy_database(old_name, new_name, host_port)
204
+
205
+ old_object = @client.db(old_name).collection('copy-test').find.next_document
206
+ new_object = @client.db(new_name).collection('copy-test').find.next_document
207
+ assert_equal old_object, new_object
208
+ end
209
+
210
+ def test_database_names
211
+ @client.drop_database(TEST_DB)
212
+ @client.db(TEST_DB).collection('info-test').insert('a' => 1)
213
+
214
+ names = @client.database_names
215
+ assert_not_nil names
216
+ assert_kind_of Array, names
217
+ assert names.length >= 1
218
+ assert names.include?(TEST_DB)
219
+ end
220
+
221
+ def test_logging
222
+ output = StringIO.new
223
+ logger = Logger.new(output)
224
+ logger.level = Logger::DEBUG
225
+ standard_connection(:logger => logger).db(TEST_DB)
226
+ assert output.string.include?("admin['$cmd'].find")
227
+ end
228
+
229
+ def test_logging_duration
230
+ output = StringIO.new
231
+ logger = Logger.new(output)
232
+ logger.level = Logger::DEBUG
233
+ standard_connection(:logger => logger).db(TEST_DB)
234
+ assert_match(/\(\d+.\d{1}ms\)/, output.string)
235
+ assert output.string.include?("admin['$cmd'].find")
236
+ end
237
+
238
+ def test_connection_logger
239
+ output = StringIO.new
240
+ logger = Logger.new(output)
241
+ logger.level = Logger::DEBUG
242
+ connection = standard_connection(:logger => logger)
243
+ assert_equal logger, connection.logger
244
+
245
+ connection.logger.debug 'testing'
246
+ assert output.string.include?('testing')
247
+ end
248
+
249
+ def test_drop_database
250
+ db = @client.db(TEST_DB + '_drop_test')
251
+ coll = db.collection('temp')
252
+ coll.remove
253
+ coll.insert(:name => 'temp')
254
+ assert_equal 1, coll.count()
255
+ assert @client.database_names.include?(TEST_DB + '_drop_test')
256
+
257
+ @client.drop_database(TEST_DB + '_drop_test')
258
+ assert !@client.database_names.include?(TEST_DB + '_drop_test')
259
+ end
260
+
261
+ def test_nodes
262
+ silently do
263
+ @client = MongoClient.multi([['foo', 27017], ['bar', 27018]], :connect => false)
264
+ end
265
+ seeds = @client.seeds
266
+ assert_equal 2, seeds.length
267
+ assert_equal ['foo', 27017], seeds[0]
268
+ assert_equal ['bar', 27018], seeds[1]
269
+ end
270
+
271
+ def test_fsync_lock
272
+ assert !@client.locked?
273
+ @client.lock!
274
+ assert @client.locked?
275
+ assert [1, true].include?(@client['admin']['$cmd.sys.inprog'].find_one['fsyncLock'])
276
+ assert_match(/unlock/, @client.unlock!['info'])
277
+ unlocked = false
278
+ counter = 0
279
+ while counter < 100
280
+ if @client['admin']['$cmd.sys.inprog'].find_one['fsyncLock'].nil?
281
+ unlocked = true
282
+ break
283
+ else
284
+ counter += 1
285
+ end
286
+ end
287
+ assert !@client.locked?
288
+ assert unlocked, "mongod failed to unlock"
289
+ end
290
+
291
+ def test_max_bson_size_value
292
+ conn = standard_connection(:connect => false)
293
+
294
+ admin_db = Object.new
295
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxBsonObjectSize' => 15_000_000})
296
+ conn.expects(:[]).with('admin').returns(admin_db)
297
+ conn.connect
298
+ assert_equal 15_000_000, conn.max_bson_size
299
+
300
+ conn = standard_connection
301
+ if conn.server_version > "1.7.2"
302
+ assert_equal conn['admin'].command({:ismaster => 1})['maxBsonObjectSize'], conn.max_bson_size
303
+ end
304
+ end
305
+
306
+ def test_max_message_size_value
307
+ conn = standard_connection(:connect => false)
308
+
309
+ admin_db = Object.new
310
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxMessageSizeBytes' => 20_000_000})
311
+ conn.expects(:[]).with('admin').returns(admin_db)
312
+ conn.connect
313
+
314
+ assert_equal 20_000_000, conn.max_message_size
315
+
316
+ conn = standard_connection
317
+ maxMessageSizeBytes = conn['admin'].command({:ismaster => 1})['maxMessageSizeBytes']
318
+ if conn.server_version.to_s[/([^-]+)/,1] >= "2.4.0"
319
+ assert_equal 48_000_000, maxMessageSizeBytes
320
+ elsif conn.server_version > "2.3.2"
321
+ assert_equal conn.max_bson_size, maxMessageSizeBytes
322
+ end
323
+ end
324
+
325
+ def test_max_bson_size_with_no_reported_max_size
326
+ conn = standard_connection(:connect => false)
327
+
328
+ admin_db = Object.new
329
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
330
+ conn.expects(:[]).with('admin').returns(admin_db)
331
+
332
+ conn.connect
333
+ assert_equal Mongo::DEFAULT_MAX_BSON_SIZE, conn.max_bson_size
334
+ end
335
+
336
+ def test_max_message_size_with_no_reported_max_size
337
+ conn = standard_connection(:connect => false)
338
+
339
+ admin_db = Object.new
340
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
341
+ conn.expects(:[]).with('admin').returns(admin_db)
342
+
343
+ conn.connect
344
+ assert_equal Mongo::DEFAULT_MAX_BSON_SIZE * Mongo::MESSAGE_SIZE_FACTOR, conn.max_message_size
345
+ end
346
+
347
+ def test_max_wire_version_and_min_wire_version_values
348
+ conn = standard_connection(:connect => false)
349
+
350
+ admin_db = Object.new
351
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxWireVersion' => 1, 'minWireVersion' => 1, 'maxWriteBatchSize' => 999})
352
+ conn.expects(:[]).with('admin').returns(admin_db)
353
+ conn.connect
354
+
355
+ assert_equal 1, conn.max_wire_version
356
+ assert_equal 1, conn.min_wire_version
357
+ assert_equal 999, conn.max_write_batch_size
358
+ end
359
+
360
+ def test_max_wire_version_and_min_wire_version_values_with_no_reported_values
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
+ conn.connect
367
+
368
+ assert_equal 0, conn.max_wire_version
369
+ assert_equal 0, conn.min_wire_version
370
+ assert_equal Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE, conn.max_write_batch_size
371
+ end
372
+
373
+ def test_wire_version_feature
374
+ conn = standard_connection(:connect => false)
375
+ conn.stubs(:min_wire_version).returns(0)
376
+ conn.stubs(:max_wire_version).returns(1)
377
+ assert_true conn.wire_version_feature?(0)
378
+ assert_true conn.wire_version_feature?(1)
379
+ assert_false conn.wire_version_feature?(2)
380
+ assert_false conn.wire_version_feature?(-1)
381
+ end
382
+
383
+ def test_wire_version_not_in_range
384
+ [
385
+ [Mongo::MongoClient::MAX_WIRE_VERSION+1, Mongo::MongoClient::MAX_WIRE_VERSION+1],
386
+ [Mongo::MongoClient::MIN_WIRE_VERSION-1, Mongo::MongoClient::MIN_WIRE_VERSION-1]
387
+ ].each do |min_wire_version, max_wire_version|
388
+ conn = standard_connection(:connect => false)
389
+ admin_db = Object.new
390
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version})
391
+ conn.expects(:[]).with('admin').returns(admin_db)
392
+ assert_raises Mongo::ConnectionFailure do
393
+ conn.connect
394
+ end
395
+ end
396
+ end
397
+
398
+ def test_use_write_command
399
+ with_write_commands(@client) do
400
+ assert_true @client.use_write_command?({:w => 1})
401
+ assert_false @client.use_write_command?({:w => 0})
402
+ end
403
+ with_write_operations(@client) do
404
+ assert_false @client.use_write_command?({:w => 1})
405
+ assert_false @client.use_write_command?({:w => 0})
406
+ end
407
+ end
408
+
409
+ def test_connection_activity
410
+ conn = standard_connection
411
+ assert conn.active?
412
+
413
+ conn.primary_pool.close
414
+ assert !conn.active?
415
+
416
+ # Simulate a dropped connection.
417
+ dropped_socket = mock('dropped_socket')
418
+ dropped_socket.stubs(:read).raises(Errno::ECONNRESET)
419
+ dropped_socket.stubs(:send).raises(Errno::ECONNRESET)
420
+ dropped_socket.stub_everything
421
+
422
+ conn.primary_pool.host = 'localhost'
423
+ conn.primary_pool.port = Mongo::MongoClient::DEFAULT_PORT
424
+ conn.primary_pool.instance_variable_set("@pids", {dropped_socket => Process.pid})
425
+ conn.primary_pool.instance_variable_set("@sockets", [dropped_socket])
426
+
427
+ assert !conn.active?
428
+ end
429
+
430
+ context "Saved authentications" do
431
+ setup do
432
+ @client = standard_connection
433
+
434
+ @auth = {
435
+ :db_name => TEST_DB,
436
+ :username => 'bob',
437
+ :password => 'secret',
438
+ :source => TEST_DB,
439
+ :mechanism => 'MONGODB-CR'
440
+ }
441
+
442
+ @client.auths << @auth
443
+ end
444
+
445
+ teardown do
446
+ @client.clear_auths
447
+ end
448
+
449
+ should "save and validate the authentication" do
450
+ assert_equal Authentication.validate_credentials(@auth), @client.auths.first
451
+ end
452
+
453
+ should "not allow multiple authentications for the same db" do
454
+ auth = {
455
+ :db_name => TEST_DB,
456
+ :username => 'mickey',
457
+ :password => 'm0u53',
458
+ :source => nil,
459
+ :mechanism => nil
460
+ }
461
+
462
+ assert_raise Mongo::MongoArgumentError do
463
+ @client.add_auth(
464
+ auth[:db_name],
465
+ auth[:username],
466
+ auth[:password],
467
+ auth[:source],
468
+ auth[:mechanism])
469
+ end
470
+ end
471
+
472
+ should "remove auths by database" do
473
+ @client.remove_auth('non-existent database')
474
+ assert_equal 1, @client.auths.length
475
+
476
+ @client.remove_auth(TEST_DB)
477
+ assert_equal 0, @client.auths.length
478
+ end
479
+
480
+ should "remove all auths" do
481
+ @client.clear_auths
482
+ assert_equal 0, @client.auths.length
483
+ end
484
+ end
485
+
486
+ context "Socket pools" do
487
+ context "checking out writers" do
488
+ setup do
489
+ @con = standard_connection(:pool_size => 10, :pool_timeout => 10)
490
+ @coll = @con[TEST_DB]['test-connection-exceptions']
491
+ end
492
+
493
+ should "close the connection on send_message for major exceptions" do
494
+ @con.stubs(:checkout_writer).raises(SystemStackError)
495
+ @con.stubs(:checkout_reader).raises(SystemStackError)
496
+ @con.expects(:close)
497
+ begin
498
+ @coll.insert({:foo => "bar"})
499
+ rescue SystemStackError
500
+ end
501
+ end
502
+
503
+ should "close the connection on send_message_with_gle for major exceptions" do
504
+ @con.stubs(:checkout_writer).raises(SystemStackError)
505
+ @con.stubs(:checkout_reader).raises(SystemStackError)
506
+ @con.expects(:close)
507
+ begin
508
+ @coll.insert({:foo => "bar"}, :w => 1)
509
+ rescue SystemStackError
510
+ end
511
+ end
512
+
513
+ should "close the connection on receive_message for major exceptions" do
514
+ @con.expects(:checkout_reader).raises(SystemStackError)
515
+ @con.expects(:close)
516
+ begin
517
+ @coll.find.next
518
+ rescue SystemStackError
519
+ end
520
+ end
521
+ end
522
+ end
523
+
524
+ context "Connection exceptions" do
525
+ setup do
526
+ @con = standard_connection(:pool_size => 10, :pool_timeout => 10)
527
+ @coll = @con[TEST_DB]['test-connection-exceptions']
528
+ end
529
+
530
+ should "release connection if an exception is raised on send_message" do
531
+ @con.stubs(:send_message_on_socket).raises(ConnectionFailure)
532
+ assert_equal 0, @con.primary_pool.checked_out.size
533
+ assert_raise ConnectionFailure do
534
+ @coll.insert({:test => "insert"})
535
+ end
536
+ assert_equal 0, @con.primary_pool.checked_out.size
537
+ end
538
+
539
+ should "release connection if an exception is raised on write concern :w => 1" do
540
+ @con.stubs(:receive).raises(ConnectionFailure)
541
+ assert_equal 0, @con.primary_pool.checked_out.size
542
+ assert_raise ConnectionFailure do
543
+ @coll.insert({:test => "insert"}, :w => 1)
544
+ end
545
+ assert_equal 0, @con.primary_pool.checked_out.size
546
+ end
547
+
548
+ should "release connection if an exception is raised on receive_message" do
549
+ @con.stubs(:receive).raises(ConnectionFailure)
550
+ assert_equal 0, @con.read_pool.checked_out.size
551
+ assert_raise ConnectionFailure do
552
+ @coll.find.to_a
553
+ end
554
+ assert_equal 0, @con.read_pool.checked_out.size
555
+ end
556
+
557
+ should "show a proper exception message if an IOError is raised while closing a socket" do
558
+ TCPSocket.any_instance.stubs(:close).raises(IOError.new)
559
+
560
+ @con.primary_pool.checkout_new_socket
561
+ @con.primary_pool.expects(:warn)
562
+ assert @con.primary_pool.close
563
+ end
564
+ end
565
+ end