Skip to content

Commit 8ca8f81

Browse files
committed
fix(NODE-5106): refactor testing
1 parent 5840d79 commit 8ca8f81

File tree

3 files changed

+60
-71
lines changed

3 files changed

+60
-71
lines changed

src/mongo_client.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,7 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
426426
* Create a topology to open the connection, must be locked to avoid topology leaks in concurrency scenario.
427427
* Locking is enforced by the connect method.
428428
*
429-
* When decorators available put implementation back to original connect methods
430-
* and enforce locking via a dedicated decorator.
431-
* @see https://github.com/mongodb/node-mongodb-native/pull/3596#discussion_r1134211500
429+
* @internal
432430
*/
433431
private async _connect(): Promise<this> {
434432
if (this.topology && this.topology.isConnected()) {

test/integration/mongo_client.test.ts

Lines changed: 0 additions & 68 deletions
This file was deleted.

test/integration/node-specific/mongo_client.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,65 @@ describe('class MongoClient', function () {
517517
);
518518
});
519519

520+
context('concurrent #connect()', () => {
521+
let client: MongoClient;
522+
let topologyOpenEvents;
523+
524+
/** Keep track number of call to client connect to close as many as connect (otherwise leak_checker hook will failed) */
525+
let clientConnectCounter: number;
526+
527+
/**
528+
* Wrap the connect method of the client to keep track
529+
* of number of times connect is called
530+
*/
531+
function clientConnect() {
532+
if (!client) {
533+
return;
534+
}
535+
clientConnectCounter++;
536+
return client.connect();
537+
}
538+
539+
beforeEach(async function () {
540+
client = this.configuration.newClient();
541+
topologyOpenEvents = [];
542+
clientConnectCounter = 0;
543+
client.on('open', event => topologyOpenEvents.push(event));
544+
});
545+
546+
afterEach(async function () {
547+
// close `clientConnectCounter` times
548+
const clientClosePromises = Array.from({ length: clientConnectCounter }, () =>
549+
client.close()
550+
);
551+
await Promise.all(clientClosePromises);
552+
});
553+
554+
it('parallel client connect calls only create one topology', async function () {
555+
await Promise.all([clientConnect(), clientConnect(), clientConnect()]);
556+
557+
expect(topologyOpenEvents).to.have.lengthOf(1);
558+
expect(client.topology?.isConnected()).to.be.true;
559+
});
560+
561+
it('when connect rejects lock is released regardless', async function () {
562+
const internalConnectStub = sinon.stub(client, '_connect' as keyof MongoClient);
563+
internalConnectStub.onFirstCall().rejects(new Error('cannot connect'));
564+
565+
// first call rejected to simulate a connection failure
566+
const error = await clientConnect()!.catch(error => error);
567+
expect(error).to.match(/cannot connect/);
568+
569+
internalConnectStub.restore();
570+
571+
// second call should connect
572+
await clientConnect();
573+
574+
expect(topologyOpenEvents).to.have.lengthOf(1);
575+
expect(client.topology?.isConnected()).to.be.true;
576+
});
577+
});
578+
520579
context('#close()', () => {
521580
let client: MongoClient;
522581
let db: Db;

0 commit comments

Comments
 (0)