@@ -738,7 +738,8 @@ describe('CRUD Prose Spec Tests', () => {
738738 async test ( ) {
739739 const error = await client
740740 . bulkWrite ( [ { name : 'insertOne' , namespace : 'db.coll' , document : document } ] , {
741- writeConcern : { w : 0 }
741+ writeConcern : { w : 0 } ,
742+ ordered : false
742743 } )
743744 . catch ( error => error ) ;
744745 expect ( error . message ) . to . include ( 'Client bulk write operation ops of length' ) ;
@@ -763,7 +764,7 @@ describe('CRUD Prose Spec Tests', () => {
763764 const error = await client
764765 . bulkWrite (
765766 [ { name : 'replaceOne' , namespace : 'db.coll' , filter : { } , replacement : document } ] ,
766- { writeConcern : { w : 0 } }
767+ { writeConcern : { w : 0 } , ordered : false }
767768 )
768769 . catch ( error => error ) ;
769770 expect ( error . message ) . to . include ( 'Client bulk write operation ops of length' ) ;
@@ -1079,4 +1080,89 @@ describe('CRUD Prose Spec Tests', () => {
10791080 expect ( command ) . to . have . property ( 'maxTimeMS' , 2000 ) ;
10801081 } ) ;
10811082 } ) ;
1083+
1084+ describe ( '15. `MongoClient.bulkWrite` with unacknowledged write concern uses `w:0` for all batches' , function ( ) {
1085+ // This test must only be run on 8.0+ servers. This test must be skipped on Atlas Serverless.
1086+ // If testing with a sharded cluster, only connect to one mongos. This is intended to ensure the `countDocuments` operation
1087+ // uses the same connection as the `bulkWrite` to get the correct connection count. (See
1088+ // [DRIVERS-2921](https://jira.mongodb.org/browse/DRIVERS-2921)).
1089+ // Construct a `MongoClient` (referred to as `client`) with
1090+ // [command monitoring](../../command-logging-and-monitoring/command-logging-and-monitoring.md) enabled to observe
1091+ // CommandStartedEvents. Perform a `hello` command using `client` and record the `maxBsonObjectSize` and
1092+ // `maxMessageSizeBytes` values in the response.
1093+ // Construct a `MongoCollection` (referred to as `coll`) for the collection "db.coll". Drop `coll`.
1094+ // Use the `create` command to create "db.coll" to workaround [SERVER-95537](https://jira.mongodb.org/browse/SERVER-95537).
1095+ // Construct the following write model (referred to as `model`):
1096+ // InsertOne: {
1097+ // "namespace": "db.coll",
1098+ // "document": { "a": "b".repeat(maxBsonObjectSize - 500) }
1099+ // }
1100+ // Construct a list of write models (referred to as `models`) with `model` repeated
1101+ // `maxMessageSizeBytes / maxBsonObjectSize + 1` times.
1102+ // Call `client.bulkWrite` with `models`. Pass `BulkWriteOptions` with `ordered` set to `false` and `writeConcern` set to
1103+ // an unacknowledged write concern. Assert no error occurred. Assert the result indicates the write was unacknowledged.
1104+ // Assert that two CommandStartedEvents (referred to as `firstEvent` and `secondEvent`) were observed for the `bulkWrite`
1105+ // command. Assert that the length of `firstEvent.command.ops` is `maxMessageSizeBytes / maxBsonObjectSize`. Assert that
1106+ // the length of `secondEvent.command.ops` is 1. If the driver exposes `operationId`s in its CommandStartedEvents, assert
1107+ // that `firstEvent.operationId` is equal to `secondEvent.operationId`. Assert both commands include
1108+ // `writeConcern: {w: 0}`.
1109+ // To force completion of the `w:0` writes, execute `coll.countDocuments` and expect the returned count is
1110+ // `maxMessageSizeBytes / maxBsonObjectSize + 1`. This is intended to avoid incomplete writes interfering with other tests
1111+ // that may use this collection.
1112+ let client : MongoClient ;
1113+ let maxBsonObjectSize ;
1114+ let maxMessageSizeBytes ;
1115+ let numModels ;
1116+ let models : AnyClientBulkWriteModel [ ] = [ ] ;
1117+ const commands : CommandStartedEvent [ ] = [ ] ;
1118+
1119+ beforeEach ( async function ( ) {
1120+ const uri = this . configuration . url ( {
1121+ useMultipleMongoses : false
1122+ } ) ;
1123+ client = this . configuration . newClient ( uri , { monitorCommands : true } ) ;
1124+ await client . connect ( ) ;
1125+ await client
1126+ . db ( 'db' )
1127+ . collection ( 'coll' )
1128+ . drop ( )
1129+ . catch ( ( ) => null ) ;
1130+ await client . db ( 'db' ) . createCollection ( 'coll' ) ;
1131+ const hello = await client . db ( 'admin' ) . command ( { hello : 1 } ) ;
1132+ maxBsonObjectSize = hello . maxBsonObjectSize ;
1133+ maxMessageSizeBytes = hello . maxMessageSizeBytes ;
1134+ numModels = Math . floor ( maxMessageSizeBytes / maxBsonObjectSize ) + 1 ;
1135+ models = Array . from ( { length : numModels } , ( ) => {
1136+ return {
1137+ name : 'insertOne' ,
1138+ namespace : 'db.coll' ,
1139+ document : {
1140+ a : 'b' . repeat ( maxBsonObjectSize - 500 )
1141+ }
1142+ } ;
1143+ } ) ;
1144+
1145+ client . on ( 'commandStarted' , filterForCommands ( 'bulkWrite' , commands ) ) ;
1146+ commands . length = 0 ;
1147+ } ) ;
1148+
1149+ afterEach ( async function ( ) {
1150+ await client . close ( ) ;
1151+ } ) ;
1152+
1153+ it ( 'performs all writes unacknowledged' , {
1154+ metadata : { requires : { mongodb : '>=8.0.0' , serverless : 'forbid' } } ,
1155+ async test ( ) {
1156+ const result = await client . bulkWrite ( models , { ordered : false , writeConcern : { w : 0 } } ) ;
1157+ expect ( result ) . to . deep . equal ( { ok : 1 } ) ;
1158+ expect ( commands . length ) . to . equal ( 2 ) ;
1159+ expect ( commands [ 0 ] . command . ops . length ) . to . equal ( numModels - 1 ) ;
1160+ expect ( commands [ 0 ] . command . writeConcern . w ) . to . equal ( 0 ) ;
1161+ expect ( commands [ 1 ] . command . ops . length ) . to . equal ( 1 ) ;
1162+ expect ( commands [ 1 ] . command . writeConcern . w ) . to . equal ( 0 ) ;
1163+ const count = await client . db ( 'db' ) . collection ( 'coll' ) . countDocuments ( ) ;
1164+ expect ( count ) . to . equal ( numModels ) ;
1165+ }
1166+ } ) ;
1167+ } ) ;
10821168} ) ;
0 commit comments