mongo 1.10.0.rc0 → 1.10.0.rc1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/VERSION +1 -1
- data/lib/mongo/bulk_write_collection_view.rb +31 -3
- data/lib/mongo/collection.rb +69 -25
- data/lib/mongo/collection_writer.rb +3 -2
- data/lib/mongo/connection/node.rb +5 -0
- data/lib/mongo/cursor.rb +4 -1
- data/lib/mongo/db.rb +23 -41
- data/lib/mongo/functional.rb +2 -0
- data/lib/mongo/functional/authentication.rb +18 -3
- data/lib/mongo/functional/sasl_java.rb +48 -0
- data/lib/mongo/functional/uri_parser.rb +62 -50
- data/lib/mongo/mongo_client.rb +24 -9
- data/lib/mongo/mongo_replica_set_client.rb +16 -5
- data/lib/mongo/networking.rb +3 -3
- data/lib/mongo/utils/conversions.rb +2 -1
- data/test/functional/authentication_test.rb +6 -1
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +573 -226
- data/test/functional/client_test.rb +3 -1
- data/test/functional/collection_test.rb +336 -17
- data/test/functional/conversions_test.rb +32 -0
- data/test/functional/cursor_test.rb +3 -3
- data/test/functional/db_api_test.rb +2 -2
- data/test/functional/db_test.rb +24 -0
- data/test/functional/uri_test.rb +49 -32
- data/test/helpers/test_unit.rb +8 -0
- data/test/replica_set/authentication_test.rb +5 -1
- data/test/replica_set/client_test.rb +5 -4
- data/test/replica_set/max_values_test.rb +6 -0
- data/test/shared/authentication/basic_auth_shared.rb +101 -30
- data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
- data/test/shared/authentication/gssapi_shared.rb +164 -0
- data/test/shared/ssl_shared.rb +49 -27
- data/test/unit/client_test.rb +4 -2
- data/test/unit/connection_test.rb +4 -2
- data/test/unit/cursor_test.rb +12 -0
- data/test/unit/db_test.rb +6 -0
- metadata +27 -20
- metadata.gz.sig +0 -0
@@ -0,0 +1,133 @@
|
|
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
|
+
|
17
|
+
class BulkApiStressTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
# Generate a large string of 'size' MB (estimated
|
20
|
+
# by a string of 'size' * 1024 * 1024 characters).
|
21
|
+
def generate_large_string(size)
|
22
|
+
s = "a" * (size * 1024 * 1024)
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup
|
26
|
+
@client = standard_connection
|
27
|
+
@db = @client[TEST_DB]
|
28
|
+
@coll = @db["bulk-api-stress-tests"]
|
29
|
+
@coll.remove
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_ordered_batch_large_inserts
|
33
|
+
bulk = @coll.initialize_ordered_bulk_op
|
34
|
+
s = generate_large_string(4)
|
35
|
+
|
36
|
+
for i in 0..5
|
37
|
+
bulk.insert({:_id => i, :msg => s})
|
38
|
+
end
|
39
|
+
bulk.insert({:_id => 3}) # error
|
40
|
+
bulk.insert({:_id => 100})
|
41
|
+
|
42
|
+
ex = assert_raise BulkWriteError do
|
43
|
+
bulk.execute
|
44
|
+
end
|
45
|
+
|
46
|
+
error_details = ex.result
|
47
|
+
assert_equal 6, error_details["nInserted"]
|
48
|
+
assert_equal 1, error_details["writeErrors"].length
|
49
|
+
error = error_details["writeErrors"][0]
|
50
|
+
assert_equal 11000, error["code"] # duplicate key error
|
51
|
+
assert error["errmsg"].kind_of? String
|
52
|
+
assert_equal 6, error["index"]
|
53
|
+
assert_equal 6, @coll.count()
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_unordered_batch_large_inserts
|
57
|
+
bulk = @coll.initialize_unordered_bulk_op
|
58
|
+
s = generate_large_string(4)
|
59
|
+
|
60
|
+
for i in 0..5
|
61
|
+
bulk.insert({:_id => i, :msg => s})
|
62
|
+
end
|
63
|
+
bulk.insert({:_id => 3}) # error
|
64
|
+
bulk.insert({:_id => 100})
|
65
|
+
|
66
|
+
ex = assert_raise BulkWriteError do
|
67
|
+
bulk.execute
|
68
|
+
end
|
69
|
+
|
70
|
+
error_details = ex.result
|
71
|
+
assert_equal 7, error_details["nInserted"]
|
72
|
+
assert_equal 1, error_details["writeErrors"].length
|
73
|
+
error = error_details["writeErrors"][0]
|
74
|
+
assert_equal 11000, error["code"] # duplicate key error
|
75
|
+
assert error["errmsg"].kind_of? String
|
76
|
+
assert_equal 6, error["index"]
|
77
|
+
assert_equal 7, @coll.count()
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_large_single_insert
|
81
|
+
bulk = @coll.initialize_unordered_bulk_op
|
82
|
+
s = generate_large_string(17)
|
83
|
+
bulk.insert({:a => s})
|
84
|
+
# RUBY-730:
|
85
|
+
# ex = assert_raise BulkWriteError do
|
86
|
+
# bulk.execute
|
87
|
+
# end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_ordered_batch_large_batch
|
91
|
+
bulk = @coll.initialize_ordered_bulk_op
|
92
|
+
|
93
|
+
bulk.insert({:_id => 1600})
|
94
|
+
for i in 0..2000
|
95
|
+
bulk.insert({:_id => i})
|
96
|
+
end
|
97
|
+
|
98
|
+
ex = assert_raise BulkWriteError do
|
99
|
+
bulk.execute
|
100
|
+
end
|
101
|
+
|
102
|
+
error_details = ex.result
|
103
|
+
assert_equal 1601, error_details["nInserted"]
|
104
|
+
assert_equal 1, error_details["writeErrors"].length
|
105
|
+
error = error_details["writeErrors"][0]
|
106
|
+
assert_equal 11000, error["code"] # duplicate key error
|
107
|
+
assert error["errmsg"].kind_of? String
|
108
|
+
assert_equal 1601, error["index"]
|
109
|
+
assert_equal 1601, @coll.count()
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_unordered_batch_large_batch
|
113
|
+
bulk = @coll.initialize_unordered_bulk_op
|
114
|
+
|
115
|
+
bulk.insert({:_id => 1600})
|
116
|
+
for i in 0..2000
|
117
|
+
bulk.insert({:_id => i})
|
118
|
+
end
|
119
|
+
|
120
|
+
ex = assert_raise BulkWriteError do
|
121
|
+
bulk.execute
|
122
|
+
end
|
123
|
+
|
124
|
+
error_details = ex.result
|
125
|
+
assert_equal 2001, error_details["nInserted"]
|
126
|
+
assert_equal 1, error_details["writeErrors"].length
|
127
|
+
error = error_details["writeErrors"][0]
|
128
|
+
assert_equal 11000, error["code"] # duplicate key error
|
129
|
+
assert error["errmsg"].kind_of? String
|
130
|
+
assert_equal 1601, error["index"]
|
131
|
+
assert_equal 2001, @coll.count()
|
132
|
+
end
|
133
|
+
end
|
@@ -21,7 +21,7 @@ module Mongo
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class BulkWriteCollectionView
|
24
|
-
public :update_doc?, :replace_doc?, :merge_result
|
24
|
+
public :update_doc?, :replace_doc?, :nil_tally, :merge_result
|
25
25
|
|
26
26
|
# for reference and future server direction
|
27
27
|
def generate_batch_commands(groups, write_concern)
|
@@ -184,105 +184,422 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
184
184
|
bulk.insert({:x => 4})
|
185
185
|
end
|
186
186
|
|
187
|
+
def nil_tally_responses(responses, key)
|
188
|
+
result = {}
|
189
|
+
responses.each do |response|
|
190
|
+
@bulk.nil_tally(result, key, response[key])
|
191
|
+
end
|
192
|
+
result
|
193
|
+
end
|
194
|
+
|
187
195
|
context "Bulk API CollectionView" do
|
188
196
|
setup do
|
189
197
|
default_setup
|
190
198
|
end
|
191
199
|
|
200
|
+
# ----- INSERT -----
|
201
|
+
|
202
|
+
should "set :insert, :documents, terminate and return view for #insert" do
|
203
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
204
|
+
@collection.remove
|
205
|
+
document = {:a => 5}
|
206
|
+
result = @bulk.insert(document)
|
207
|
+
assert_is_bulk_write_collection_view(result)
|
208
|
+
assert_bulk_op_pushed [:insert, {:d => document}], @bulk
|
209
|
+
result = @bulk.execute
|
210
|
+
assert_match_document(
|
211
|
+
{
|
212
|
+
"ok" => 1,
|
213
|
+
"n" => 1,
|
214
|
+
"nInserted" => 1
|
215
|
+
}, result, "wire_version:#{wire_version}")
|
216
|
+
assert_equal 1, @collection.count
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
should "error out on $-prefixed keys with #insert" do
|
221
|
+
assert_raise BulkWriteError do
|
222
|
+
@bulk.insert({ "$key" => 1 })
|
223
|
+
@bulk.execute
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
should "attempt to run #insert with find() and succeed, ignoring find()" do
|
228
|
+
@bulk.find({}).insert({})
|
229
|
+
@bulk.execute
|
230
|
+
end
|
231
|
+
|
232
|
+
# ----- FIND -----
|
233
|
+
|
192
234
|
should "set :q and return view for #find" do
|
193
235
|
result = @bulk.find(@q)
|
194
236
|
assert_is_bulk_write_collection_view(result)
|
195
237
|
assert_equal @q, @bulk.op_args[:q]
|
238
|
+
@bulk.find({})
|
239
|
+
assert_equal({}, @bulk.op_args[:q])
|
240
|
+
@bulk.find(:a => 1)
|
241
|
+
assert_equal({:a => 1}, @bulk.op_args[:q])
|
196
242
|
end
|
197
243
|
|
244
|
+
should "raise an exception for empty #find" do
|
245
|
+
assert_raise MongoArgumentError do
|
246
|
+
@bulk.find({})
|
247
|
+
@bulk.execute
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# ----- UPDATE -----
|
252
|
+
|
198
253
|
should "set :upsert for #upsert" do
|
199
254
|
result = @bulk.find(@q).upsert
|
200
255
|
assert_is_bulk_write_collection_view(result)
|
201
256
|
assert_true result.op_args[:upsert]
|
202
257
|
end
|
203
258
|
|
259
|
+
should "check arg for update, set :update, :u, :multi, terminate and return view for #update" do
|
260
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
261
|
+
@collection.remove
|
262
|
+
@collection.insert({:a => 1, :b => 1})
|
263
|
+
@collection.insert({:a => 2, :b => 1})
|
264
|
+
@collection.insert({:a => 2, :b => 1})
|
265
|
+
bulk = @collection.initialize_ordered_bulk_op
|
266
|
+
|
267
|
+
u = {"$inc" => {:b => 1}}
|
268
|
+
q = {:a => 2}
|
269
|
+
|
270
|
+
assert_raise_error(MongoArgumentError, "non-nil query must be set via find") do
|
271
|
+
bulk.update(u)
|
272
|
+
end
|
273
|
+
assert_raise_error(MongoArgumentError, "document must start with an operator") do
|
274
|
+
bulk.find(q).update(q)
|
275
|
+
end
|
276
|
+
|
277
|
+
result = bulk.find({:a => 2}).update(u)
|
278
|
+
assert_is_bulk_write_collection_view(result)
|
279
|
+
assert_bulk_op_pushed [:update, {:q => q, :u => u, :multi => true}], bulk
|
280
|
+
|
281
|
+
result = bulk.execute
|
282
|
+
assert_match_document(
|
283
|
+
{
|
284
|
+
"ok" => 1,
|
285
|
+
"n" => 2,
|
286
|
+
"nMatched" => 2,
|
287
|
+
"nModified" => batch_commands?(wire_version) ? 2 : nil,
|
288
|
+
}, result, "wire_version:#{wire_version}")
|
289
|
+
assert_equal 1, @collection.find({:b => 1}).count
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# ----- UPDATE_ONE -----
|
294
|
+
|
204
295
|
should "check arg for update, set :update, :u, :multi, terminate and return view for #update_one" do
|
205
|
-
|
206
|
-
@
|
296
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
297
|
+
@collection.remove
|
298
|
+
@collection.insert({:a => 1})
|
299
|
+
@collection.insert({:a => 1, :b => 2})
|
300
|
+
bulk = @collection.initialize_ordered_bulk_op
|
301
|
+
|
302
|
+
assert_raise_error(MongoArgumentError, "non-nil query must be set via find") do
|
303
|
+
bulk.update_one(@u)
|
304
|
+
end
|
305
|
+
assert_raise_error(MongoArgumentError, "document must start with an operator") do
|
306
|
+
bulk.find(@q).update_one(@r)
|
307
|
+
end
|
308
|
+
result = bulk.find(@q).update_one(@u)
|
309
|
+
assert_is_bulk_write_collection_view(result)
|
310
|
+
assert_bulk_op_pushed [:update, {:q => @q, :u => @u, :multi => false}], bulk
|
311
|
+
result = bulk.execute
|
312
|
+
assert_match_document(
|
313
|
+
{
|
314
|
+
"ok" => 1,
|
315
|
+
"n" => 1,
|
316
|
+
"nMatched" => 1,
|
317
|
+
"nModified" => batch_commands?(wire_version) ? 1 : nil,
|
318
|
+
}, result, "wire_version:#{wire_version}")
|
319
|
+
assert_equal 2, @collection.count
|
207
320
|
end
|
208
|
-
result = @bulk.find(@q).update_one(@u)
|
209
|
-
assert_is_bulk_write_collection_view(result)
|
210
|
-
assert_bulk_op_pushed [:update, {:q => @q, :u => @u, :multi => false}], @bulk
|
211
321
|
end
|
212
322
|
|
213
|
-
should "
|
214
|
-
assert_raise
|
215
|
-
|
323
|
+
should "error-out in server when $-prefixed key is passed to #update_one" do
|
324
|
+
assert_raise BulkWriteError do
|
325
|
+
oh = BSON::OrderedHash.new
|
326
|
+
oh["$key"] = 1
|
327
|
+
oh[:a] = 1
|
328
|
+
@bulk.find(@q).update(oh)
|
329
|
+
@bulk.execute
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
should "error-out in driver when first field passed to #update_one is not operator" do
|
334
|
+
assert_raise_error(MongoArgumentError, "document must start with an operator") do
|
335
|
+
oh = BSON::OrderedHash.new
|
336
|
+
oh[:a] = 1
|
337
|
+
oh["$key"] = 1
|
338
|
+
@bulk.find(@q).update(oh)
|
216
339
|
end
|
217
|
-
result = @bulk.find(@q).update(@u)
|
218
|
-
assert_is_bulk_write_collection_view(result)
|
219
|
-
assert_bulk_op_pushed [:update, {:q => @q, :u => @u, :multi => true}], @bulk
|
220
340
|
end
|
221
341
|
|
342
|
+
# ----- REPLACE_ONE -----
|
343
|
+
|
222
344
|
should "check arg for replacement, set :update, :u, :multi, terminate and return view for #replace_one" do
|
223
|
-
|
224
|
-
@
|
345
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
346
|
+
@collection.remove
|
347
|
+
@collection.insert({:a => 1})
|
348
|
+
@collection.insert({:a => 1})
|
349
|
+
bulk = @collection.initialize_ordered_bulk_op
|
350
|
+
q = {:a => 1}
|
351
|
+
r = {:a => 2}
|
352
|
+
|
353
|
+
assert_raise_error(MongoArgumentError, "non-nil query must be set via find") do
|
354
|
+
bulk.replace_one(q)
|
355
|
+
end
|
356
|
+
assert_raise_error(MongoArgumentError, "document must not contain any operators") do
|
357
|
+
bulk.find(q).replace_one(@u)
|
358
|
+
end
|
359
|
+
|
360
|
+
result = bulk.find(q).replace_one(r)
|
361
|
+
assert_is_bulk_write_collection_view(result)
|
362
|
+
assert_bulk_op_pushed [:update, {:q => q, :u => r, :multi => false}], bulk
|
363
|
+
|
364
|
+
result = bulk.execute
|
365
|
+
assert_match_document(
|
366
|
+
{
|
367
|
+
"ok" => 1,
|
368
|
+
"n" => 1,
|
369
|
+
"nMatched" => 1,
|
370
|
+
"nModified" => batch_commands?(wire_version) ? 1 : nil,
|
371
|
+
}, result, "wire_version:#{wire_version}")
|
372
|
+
assert_equal 1, @collection.find(q).count
|
225
373
|
end
|
226
|
-
result = @bulk.find(@q).replace_one(@r)
|
227
|
-
assert_is_bulk_write_collection_view(result)
|
228
|
-
assert_bulk_op_pushed [:update, {:q => @q, :u => @r, :multi => false}], @bulk
|
229
374
|
end
|
230
375
|
|
231
|
-
|
232
|
-
result = @bulk.find(@q).remove_one
|
233
|
-
assert_is_bulk_write_collection_view(result)
|
234
|
-
assert_bulk_op_pushed [:delete, {:q => @q, :limit => 1}], @bulk
|
376
|
+
# ----- REMOVE -----
|
235
377
|
|
378
|
+
should "remove all documents when empty selector is passed to #remove" do
|
379
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
380
|
+
@collection.insert({:a => 1})
|
381
|
+
@collection.insert({:a => 2})
|
382
|
+
@bulk.find({}).remove
|
383
|
+
result = @bulk.execute
|
384
|
+
assert_equal 0, @collection.count
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
should "#remove only documents that match selector" do
|
389
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
390
|
+
@collection.remove
|
391
|
+
@collection.insert({:a => 1})
|
392
|
+
@collection.insert({:a => 2})
|
393
|
+
@bulk.find({:a => 1}).remove
|
394
|
+
result = @bulk.execute
|
395
|
+
assert_equal 1, @collection.count
|
396
|
+
# should fail if we re-execute
|
397
|
+
assert_raise_error(MongoArgumentError, "batch is empty") do
|
398
|
+
@bulk.execute
|
399
|
+
end
|
400
|
+
end
|
236
401
|
end
|
237
402
|
|
238
403
|
should "set :remove, :q, :limit, terminate and return view for #remove" do
|
404
|
+
assert_raise_error(MongoArgumentError, "non-nil query must be set via find") do
|
405
|
+
@bulk.remove
|
406
|
+
end
|
239
407
|
result = @bulk.find(@q).remove
|
240
408
|
assert_is_bulk_write_collection_view(result)
|
241
409
|
assert_bulk_op_pushed [:delete, {:q => @q, :limit => 0}], @bulk
|
242
410
|
end
|
243
411
|
|
244
|
-
|
245
|
-
|
246
|
-
|
412
|
+
# ----- REMOVE_ONE -----
|
413
|
+
|
414
|
+
should "set :remove, :q, :limit, terminate and return view for #remove_one" do
|
415
|
+
assert_raise_error(MongoArgumentError, "non-nil query must be set via find") do
|
416
|
+
@bulk.remove_one
|
417
|
+
end
|
418
|
+
result = @bulk.find(@q).remove_one
|
247
419
|
assert_is_bulk_write_collection_view(result)
|
248
|
-
assert_bulk_op_pushed [:
|
420
|
+
assert_bulk_op_pushed [:delete, {:q => @q, :limit => 1}], @bulk
|
421
|
+
end
|
422
|
+
|
423
|
+
should "remove only one of several matching documents for #remove_one" do
|
424
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
425
|
+
@collection.remove
|
426
|
+
@collection.insert({:a => 1, :b => 1})
|
427
|
+
@collection.insert({:a => 1, :b => 2})
|
428
|
+
@bulk.find({:a => 1}).remove_one
|
429
|
+
result = @bulk.execute
|
430
|
+
assert_match_document(
|
431
|
+
{
|
432
|
+
"ok" => 1,
|
433
|
+
"n" => 1,
|
434
|
+
"nRemoved" => 1,
|
435
|
+
"nModified" => nil,
|
436
|
+
}, result, "wire_version:#{wire_version}")
|
437
|
+
assert_equal 1, @collection.count
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
# ----- UPSERT-UPDATE -----
|
442
|
+
|
443
|
+
should "handle single upsert - spec Handling upserts" do # chose array always for upserted value
|
444
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
445
|
+
@collection.remove
|
446
|
+
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
447
|
+
bulk = @collection.initialize_ordered_bulk_op
|
448
|
+
|
449
|
+
assert_raise_error(MongoArgumentError, "non-nil query must be set via find") do
|
450
|
+
@bulk.upsert.update({"$set" => {:a => 1}})
|
451
|
+
end
|
452
|
+
|
453
|
+
bulk.find({:a => 1}).upsert.update({'$set' => {:a => 2}})
|
454
|
+
result = bulk.execute
|
455
|
+
assert_match_document(
|
456
|
+
{
|
457
|
+
"ok" => 1,
|
458
|
+
"n" => 1,
|
459
|
+
"nMatched" => 0,
|
460
|
+
"nUpserted" => 1,
|
461
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil,
|
462
|
+
"upserted" => [
|
463
|
+
{"_id" => BSON::ObjectId('52a16767bb67fbc77e26a310'), "index" => 0}
|
464
|
+
]
|
465
|
+
}, result, "wire_version:#{wire_version}")
|
466
|
+
end
|
249
467
|
end
|
250
468
|
|
251
|
-
should "
|
252
|
-
@
|
469
|
+
should "run #upsert.update without affecting non-upsert updates" do
|
470
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
471
|
+
@collection.remove
|
253
472
|
|
254
|
-
|
255
|
-
|
473
|
+
bulk = @collection.initialize_unordered_bulk_op
|
474
|
+
bulk.find({:a => 1}).update({"$set" => {:x => 1}})
|
475
|
+
bulk.find({:a => 2}).upsert.update({"$set" => {:x => 2}})
|
476
|
+
result = bulk.execute
|
477
|
+
assert_match_document(
|
478
|
+
{
|
479
|
+
"ok" => 1,
|
480
|
+
"n" => 1,
|
481
|
+
"nMatched" => 0,
|
482
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil,
|
483
|
+
"nUpserted" => 1,
|
484
|
+
"upserted" => [
|
485
|
+
{"_id" => BSON::ObjectId('52a16767bb67fbc77e26a310'), "index" => 1}
|
486
|
+
]
|
487
|
+
}, result, "wire_version:#{wire_version}")
|
256
488
|
|
257
|
-
|
258
|
-
|
489
|
+
# Repeat the batch and nMatched = 1, nUpserted = 0
|
490
|
+
bulk2 = @collection.initialize_unordered_bulk_op
|
491
|
+
bulk2.find({:a => 1}).update({"$set" => {:x => 1}})
|
492
|
+
bulk2.find({:a => 2}).upsert.update({"$set" => {:x => 2}})
|
493
|
+
result2 = bulk2.execute
|
494
|
+
assert_match_document(
|
495
|
+
{
|
496
|
+
"ok" => 1,
|
497
|
+
"n" => 1,
|
498
|
+
"nMatched" => 1,
|
499
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil
|
500
|
+
}, result2, "wire_version:#{wire_version}")
|
501
|
+
end
|
502
|
+
end
|
259
503
|
|
260
|
-
|
261
|
-
@bulk.find({:a => 3}).replace_one({:x => 3})
|
504
|
+
# ----- UPSERT-UPDATE_ONE -----
|
262
505
|
|
263
|
-
|
264
|
-
@
|
506
|
+
should "#upsert a document without affecting non-upsert update_ones" do
|
507
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
508
|
+
@collection.remove
|
509
|
+
bulk = @collection.initialize_unordered_bulk_op
|
265
510
|
|
266
|
-
|
267
|
-
|
511
|
+
bulk.find({:a => 1}).update_one({"$set" => {:x => 1}})
|
512
|
+
bulk.find({:a => 2}).upsert.update_one({"$set" => {:x => 2}})
|
513
|
+
result = bulk.execute
|
514
|
+
assert_match_document(
|
515
|
+
{
|
516
|
+
"ok" => 1,
|
517
|
+
"n" => 1,
|
518
|
+
"nMatched" => 0,
|
519
|
+
"nUpserted" => 1,
|
520
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil,
|
521
|
+
"upserted" => [
|
522
|
+
{"_id" => BSON::ObjectId('52a16767bb67fbc77e26a310'), "index" => 1}
|
523
|
+
]
|
524
|
+
}, result, "wire_version:#{wire_version}")
|
525
|
+
end
|
526
|
+
end
|
268
527
|
|
269
|
-
|
270
|
-
@
|
528
|
+
should "only update one matching document with #upsert-update_one" do
|
529
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
530
|
+
@collection.remove
|
531
|
+
@collection.insert({:a => 1})
|
532
|
+
@collection.insert({:a => 1})
|
271
533
|
|
272
|
-
|
273
|
-
|
534
|
+
bulk = @collection.initialize_unordered_bulk_op
|
535
|
+
bulk.find({:a => 1}).update_one({"$set" => {:x => 1}})
|
536
|
+
result = bulk.execute
|
537
|
+
assert_match_document(
|
538
|
+
{
|
539
|
+
"ok" => 1,
|
540
|
+
"n" => 1,
|
541
|
+
"nMatched" => 1,
|
542
|
+
"nModified" => batch_commands?(wire_version) ? 1 : nil,
|
543
|
+
}, result, "wire_version:#{wire_version}")
|
544
|
+
end
|
545
|
+
end
|
274
546
|
|
275
|
-
|
276
|
-
@bulk.find({:a => 5}).remove
|
547
|
+
# ----- UPSERT-REPLACE_ONE -----
|
277
548
|
|
278
|
-
|
279
|
-
@
|
549
|
+
should "not affect non-upsert replace_ones in same batch as #upsert-replace_one" do
|
550
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
551
|
+
@collection.remove
|
552
|
+
bulk = @collection.initialize_unordered_bulk_op
|
553
|
+
bulk.find({:a => 1}).replace_one({:x => 1})
|
554
|
+
bulk.find({:a => 2}).upsert.replace_one({:x => 2})
|
555
|
+
result = bulk.execute
|
556
|
+
assert_match_document(
|
557
|
+
{
|
558
|
+
"ok" => 1,
|
559
|
+
"n" => 1,
|
560
|
+
"nMatched" => 0,
|
561
|
+
"nUpserted" => 1,
|
562
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil,
|
563
|
+
"upserted" => [
|
564
|
+
{"_id" => BSON::ObjectId('52a16767bb67fbc77e26a310'), "index" => 1}
|
565
|
+
]
|
566
|
+
}, result, "wire_version:#{wire_version}")
|
567
|
+
assert_equal 1, @collection.count
|
568
|
+
end
|
569
|
+
end
|
280
570
|
|
281
|
-
|
282
|
-
|
283
|
-
|
571
|
+
should "only replace one matching document with #upsert-replace_one" do
|
572
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
573
|
+
@collection.remove
|
574
|
+
@collection.insert({:a => 1})
|
575
|
+
@collection.insert({:a => 1})
|
576
|
+
bulk = @collection.initialize_unordered_bulk_op
|
577
|
+
bulk.find({:a => 1}).replace_one({:x => 1})
|
578
|
+
bulk.find({:a => 2}).upsert.replace_one({:x => 2})
|
579
|
+
result = bulk.execute
|
580
|
+
assert_match_document(
|
581
|
+
{
|
582
|
+
"ok" => 1,
|
583
|
+
"n" => 2,
|
584
|
+
"nMatched" => 1,
|
585
|
+
"nUpserted" => 1,
|
586
|
+
"nModified" => batch_commands?(wire_version) ? 1 : nil,
|
587
|
+
"upserted" => [
|
588
|
+
{"_id" => BSON::ObjectId('52a16767bb67fbc77e26a310'), "index" => 1}
|
589
|
+
]
|
590
|
+
}, result, "wire_version:#{wire_version}")
|
591
|
+
assert_equal 3, @collection.count
|
592
|
+
end
|
284
593
|
end
|
285
594
|
|
595
|
+
should "tally given all numbers or return nil for #nil_tally" do
|
596
|
+
assert_equal({"nM" => 6}, nil_tally_responses([{"nM" => 1}, {"nM" => 2}, {"nM" => 3}], "nM"))
|
597
|
+
assert_equal({"nM" => nil}, nil_tally_responses([{"nM" => 1}, { }, {"nM" => 3}], "nM"))
|
598
|
+
assert_equal({"nM" => nil}, nil_tally_responses([{"nM" => 1}, {"nM" => nil}, {"nM" => 3}], "nM"))
|
599
|
+
end
|
600
|
+
|
601
|
+
# ----- MIXED OPS, ORDERED -----
|
602
|
+
|
286
603
|
should "execute, return result and reset @ops for #execute" do
|
287
604
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
288
605
|
@collection.remove
|
@@ -309,7 +626,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
309
626
|
"nInserted" => 6,
|
310
627
|
"nMatched" => 5,
|
311
628
|
"nUpserted" => 1,
|
312
|
-
"nModified" => 5,
|
629
|
+
"nModified" => batch_commands?(wire_version) ? 5 : nil,
|
313
630
|
"nRemoved" => 2,
|
314
631
|
"upserted" => [
|
315
632
|
{
|
@@ -318,31 +635,45 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
318
635
|
}
|
319
636
|
]
|
320
637
|
}, result, "wire_version:#{wire_version}")
|
638
|
+
assert_equal(batch_commands?(wire_version), result.has_key?("nModified"), "wire_version:#{wire_version}")
|
321
639
|
assert_false(@collection.find.to_a.empty?, "wire_version:#{wire_version}")
|
322
640
|
assert_equal [{"a"=>1, "x"=>2}, {"a"=>2, "x"=>4}, {"x"=>3}, {"x"=>3}, {"x"=>4}], sort_docs(@collection.find.to_a.collect { |doc| doc.delete("_id"); doc })
|
323
641
|
end
|
324
642
|
end
|
325
643
|
|
326
|
-
should "run
|
644
|
+
should "run spec Ordered Bulk Operations" do
|
327
645
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
328
|
-
@
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
646
|
+
@bulk.insert({:a => 1})
|
647
|
+
@bulk.insert({:a => 2})
|
648
|
+
@bulk.insert({:a => 3})
|
649
|
+
@bulk.find({:a => 2}).upsert.update({'$set' => {:a => 4}})
|
650
|
+
@bulk.find({:a => 1}).remove_one
|
651
|
+
@bulk.insert({:a => 5})
|
652
|
+
result = @bulk.execute({:w => 1})
|
653
|
+
assert_match_document(
|
654
|
+
{
|
655
|
+
"ok" => 1,
|
656
|
+
"n" => 6,
|
657
|
+
"nInserted" => 4,
|
658
|
+
"nMatched" => 1,
|
659
|
+
"nModified" => batch_commands?(wire_version) ? 1 : nil,
|
660
|
+
"nRemoved" => 1,
|
661
|
+
}, result, "wire_version:#{wire_version}")
|
335
662
|
end
|
336
663
|
end
|
337
664
|
|
665
|
+
# ----- MIXED OPS, UNORDERED -----
|
666
|
+
|
338
667
|
should "run unordered big example" do
|
339
668
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
340
669
|
@collection.remove
|
341
670
|
@bulk = @collection.initialize_unordered_bulk_op
|
342
671
|
big_example(@bulk)
|
343
672
|
write_concern = {:w => 1} #{:w => 1. :j => 1} #nojournal for tests
|
344
|
-
result = @bulk.execute(write_concern)
|
673
|
+
result = @bulk.execute(write_concern)
|
674
|
+
assert_equal(6, result["nInserted"])
|
345
675
|
assert_true(result["n"] > 0, "wire_version:#{wire_version}")
|
676
|
+
assert_equal(batch_commands?(wire_version), result.has_key?("nModified"), "wire_version:#{wire_version}")
|
346
677
|
assert_false(@collection.find.to_a.empty?, "wire_version:#{wire_version}")
|
347
678
|
end
|
348
679
|
end
|
@@ -353,29 +684,73 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
353
684
|
@bulk = @collection.initialize_unordered_bulk_op
|
354
685
|
big_example(@bulk)
|
355
686
|
write_concern = {:w => 0}
|
356
|
-
result = @bulk.execute(write_concern)
|
687
|
+
result = @bulk.execute(write_concern)
|
357
688
|
assert_equal(true, result, "wire_version:#{wire_version}")
|
358
689
|
assert_false(@collection.find.to_a.empty?, "wire_version:#{wire_version}")
|
359
690
|
end
|
360
691
|
end
|
361
692
|
|
362
|
-
should "run unordered bulk operations in one batch per write-type" do
|
363
|
-
with_write_commands(@db.connection) do
|
364
|
-
@collection.expects(:batch_write).at_most(3).returns([[], [], [], []])
|
365
|
-
bulk = @collection.initialize_unordered_bulk_op
|
366
|
-
bulk.insert({:_id => 1, :a => 1})
|
367
|
-
bulk.find({:_id => 1, :a => 1}).update({"$inc" => {:x => 1}})
|
368
|
-
bulk.find({:_id => 1, :a => 1}).remove
|
369
|
-
bulk.insert({:_id => 2, :a => 2})
|
370
|
-
bulk.find({:_id => 2, :a => 2}).update({"$inc" => {:x => 2}})
|
371
|
-
bulk.find({:_id => 2, :a => 2}).remove
|
372
|
-
bulk.insert({:_id => 3, :a => 3})
|
373
|
-
bulk.find({:_id => 3, :a => 3}).update({"$inc" => {:x => 3}})
|
374
|
-
bulk.find({:_id => 3, :a => 3}).remove
|
375
|
-
result = bulk.execute # unordered varies, don't use assert_match_document
|
693
|
+
should "run unordered bulk operations in one batch per write-type" do
|
694
|
+
with_write_commands(@db.connection) do
|
695
|
+
@collection.expects(:batch_write).at_most(3).returns([[], [], [], []])
|
696
|
+
bulk = @collection.initialize_unordered_bulk_op
|
697
|
+
bulk.insert({:_id => 1, :a => 1})
|
698
|
+
bulk.find({:_id => 1, :a => 1}).update({"$inc" => {:x => 1}})
|
699
|
+
bulk.find({:_id => 1, :a => 1}).remove
|
700
|
+
bulk.insert({:_id => 2, :a => 2})
|
701
|
+
bulk.find({:_id => 2, :a => 2}).update({"$inc" => {:x => 2}})
|
702
|
+
bulk.find({:_id => 2, :a => 2}).remove
|
703
|
+
bulk.insert({:_id => 3, :a => 3})
|
704
|
+
bulk.find({:_id => 3, :a => 3}).update({"$inc" => {:x => 3}})
|
705
|
+
bulk.find({:_id => 3, :a => 3}).remove
|
706
|
+
result = bulk.execute # unordered varies, don't use assert_match_document
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
should "run spec Unordered Bulk Operations" do
|
711
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
712
|
+
bulk = @collection.initialize_unordered_bulk_op
|
713
|
+
bulk.insert({:_id => 1})
|
714
|
+
bulk.find({:_id => 2}).update_one({'$inc' => { :x => 1 }})
|
715
|
+
bulk.find({:_id => 3}).remove_one
|
716
|
+
bulk.insert({:_id => 4})
|
717
|
+
bulk.find({:_id => 5}).update_one({'$inc' => { :x => 1 }})
|
718
|
+
bulk.find({:_id => 6}).remove_one
|
719
|
+
result = nil
|
720
|
+
begin
|
721
|
+
result = bulk.execute
|
722
|
+
rescue => ex
|
723
|
+
result = ex.result
|
724
|
+
end
|
725
|
+
# for write commands internally the driver will execute 3. One each for the inserts, updates and removes.
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
# ----- EMPTY BATCH -----
|
730
|
+
|
731
|
+
should "handle empty bulk op" do
|
732
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
733
|
+
assert_raise_error(MongoArgumentError, Mongo::BulkWriteCollectionView::EMPTY_BATCH_MSG) do
|
734
|
+
@bulk.execute
|
735
|
+
end
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
should "handle insert of overly large document" do
|
740
|
+
large_doc = {"a" => "y"*(2*@client.max_message_size)}
|
741
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
742
|
+
ex = assert_raise Mongo::BulkWriteError do
|
743
|
+
@collection.remove
|
744
|
+
bulk = @collection.initialize_unordered_bulk_op
|
745
|
+
bulk.insert(large_doc)
|
746
|
+
puts "bulk.execute:#{bulk.execute.inspect}"
|
747
|
+
end
|
748
|
+
assert_equal 22, ex.result["writeErrors"].first["code"]
|
376
749
|
end
|
377
750
|
end
|
378
751
|
|
752
|
+
# ----- ORDERED, WITH ERRORS -----
|
753
|
+
|
379
754
|
should "handle error for duplicate key with offset" do
|
380
755
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
381
756
|
@collection.remove
|
@@ -401,28 +776,11 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
401
776
|
"errmsg" => "batch item errors occurred",
|
402
777
|
"nInserted" => 1,
|
403
778
|
"nMatched" => 0,
|
404
|
-
"nModified" => 0
|
779
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil
|
405
780
|
}, result, "wire_version:#{wire_version}")
|
406
781
|
end
|
407
782
|
end
|
408
783
|
|
409
|
-
should "handle error for unordered multiple duplicate key with offset" do
|
410
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
411
|
-
@collection.remove
|
412
|
-
@bulk = @collection.initialize_unordered_bulk_op
|
413
|
-
@bulk.find({:a => 1}).remove
|
414
|
-
@bulk.insert({:_id => 1, :a => 1})
|
415
|
-
@bulk.insert({:_id => 1, :a => 2})
|
416
|
-
@bulk.insert({:_id => 3, :a => 3})
|
417
|
-
@bulk.insert({:_id => 3, :a => 3})
|
418
|
-
ex = assert_raise BulkWriteError do
|
419
|
-
@bulk.execute
|
420
|
-
end
|
421
|
-
result = ex.result # unordered varies, don't use assert_bulk_exception
|
422
|
-
assert_not_nil(result["writeErrors"], "wire_version:#{wire_version}")
|
423
|
-
end
|
424
|
-
end
|
425
|
-
|
426
784
|
should "handle error for serialization with offset" do
|
427
785
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
428
786
|
@collection.remove
|
@@ -449,12 +807,12 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
449
807
|
"errmsg" => "batch item errors occurred",
|
450
808
|
"nInserted" => 1,
|
451
809
|
"nMatched" => 0,
|
452
|
-
"nModified" => 0
|
810
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil
|
453
811
|
}, result, "wire_version:#{wire_version}")
|
454
812
|
end
|
455
813
|
end
|
456
814
|
|
457
|
-
should "run ordered bulk op - spec Modes of Execution" do
|
815
|
+
should "run ordered bulk op - spec Modes of Execution" do
|
458
816
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
459
817
|
@collection.remove
|
460
818
|
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
@@ -469,66 +827,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
469
827
|
end
|
470
828
|
end
|
471
829
|
|
472
|
-
should "
|
473
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
474
|
-
@collection.remove
|
475
|
-
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
476
|
-
bulk = @collection.initialize_unordered_bulk_op
|
477
|
-
bulk.insert({:a => 1})
|
478
|
-
bulk.insert({:a => 2})
|
479
|
-
bulk.find({:a => 2}).update({'$set' => {:a => 1}}) # Clashes with unique index
|
480
|
-
bulk.find({:a => 3}).remove
|
481
|
-
bulk.find({:a => 2}).update({'$set' => {:a => 1}}) # Clashes with unique index
|
482
|
-
ex = assert_raise BulkWriteError do
|
483
|
-
bulk.execute
|
484
|
-
end
|
485
|
-
result = ex.result
|
486
|
-
assert(result["writeErrors"].size > 1, "wire_version:#{wire_version}")
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
should "run spec Ordered Bulk Operations" do # spec fix pending
|
491
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
492
|
-
@bulk.insert({:a => 1})
|
493
|
-
@bulk.insert({:a => 2})
|
494
|
-
@bulk.insert({:a => 3})
|
495
|
-
@bulk.find({:a => 2}).upsert.update({'$set' => {:a => 4}})
|
496
|
-
@bulk.find({:a => 1}).remove_one
|
497
|
-
@bulk.insert({:a => 5})
|
498
|
-
result = @bulk.execute({:w => 1})
|
499
|
-
assert_match_document(
|
500
|
-
{
|
501
|
-
"ok" => 1,
|
502
|
-
"n" => 6,
|
503
|
-
"nInserted" => 4,
|
504
|
-
"nMatched" => 1,
|
505
|
-
"nModified" => 1,
|
506
|
-
"nRemoved" => 1,
|
507
|
-
}, result, "wire_version:#{wire_version}")
|
508
|
-
# for write commands there will be in sequence insert, update, remove, insert
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
should "run spec Unordered Bulk Operations" do
|
513
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
514
|
-
bulk = @collection.initialize_unordered_bulk_op
|
515
|
-
bulk.insert({:_id => 1})
|
516
|
-
bulk.find({:_id => 2}).update_one({'$inc' => { :x => 1 }})
|
517
|
-
bulk.find({:_id => 3}).remove_one
|
518
|
-
bulk.insert({:_id => 4})
|
519
|
-
bulk.find({:_id => 5}).update_one({'$inc' => { :x => 1 }})
|
520
|
-
bulk.find({:_id => 6}).remove_one
|
521
|
-
result = nil
|
522
|
-
begin
|
523
|
-
result = bulk.execute
|
524
|
-
rescue => ex
|
525
|
-
result = ex.result
|
526
|
-
end
|
527
|
-
# for write commands internally the driver will execute 3. One each for the inserts, updates and removes.
|
528
|
-
end
|
529
|
-
end
|
530
|
-
|
531
|
-
should "handle duplicate key error - spec Merging Results" do # spec fix pending
|
830
|
+
should "handle duplicate key error - spec Merging Results" do
|
532
831
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
533
832
|
@collection.remove
|
534
833
|
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
@@ -555,37 +854,11 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
555
854
|
"errmsg" => "batch item errors occurred",
|
556
855
|
"nInserted" => 2,
|
557
856
|
"nMatched" => 0,
|
558
|
-
"nModified" => 0
|
857
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil
|
559
858
|
}, result, "wire_version:#{wire_version}")
|
560
859
|
end
|
561
860
|
end
|
562
861
|
|
563
|
-
# should "handle error with deferred write concern error - spec Merging Results" do
|
564
|
-
# end # see test/replica_set/insert_test.rb
|
565
|
-
|
566
|
-
should "handle unordered errors - spec Merging Results" do # spec fix pending
|
567
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
568
|
-
@collection.remove
|
569
|
-
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
570
|
-
bulk = @collection.initialize_unordered_bulk_op
|
571
|
-
bulk.insert({:a => 1})
|
572
|
-
bulk.find({:a => 1}).upsert.update({'$set' => {:a => 2}})
|
573
|
-
bulk.insert({:a => 2})
|
574
|
-
ex = assert_raise BulkWriteError do
|
575
|
-
bulk.execute
|
576
|
-
end
|
577
|
-
result = ex.result # unordered varies, don't use assert_bulk_exception
|
578
|
-
assert_equal(1, result['ok'], "wire_version:#{wire_version}")
|
579
|
-
assert_equal(2, result['n'], "wire_version:#{wire_version}")
|
580
|
-
err_details = result['writeErrors']
|
581
|
-
assert_equal([2,nil,1][wire_version], err_details.first['index'], "wire_version:#{wire_version}")
|
582
|
-
assert_match(/duplicate key error/, err_details.first['errmsg'], "wire_version:#{wire_version}")
|
583
|
-
end
|
584
|
-
end
|
585
|
-
|
586
|
-
# should "handle unordered errors with deferred write concern error - spec Merging Results" do # TODO - spec review
|
587
|
-
# end # see test/replica_set/insert_test.rb
|
588
|
-
|
589
862
|
should "report user index - spec Merging errors" do
|
590
863
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
591
864
|
@collection.remove
|
@@ -613,28 +886,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
613
886
|
"errmsg" => "batch item errors occurred",
|
614
887
|
"nInserted" => 2,
|
615
888
|
"nMatched" => 0,
|
616
|
-
"nModified" => 0
|
617
|
-
}, result, "wire_version:#{wire_version}")
|
618
|
-
end
|
619
|
-
end
|
620
|
-
|
621
|
-
should "handle single upsert - spec Handling upserts" do # chose array always for upserted value
|
622
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
623
|
-
@collection.remove
|
624
|
-
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
625
|
-
bulk = @collection.initialize_ordered_bulk_op
|
626
|
-
bulk.find({:a => 1}).upsert.update({'$set' => {:a => 2}})
|
627
|
-
result = bulk.execute
|
628
|
-
assert_match_document(
|
629
|
-
{
|
630
|
-
"ok" => 1,
|
631
|
-
"n" => 1,
|
632
|
-
"nMatched" => 0,
|
633
|
-
"nUpserted" => 1,
|
634
|
-
"nModified" => 0,
|
635
|
-
"upserted" => [
|
636
|
-
{"_id" => BSON::ObjectId('52a16767bb67fbc77e26a310'), "index" => 0}
|
637
|
-
]
|
889
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil
|
638
890
|
}, result, "wire_version:#{wire_version}")
|
639
891
|
end
|
640
892
|
end
|
@@ -653,7 +905,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
653
905
|
"n" => 2,
|
654
906
|
"nMatched" => 0,
|
655
907
|
"nUpserted" => 2,
|
656
|
-
"nModified" => 0,
|
908
|
+
"nModified" => batch_commands?(wire_version) ? 0 : nil,
|
657
909
|
"upserted" => [
|
658
910
|
{"index" => 0, "_id" => BSON::ObjectId('52a1e37cbb67fbc77e26a338')},
|
659
911
|
{"index" => 1, "_id" => BSON::ObjectId('52a1e37cbb67fbc77e26a339')}
|
@@ -662,28 +914,6 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
662
914
|
end
|
663
915
|
end
|
664
916
|
|
665
|
-
should "handle multiple errors for unordered bulk write" do
|
666
|
-
with_write_commands_and_operations(@db.connection) do |wire_version|
|
667
|
-
@collection.remove
|
668
|
-
@bulk = @collection.initialize_unordered_bulk_op
|
669
|
-
@bulk.insert({:_id => 1, :a => 1})
|
670
|
-
@bulk.insert({:_id => 1, :a => 2})
|
671
|
-
@bulk.insert(generate_sized_doc(@@client.max_message_size + 1))
|
672
|
-
@bulk.insert({:_id => 3, :a => 3})
|
673
|
-
@bulk.find({:a => 4}).upsert.replace_one({:x => 3})
|
674
|
-
ex = assert_raise BulkWriteError do
|
675
|
-
@bulk.execute
|
676
|
-
end
|
677
|
-
result = ex.result # unordered varies, don't use assert_bulk_exception
|
678
|
-
assert_equal(1, result['ok'], "wire_version:#{wire_version}")
|
679
|
-
assert_equal(3, result['n'], "wire_version:#{wire_version}")
|
680
|
-
err_details = result['writeErrors']
|
681
|
-
assert_match(/duplicate key error/, err_details.find { |e| e['code']==11000 }['errmsg'], "wire_version:#{wire_version}")
|
682
|
-
assert_match(/too large/, err_details.find { |e| e['index']==2 }['errmsg'], "wire_version:#{wire_version}")
|
683
|
-
assert_not_nil(result['upserted'].find { |e| e['index']==4 }, "wire_version:#{wire_version}")
|
684
|
-
end
|
685
|
-
end
|
686
|
-
|
687
917
|
should "handle replication usage error" do
|
688
918
|
with_no_replication(@db.connection) do
|
689
919
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
@@ -731,6 +961,87 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
731
961
|
end
|
732
962
|
end
|
733
963
|
|
964
|
+
# ----- UNORDERED, WITH ERRORS -----
|
965
|
+
|
966
|
+
should "handle error for unordered multiple duplicate key with offset" do
|
967
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
968
|
+
@collection.remove
|
969
|
+
@bulk = @collection.initialize_unordered_bulk_op
|
970
|
+
@bulk.find({:a => 1}).remove
|
971
|
+
@bulk.insert({:_id => 1, :a => 1})
|
972
|
+
@bulk.insert({:_id => 1, :a => 2})
|
973
|
+
@bulk.insert({:_id => 3, :a => 3})
|
974
|
+
@bulk.insert({:_id => 3, :a => 3})
|
975
|
+
ex = assert_raise BulkWriteError do
|
976
|
+
@bulk.execute
|
977
|
+
end
|
978
|
+
result = ex.result
|
979
|
+
assert_true (0 < result["nInserted"] && result["nInserted"] < 3)
|
980
|
+
assert_not_nil(result["writeErrors"], "wire_version:#{wire_version}")
|
981
|
+
end
|
982
|
+
end
|
983
|
+
|
984
|
+
should "run unordered bulk op - spec Modes of Execution" do
|
985
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
986
|
+
@collection.remove
|
987
|
+
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
988
|
+
bulk = @collection.initialize_unordered_bulk_op
|
989
|
+
bulk.insert({:a => 1})
|
990
|
+
bulk.insert({:a => 2})
|
991
|
+
bulk.find({:a => 2}).update({'$set' => {:a => 1}}) # Clashes with unique index
|
992
|
+
bulk.find({:a => 3}).remove
|
993
|
+
bulk.find({:a => 2}).update({'$set' => {:a => 1}}) # Clashes with unique index
|
994
|
+
ex = assert_raise BulkWriteError do
|
995
|
+
bulk.execute
|
996
|
+
end
|
997
|
+
result = ex.result
|
998
|
+
assert(result["writeErrors"].size > 1, "wire_version:#{wire_version}")
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
should "handle unordered errors - spec Merging Results" do
|
1003
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
1004
|
+
@collection.remove
|
1005
|
+
@collection.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
1006
|
+
bulk = @collection.initialize_unordered_bulk_op
|
1007
|
+
bulk.insert({:a => 1})
|
1008
|
+
bulk.find({:a => 1}).upsert.update({'$set' => {:a => 2}})
|
1009
|
+
bulk.insert({:a => 2})
|
1010
|
+
ex = assert_raise BulkWriteError do
|
1011
|
+
bulk.execute
|
1012
|
+
end
|
1013
|
+
result = ex.result # unordered varies, don't use assert_bulk_exception
|
1014
|
+
assert_equal(1, result['ok'], "wire_version:#{wire_version}")
|
1015
|
+
assert_equal(2, result['n'], "wire_version:#{wire_version}")
|
1016
|
+
err_details = result['writeErrors']
|
1017
|
+
assert_match(/duplicate key error/, err_details.first['errmsg'], "wire_version:#{wire_version}")
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
should "handle multiple errors for unordered bulk write" do
|
1022
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
1023
|
+
@collection.remove
|
1024
|
+
@bulk = @collection.initialize_unordered_bulk_op
|
1025
|
+
@bulk.insert({:_id => 1, :a => 1})
|
1026
|
+
@bulk.insert({:_id => 1, :a => 2})
|
1027
|
+
@bulk.insert(generate_sized_doc(@@client.max_message_size + 1))
|
1028
|
+
@bulk.insert({:_id => 3, :a => 3})
|
1029
|
+
@bulk.find({:a => 4}).upsert.replace_one({:x => 3})
|
1030
|
+
ex = assert_raise BulkWriteError do
|
1031
|
+
@bulk.execute
|
1032
|
+
end
|
1033
|
+
result = ex.result # unordered varies, don't use assert_bulk_exception
|
1034
|
+
assert_equal(1, result['ok'], "wire_version:#{wire_version}")
|
1035
|
+
assert_equal(3, result['n'], "wire_version:#{wire_version}")
|
1036
|
+
err_details = result['writeErrors']
|
1037
|
+
assert_match(/duplicate key error/, err_details.find { |e| e['code']==11000 }['errmsg'], "wire_version:#{wire_version}")
|
1038
|
+
assert_match(/too large/, err_details.find { |e| e['index']==2 }['errmsg'], "wire_version:#{wire_version}")
|
1039
|
+
assert_not_nil(result['upserted'].find { |e| e['index']==4 }, "wire_version:#{wire_version}")
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
# ----- NO_JOURNAL -----
|
1044
|
+
|
734
1045
|
should "handle journaling error" do
|
735
1046
|
with_no_journaling(@db.connection) do
|
736
1047
|
with_write_commands_and_operations(@db.connection) do |wire_version|
|
@@ -777,6 +1088,42 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
|
|
777
1088
|
end
|
778
1089
|
end
|
779
1090
|
end
|
780
|
-
end
|
781
1091
|
|
1092
|
+
# ----- W = 0 -----
|
1093
|
+
|
1094
|
+
should "run ordered big example with w 0" do
|
1095
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
1096
|
+
@collection.remove
|
1097
|
+
big_example(@bulk)
|
1098
|
+
result = @bulk.execute({:w => 0})
|
1099
|
+
assert_equal(true, result, "wire_version:#{wire_version}")
|
1100
|
+
assert_false(@collection.find.to_a.empty?, "wire_version:#{wire_version}")
|
1101
|
+
assert_equal [{"a"=>1, "x"=>2}, {"a"=>2, "x"=>4}, {"x"=>3}, {"x"=>3}, {"x"=>4}], sort_docs(@collection.find.to_a.collect { |doc| doc.delete("_id"); doc })
|
1102
|
+
end
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
should "running with w 0 should not report write errors" do
|
1106
|
+
with_write_commands_and_operations(@db.connection) do
|
1107
|
+
@bulk.insert({:_id => 1, :a => 1 })
|
1108
|
+
@bulk.insert({:_id => 1, :a => 2 })
|
1109
|
+
@bulk.execute({:w => 0}) # should raise no duplicate key error
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
# ----- W > 0 WITH STANDALONE -----
|
1114
|
+
|
1115
|
+
should "disallow w > 0 against a standalone" do
|
1116
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
1117
|
+
@collection.remove
|
1118
|
+
@bulk.insert({:_id => 1, :a => 1 })
|
1119
|
+
@bulk.insert({:_id => 2, :a => 1 })
|
1120
|
+
@bulk.insert({:_id => 3, :a => 1 })
|
1121
|
+
assert_raise_error BulkWriteError do
|
1122
|
+
@bulk.execute({:w => 2})
|
1123
|
+
end
|
1124
|
+
assert (@collection.count == batch_commands?(wire_version) ? 0 : 1)
|
1125
|
+
end
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
end
|
782
1129
|
end
|