|
1 | 1 | /* Anything javascript specific relating to timeouts */
|
2 | 2 | import { expect } from 'chai';
|
3 |
| -import * as semver from 'semver'; |
4 | 3 | import * as sinon from 'sinon';
|
5 | 4 |
|
6 | 5 | import {
|
7 | 6 | BSON,
|
8 | 7 | type ClientSession,
|
| 8 | + Code, |
9 | 9 | type Collection,
|
10 | 10 | Connection,
|
11 | 11 | type Db,
|
@@ -231,15 +231,56 @@ describe('CSOT driver tests', () => {
|
231 | 231 | });
|
232 | 232 | });
|
233 | 233 |
|
234 |
| - describe('when a maxTimeExpired error is returned inside a writeErrors array', () => { |
235 |
| - // Okay so allegedly this can never happen. |
236 |
| - // But the spec says it can, so let's be defensive and support it. |
| 234 | + describe('when a maxTimeExpired error is returned as the first error in a writeErrors array', () => { |
237 | 235 | // {ok: 1, writeErrors: [{code: 50, codeName: "MaxTimeMSExpired", errmsg: "operation time limit exceeded"}]}
|
238 | 236 |
|
| 237 | + let client; |
| 238 | + let collection: Collection; |
| 239 | + |
| 240 | + beforeEach(async function () { |
| 241 | + const utilClient = this.configuration.newClient(); |
| 242 | + const collectionTmp = utilClient.db('test_db').collection('bulkWriteErrors'); |
| 243 | + await collectionTmp.drop().catch(() => null); |
| 244 | + await collectionTmp.insertMany(Array.from({ length: 1000 }, () => ({}))); |
| 245 | + utilClient.close(); |
| 246 | + |
| 247 | + client = this.configuration.newClient({ timeoutMS: 500_000, monitorCommands: true }); |
| 248 | + collection = client.db('test_db').collection('bulkWriteErrors'); |
| 249 | + }); |
| 250 | + |
| 251 | + afterEach(async () => { |
| 252 | + collection = undefined; |
| 253 | + await client.close(); |
| 254 | + }); |
| 255 | + |
| 256 | + it('throws a MongoOperationTimeoutError error and emits command succeeded', async () => { |
| 257 | + const updateOne = { |
| 258 | + filter: { $where: new Code('function () { sleep(1 * 100); return true; }') }, |
| 259 | + update: { $inc: { x: 1 } } |
| 260 | + }; |
| 261 | + |
| 262 | + const error = await collection.bulkWrite([{ updateOne }], { maxTimeMS: 4 }).catch(e => e); |
| 263 | + |
| 264 | + expect(error).to.be.instanceOf(MongoOperationTimeoutError); |
| 265 | + expect(error.cause).to.be.instanceOf(MongoServerError); |
| 266 | + expect(error.cause).to.have.property('code', 50); |
| 267 | + |
| 268 | + expect(commandsSucceeded).to.have.lengthOf(1); |
| 269 | + expect(commandsSucceeded).to.have.nested.property('[0].reply.writeErrors[0].code', 50); |
| 270 | + }); |
| 271 | + }); |
| 272 | + |
| 273 | + describe('when a maxTimeExpired error is returned deeper inside a writeErrors array', () => { |
| 274 | + // The server should always return one maxTimeExpiredError at the front of the writeErrors array |
| 275 | + // But for the sake of defensive programming we will find any maxTime error in the array. |
| 276 | + |
239 | 277 | beforeEach(async () => {
|
240 | 278 | const writeErrorsReply = BSON.serialize({
|
241 | 279 | ok: 1,
|
242 | 280 | writeErrors: [
|
| 281 | + { code: 2, codeName: 'MaxTimeMSExpired', errmsg: 'operation time limit exceeded' }, |
| 282 | + { code: 3, codeName: 'MaxTimeMSExpired', errmsg: 'operation time limit exceeded' }, |
| 283 | + { code: 4, codeName: 'MaxTimeMSExpired', errmsg: 'operation time limit exceeded' }, |
243 | 284 | { code: 50, codeName: 'MaxTimeMSExpired', errmsg: 'operation time limit exceeded' }
|
244 | 285 | ]
|
245 | 286 | });
|
|
0 commit comments