mongo 2.11.0 → 2.11.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +24 -0
  5. data/lib/mongo/address.rb +53 -37
  6. data/lib/mongo/auth.rb +30 -10
  7. data/lib/mongo/auth/cr.rb +1 -0
  8. data/lib/mongo/auth/cr/conversation.rb +13 -13
  9. data/lib/mongo/auth/ldap.rb +2 -1
  10. data/lib/mongo/auth/ldap/conversation.rb +9 -12
  11. data/lib/mongo/auth/scram.rb +1 -0
  12. data/lib/mongo/auth/scram/conversation.rb +36 -27
  13. data/lib/mongo/auth/user.rb +7 -1
  14. data/lib/mongo/auth/x509.rb +2 -1
  15. data/lib/mongo/auth/x509/conversation.rb +9 -9
  16. data/lib/mongo/bulk_write/transformable.rb +3 -3
  17. data/lib/mongo/client.rb +17 -6
  18. data/lib/mongo/cluster.rb +67 -49
  19. data/lib/mongo/cluster/sdam_flow.rb +87 -3
  20. data/lib/mongo/collection/view/readable.rb +3 -1
  21. data/lib/mongo/collection/view/writable.rb +3 -3
  22. data/lib/mongo/cursor/builder/kill_cursors_command.rb +8 -1
  23. data/lib/mongo/cursor/builder/op_kill_cursors.rb +8 -1
  24. data/lib/mongo/database.rb +1 -1
  25. data/lib/mongo/grid/file.rb +5 -0
  26. data/lib/mongo/grid/file/chunk.rb +2 -0
  27. data/lib/mongo/grid/fs_bucket.rb +15 -13
  28. data/lib/mongo/grid/stream/write.rb +9 -3
  29. data/lib/mongo/protocol/serializers.rb +12 -2
  30. data/lib/mongo/retryable.rb +33 -8
  31. data/lib/mongo/server.rb +13 -6
  32. data/lib/mongo/server/connection.rb +15 -8
  33. data/lib/mongo/server/connection_base.rb +7 -4
  34. data/lib/mongo/server/description.rb +34 -21
  35. data/lib/mongo/server/monitor.rb +1 -1
  36. data/lib/mongo/server/monitor/connection.rb +2 -3
  37. data/lib/mongo/session.rb +10 -10
  38. data/lib/mongo/socket.rb +10 -1
  39. data/lib/mongo/uri.rb +1 -1
  40. data/lib/mongo/version.rb +1 -1
  41. data/mongo.gemspec +1 -1
  42. data/spec/README.md +13 -0
  43. data/spec/integration/auth_spec.rb +27 -8
  44. data/spec/integration/bson_symbol_spec.rb +34 -0
  45. data/spec/integration/client_construction_spec.rb +14 -0
  46. data/spec/integration/client_options_spec.rb +5 -5
  47. data/spec/integration/connection_spec.rb +57 -9
  48. data/spec/integration/crud_spec.rb +45 -0
  49. data/spec/integration/cursor_reaping_spec.rb +2 -1
  50. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  51. data/spec/integration/retryable_errors_spec.rb +204 -39
  52. data/spec/integration/retryable_writes_spec.rb +36 -36
  53. data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +98 -0
  54. data/spec/lite_spec_helper.rb +1 -0
  55. data/spec/mongo/address_spec.rb +19 -13
  56. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  57. data/spec/mongo/auth/scram/conversation_spec.rb +25 -14
  58. data/spec/mongo/auth/user/view_spec.rb +36 -1
  59. data/spec/mongo/auth/user_spec.rb +12 -0
  60. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  61. data/spec/mongo/bulk_write_spec.rb +2 -2
  62. data/spec/mongo/client_construction_spec.rb +1 -21
  63. data/spec/mongo/cluster_spec.rb +57 -0
  64. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  65. data/spec/mongo/collection_spec.rb +26 -2
  66. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +56 -0
  67. data/spec/mongo/server/connection_spec.rb +76 -8
  68. data/spec/mongo/server/monitor/connection_spec.rb +14 -7
  69. data/spec/mongo/socket/ssl_spec.rb +132 -98
  70. data/spec/mongo/socket/tcp_spec.rb +1 -9
  71. data/spec/mongo/uri_spec.rb +1 -1
  72. data/spec/runners/sdam/verifier.rb +91 -0
  73. data/spec/spec_tests/data/sdam/rs/primary_address_change.yml +29 -0
  74. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +27 -23
  75. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +56 -79
  76. data/spec/spec_tests/data/sdam/sharded/primary_address_change.yml +21 -0
  77. data/spec/spec_tests/data/sdam/sharded/primary_mismatched_me.yml +22 -0
  78. data/spec/spec_tests/data/sdam/single/primary_address_change.yml +24 -0
  79. data/spec/spec_tests/data/sdam/single/primary_mismatched_me.yml +25 -0
  80. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +159 -0
  81. data/spec/spec_tests/data/sdam_monitoring/{replica_set_other_seed.yml → replica_set_with_primary_change.yml} +97 -101
  82. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +22 -18
  83. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +90 -0
  84. data/spec/spec_tests/sdam_monitoring_spec.rb +9 -4
  85. data/spec/support/cluster_config.rb +36 -0
  86. data/spec/support/cluster_tools.rb +5 -3
  87. data/spec/support/command_monitoring.rb +1 -1
  88. data/spec/support/constraints.rb +18 -18
  89. data/spec/support/lite_constraints.rb +8 -0
  90. data/spec/support/sdam_monitoring.rb +0 -115
  91. data/spec/support/server_discovery_and_monitoring.rb +2 -0
  92. data/spec/support/spec_config.rb +1 -1
  93. data/spec/support/utils.rb +11 -1
  94. metadata +687 -659
  95. metadata.gz.sig +3 -2
