From 791029fcac2c898c3f60463e5d59da342700c3d9 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Tue, 3 Sep 2024 16:23:47 -0400 Subject: [PATCH 01/22] initial commit --- src/cmap/commands.ts | 2 +- .../read-write-concern/write_concern.test.ts | 5 +++-- test/unit/commands.test.ts | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index 19dd8e1a657..954455bc154 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -450,7 +450,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || false; + this.moreToCome = options.moreToCome || options.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index 58901e513b5..c995a1b928a 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -11,7 +11,7 @@ import { import * as mock from '../../tools/mongodb-mock/index'; import { filterForCommands } from '../shared'; -describe('Write Concern', function () { +describe.only('Write Concern', function () { context('when the WriteConcern is set in the uri', function () { let client; const events: CommandStartedEvent[] = []; @@ -29,7 +29,8 @@ describe('Write Concern', function () { expect(events[0]).to.containSubset({ commandName: 'insert', command: { - writeConcern: { w: 0 } + writeConcern: { w: 0 }, + moreToCome: true } }); }); diff --git a/test/unit/commands.test.ts b/test/unit/commands.test.ts index f6ba300b7aa..93831530955 100644 --- a/test/unit/commands.test.ts +++ b/test/unit/commands.test.ts @@ -6,6 +6,8 @@ import * as compression from '../../src/cmap/wire_protocol/compression'; import { compress, Compressor, + Connection, + MongoClient, OP_MSG, OP_QUERY, OpCompressedRequest, @@ -109,3 +111,14 @@ describe('class OpCompressedRequest', () => { } }); }); + +describe.only('fire-and-forget', () => { + describe('OpMsgRequest', () => { + context('when writeConcern.w is 0', () => { + it('moreToCome is set to true', async () => { + const request = new OpMsgRequest('db', { a: 1 }, { writeConcern: { w: 0 } }); + expect(request.moreToCome).to.be.true; + }); + }); + }); +}); From d1a1931a460b0b17c6083b603e54bdbdf6932423 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Tue, 3 Sep 2024 18:15:27 -0400 Subject: [PATCH 02/22] enforce no response when moreToCome is set --- src/cmap/connection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index 1e4afc7f387..8a52f4e71bc 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -438,7 +438,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse) { + if (options.noResponse || ('moreToCome' in message && message?.moreToCome)) { yield MongoDBResponse.empty; return; } From ebd4b44854cf8048016eff515e50d9a4aa82ea6f Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 6 Sep 2024 16:54:49 -0400 Subject: [PATCH 03/22] ready for review lint fix lont fix 2 --- src/cmap/commands.ts | 2 +- src/cmap/connection.ts | 12 +- .../read-write-concern/write_concern.test.ts | 143 +++++++++++++++++- test/unit/commands.test.ts | 10 +- 4 files changed, 152 insertions(+), 15 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index ff9636f1828..a7554ff8819 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -465,7 +465,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || options.writeConcern?.w === 0 || false; + this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index f6a178f9797..be819c7a6cc 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -438,7 +438,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse || ('moreToCome' in message && message?.moreToCome)) { + if (options.noResponse) { yield MongoDBResponse.empty; return; } @@ -500,9 +500,13 @@ export class Connection extends TypedEventEmitter { let document: MongoDBResponse | undefined = undefined; /** Cached result of a toObject call */ let object: Document | undefined = undefined; + const wireOptions = options; + if (message instanceof OpMsgRequest) { + wireOptions.noResponse = options.noResponse || message.moreToCome; + } try { this.throwIfAborted(); - for await (document of this.sendWire(message, options, responseType)) { + for await (document of this.sendWire(message, wireOptions, responseType)) { object = undefined; if (options.session != null) { updateSessionFromResponse(options.session, document); @@ -526,7 +530,7 @@ export class Connection extends TypedEventEmitter { new CommandSucceededEvent( this, message, - options.noResponse ? undefined : (object ??= document.toObject(bsonOptions)), + wireOptions.noResponse ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), started, this.description.serverConnectionId ) @@ -629,8 +633,8 @@ export class Connection extends TypedEventEmitter { }); const buffer = Buffer.concat(await finalCommand.toBin()); - if (this.socket.write(buffer)) return; + return await once(this.socket, 'drain'); } diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index c995a1b928a..b00e971312d 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -1,17 +1,21 @@ import { expect } from 'chai'; import { on, once } from 'events'; +import { gte } from 'semver'; +import * as sinon from 'sinon'; import { type Collection, type CommandStartedEvent, + type CommandSucceededEvent, type Db, LEGACY_HELLO_COMMAND, - MongoClient + MongoClient, + OpMsgRequest } from '../../mongodb'; import * as mock from '../../tools/mongodb-mock/index'; import { filterForCommands } from '../shared'; -describe.only('Write Concern', function () { +describe('Write Concern', function () { context('when the WriteConcern is set in the uri', function () { let client; const events: CommandStartedEvent[] = []; @@ -29,8 +33,7 @@ describe.only('Write Concern', function () { expect(events[0]).to.containSubset({ commandName: 'insert', command: { - writeConcern: { w: 0 }, - moreToCome: true + writeConcern: { w: 0 } } }); }); @@ -169,4 +172,136 @@ describe.only('Write Concern', function () { }); }); }); + + describe('fire-and-forget protocol', function () { + context('when writeConcern = 0 and OP_MSG is used', function () { + const writeOperations: { name: string; command: any; expectedReturnVal: any }[] = [ + { + name: 'insertOne', + command: client => client.db('test').collection('test').insertOne({ a: 1 }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'insertMany', + command: client => + client + .db('test') + .collection('test') + .insertMany([{ a: 1 }, { b: 2 }]), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'updateOne', + command: client => + client + .db('test') + .collection('test') + .updateOne({ i: 128 }, { $set: { c: 2 } }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'updateMany', + command: client => + client + .db('test') + .collection('test') + .updateMany({ name: 'foobar' }, { $set: { name: 'fizzbuzz' } }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'deleteOne', + command: client => client.db('test').collection('test').deleteOne({ a: 1 }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'deleteMany', + command: client => client.db('test').collection('test').deleteMany({ name: 'foobar' }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'replaceOne', + command: client => client.db('test').collection('test').replaceOne({ a: 1 }, { b: 2 }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'removeUser', + command: client => client.db('test').removeUser('albert'), + expectedReturnVal: true + }, + { + name: 'findAndModify', + command: client => + client + .db('test') + .collection('test') + .findOneAndUpdate({}, { $setOnInsert: { a: 1 } }, { upsert: true }), + expectedReturnVal: null + }, + { + name: 'dropDatabase', + command: client => client.db('test').dropDatabase(), + expectedReturnVal: true + }, + { + name: 'dropCollection', + command: client => client.db('test').dropCollection('test'), + expectedReturnVal: true + }, + { + name: 'dropIndexes', + command: client => client.db('test').collection('test').dropIndex('a'), + expectedReturnVal: { ok: 1 } + }, + { + name: 'createIndexes', + command: client => client.db('test').collection('test').createIndex({ a: 1 }), + expectedReturnVal: 'a_1' + }, + { + name: 'createCollection', + command: client => client.db('test').createCollection('test'), + expectedReturnVal: {} + } + ]; + + for (const op of writeOperations) { + context(`when the write operation ${op.name} is run`, function () { + let client; + let spy; + + beforeEach(async function () { + if (gte('3.6.0', this.configuration.version)) { + this.currentTest.skipReason = 'Test requires OP_MSG, needs to be on MongoDB 3.6+'; + this.skip(); + } + spy = sinon.spy(OpMsgRequest.prototype, 'toBin'); + client = this.configuration.newClient({ monitorCommands: true, w: 0 }); + await client.connect(); + }); + + afterEach(function () { + sinon.restore(); + client.close(); + }); + + it('the request should have moreToCome bit set', async function () { + await op.command(client); + expect(spy.returnValues[spy.returnValues.length - 1][0][16]).to.equal(2); + }); + + it('the return value of the command should be nullish', async function () { + const result = await op.command(client); + expect(result).to.containSubset(op.expectedReturnVal); + }); + + it('commandSucceededEvent should have reply with only {ok: 1}', async function () { + const events: CommandSucceededEvent[] = []; + client.on('commandSucceeded', event => events.push(event)); + await op.command(client); + expect(events[0]).to.containSubset({ reply: { ok: 1 } }); + }); + }); + } + }); + }); }); diff --git a/test/unit/commands.test.ts b/test/unit/commands.test.ts index 93831530955..2b2cf5f58b4 100644 --- a/test/unit/commands.test.ts +++ b/test/unit/commands.test.ts @@ -6,8 +6,6 @@ import * as compression from '../../src/cmap/wire_protocol/compression'; import { compress, Compressor, - Connection, - MongoClient, OP_MSG, OP_QUERY, OpCompressedRequest, @@ -112,11 +110,11 @@ describe('class OpCompressedRequest', () => { }); }); -describe.only('fire-and-forget', () => { - describe('OpMsgRequest', () => { - context('when writeConcern.w is 0', () => { +describe('OpMsgRequest', () => { + describe('fire-and-forget', () => { + context('when writeConcern = 0', () => { it('moreToCome is set to true', async () => { - const request = new OpMsgRequest('db', { a: 1 }, { writeConcern: { w: 0 } }); + const request = new OpMsgRequest('db', { a: 1, writeConcern: { w: 0 } }, {}); expect(request.moreToCome).to.be.true; }); }); From 86e1a917981c0e2a485dde994e72ac014b1197d2 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 6 Sep 2024 17:04:51 -0400 Subject: [PATCH 04/22] tsdoc updateg --- src/write_concern.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/write_concern.ts b/src/write_concern.ts index 456b7e8d83b..8f2b288736a 100644 --- a/src/write_concern.ts +++ b/src/write_concern.ts @@ -58,7 +58,10 @@ interface CommandWriteConcernOptions { * @see https://www.mongodb.com/docs/manual/reference/write-concern/ */ export class WriteConcern { - /** Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. */ + /** + * Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. + * If w is 0 and is set on the command in the request, the server will not send a response. + */ readonly w?: W; /** Request acknowledgment that the write operation has been written to the on-disk journal */ readonly journal?: boolean; From d892ccca23654b109bf09d4b9b10e1b1bd5af47f Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 6 Sep 2024 17:19:46 -0400 Subject: [PATCH 05/22] lint fix remove extra newline remove extra newline --- src/cmap/connection.ts | 2 +- src/write_concern.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index be819c7a6cc..3cada6392cc 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -633,8 +633,8 @@ export class Connection extends TypedEventEmitter { }); const buffer = Buffer.concat(await finalCommand.toBin()); - if (this.socket.write(buffer)) return; + if (this.socket.write(buffer)) return; return await once(this.socket, 'drain'); } diff --git a/src/write_concern.ts b/src/write_concern.ts index 8f2b288736a..390646a3be0 100644 --- a/src/write_concern.ts +++ b/src/write_concern.ts @@ -58,10 +58,10 @@ interface CommandWriteConcernOptions { * @see https://www.mongodb.com/docs/manual/reference/write-concern/ */ export class WriteConcern { - /** - * Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. - * If w is 0 and is set on the command in the request, the server will not send a response. - */ + /** + * Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. + * If w is 0 and is set on a write operation, the server will not send a response. + */ readonly w?: W; /** Request acknowledgment that the write operation has been written to the on-disk journal */ readonly journal?: boolean; From 5df9384349fce91fa27a53e1bdaa99b6749e93a9 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 9 Sep 2024 10:22:18 -0400 Subject: [PATCH 06/22] fix failing test --- src/cmap/connection.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index 3cada6392cc..49726fdded1 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -438,7 +438,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse) { + if (options.noResponse || ('moreToCome' in message && message.moreToCome)) { yield MongoDBResponse.empty; return; } @@ -500,13 +500,9 @@ export class Connection extends TypedEventEmitter { let document: MongoDBResponse | undefined = undefined; /** Cached result of a toObject call */ let object: Document | undefined = undefined; - const wireOptions = options; - if (message instanceof OpMsgRequest) { - wireOptions.noResponse = options.noResponse || message.moreToCome; - } try { this.throwIfAborted(); - for await (document of this.sendWire(message, wireOptions, responseType)) { + for await (document of this.sendWire(message, options, responseType)) { object = undefined; if (options.session != null) { updateSessionFromResponse(options.session, document); @@ -530,7 +526,11 @@ export class Connection extends TypedEventEmitter { new CommandSucceededEvent( this, message, - wireOptions.noResponse ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), + options.noResponse + ? undefined + : 'moreToCome' in message && message.moreToCome + ? { ok: 1 } + : (object ??= document.toObject(bsonOptions)), started, this.description.serverConnectionId ) From 1e522639495fdb4d473ef3e3e785f1dfcd9698b3 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 9 Sep 2024 16:25:00 -0400 Subject: [PATCH 07/22] fix failing tests --- test/integration/read-write-concern/write_concern.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index b00e971312d..9d479a22718 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -13,6 +13,7 @@ import { OpMsgRequest } from '../../mongodb'; import * as mock from '../../tools/mongodb-mock/index'; +import { sleep } from '../../tools/utils'; import { filterForCommands } from '../shared'; describe('Write Concern', function () { @@ -98,6 +99,7 @@ describe('Write Concern', function () { afterEach(async function () { await db.dropDatabase(); + await sleep(1000); await client.close(); }); @@ -134,9 +136,10 @@ describe('Write Concern', function () { await col.createIndex({ b: -1 }); await col.createIndex({ a: 1, b: -1 }); + await sleep(1000); + const listIndexesResult = col.listIndexes({ batchSize: 2 }); const err = await listIndexesResult.toArray().catch(e => e); - expect(err).to.not.be.instanceOf(Error); }); @@ -165,6 +168,8 @@ describe('Write Concern', function () { { writeConcern: { w: 'majority' } } ); + await sleep(1000); + const err = await changes.next().catch(e => e); expect(err).to.not.be.instanceOf(Error); } From 7ca5e034a43522e07697915058b9928f8a364855 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 12 Sep 2024 12:02:27 -0400 Subject: [PATCH 08/22] requested changes 1 --- test/integration/read-write-concern/write_concern.test.ts | 8 +------- test/unit/commands.test.ts | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index 9d479a22718..64e656e4df4 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -13,7 +13,6 @@ import { OpMsgRequest } from '../../mongodb'; import * as mock from '../../tools/mongodb-mock/index'; -import { sleep } from '../../tools/utils'; import { filterForCommands } from '../shared'; describe('Write Concern', function () { @@ -98,8 +97,7 @@ describe('Write Concern', function () { }); afterEach(async function () { - await db.dropDatabase(); - await sleep(1000); + await db.dropDatabase({ writeConcern: { w: 'majority' } }); await client.close(); }); @@ -136,8 +134,6 @@ describe('Write Concern', function () { await col.createIndex({ b: -1 }); await col.createIndex({ a: 1, b: -1 }); - await sleep(1000); - const listIndexesResult = col.listIndexes({ batchSize: 2 }); const err = await listIndexesResult.toArray().catch(e => e); expect(err).to.not.be.instanceOf(Error); @@ -168,8 +164,6 @@ describe('Write Concern', function () { { writeConcern: { w: 'majority' } } ); - await sleep(1000); - const err = await changes.next().catch(e => e); expect(err).to.not.be.instanceOf(Error); } diff --git a/test/unit/commands.test.ts b/test/unit/commands.test.ts index 2b2cf5f58b4..3f601c678c0 100644 --- a/test/unit/commands.test.ts +++ b/test/unit/commands.test.ts @@ -111,7 +111,7 @@ describe('class OpCompressedRequest', () => { }); describe('OpMsgRequest', () => { - describe('fire-and-forget', () => { + describe('#constructor', () => { context('when writeConcern = 0', () => { it('moreToCome is set to true', async () => { const request = new OpMsgRequest('db', { a: 1, writeConcern: { w: 0 } }, {}); From 8243f9953e3a220a917790c23546087dfe9caeb2 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 12 Sep 2024 17:31:59 -0400 Subject: [PATCH 09/22] remove moreToCome as an option on the request - only on the reply --- src/cmap/commands.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index a7554ff8819..02f7fa0d7e9 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -50,7 +50,6 @@ export interface OpQueryOptions extends CommandOptions { secondaryOk?: boolean; requestId?: number; - moreToCome?: boolean; exhaustAllowed?: boolean; } @@ -412,7 +411,6 @@ export interface OpMsgOptions { ignoreUndefined: boolean; checkKeys: boolean; maxBsonSize: number; - moreToCome: boolean; exhaustAllowed: boolean; readPreference: ReadPreference; } @@ -465,7 +463,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; + this.moreToCome = command.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } From 7c607fd8356190e222aedba6be32edd40e703059 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 12 Sep 2024 17:46:37 -0400 Subject: [PATCH 10/22] add check to remove wordiness --- src/cmap/commands.ts | 2 ++ src/cmap/connection.ts | 4 ++-- test/integration/node-specific/mongo_client.test.ts | 2 +- test/integration/read-write-concern/write_concern.test.ts | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index 02f7fa0d7e9..a613447a06f 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -73,6 +73,8 @@ export class OpQueryRequest { awaitData: boolean; exhaust: boolean; partial: boolean; + /** moreToCome is an OP_MSG only concept */ + moreToCome = false; constructor( public databaseName: string, diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index c8b51528704..986cce46b6e 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -439,7 +439,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse || ('moreToCome' in message && message.moreToCome)) { + if (options.noResponse || message.moreToCome) { yield MongoDBResponse.empty; return; } @@ -529,7 +529,7 @@ export class Connection extends TypedEventEmitter { message, options.noResponse ? undefined - : 'moreToCome' in message && message.moreToCome + : message.moreToCome ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), started, diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 634516f8f76..bf94cbab7d6 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.have.property('reply', undefined); // noReponse: true + expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); }); context('when server selection would return no servers', () => { diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index 64e656e4df4..9db7269b89f 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -136,6 +136,7 @@ describe('Write Concern', function () { const listIndexesResult = col.listIndexes({ batchSize: 2 }); const err = await listIndexesResult.toArray().catch(e => e); + expect(err).to.not.be.instanceOf(Error); }); From 8b59ecd10c96d10128003bca574952a4b0c8a200 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 10:44:20 -0400 Subject: [PATCH 11/22] remove extraneous change --- test/integration/node-specific/mongo_client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index bf94cbab7d6..7ef0ecfc321 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); + expect(endEvents[0]).to.property('reply', undefined); }); context('when server selection would return no servers', () => { From 6422402188bb3fd8573a96c19dda0027dacbcdae Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 10:57:11 -0400 Subject: [PATCH 12/22] deprecate noResponse --- src/operations/command.ts | 1 + src/operations/run_command.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/operations/command.ts b/src/operations/command.ts index 94ccc6ceafe..51a6f647e93 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,6 +55,7 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; + /** @deprecated Will be removed in the next major version. Set writeConcern.w to 0 instead. */ noResponse?: boolean; } diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index ad7d02c044f..7c8abb76333 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -51,6 +51,7 @@ export class RunAdminCommandOperation extends AbstractOperation constructor( public command: Document, public override options: RunCommandOptions & { + /** @deprecated Will be removed in the next major version, and replaced with an option to set writeConcern.w to 0 */ noResponse?: boolean; bypassPinningCheck?: boolean; } From ee93834b08ca7556b30125cce8399b11b35d9dd8 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 15:59:46 -0400 Subject: [PATCH 13/22] add moreToCome back on the request --- src/cmap/commands.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index a613447a06f..1cc074b3b1c 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -50,6 +50,7 @@ export interface OpQueryOptions extends CommandOptions { secondaryOk?: boolean; requestId?: number; + moreToCome?: boolean; exhaustAllowed?: boolean; } @@ -408,12 +409,21 @@ const OPTS_EXHAUST_ALLOWED = 1 << 16; /** @internal */ export interface OpMsgOptions { - requestId: number; - serializeFunctions: boolean; - ignoreUndefined: boolean; - checkKeys: boolean; - maxBsonSize: number; - exhaustAllowed: boolean; + socketTimeoutMS?: number; + session?: ClientSession; + numberToSkip?: number; + numberToReturn?: number; + returnFieldSelector?: Document; + pre32Limit?: number; + serializeFunctions?: boolean; + ignoreUndefined?: boolean; + maxBsonSize?: number; + checkKeys?: boolean; + secondaryOk?: boolean; + + requestId?: number; + moreToCome?: boolean; + exhaustAllowed?: boolean; readPreference: ReadPreference; } @@ -465,7 +475,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = command.writeConcern?.w === 0 || false; + this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } From 56772b7f72795e6564edd74c711014e8daea3377 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 16:07:26 -0400 Subject: [PATCH 14/22] update deprecation comment --- src/operations/command.ts | 7 ++++++- src/operations/run_command.ts | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/operations/command.ts b/src/operations/command.ts index 51a6f647e93..8bfa111edfa 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,7 +55,12 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; - /** @deprecated Will be removed in the next major version. Set writeConcern.w to 0 instead. */ + /** + * @deprecated + * Will be removed in the next major version. Set writeConcern.w to 0 instead. + * + * **WARNING:** When this flag is true, it may result in indeterminate driver behavior. + */ noResponse?: boolean; } diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index 7c8abb76333..ad7d02c044f 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -51,7 +51,6 @@ export class RunAdminCommandOperation extends AbstractOperation constructor( public command: Document, public override options: RunCommandOptions & { - /** @deprecated Will be removed in the next major version, and replaced with an option to set writeConcern.w to 0 */ noResponse?: boolean; bypassPinningCheck?: boolean; } From 6104c57e71a6fc4ad202f8185cde69655af8f5cb Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 16 Sep 2024 10:51:54 -0400 Subject: [PATCH 15/22] remove noResponse deprecation - do in node-6377 lint fix --- src/cmap/commands.ts | 2 +- src/operations/command.ts | 6 ------ test/integration/node-specific/mongo_client.test.ts | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index 1cc074b3b1c..73ef1f2e1f4 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -475,7 +475,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; + this.moreToCome = options.moreToCome ?? command.writeConcern?.w === 0; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } diff --git a/src/operations/command.ts b/src/operations/command.ts index 8bfa111edfa..94ccc6ceafe 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,12 +55,6 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; - /** - * @deprecated - * Will be removed in the next major version. Set writeConcern.w to 0 instead. - * - * **WARNING:** When this flag is true, it may result in indeterminate driver behavior. - */ noResponse?: boolean; } diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 7ef0ecfc321..634516f8f76 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.property('reply', undefined); + expect(endEvents[0]).to.have.property('reply', undefined); // noReponse: true }); context('when server selection would return no servers', () => { From 419a84843b888122cd7c8ced41f4cf7d8d057205 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 16 Sep 2024 11:30:19 -0400 Subject: [PATCH 16/22] fix(NODE-6377): Remove noResponse option temp temp2 --- src/cmap/connection.ts | 12 ++++------ src/mongo_client.ts | 2 +- src/operations/command.ts | 1 - src/operations/run_command.ts | 7 +++--- .../connection.test.ts | 15 ++++++++++++ .../node-specific/mongo_client.test.ts | 4 ++-- test/unit/cmap/connection.test.ts | 23 ------------------- 7 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index 986cce46b6e..4bcb4850e5c 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -81,7 +81,6 @@ export interface CommandOptions extends BSONSerializeOptions { /** Session to use for the operation */ session?: ClientSession; documentsReturnedIn?: string; - noResponse?: boolean; omitReadPreference?: boolean; // TODO(NODE-2802): Currently the CommandOptions take a property willRetryWrite which is a hint @@ -94,6 +93,9 @@ export interface CommandOptions extends BSONSerializeOptions { writeConcern?: WriteConcern; directConnection?: boolean; + + // Triggers fire-and-forget protocol for commands that don't support WriteConcern + moreToCome?: boolean; } /** @public */ @@ -439,7 +441,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse || message.moreToCome) { + if (message.moreToCome) { yield MongoDBResponse.empty; return; } @@ -527,11 +529,7 @@ export class Connection extends TypedEventEmitter { new CommandSucceededEvent( this, message, - options.noResponse - ? undefined - : message.moreToCome - ? { ok: 1 } - : (object ??= document.toObject(bsonOptions)), + message.moreToCome ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), started, this.description.serverConnectionId ) diff --git a/src/mongo_client.ts b/src/mongo_client.ts index e8aae516392..c2c42c0318b 100644 --- a/src/mongo_client.ts +++ b/src/mongo_client.ts @@ -628,7 +628,7 @@ export class MongoClient extends TypedEventEmitter implements this, new RunAdminCommandOperation( { endSessions }, - { readPreference: ReadPreference.primaryPreferred, noResponse: true } + { readPreference: ReadPreference.primaryPreferred, moreToCome: true } ) ); } catch (error) { diff --git a/src/operations/command.ts b/src/operations/command.ts index 94ccc6ceafe..3786753bc6e 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,7 +55,6 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; - noResponse?: boolean; } /** @internal */ diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index ad7d02c044f..ae24a9a6dfd 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -5,8 +5,9 @@ import { type TODO_NODE_3286 } from '../mongo_types'; import type { ReadPreferenceLike } from '../read_preference'; import type { Server } from '../sdam/server'; import type { ClientSession } from '../sessions'; +import type { WriteConcern } from '../write_concern'; import { MongoDBNamespace } from '../utils'; -import { AbstractOperation } from './operation'; +import { Aspect, defineAspects, AbstractOperation } from './operation'; /** @public */ export type RunCommandOptions = { @@ -51,7 +52,7 @@ export class RunAdminCommandOperation extends AbstractOperation constructor( public command: Document, public override options: RunCommandOptions & { - noResponse?: boolean; + moreToCome?: boolean; bypassPinningCheck?: boolean; } ) { @@ -72,4 +73,4 @@ export class RunAdminCommandOperation extends AbstractOperation }); return res; } -} +} \ No newline at end of file diff --git a/test/integration/connection-monitoring-and-pooling/connection.test.ts b/test/integration/connection-monitoring-and-pooling/connection.test.ts index 1192dfdbcd4..e0b21c2f54b 100644 --- a/test/integration/connection-monitoring-and-pooling/connection.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection.test.ts @@ -144,6 +144,21 @@ describe('Connection', function () { } } }); + + it('supports fire-and-forget messages', async function () { + const options: ConnectionOptions = { + ...commonConnectOptions, + connectionType: Connection, + ...this.configuration.options, + metadata: makeClientMetadata({ driverInfo: {} }), + extendedMetadata: addContainerMetadata(makeClientMetadata({ driverInfo: {} })) + }; + + const conn = await connect(options); + const readSpy = sinon.spy(conn, 'readMany'); + await conn.command(ns('$admin.cmd'), { ping: 1 }, { moreToCome: true }); + expect(readSpy).to.not.have.been.called; + }); }); describe('Connection - functional', function () { diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 634516f8f76..7d853e21007 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -682,7 +682,7 @@ describe('class MongoClient', function () { expect(result2).to.have.property('ok', 1); }); - it('sends endSessions with noResponse set', async () => { + it('sends endSessions with writeConcern w = 0 set', async () => { const session = client.startSession(); // make a session to be ended await client.db('test').command({ ping: 1 }, { session }); await session.endSession(); @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.have.property('reply', undefined); // noReponse: true + expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); // writeConcern.w = 0 }); context('when server selection would return no servers', () => { diff --git a/test/unit/cmap/connection.test.ts b/test/unit/cmap/connection.test.ts index 75d5c246f24..639de5a0817 100644 --- a/test/unit/cmap/connection.test.ts +++ b/test/unit/cmap/connection.test.ts @@ -28,29 +28,6 @@ describe('new Connection()', function () { before(() => mock.createServer().then(s => (server = s))); - it('supports fire-and-forget messages', async function () { - server.setMessageHandler(request => { - const doc = request.document; - if (isHello(doc)) { - request.reply(mock.HELLO); - } - - // black hole all other requests - }); - - const options = { - ...connectionOptionsDefaults, - connectionType: Connection, - hostAddress: server.hostAddress(), - authProviders: new MongoClientAuthProviders() - }; - - const conn = await connect(options); - const readSpy = sinon.spy(conn, 'readMany'); - await conn.command(ns('$admin.cmd'), { ping: 1 }, { noResponse: true }); - expect(readSpy).to.not.have.been.called; - }); - it('destroys streams which time out', async function () { server.setMessageHandler(request => { const doc = request.document; From 4a94e4e458dfc255c878b4ba74f5d0942760d808 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 16 Sep 2024 16:21:42 -0400 Subject: [PATCH 17/22] lint fix --- src/operations/run_command.ts | 5 ++--- test/unit/collection.test.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index ae24a9a6dfd..289bfed18dd 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -5,9 +5,8 @@ import { type TODO_NODE_3286 } from '../mongo_types'; import type { ReadPreferenceLike } from '../read_preference'; import type { Server } from '../sdam/server'; import type { ClientSession } from '../sessions'; -import type { WriteConcern } from '../write_concern'; import { MongoDBNamespace } from '../utils'; -import { Aspect, defineAspects, AbstractOperation } from './operation'; +import { AbstractOperation } from './operation'; /** @public */ export type RunCommandOptions = { @@ -73,4 +72,4 @@ export class RunAdminCommandOperation extends AbstractOperation }); return res; } -} \ No newline at end of file +} diff --git a/test/unit/collection.test.ts b/test/unit/collection.test.ts index b050e69dc92..a6f40e7783b 100644 --- a/test/unit/collection.test.ts +++ b/test/unit/collection.test.ts @@ -15,7 +15,7 @@ describe('Collection', function () { }); context('#createIndex', () => { - it('should error when createIndex fails', function (done) { + it.only('should error when createIndex fails', function (done) { const ERROR_RESPONSE = { ok: 0, errmsg: From 3787250c7624aa0ac5b33bd36c3e48e137befcee Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 19 Sep 2024 18:11:11 -0400 Subject: [PATCH 18/22] move unit to integration test to get correct maxWireVersion for opMsg --- .../collection-management/collection.test.ts | 46 ++++++++++++++++- test/unit/collection.test.ts | 49 ------------------- 2 files changed, 44 insertions(+), 51 deletions(-) diff --git a/test/integration/collection-management/collection.test.ts b/test/integration/collection-management/collection.test.ts index 809b4697dea..b099a812fc5 100644 --- a/test/integration/collection-management/collection.test.ts +++ b/test/integration/collection-management/collection.test.ts @@ -1,6 +1,13 @@ import { expect } from 'chai'; - -import { Collection, type Db, type MongoClient, MongoServerError } from '../../mongodb'; +import * as sinon from 'sinon'; + +import { + Collection, + CreateIndexesOperation, + type Db, + type MongoClient, + MongoServerError +} from '../../mongodb'; import { type FailPoint } from '../../tools/utils'; import { setupDatabase } from '../shared'; @@ -422,6 +429,41 @@ describe('Collection', function () { }); }); + describe('#createIndex', () => { + let client: MongoClient; + let db: Db; + let coll: Collection<{ a: string }>; + const ERROR_RESPONSE = { + ok: 0, + errmsg: + 'WiredTigerIndex::insert: key too large to index, failing 1470 { : "56f37cb8e4b089e98d52ab0e", : "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..." }', + code: 17280 + }; + + beforeEach(async function () { + client = configuration.newClient({ w: 1 }); + db = client.db(configuration.db); + coll = db.collection('test_coll'); + await client.connect(); + sinon.stub(CreateIndexesOperation.prototype, 'execute').callsFake(() => { + throw ERROR_RESPONSE; + }); + }); + + afterEach(async function () { + await coll.drop(); + await client.close(); + sinon.restore(); + }); + + it('should error when createIndex fails', async function () { + const e = await coll.createIndex({ a: 1 }).catch(e => e); + expect(e).to.have.property('ok', ERROR_RESPONSE.ok); + expect(e).to.have.property('errmsg', ERROR_RESPONSE.errmsg); + expect(e).to.have.property('code', ERROR_RESPONSE.code); + }); + }); + describe('countDocuments()', function () { let client: MongoClient; let collection: Collection<{ test: string }>; diff --git a/test/unit/collection.test.ts b/test/unit/collection.test.ts index a6f40e7783b..c45712abebc 100644 --- a/test/unit/collection.test.ts +++ b/test/unit/collection.test.ts @@ -14,55 +14,6 @@ describe('Collection', function () { await cleanup(); }); - context('#createIndex', () => { - it.only('should error when createIndex fails', function (done) { - const ERROR_RESPONSE = { - ok: 0, - errmsg: - 'WiredTigerIndex::insert: key too large to index, failing 1470 { : "56f37cb8e4b089e98d52ab0e", : "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..." }', - code: 17280 - }; - - server.setMessageHandler(request => { - const doc = request.document; - - if (isHello(doc)) { - return request.reply(Object.assign({}, HELLO)); - } - - if (doc.createIndexes) { - return request.reply(ERROR_RESPONSE); - } - - if (doc.insert === 'system.indexes') { - return request.reply(ERROR_RESPONSE); - } - }); - - const client = new MongoClient(`mongodb://${server.uri()}`); - - const close = e => client.close().then(() => done(e)); - - client - .connect() - .then(() => client.db('foo').collection('bar')) - .then(coll => coll.createIndex({ a: 1 })) - .then( - () => close('Expected createIndex to fail, but it succeeded'), - e => { - try { - expect(e).to.have.property('ok', ERROR_RESPONSE.ok); - expect(e).to.have.property('errmsg', ERROR_RESPONSE.errmsg); - expect(e).to.have.property('code', ERROR_RESPONSE.code); - close(null); - } catch (err) { - close(err); - } - } - ); - }); - }); - context('#aggregate', () => { // general test for aggregate function function testAggregate(config, done) { From 4eb7c120213d5774553360e6e0f6d0c8e14629d0 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Tue, 24 Sep 2024 17:08:58 -0400 Subject: [PATCH 19/22] requested changes team review --- src/cmap/connection.ts | 2 +- test/integration/node-specific/mongo_client.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index 4bcb4850e5c..6b8ed3f458a 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -94,7 +94,7 @@ export interface CommandOptions extends BSONSerializeOptions { directConnection?: boolean; - // Triggers fire-and-forget protocol for commands that don't support WriteConcern + /** Triggers fire-and-forget protocol for commands that don't support WriteConcern */ moreToCome?: boolean; } diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 7d853e21007..7d3f901fb57 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); // writeConcern.w = 0 + expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); // moreToCome = true }); context('when server selection would return no servers', () => { From b133f86e742aa6bc495fc243fd40f14c669a2e1f Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Wed, 25 Sep 2024 16:48:40 -0400 Subject: [PATCH 20/22] fix failing tests --- .../collection-management/collection.test.ts | 1 - .../connection.test.ts | 29 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/test/integration/collection-management/collection.test.ts b/test/integration/collection-management/collection.test.ts index b099a812fc5..d73a1f229a4 100644 --- a/test/integration/collection-management/collection.test.ts +++ b/test/integration/collection-management/collection.test.ts @@ -451,7 +451,6 @@ describe('Collection', function () { }); afterEach(async function () { - await coll.drop(); await client.close(); sinon.restore(); }); diff --git a/test/integration/connection-monitoring-and-pooling/connection.test.ts b/test/integration/connection-monitoring-and-pooling/connection.test.ts index e0b21c2f54b..6ea2ce04135 100644 --- a/test/integration/connection-monitoring-and-pooling/connection.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection.test.ts @@ -145,19 +145,22 @@ describe('Connection', function () { } }); - it('supports fire-and-forget messages', async function () { - const options: ConnectionOptions = { - ...commonConnectOptions, - connectionType: Connection, - ...this.configuration.options, - metadata: makeClientMetadata({ driverInfo: {} }), - extendedMetadata: addContainerMetadata(makeClientMetadata({ driverInfo: {} })) - }; - - const conn = await connect(options); - const readSpy = sinon.spy(conn, 'readMany'); - await conn.command(ns('$admin.cmd'), { ping: 1 }, { moreToCome: true }); - expect(readSpy).to.not.have.been.called; + it('supports fire-and-forget messages', { + metadata: { requires: { apiVersion: false, topology: '!load-balanced' } }, + test: async function () { + const options: ConnectionOptions = { + ...commonConnectOptions, + connectionType: Connection, + ...this.configuration.options, + metadata: makeClientMetadata({ driverInfo: {} }), + extendedMetadata: addContainerMetadata(makeClientMetadata({ driverInfo: {} })) + }; + + const conn = await connect(options); + const readSpy = sinon.spy(conn, 'readMany'); + await conn.command(ns('$admin.cmd'), { ping: 1 }, { moreToCome: true }); + expect(readSpy).to.not.have.been.called; + } }); }); From 29d8330e86c29060cc98315f8a0a420df211bf97 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 26 Sep 2024 16:19:09 -0400 Subject: [PATCH 21/22] fix test --- .../connection-monitoring-and-pooling/connection.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/connection-monitoring-and-pooling/connection.test.ts b/test/integration/connection-monitoring-and-pooling/connection.test.ts index 6ea2ce04135..02693e07804 100644 --- a/test/integration/connection-monitoring-and-pooling/connection.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection.test.ts @@ -160,6 +160,7 @@ describe('Connection', function () { const readSpy = sinon.spy(conn, 'readMany'); await conn.command(ns('$admin.cmd'), { ping: 1 }, { moreToCome: true }); expect(readSpy).to.not.have.been.called; + conn?.destroy(); } }); }); From b4b0866dc2315c2a7834bd15ba36df9dd2057ae2 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 27 Sep 2024 05:32:04 -0400 Subject: [PATCH 22/22] fix failing noauth tests --- .../connection-monitoring-and-pooling/connection.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/connection-monitoring-and-pooling/connection.test.ts b/test/integration/connection-monitoring-and-pooling/connection.test.ts index 02693e07804..78433f0665e 100644 --- a/test/integration/connection-monitoring-and-pooling/connection.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection.test.ts @@ -297,8 +297,8 @@ describe('Connection', function () { }); afterEach(async function () { - await client.close(); mockServer.destroy(); + await client.close(); sinon.restore(); });