From f3438ea10ec71083a3cbbc63fd56c1ad86f42ed4 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 14 Jul 2023 11:59:26 -0400 Subject: [PATCH 1/6] fix(NODE-5228): fix ConnectionPoolCreatedEvent --- src/cmap/connection_pool_events.ts | 9 +- .../connection_pool.test.ts | 110 ++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 test/integration/connection-monitoring-and-pooling/connection_pool.test.ts diff --git a/src/cmap/connection_pool_events.ts b/src/cmap/connection_pool_events.ts index 4c904441332..cda2905e8a9 100644 --- a/src/cmap/connection_pool_events.ts +++ b/src/cmap/connection_pool_events.ts @@ -54,14 +54,19 @@ export abstract class ConnectionPoolMonitoringEvent { */ export class ConnectionPoolCreatedEvent extends ConnectionPoolMonitoringEvent { /** The options used to create this connection pool */ - options?: ConnectionPoolOptions; + options?: Pick< + ConnectionPoolOptions, + 'maxPoolSize' | 'minPoolSize' | 'maxConnecting' | 'maxIdleTimeMS' | 'waitQueueTimeoutMS' + >; /** @internal */ name = CONNECTION_POOL_CREATED; /** @internal */ constructor(pool: ConnectionPool) { super(pool); - this.options = pool.options; + const { maxConnecting, maxPoolSize, minPoolSize, maxIdleTimeMS, waitQueueTimeoutMS } = + pool.options; + this.options = { maxConnecting, maxPoolSize, minPoolSize, maxIdleTimeMS, waitQueueTimeoutMS }; } } diff --git a/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts b/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts new file mode 100644 index 00000000000..8dd6bec1913 --- /dev/null +++ b/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts @@ -0,0 +1,110 @@ +import { once } from 'node:events'; + +import { expect } from 'chai'; + +import { + ConnectionPoolCreatedEvent, + type Db, + type MongoClient, + type MongoClientOptions +} from '../../mongodb'; + +describe('Connection Pool', function () { + let client: MongoClient; + let db: Db; + afterEach(async function () { + if (client) { + if (db) { + await db.dropDatabase(); + } + await client.close(); + } + }); + describe('Events', function () { + describe('ConnectionPoolCreatedEvent', function () { + it('is emitted on client connect', async function () { + client = this.configuration.newClient(); + const pConnectionPoolCreated = once(client, 'connectionPoolCreated'); + await client.connect(); + + expect((await pConnectionPoolCreated)[0]).to.be.instanceOf(ConnectionPoolCreatedEvent); + }); + + context('when no connection pool options are passed in', function () { + let pConnectionPoolCreated: Promise; + let connectionPoolCreated: ConnectionPoolCreatedEvent; + beforeEach(async function () { + client = this.configuration.newClient({}, {}); + pConnectionPoolCreated = once(client, 'connectionPoolCreated'); + await client.connect(); + + connectionPoolCreated = (await pConnectionPoolCreated)[0]; + }); + + it('the options field matches the default options', function () { + expect(connectionPoolCreated).to.have.deep.property('options', { + waitQueueTimeoutMS: 0, + maxIdleTimeMS: 0, + maxConnecting: 2, + minPoolSize: 0, + maxPoolSize: 100 + }); + }); + }); + + context('when valid non-default connection pool options are passed in', function () { + let pConnectionPoolCreated: Promise; + let connectionPoolCreated: ConnectionPoolCreatedEvent; + const options = { + waitQueueTimeoutMS: 2000, + maxIdleTimeMS: 1, + maxConnecting: 3, + minPoolSize: 1, + maxPoolSize: 101 + }; + beforeEach(async function () { + client = this.configuration.newClient({}, options); + pConnectionPoolCreated = once(client, 'connectionPoolCreated'); + await client.connect(); + + connectionPoolCreated = (await pConnectionPoolCreated)[0]; + }); + + it('the options field only contains keys and values matching the non-default options', function () { + expect(connectionPoolCreated).to.have.deep.property('options', options); + }); + }); + + context('when non connection pool options are passed in', function () { + let pConnectionPoolCreated: Promise; + let connectionPoolCreated: ConnectionPoolCreatedEvent; + const options: MongoClientOptions = { + waitQueueTimeoutMS: 2000, + maxIdleTimeMS: 1, + maxConnecting: 3, + minPoolSize: 1, + maxPoolSize: 101, + tls: true + }; + const optionsNoMetadata = { + waitQueueTimeoutMS: 2000, + maxIdleTimeMS: 1, + maxConnecting: 3, + minPoolSize: 1, + maxPoolSize: 101 + }; + beforeEach(async function () { + client = this.configuration.newClient({}, options); + pConnectionPoolCreated = once(client, 'connectionPoolCreated'); + await client.connect(); + + connectionPoolCreated = (await pConnectionPoolCreated)[0]; + }); + + it('the options field only contains keys and values associated with connection pool', function () { + expect(connectionPoolCreated).to.have.deep.property('options', optionsNoMetadata); + }); + }); + }); + }); +}); From fb6e07644361563bd01f8a0b4e31adc7abd7d842 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 14 Jul 2023 15:18:38 -0400 Subject: [PATCH 2/6] test(NODE-5228): make options required and add unit tests --- src/cmap/connection_pool_events.ts | 2 +- test/unit/cmap/connection_pool_events.test.ts | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/unit/cmap/connection_pool_events.test.ts diff --git a/src/cmap/connection_pool_events.ts b/src/cmap/connection_pool_events.ts index cda2905e8a9..379bc2d5217 100644 --- a/src/cmap/connection_pool_events.ts +++ b/src/cmap/connection_pool_events.ts @@ -54,7 +54,7 @@ export abstract class ConnectionPoolMonitoringEvent { */ export class ConnectionPoolCreatedEvent extends ConnectionPoolMonitoringEvent { /** The options used to create this connection pool */ - options?: Pick< + options: Pick< ConnectionPoolOptions, 'maxPoolSize' | 'minPoolSize' | 'maxConnecting' | 'maxIdleTimeMS' | 'waitQueueTimeoutMS' >; diff --git a/test/unit/cmap/connection_pool_events.test.ts b/test/unit/cmap/connection_pool_events.test.ts new file mode 100644 index 00000000000..83aa2158b1a --- /dev/null +++ b/test/unit/cmap/connection_pool_events.test.ts @@ -0,0 +1,63 @@ +import { expect } from 'chai'; +import { ConnectionPool, ConnectionPoolCreatedEvent } from '../../../mongodb'; + + +describe('Connection Pool Events', function() { + const connectionPoolMock = { + address: 'localhost:9000', + time: new Date(), + }; + + const allowedFields = [ + 'waitQueueTimeoutMS', + 'maxIdleTimeMS', + 'maxConnecting', + 'minPoolSize', + 'maxPoolSize' + + ]; + describe('ConnectionPoolCreatedEvent', function() { + describe('constructor', function() { + context('when provided expected option fields', function() { + it(`Sets the allowed fields appropriately`, function() { + const options = { + maxIdleTimeMS: 0, + maxConnecting: 2, + minPoolSize: 0, + maxPoolSize: 100, + waitQueueTimeoutMS: 1000 + }; + const event = new ConnectionPoolCreatedEvent({ ...connectionPoolMock, options } as unknown as ConnectionPool); + + expect(event).to.have.deep.property('options', options); + }); + }); + context('when provided unallowed fields', function() { + it('only stores expected fields', function() { + const options = { + maxIdleTimeMS: 0, + maxConnecting: 2, + minPoolSize: 0, + maxPoolSize: 100, + waitQueueTimeoutMS: 1000, + credentials: { + user: 'user', + pass: 'pass' + }, + foo: 'foo', + hello: 'world' + }; + const event = new ConnectionPoolCreatedEvent({ ...connectionPoolMock, options } as unknown as ConnectionPool); + + expect(event).to.have.deep.property('options', { + maxIdleTimeMS: 0, + maxConnecting: 2, + minPoolSize: 0, + maxPoolSize: 100, + waitQueueTimeoutMS: 1000, + }); + }); + }); + }); + }); +}); From 5d34e018d6ba6b55a707d61d25504e846c0c706d Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 14 Jul 2023 15:19:06 -0400 Subject: [PATCH 3/6] chore(NODE-5228): rebuild lockfile --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 05084a792b8..59d024a7f31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,7 +62,7 @@ "yargs": "^17.7.2" }, "engines": { - "node": ">=14.20.1" + "node": ">=16.20.1" }, "optionalDependencies": { "saslprep": "^1.0.3" From 626a134daf567897042054a8083146e56fa473ea Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 14 Jul 2023 15:31:08 -0400 Subject: [PATCH 4/6] test(NODE-5228): update tests --- .../connection_pool.test.ts | 10 +---- test/unit/cmap/connection_pool_events.test.ts | 38 +++++++++---------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts b/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts index 8dd6bec1913..b5b4dd72b7d 100644 --- a/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts @@ -3,7 +3,7 @@ import { once } from 'node:events'; import { expect } from 'chai'; import { - ConnectionPoolCreatedEvent, + type ConnectionPoolCreatedEvent, type Db, type MongoClient, type MongoClientOptions @@ -22,14 +22,6 @@ describe('Connection Pool', function () { }); describe('Events', function () { describe('ConnectionPoolCreatedEvent', function () { - it('is emitted on client connect', async function () { - client = this.configuration.newClient(); - const pConnectionPoolCreated = once(client, 'connectionPoolCreated'); - await client.connect(); - - expect((await pConnectionPoolCreated)[0]).to.be.instanceOf(ConnectionPoolCreatedEvent); - }); - context('when no connection pool options are passed in', function () { let pConnectionPoolCreated: Promise; let connectionPoolCreated: ConnectionPoolCreatedEvent; diff --git a/test/unit/cmap/connection_pool_events.test.ts b/test/unit/cmap/connection_pool_events.test.ts index 83aa2158b1a..54337fbaa27 100644 --- a/test/unit/cmap/connection_pool_events.test.ts +++ b/test/unit/cmap/connection_pool_events.test.ts @@ -1,25 +1,17 @@ import { expect } from 'chai'; -import { ConnectionPool, ConnectionPoolCreatedEvent } from '../../../mongodb'; +import { type ConnectionPool, ConnectionPoolCreatedEvent } from '../../mongodb'; -describe('Connection Pool Events', function() { +describe('Connection Pool Events', function () { const connectionPoolMock = { address: 'localhost:9000', - time: new Date(), + time: new Date() }; - const allowedFields = [ - 'waitQueueTimeoutMS', - 'maxIdleTimeMS', - 'maxConnecting', - 'minPoolSize', - 'maxPoolSize' - - ]; - describe('ConnectionPoolCreatedEvent', function() { - describe('constructor', function() { - context('when provided expected option fields', function() { - it(`Sets the allowed fields appropriately`, function() { + describe('ConnectionPoolCreatedEvent', function () { + describe('constructor', function () { + context('when provided expected option fields', function () { + it(`Sets the allowed fields appropriately`, function () { const options = { maxIdleTimeMS: 0, maxConnecting: 2, @@ -27,13 +19,16 @@ describe('Connection Pool Events', function() { maxPoolSize: 100, waitQueueTimeoutMS: 1000 }; - const event = new ConnectionPoolCreatedEvent({ ...connectionPoolMock, options } as unknown as ConnectionPool); + const event = new ConnectionPoolCreatedEvent({ + ...connectionPoolMock, + options + } as unknown as ConnectionPool); expect(event).to.have.deep.property('options', options); }); }); - context('when provided unallowed fields', function() { - it('only stores expected fields', function() { + context('when provided unallowed fields', function () { + it('only stores expected fields', function () { const options = { maxIdleTimeMS: 0, maxConnecting: 2, @@ -47,14 +42,17 @@ describe('Connection Pool Events', function() { foo: 'foo', hello: 'world' }; - const event = new ConnectionPoolCreatedEvent({ ...connectionPoolMock, options } as unknown as ConnectionPool); + const event = new ConnectionPoolCreatedEvent({ + ...connectionPoolMock, + options + } as unknown as ConnectionPool); expect(event).to.have.deep.property('options', { maxIdleTimeMS: 0, maxConnecting: 2, minPoolSize: 0, maxPoolSize: 100, - waitQueueTimeoutMS: 1000, + waitQueueTimeoutMS: 1000 }); }); }); From 0d3edadd33356dd9a88807c5f9a03f175a704abb Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 14 Jul 2023 15:54:17 -0400 Subject: [PATCH 5/6] test(NODE-5228): remove unneded test --- .../connection_pool.test.ts | 38 +------------------ 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts b/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts index b5b4dd72b7d..3f4317e372c 100644 --- a/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection_pool.test.ts @@ -2,12 +2,7 @@ import { once } from 'node:events'; import { expect } from 'chai'; -import { - type ConnectionPoolCreatedEvent, - type Db, - type MongoClient, - type MongoClientOptions -} from '../../mongodb'; +import { type ConnectionPoolCreatedEvent, type Db, type MongoClient } from '../../mongodb'; describe('Connection Pool', function () { let client: MongoClient; @@ -66,37 +61,6 @@ describe('Connection Pool', function () { expect(connectionPoolCreated).to.have.deep.property('options', options); }); }); - - context('when non connection pool options are passed in', function () { - let pConnectionPoolCreated: Promise; - let connectionPoolCreated: ConnectionPoolCreatedEvent; - const options: MongoClientOptions = { - waitQueueTimeoutMS: 2000, - maxIdleTimeMS: 1, - maxConnecting: 3, - minPoolSize: 1, - maxPoolSize: 101, - tls: true - }; - const optionsNoMetadata = { - waitQueueTimeoutMS: 2000, - maxIdleTimeMS: 1, - maxConnecting: 3, - minPoolSize: 1, - maxPoolSize: 101 - }; - beforeEach(async function () { - client = this.configuration.newClient({}, options); - pConnectionPoolCreated = once(client, 'connectionPoolCreated'); - await client.connect(); - - connectionPoolCreated = (await pConnectionPoolCreated)[0]; - }); - - it('the options field only contains keys and values associated with connection pool', function () { - expect(connectionPoolCreated).to.have.deep.property('options', optionsNoMetadata); - }); - }); }); }); }); From addbde504165ddc0f692e55dee4ad152878e8186 Mon Sep 17 00:00:00 2001 From: Warren James Date: Fri, 14 Jul 2023 17:41:24 -0400 Subject: [PATCH 6/6] test(NODE-5228): add type test --- test/types/connection_pool_events.test-d.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/types/connection_pool_events.test-d.ts diff --git a/test/types/connection_pool_events.test-d.ts b/test/types/connection_pool_events.test-d.ts new file mode 100644 index 00000000000..a059e782cc0 --- /dev/null +++ b/test/types/connection_pool_events.test-d.ts @@ -0,0 +1,20 @@ +import { once } from 'events'; +import { expectType } from 'tsd'; + +import type { ConnectionPoolCreatedEvent } from '../mongodb'; +import { MongoClient } from '../mongodb'; + +const client: MongoClient = new MongoClient(''); +const p = once(client, 'connectionPoolCreated'); +await client.connect(); + +const ev: ConnectionPoolCreatedEvent = (await p)[0]; +expectType(ev); + +expectType<{ + maxPoolSize: number; + minPoolSize: number; + maxConnecting: number; + maxIdleTimeMS: number; + waitQueueTimeoutMS: number; +}>(ev.options);