@@ -292,6 +292,143 @@ test_index_offset (void)
292
292
}
293
293
294
294
295
+ static void
296
+ test_bulk_edge_case_372 (void )
297
+ {
298
+ mongoc_client_t * client ;
299
+ mongoc_collection_t * collection ;
300
+ mongoc_bulk_operation_t * bulk ;
301
+ bson_error_t error ;
302
+ bson_iter_t iter ;
303
+ bson_iter_t citer ;
304
+ bson_iter_t child ;
305
+ const char * str ;
306
+ bson_t * selector ;
307
+ bson_t * update ;
308
+ bson_t reply ;
309
+ bool r ;
310
+ int count ;
311
+ int vmaj = 0 ;
312
+ int vmin = 0 ;
313
+ int vmic = 0 ;
314
+
315
+ client = mongoc_client_new (gTestUri );
316
+ assert (client );
317
+
318
+ collection = get_test_collection (client , "CDRIVER_372" );
319
+ assert (collection );
320
+
321
+ bulk = mongoc_collection_create_bulk_operation (collection , true, NULL );
322
+ assert (bulk );
323
+
324
+ selector = BCON_NEW ("_id" , BCON_INT32 (0 ));
325
+ update = BCON_NEW ("$set" , "{" , "a" , BCON_INT32 (0 ), "}" );
326
+ mongoc_bulk_operation_update_one (bulk , selector , update , true);
327
+ bson_destroy (selector );
328
+ bson_destroy (update );
329
+
330
+ selector = BCON_NEW ("a" , BCON_INT32 (1 ));
331
+ update = BCON_NEW ("_id" , BCON_INT32 (1 ));
332
+ mongoc_bulk_operation_replace_one (bulk , selector , update , true);
333
+ bson_destroy (selector );
334
+ bson_destroy (update );
335
+
336
+ r = mongoc_client_get_server_status (client , NULL , & reply , & error );
337
+ if (!r ) fprintf (stderr , "%s\n" , error .message );
338
+ assert (r );
339
+
340
+ if (bson_iter_init_find (& iter , & reply , "version" ) &&
341
+ BSON_ITER_HOLDS_UTF8 (& iter ) &&
342
+ (str = bson_iter_utf8 (& iter , NULL ))) {
343
+ sscanf (str , "%d.%d.%d" , & vmaj , & vmin , & vmic );
344
+ }
345
+
346
+ bson_destroy (& reply );
347
+
348
+ if (vmaj >=2 || (vmaj == 2 && vmin >= 6 )) {
349
+ /* This is just here to make the counts right in all cases. */
350
+ selector = BCON_NEW ("_id" , BCON_INT32 (2 ));
351
+ update = BCON_NEW ("_id" , BCON_INT32 (2 ));
352
+ mongoc_bulk_operation_replace_one (bulk , selector , update , true);
353
+ bson_destroy (selector );
354
+ bson_destroy (update );
355
+ } else {
356
+ /* This case is only possible in MongoDB versions before 2.6. */
357
+ selector = BCON_NEW ("_id" , BCON_INT32 (3 ));
358
+ update = BCON_NEW ("_id" , BCON_INT32 (2 ));
359
+ mongoc_bulk_operation_replace_one (bulk , selector , update , true);
360
+ bson_destroy (selector );
361
+ bson_destroy (update );
362
+ }
363
+
364
+ r = mongoc_bulk_operation_execute (bulk , & reply , & error );
365
+ if (!r ) fprintf (stderr , "%s\n" , error .message );
366
+ assert (r );
367
+
368
+ #if 0
369
+ printf ("%s\n" , bson_as_json (& reply , NULL ));
370
+ #endif
371
+
372
+ assert (bson_iter_init_find (& iter , & reply , "nMatched" ) &&
373
+ BSON_ITER_HOLDS_INT32 (& iter ) &&
374
+ (0 == bson_iter_int32 (& iter )));
375
+ assert (bson_iter_init_find (& iter , & reply , "nUpserted" ) &&
376
+ BSON_ITER_HOLDS_INT32 (& iter ) &&
377
+ (3 == bson_iter_int32 (& iter )));
378
+ assert (bson_iter_init_find (& iter , & reply , "nInserted" ) &&
379
+ BSON_ITER_HOLDS_INT32 (& iter ) &&
380
+ (0 == bson_iter_int32 (& iter )));
381
+ assert (bson_iter_init_find (& iter , & reply , "nRemoved" ) &&
382
+ BSON_ITER_HOLDS_INT32 (& iter ) &&
383
+ (0 == bson_iter_int32 (& iter )));
384
+
385
+ assert (bson_iter_init_find (& iter , & reply , "upserted" ) &&
386
+ BSON_ITER_HOLDS_ARRAY (& iter ) &&
387
+ bson_iter_recurse (& iter , & citer ));
388
+
389
+ assert (bson_iter_next (& citer ));
390
+ assert (BSON_ITER_HOLDS_DOCUMENT (& citer ));
391
+ assert (bson_iter_recurse (& citer , & child ));
392
+ assert (bson_iter_find (& child , "_id" ));
393
+ assert (BSON_ITER_HOLDS_INT32 (& child ));
394
+ assert (0 == bson_iter_int32 (& child ));
395
+ assert (bson_iter_recurse (& citer , & child ));
396
+ assert (bson_iter_find (& child , "index" ));
397
+ assert (BSON_ITER_HOLDS_INT32 (& child ));
398
+ assert (0 == bson_iter_int32 (& child ));
399
+
400
+ assert (bson_iter_next (& citer ));
401
+ assert (BSON_ITER_HOLDS_DOCUMENT (& citer ));
402
+ assert (bson_iter_recurse (& citer , & child ));
403
+ assert (bson_iter_find (& child , "_id" ));
404
+ assert (BSON_ITER_HOLDS_INT32 (& child ));
405
+ assert (1 == bson_iter_int32 (& child ));
406
+ assert (bson_iter_recurse (& citer , & child ));
407
+ assert (bson_iter_find (& child , "index" ));
408
+ assert (BSON_ITER_HOLDS_INT32 (& child ));
409
+ assert (1 == bson_iter_int32 (& child ));
410
+
411
+ assert (bson_iter_next (& citer ));
412
+ assert (BSON_ITER_HOLDS_DOCUMENT (& citer ));
413
+ assert (bson_iter_recurse (& citer , & child ));
414
+ assert (bson_iter_find (& child , "_id" ));
415
+ assert (BSON_ITER_HOLDS_INT32 (& child ));
416
+ assert (2 == bson_iter_int32 (& child ));
417
+ assert (bson_iter_recurse (& citer , & child ));
418
+ assert (bson_iter_find (& child , "index" ));
419
+ assert (BSON_ITER_HOLDS_INT32 (& child ));
420
+ assert (2 == bson_iter_int32 (& child ));
421
+
422
+ assert (!bson_iter_next (& citer ));
423
+
424
+ bson_destroy (& reply );
425
+
426
+ mongoc_bulk_operation_destroy (bulk );
427
+ mongoc_collection_destroy (collection );
428
+ mongoc_client_destroy (client );
429
+ }
430
+
431
+
295
432
void
296
433
test_bulk_install (TestSuite * suite )
297
434
{
@@ -300,6 +437,7 @@ test_bulk_install (TestSuite *suite)
300
437
TestSuite_Add (suite , "/BulkOperation/basic" , test_bulk );
301
438
TestSuite_Add (suite , "/BulkOperation/update_upserted" , test_update_upserted );
302
439
TestSuite_Add (suite , "/BulkOperation/index_offset" , test_index_offset );
440
+ TestSuite_Add (suite , "/BulkOperation/CDRIVER-372" , test_bulk_edge_case_372 );
303
441
304
442
atexit (cleanup_globals );
305
443
}
0 commit comments