From 45db8c00dc93a045c476eb912f63eac61733e70a Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Mon, 6 Apr 2026 15:32:51 -0700 Subject: [PATCH 1/6] test(NODE-7508): Fix inconsistent wording for prose retryable writes test 6, case 3 --- .../retryable_writes.spec.prose.test.ts | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts index 4edeb0ef28f..d61d8cfe68f 100644 --- a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts +++ b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts @@ -239,38 +239,40 @@ describe('Retryable Writes Spec Prose', () => { * Additionally, this test requires drivers to set a fail point after an insertOne operation but before the subsequent retry. * Drivers that are unable to set a failCommand after the CommandSucceededEvent SHOULD use mocking or write a unit test to cover the same sequence of events. * - * Create a client with retryWrites=true. + * 1. Create a client with retryWrites=true. * - * Configure a fail point with error code 91 (ShutdownInProgress): + * 2. Configure a fail point with error code `91` (ShutdownInProgress) with the `RetryableError` and + * `SystemOverloadedError` error labels: * ```js * db.adminCommand({ * configureFailPoint: 'failCommand', * mode: { times: 1 }, * data: { - * writeConcernError: { - * code: 91, - * errorLabels: ['RetryableWriteError'] - * }, * failCommands: ['insert'] + * errorLabels: ['RetryableError', 'SystemOverloadedError'], + * errorCode: 91, * } * }); * ``` - * Via the command monitoring CommandSucceededEvent, configure a fail point with error code 10107 (NotWritablePrimary) and a NoWritesPerformed label: + * + * 3. Via the command monitoring CommandSucceededEvent, configure a fail point with error code `91` (ShutdownInProgress) and + * the `NoWritesPerformed`, `RetryableError` and `SystemOverloadedError` labels: * * ```js * db.adminCommand({ * configureFailPoint: 'failCommand', - * mode: { times: 1 }, + * mode: 'alwaysOn', * data: { - * errorCode: 10107, - * errorLabels: ['RetryableWriteError', 'NoWritesPerformed'], * failCommands: ['insert'] + * errorLabels: [ 'RetryableError', 'SystemOverloadedError', 'NoWritesPerformed'], + * errorCode: 91, * } * }); * ``` - * Drivers SHOULD only configure the 10107 fail point command if the the succeeded event is for the 91 error configured in step 2. + * + * Drivers SHOULD configure the second fail point command only if the event is for the first error configured in step 2. * - * Attempt an insertOne operation on any record for any database and collection. For the resulting error, assert that the associated error code is 91. + * 4. Attempt an insertOne operation on any record for any database and collection. For the resulting error, assert that the associated error code is 91. */ it( 'when a retry attempt fails with an error labeled NoWritesPerformed, drivers MUST return the original error', @@ -279,7 +281,8 @@ describe('Retryable Writes Spec Prose', () => { const serverCommandStub = sinon.stub(Server.prototype, 'command'); serverCommandStub.onCall(0).rejects( new MongoWriteConcernError({ - errorLabels: ['RetryableWriteError'], + // errorLabels: ['RetryableError', 'SystemOverloadedError'], // expected changes, tests fail + errorLabels: ['RetryableWriteError'], // original, tests pass writeConcernError: { errmsg: 'ShutdownInProgress error', code: 91 }, ok: 1 }) @@ -287,8 +290,10 @@ describe('Retryable Writes Spec Prose', () => { serverCommandStub.onCall(1).returns( Promise.reject( new MongoWriteConcernError({ - errorLabels: ['RetryableWriteError', 'NoWritesPerformed'], - writeConcernError: { errmsg: 'NotWritablePrimary error', errorCode: 10107 } + errorLabels: ['RetryableWriteError', 'NoWritesPerformed'], // original, tests pass + // errorLabels: ['RetryableError', 'SystemOverloadedError', 'NoWritesPerformed'], // expected changes, tests fail + writeConcernError: { errmsg: 'NotWritablePrimary error', code: 91 }, // my changes + ok: 1 }) ) ); @@ -526,10 +531,10 @@ describe('Retryable Writes Spec Prose', () => { serverCommandStub.callCount === 1 ? [MongoErrorLabel.RetryableError, MongoErrorLabel.SystemOverloadedError] : [ - MongoErrorLabel.RetryableError, - MongoErrorLabel.SystemOverloadedError, - MongoErrorLabel.NoWritesPerformed - ]; + MongoErrorLabel.RetryableError, + MongoErrorLabel.SystemOverloadedError, + MongoErrorLabel.NoWritesPerformed + ]; throw new MongoServerError({ message: 'Server Error', From e4b900f2163810b8ad729e99e1487e4a6e62503e Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Tue, 7 Apr 2026 07:30:03 -0700 Subject: [PATCH 2/6] lint fixes --- .../retryable_writes.spec.prose.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts index d61d8cfe68f..86ce484384c 100644 --- a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts +++ b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts @@ -254,7 +254,7 @@ describe('Retryable Writes Spec Prose', () => { * } * }); * ``` - * + * * 3. Via the command monitoring CommandSucceededEvent, configure a fail point with error code `91` (ShutdownInProgress) and * the `NoWritesPerformed`, `RetryableError` and `SystemOverloadedError` labels: * @@ -269,7 +269,7 @@ describe('Retryable Writes Spec Prose', () => { * } * }); * ``` - * + * * Drivers SHOULD configure the second fail point command only if the event is for the first error configured in step 2. * * 4. Attempt an insertOne operation on any record for any database and collection. For the resulting error, assert that the associated error code is 91. @@ -531,10 +531,10 @@ describe('Retryable Writes Spec Prose', () => { serverCommandStub.callCount === 1 ? [MongoErrorLabel.RetryableError, MongoErrorLabel.SystemOverloadedError] : [ - MongoErrorLabel.RetryableError, - MongoErrorLabel.SystemOverloadedError, - MongoErrorLabel.NoWritesPerformed - ]; + MongoErrorLabel.RetryableError, + MongoErrorLabel.SystemOverloadedError, + MongoErrorLabel.NoWritesPerformed + ]; throw new MongoServerError({ message: 'Server Error', From 49db2b15142d42fd0d7e8c1a21fbd183d084be43 Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Tue, 7 Apr 2026 09:42:04 -0700 Subject: [PATCH 3/6] revert unnecessary changes --- .../retryable_writes.spec.prose.test.ts | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts index 86ce484384c..4edeb0ef28f 100644 --- a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts +++ b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts @@ -239,40 +239,38 @@ describe('Retryable Writes Spec Prose', () => { * Additionally, this test requires drivers to set a fail point after an insertOne operation but before the subsequent retry. * Drivers that are unable to set a failCommand after the CommandSucceededEvent SHOULD use mocking or write a unit test to cover the same sequence of events. * - * 1. Create a client with retryWrites=true. + * Create a client with retryWrites=true. * - * 2. Configure a fail point with error code `91` (ShutdownInProgress) with the `RetryableError` and - * `SystemOverloadedError` error labels: + * Configure a fail point with error code 91 (ShutdownInProgress): * ```js * db.adminCommand({ * configureFailPoint: 'failCommand', * mode: { times: 1 }, * data: { + * writeConcernError: { + * code: 91, + * errorLabels: ['RetryableWriteError'] + * }, * failCommands: ['insert'] - * errorLabels: ['RetryableError', 'SystemOverloadedError'], - * errorCode: 91, * } * }); * ``` - * - * 3. Via the command monitoring CommandSucceededEvent, configure a fail point with error code `91` (ShutdownInProgress) and - * the `NoWritesPerformed`, `RetryableError` and `SystemOverloadedError` labels: + * Via the command monitoring CommandSucceededEvent, configure a fail point with error code 10107 (NotWritablePrimary) and a NoWritesPerformed label: * * ```js * db.adminCommand({ * configureFailPoint: 'failCommand', - * mode: 'alwaysOn', + * mode: { times: 1 }, * data: { + * errorCode: 10107, + * errorLabels: ['RetryableWriteError', 'NoWritesPerformed'], * failCommands: ['insert'] - * errorLabels: [ 'RetryableError', 'SystemOverloadedError', 'NoWritesPerformed'], - * errorCode: 91, * } * }); * ``` + * Drivers SHOULD only configure the 10107 fail point command if the the succeeded event is for the 91 error configured in step 2. * - * Drivers SHOULD configure the second fail point command only if the event is for the first error configured in step 2. - * - * 4. Attempt an insertOne operation on any record for any database and collection. For the resulting error, assert that the associated error code is 91. + * Attempt an insertOne operation on any record for any database and collection. For the resulting error, assert that the associated error code is 91. */ it( 'when a retry attempt fails with an error labeled NoWritesPerformed, drivers MUST return the original error', @@ -281,8 +279,7 @@ describe('Retryable Writes Spec Prose', () => { const serverCommandStub = sinon.stub(Server.prototype, 'command'); serverCommandStub.onCall(0).rejects( new MongoWriteConcernError({ - // errorLabels: ['RetryableError', 'SystemOverloadedError'], // expected changes, tests fail - errorLabels: ['RetryableWriteError'], // original, tests pass + errorLabels: ['RetryableWriteError'], writeConcernError: { errmsg: 'ShutdownInProgress error', code: 91 }, ok: 1 }) @@ -290,10 +287,8 @@ describe('Retryable Writes Spec Prose', () => { serverCommandStub.onCall(1).returns( Promise.reject( new MongoWriteConcernError({ - errorLabels: ['RetryableWriteError', 'NoWritesPerformed'], // original, tests pass - // errorLabels: ['RetryableError', 'SystemOverloadedError', 'NoWritesPerformed'], // expected changes, tests fail - writeConcernError: { errmsg: 'NotWritablePrimary error', code: 91 }, // my changes - ok: 1 + errorLabels: ['RetryableWriteError', 'NoWritesPerformed'], + writeConcernError: { errmsg: 'NotWritablePrimary error', errorCode: 10107 } }) ) ); From 22b4a0817be12d4847b111ba85de9ace6be10eac Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Tue, 7 Apr 2026 09:59:12 -0700 Subject: [PATCH 4/6] update the correct test --- .../retryable_writes.spec.prose.test.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts index 4edeb0ef28f..5f60712a1d9 100644 --- a/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts +++ b/test/integration/retryable-writes/retryable_writes.spec.prose.test.ts @@ -490,33 +490,35 @@ describe('Retryable Writes Spec Prose', () => { 'Case 3: Test that drivers return the correct error when receiving some errors with NoWritesPerformed and some without NoWritesPerformed', { requires: { topology: 'replicaset', mongodb: '>=6.0' } }, async () => { - // 2. Configure the client to listen to CommandFailedEvents. In the attached listener, configure a fail point with error - // code `91` (NotWritablePrimary) and the `NoWritesPerformed`, `RetryableError` and `SystemOverloadedError` labels: + // 2. Configure a fail point with error code `91` (ShutdownInProgress) with the `RetryableError` and + // `SystemOverloadedError` error labels: // ```javascript // { // configureFailPoint: "failCommand", - // mode: "alwaysOn", + // mode: {times: 1}, // data: { // failCommands: ["insert"], - // errorLabels: ["RetryableError", "SystemOverloadedError", "NoWritesPerformed"], + // errorLabels: ["RetryableError", "SystemOverloadedError"], // errorCode: 91 // } // } // ``` - // 3. Configure a fail point with error code `91` (ShutdownInProgress) with the `RetryableError` and - // `SystemOverloadedError` error labels but without the `NoWritesPerformed` error label: + // 3. Via the command monitoring CommandFailedEvent, configure a fail point with error code `91` (ShutdownInProgress) and + // the `NoWritesPerformed`, `RetryableError` and `SystemOverloadedError` labels: // ```javascript // { // configureFailPoint: "failCommand", - // mode: {times: 1}, + // mode: "alwaysOn", // data: { // failCommands: ["insert"], - // errorLabels: ["RetryableError", "SystemOverloadedError"], + // errorLabels: ["RetryableError", "SystemOverloadedError", "NoWritesPerformed"], // errorCode: 91 // } // } // ``` + // Configure the second fail point command only if the failed event is for the first error configured in step 2. + const serverCommandStub = sinon .stub(Server.prototype, 'command') .callsFake(async function () { From 958796d8ca767fb4186d96f936ce994cda9476f4 Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Tue, 7 Apr 2026 12:01:26 -0700 Subject: [PATCH 5/6] skip sinon-based test in nodeless --- test/integration/crud/find.test.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/integration/crud/find.test.ts b/test/integration/crud/find.test.ts index bb6fc2146e4..0d14f237a08 100644 --- a/test/integration/crud/find.test.ts +++ b/test/integration/crud/find.test.ts @@ -8,7 +8,8 @@ import { type MongoClient, MongoServerError, ObjectId, - ReturnDocument + ReturnDocument, + runNodelessTests } from '../../mongodb'; import { assert as test, filterForCommands } from '../shared'; @@ -1078,6 +1079,11 @@ describe('Find', function () { 'regression test (NODE-6878): CursorResponse.emptyGetMore contains all CursorResponse fields', { requires: { topology: 'sharded' } }, async function () { + if (runNodelessTests) { + // This test relies on sinon spying on an internal method, but this doesn't work in nodeless due to the way sinon is bundled. + this.skip(); + } + const collection = client.db('rewind-regression').collection('bar'); await collection.deleteMany({}); From 7aceec05d2accb4822501fdddd37d780cb3bc587 Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Tue, 7 Apr 2026 13:44:34 -0700 Subject: [PATCH 6/6] remove test skip --- test/integration/crud/find.test.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/integration/crud/find.test.ts b/test/integration/crud/find.test.ts index 0d14f237a08..bb6fc2146e4 100644 --- a/test/integration/crud/find.test.ts +++ b/test/integration/crud/find.test.ts @@ -8,8 +8,7 @@ import { type MongoClient, MongoServerError, ObjectId, - ReturnDocument, - runNodelessTests + ReturnDocument } from '../../mongodb'; import { assert as test, filterForCommands } from '../shared'; @@ -1079,11 +1078,6 @@ describe('Find', function () { 'regression test (NODE-6878): CursorResponse.emptyGetMore contains all CursorResponse fields', { requires: { topology: 'sharded' } }, async function () { - if (runNodelessTests) { - // This test relies on sinon spying on an internal method, but this doesn't work in nodeless due to the way sinon is bundled. - this.skip(); - } - const collection = client.db('rewind-regression').collection('bar'); await collection.deleteMany({});