@@ -102,22 +102,22 @@ describe 'Retryable writes integration tests' do
102
102
  end
103
103
 
104
104
  it 'does not retry writes' do
105
- expect {
105
+ expect do
106
106
  operation
107
- }.to raise_error(Mongo::Error::OperationFailure, /other error/)
107
+ end.to raise_error(Mongo::Error::OperationFailure, /other error/)
108
108
  expect(expectation).to eq(unsuccessful_retry_value)
109
109
  end
110
110
 
111
111
  it 'indicates server used for operation' do
112
- expect {
112
+ expect do
113
113
  operation
114
- }.to raise_error(Mongo::Error::OperationFailure, /on #{ClusterConfig.instance.primary_address_str}/)
114
+ end.to raise_error(Mongo::Error::OperationFailure, /on #{ClusterConfig.instance.primary_address_str}/)
115
115
  end
116
116
 
117
117
  it 'indicates first attempt' do
118
- expect {
118
+ expect do
119
119
  operation
120
- }.to raise_error(Mongo::Error::OperationFailure, /attempt 1/)
120
+ end.to raise_error(Mongo::Error::OperationFailure, /attempt 1/)
121
121
  end
122
122
  end
123
123
  end
@@ -144,9 +144,9 @@ describe 'Retryable writes integration tests' do
144
144
  end
145
145
 
146
146
  it 'does not retry writes and raises the original error' do
147
- expect {
147
+ expect do
148
148
  operation
149
- }.to raise_error(error)
149
+ end.to raise_error(error)
150
150
  expect(expectation).to eq(unsuccessful_retry_value)
151
151
  end
152
152
  end
@@ -158,9 +158,9 @@ describe 'Retryable writes integration tests' do
158
158
  end
159
159
 
160
160
  it 'does not retry writes and raises the original error' do
161
- expect {
161
+ expect do
162
162
  operation
163
- }.to raise_error(error)
163
+ end.to raise_error(error)
164
164
  expect(expectation).to eq(unsuccessful_retry_value)
165
165
  end
166
166
  end
@@ -172,9 +172,9 @@ describe 'Retryable writes integration tests' do
172
172
  end
173
173
 
174
174
  it 'does not retry writes and raises the original error' do
175
- expect {
175
+ expect do
176
176
  operation
177
- }.to raise_error(error)
177
+ end.to raise_error(error)
178
178
  expect(expectation).to eq(unsuccessful_retry_value)
179
179
  end
180
180
  end
@@ -211,22 +211,22 @@ describe 'Retryable writes integration tests' do
211
211
  end
212
212
 
213
213
  it 'raises the second error' do
214
- expect {
214
+ expect do
215
215
  operation
216
- }.to raise_error(second_error)
216
+ end.to raise_error(second_error)
217
217
  expect(expectation).to eq(unsuccessful_retry_value)
218
218
  end
219
219
 
220
220
  it 'indicates server used for operation' do
221
- expect {
221
+ expect do
222
222
  operation
223
- }.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
223
+ end.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
224
224
  end
225
225
 
226
226
  it 'indicates second attempt' do
227
- expect {
227
+ expect do
228
228
  operation
229
- }.to raise_error(Mongo::Error, /attempt 2/)
229
+ end.to raise_error(Mongo::Error, /attempt 2/)
230
230
  end
231
231
  end
232
232
 
@@ -237,9 +237,9 @@ describe 'Retryable writes integration tests' do
237
237
  end
238
238
 
239
239
  it 'raises the second error' do
240
- expect {
240
+ expect do
241
241
  operation
242
- }.to raise_error(second_error)
242
+ end.to raise_error(second_error)
243
243
  expect(expectation).to eq(unsuccessful_retry_value)
244
244
  end
245
245
  end
@@ -251,9 +251,9 @@ describe 'Retryable writes integration tests' do
251
251
  end
252
252
 
253
253
  it 'raises the second error' do
254
- expect {
254
+ expect do
255
255
  operation
256
- }.to raise_error(second_error)
256
+ end.to raise_error(second_error)
257
257
  expect(expectation).to eq(unsuccessful_retry_value)
258
258
  end
259
259
  end
@@ -265,9 +265,9 @@ describe 'Retryable writes integration tests' do
265
265
  end
266
266
 
267
267
  it 'does not retry writes and raises the first error' do
268
- expect {
268
+ expect do
269
269
  operation
270
- }.to raise_error(error)
270
+ end.to raise_error(error)
271
271
  expect(expectation).to eq(unsuccessful_retry_value)
272
272
  end
273
273
  end
@@ -279,28 +279,28 @@ describe 'Retryable writes integration tests' do
279
279
  end
280
280
 
281
281
  it 'raises the first error' do
282
- expect {
282
+ expect do
283
283
  operation
284
- }.to raise_error(error)
284
+ end.to raise_error(error)
285
285
  expect(expectation).to eq(unsuccessful_retry_value)
286
286
  end
287
287
 
288
288
  it 'indicates server used for operation' do
289
- expect {
289
+ expect do
290
290
  operation
291
- }.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
291
+ end.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
292
292
  end
293
293
 
294
294
  it 'indicates first attempt' do
295
- expect {
295
+ expect do
296
296
  operation
297
- }.to raise_error(Mongo::Error, /attempt 1/)
297
+ end.to raise_error(Mongo::Error, /attempt 1/)
298
298
  end
299
299
 
300
300
  it 'indicates retry was performed' do
301
- expect {
301
+ expect do
302
302
  operation
303
- }.to raise_error(Mongo::Error, /later retry failed: StandardError/)
303
+ end.to raise_error(Mongo::Error, /later retry failed: StandardError/)
304
304
  end
305
305
  end
306
306
  end
@@ -319,9 +319,9 @@ describe 'Retryable writes integration tests' do
319
319
  end
320
320
 
321
321
  it 'does not retry writes' do
322
- expect {
322
+ expect do
323
323
  operation
324
- }.to raise_error(Mongo::Error::SocketError)
324
+ end.to raise_error(Mongo::Error::SocketError)
325
325
  expect(expectation).to eq(unsuccessful_retry_value)
326
326
  end
327
327
  end
@@ -341,9 +341,9 @@ describe 'Retryable writes integration tests' do
341
341
  end
342
342
 
343
343
  it 'does not retry writes' do
344
- expect {
344
+ expect do
345
345
  operation
346
- }.to raise_error(Mongo::Error::SocketError)
346
+ end.to raise_error(Mongo::Error::SocketError)
347
347
  expect(expectation).to eq(unsuccessful_retry_value)
348
348
  end
349
349
  end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'BSON & command size limits' do
4
+ let(:max_document_size) { 16*1024*1024 }
5
+
6
+ before do
7
+ authorized_collection.delete_many
8
+ end
9
+
10
+ # This test uses a large document that is significantly smaller than the
11
+ # size limit. It is a basic sanity check.
12
+ it 'allows user-provided documents to be 15MiB' do
13
+ document = { key: 'a' * 15*1024*1024, _id: 'foo' }
14
+
15
+ authorized_collection.insert_one(document)
16
+ end
17
+
18
+ # This test uses a large document that is significantly larger than the
19
+ # size limit. It is a basic sanity check.
20
+ it 'fails single write of oversized documents' do
21
+ document = { key: 'a' * 17*1024*1024, _id: 'foo' }
22
+
23
+ lambda do
24
+ authorized_collection.insert_one(document)
25
+ end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
26
+ end
27
+
28
+ # This test checks our bulk write splitting when documents are not close
29
+ # to the limit, but where splitting is definitely required.
30
+ it 'allows split bulk write of medium sized documents' do
31
+ # 8 documents of 4 MiB each = 32 MiB total data, should be split over
32
+ # either 2 or 3 bulk writes depending on how well the driver splits
33
+ documents = []
34
+ 1.upto(8) do |index|
35
+ documents << { key: 'a' * 4*1024*1024, _id: "in#{index}" }
36
+ end
37
+
38
+ authorized_collection.insert_many(documents)
39
+ authorized_collection.count_documents({}).should == 8
40
+ end
41
+
42
+ # This test ensures that document which are too big definitely fail insertion.
43
+ it 'fails bulk write of oversized documents' do
44
+ documents = []
45
+ 1.upto(3) do |index|
46
+ documents << { key: 'a' * 17*1024*1024, _id: "in#{index}" }
47
+ end
48
+
49
+ lambda do
50
+ authorized_collection.insert_many(documents)
51
+ end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
52
+ authorized_collection.count_documents({}).should == 0
53
+ end
54
+
55
+ it 'allows user-provided documents to be exactly 16MiB' do
56
+ # The document must contain the _id field, otherwise the server will
57
+ # add it which will increase the size of the document as persisted by
58
+ # the server.
59
+ document = { key: 'a' * (max_document_size - 28), _id: 'foo' }
60
+ expect(document.to_bson.length).to eq(max_document_size)
61
+
62
+ authorized_collection.insert_one(document)
63
+ end
64
+
65
+ it 'fails on the server when a document larger than 16MiB is inserted' do
66
+ document = { key: 'a' * (max_document_size - 27), _id: 'foo' }
67
+ expect(document.to_bson.length).to eq(max_document_size+1)
68
+
69
+ lambda do
70
+ authorized_collection.insert_one(document)
71
+ end.should raise_error(Mongo::Error::OperationFailure, /object to insert too large/)
72
+ end
73
+
74
+ it 'fails in the driver when a document larger than 16MiB+16KiB is inserted' do
75
+ document = { key: 'a' * (max_document_size - 27 + 16*1024), _id: 'foo' }
76
+ expect(document.to_bson.length).to eq(max_document_size+16*1024+1)
77
+
78
+ lambda do
79
+ authorized_collection.insert_one(document)
80
+ end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
81
+ end
82
+
83
+ it 'allows bulk writes of multiple documents of exactly 16 MiB each' do
84
+ if SpecConfig.instance.compressors
85
+ pending "RUBY-2234"
86
+ end
87
+
88
+ documents = []
89
+ 1.upto(3) do |index|
90
+ document = { key: 'a' * (max_document_size - 28), _id: "in#{index}" }
91
+ expect(document.to_bson.length).to eq(max_document_size)
92
+ documents << document
93
+ end
94
+
95
+ authorized_collection.insert_many(documents)
96
+ authorized_collection.count_documents({}).should == 3
97
+ end
98
+ end
@@ -127,6 +127,7 @@ RSpec.configure do |config|
127
127
  end
128
128
 
129
129
  config.expect_with :rspec do |c|
130
+ c.syntax = [:should, :expect]
130
131
  c.max_formatted_output_length = 10000
131
132
  end
132
133
  end
@@ -249,11 +249,7 @@ describe Mongo::Address do
249
249
  end
250
250
  end
251
251
 
252
- context 'when creating a socket using the resolver' do
253
-
254
- before do
255
- address.send(:create_resolver, SpecConfig.instance.ssl_options)
256
- end
252
+ context 'when creating a socket' do
257
253
 
258
254
  it 'uses the host, not the IP address' do
259
255
  expect(address.socket(0.0).host).to eq(socket_address_or_host)
@@ -285,6 +281,24 @@ describe Mongo::Address do
285
281
  end
286
282
  end
287
283
  end
284
+
285
+ describe ':connect_timeout option' do
286
+ clean_slate
287
+
288
+ let(:address) { Mongo::Address.new('127.0.0.1') }
289
+
290
+ it 'defaults to 10' do
291
+ RSpec::Mocks.with_temporary_scope do
292
+ resolved_address = double('address')
293
+ # This test's expectation
294
+ expect(resolved_address).to receive(:socket).with(0, {}, connect_timeout: 10)
295
+
296
+ expect(Mongo::Address::IPv4).to receive(:new).and_return(resolved_address)
297
+
298
+ address.socket(0)
299
+ end
300
+ end
301
+ end
288
302
  end
289
303
 
290
304
  describe '#to_s' do
@@ -320,12 +334,4 @@ describe Mongo::Address do
320
334
  end
321
335
  end
322
336
  end
323
-
324
- describe '#connect_timeout' do
325
- let(:address) { Mongo::Address.new('127.0.0.1') }
326
-
327
- it 'defaults to 10' do
328
- expect(address.send(:connect_timeout)).to eq(10)
329
- end
330
- end
331
337
  end
@@ -17,7 +17,7 @@ describe Mongo::Auth::LDAP::Conversation do
17
17
  describe '#start' do
18
18
 
19
19
  let(:query) do
20
- conversation.start
20
+ conversation.start(nil)
21
21
  end
22
22
 
23
23
  let(:selector) do
@@ -7,6 +7,15 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
7
7
  described_class.new(user, mechanism)
8
8
  end
9
9
 
10
+ let(:connection) do
11
+ double('connection').tap do |connection|
12
+ features = double('features')
13
+ allow(features).to receive(:op_msg_enabled?)
14
+ allow(connection).to receive(:features).and_return(features)
15
+ allow(connection).to receive(:server)
16
+ end
17
+ end
18
+
10
19
  context 'when SCRAM-SHA-1 is used' do
11
20
  min_server_fcv '3.0'
12
21
 
@@ -26,9 +35,11 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
26
35
  end
27
36
 
28
37
  describe '#start' do
38
+ # Test uses global assertions
39
+ clean_slate
29
40
 
30
41
  let(:query) do
31
- conversation.start
42
+ conversation.start(nil)
32
43
  end
33
44
 
34
45
  before do
@@ -85,7 +96,7 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
85
96
  end
86
97
 
87
98
  let(:query) do
88
- conversation.continue(reply)
99
+ conversation.continue(reply, connection)
89
100
  end
90
101
 
91
102
  let(:selector) do
@@ -117,7 +128,7 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
117
128
 
118
129
  it 'raises an error' do
119
130
  expect {
120
- conversation.continue(reply)
131
+ conversation.continue(reply, connection)
121
132
  }.to raise_error(Mongo::Error::InvalidNonce)
122
133
  end
123
134
  end
@@ -170,8 +181,8 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
170
181
  end
171
182
 
172
183
  let(:query) do
173
- conversation.continue(continue_reply)
174
- conversation.finalize(reply)
184
+ conversation.continue(continue_reply, connection)
185
+ conversation.finalize(reply, connection)
175
186
  end
176
187
 
177
188
  let(:selector) do
@@ -199,8 +210,8 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
199
210
 
200
211
  it 'raises an error' do
201
212
  expect {
202
- conversation.continue(continue_reply)
203
- conversation.finalize(reply)
213
+ conversation.continue(continue_reply, connection)
214
+ conversation.finalize(reply, connection)
204
215
  }.to raise_error(Mongo::Error::InvalidSignature)
205
216
  end
206
217
  end
@@ -226,7 +237,7 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
226
237
  describe '#start' do
227
238
 
228
239
  let(:query) do
229
- conversation.start
240
+ conversation.start(nil)
230
241
  end
231
242
 
232
243
  before do
@@ -283,7 +294,7 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
283
294
  end
284
295
 
285
296
  let(:query) do
286
- conversation.continue(reply)
297
+ conversation.continue(reply, connection)
287
298
  end
288
299
 
289
300
  let(:selector) do
@@ -315,7 +326,7 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
315
326
 
316
327
  it 'raises an error' do
317
328
  expect {
318
- conversation.continue(reply)
329
+ conversation.continue(reply, connection)
319
330
  }.to raise_error(Mongo::Error::InvalidNonce)
320
331
  end
321
332
  end
@@ -368,8 +379,8 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
368
379
  end
369
380
 
370
381
  let(:query) do
371
- conversation.continue(continue_reply)
372
- conversation.finalize(reply)
382
+ conversation.continue(continue_reply, connection)
383
+ conversation.finalize(reply, connection)
373
384
  end
374
385
 
375
386
  let(:selector) do
@@ -397,8 +408,8 @@ describe Mongo::Auth::SCRAM::Conversation, retry: 3 do
397
408
 
398
409
  it 'raises an error' do
399
410
  expect {
400
- conversation.continue(continue_reply)
401
- conversation.finalize(reply)
411
+ conversation.continue(continue_reply, connection)
412
+ conversation.finalize(reply, connection)
402
413
  }.to raise_error(Mongo::Error::InvalidSignature)
403
414
  end
404
415
  end