@@ -738,7 +738,8 @@ describe('CRUD Prose Spec Tests', () => {
738
738
async test ( ) {
739
739
const error = await client
740
740
. bulkWrite ( [ { name : 'insertOne' , namespace : 'db.coll' , document : document } ] , {
741
- writeConcern : { w : 0 }
741
+ writeConcern : { w : 0 } ,
742
+ ordered : false
742
743
} )
743
744
. catch ( error => error ) ;
744
745
expect ( error . message ) . to . include ( 'Client bulk write operation ops of length' ) ;
@@ -763,7 +764,7 @@ describe('CRUD Prose Spec Tests', () => {
763
764
const error = await client
764
765
. bulkWrite (
765
766
[ { name : 'replaceOne' , namespace : 'db.coll' , filter : { } , replacement : document } ] ,
766
- { writeConcern : { w : 0 } }
767
+ { writeConcern : { w : 0 } , ordered : false }
767
768
)
768
769
. catch ( error => error ) ;
769
770
expect ( error . message ) . to . include ( 'Client bulk write operation ops of length' ) ;
@@ -1079,4 +1080,89 @@ describe('CRUD Prose Spec Tests', () => {
1079
1080
expect ( command ) . to . have . property ( 'maxTimeMS' , 2000 ) ;
1080
1081
} ) ;
1081
1082
} ) ;
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
+ } ) ;
1082
1168
} ) ;
0 commit comments