mongo 1.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
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