Skip to content

Commit c4da623

Browse files
authoredFeb 7, 2023
fix(NODE-5026): revert "ensure that MessageStream is destroyed when connections are destroyed" (#3551)

13 files changed

+128
-279
lines changed
 

‎src/cmap/connect.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function performInitialHandshake(
9696
) {
9797
const callback: Callback<Document> = function (err, ret) {
9898
if (err && conn) {
99-
conn.destroy({ force: false });
99+
conn.destroy();
100100
}
101101
_callback(err, ret);
102102
};

‎src/cmap/connection.ts

+38-17
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ export interface ConnectionOptions
146146
metadata: ClientMetadata;
147147
}
148148

149-
/** @public */
149+
/** @internal */
150150
export interface DestroyOptions {
151151
/** Force the destruction. */
152-
force: boolean;
152+
force?: boolean;
153153
}
154154

155155
/** @public */
@@ -170,8 +170,8 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
170170
address: string;
171171
socketTimeoutMS: number;
172172
monitorCommands: boolean;
173-
/** Indicates that the connection (including underlying TCP socket) has been closed. */
174173
closed: boolean;
174+
destroyed: boolean;
175175
lastHelloMS?: number;
176176
serverApi?: ServerApi;
177177
helloOk?: boolean;
@@ -220,6 +220,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
220220
this.monitorCommands = options.monitorCommands;
221221
this.serverApi = options.serverApi;
222222
this.closed = false;
223+
this.destroyed = false;
223224
this[kHello] = null;
224225
this[kClusterTime] = null;
225226

@@ -312,7 +313,10 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
312313
if (this.closed) {
313314
return;
314315
}
315-
this.destroy({ force: false });
316+
317+
this[kStream].destroy(error);
318+
319+
this.closed = true;
316320

317321
for (const op of this[kQueue].values()) {
318322
op.cb(error);
@@ -326,7 +330,8 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
326330
if (this.closed) {
327331
return;
328332
}
329-
this.destroy({ force: false });
333+
334+
this.closed = true;
330335

331336
const message = `connection ${this.id} to ${this.address} closed`;
332337
for (const op of this[kQueue].values()) {
@@ -343,7 +348,9 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
343348
}
344349

345350
this[kDelayedTimeoutId] = setTimeout(() => {
346-
this.destroy({ force: false });
351+
this[kStream].destroy();
352+
353+
this.closed = true;
347354

348355
const message = `connection ${this.id} to ${this.address} timed out`;
349356
const beforeHandshake = this.hello == null;
@@ -452,27 +459,41 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
452459
callback(undefined, message.documents[0]);
453460
}
454461

455-
destroy(options: DestroyOptions, callback?: Callback): void {
462+
destroy(options?: DestroyOptions, callback?: Callback): void {
463+
if (typeof options === 'function') {
464+
callback = options;
465+
options = { force: false };
466+
}
467+
456468
this.removeAllListeners(Connection.PINNED);
457469
this.removeAllListeners(Connection.UNPINNED);
458470

459-
this[kMessageStream].destroy();
460-
this.closed = true;
471+
options = Object.assign({ force: false }, options);
472+
if (this[kStream] == null || this.destroyed) {
473+
this.destroyed = true;
474+
if (typeof callback === 'function') {
475+
callback();
476+
}
477+
478+
return;
479+
}
461480

462481
if (options.force) {
463482
this[kStream].destroy();
464-
if (callback) {
465-
return process.nextTick(callback);
483+
this.destroyed = true;
484+
if (typeof callback === 'function') {
485+
callback();
466486
}
487+
488+
return;
467489
}
468490

469-
if (!this[kStream].writableEnded) {
470-
this[kStream].end(callback);
471-
} else {
472-
if (callback) {
473-
return process.nextTick(callback);
491+
this[kStream].end(() => {
492+
this.destroyed = true;
493+
if (typeof callback === 'function') {
494+
callback();
474495
}
475-
}
496+
});
476497
}
477498

478499
command(

‎src/cmap/connection_pool.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
515515
ConnectionPool.CONNECTION_CLOSED,
516516
new ConnectionClosedEvent(this, conn, 'poolClosed')
517517
);
518-
conn.destroy({ force: !!options.force }, cb);
518+
conn.destroy(options, cb);
519519
},
520520
err => {
521521
this[kConnections].clear();
@@ -591,7 +591,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
591591
new ConnectionClosedEvent(this, connection, reason)
592592
);
593593
// destroy the connection
594-
process.nextTick(() => connection.destroy({ force: false }));
594+
process.nextTick(() => connection.destroy());
595595
}
596596

597597
private connectionIsStale(connection: Connection) {

‎src/sdam/server.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
244244

245245
/** Destroy the server connection */
246246
destroy(options?: DestroyOptions, callback?: Callback): void {
247-
if (typeof options === 'function') {
248-
callback = options;
249-
options = { force: false };
250-
}
247+
if (typeof options === 'function') (callback = options), (options = {});
251248
options = Object.assign({}, { force: false }, options);
252249

253250
if (this.s.state === STATE_CLOSED) {

‎src/sdam/topology.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -484,17 +484,26 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
484484
}
485485

486486
/** Close this topology */
487+
close(callback: Callback): void;
487488
close(options: CloseOptions): void;
488489
close(options: CloseOptions, callback: Callback): void;
489-
close(options?: CloseOptions, callback?: Callback): void {
490-
options = options ?? { force: false };
490+
close(options?: CloseOptions | Callback, callback?: Callback): void {
491+
if (typeof options === 'function') {
492+
callback = options;
493+
options = {};
494+
}
495+
496+
if (typeof options === 'boolean') {
497+
options = { force: options };
498+
}
499+
options = options ?? {};
491500

492501
if (this.s.state === STATE_CLOSED || this.s.state === STATE_CLOSING) {
493502
return callback?.();
494503
}
495504

496505
const destroyedServers = Array.from(this.s.servers.values(), server => {
497-
return promisify(destroyServer)(server, this, { force: !!options?.force });
506+
return promisify(destroyServer)(server, this, options as CloseOptions);
498507
});
499508

500509
Promise.all(destroyedServers)
@@ -756,7 +765,7 @@ function destroyServer(
756765
options?: DestroyOptions,
757766
callback?: Callback
758767
) {
759-
options = options ?? { force: false };
768+
options = options ?? {};
760769
for (const event of LOCAL_SERVER_EVENTS) {
761770
server.removeAllListeners(event);
762771
}

‎test/integration/crud/misc_cursors.test.js

+49-20
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const { ReadPreference } = require('../../../src/read_preference');
1313
const { ServerType } = require('../../../src/sdam/common');
1414
const { formatSort } = require('../../../src/sort');
1515
const { getSymbolFrom } = require('../../tools/utils');
16-
const { MongoExpiredSessionError } = require('../../../src/error');
1716

1817
describe('Cursor', function () {
1918
before(function () {
@@ -1906,31 +1905,61 @@ describe('Cursor', function () {
19061905
}
19071906
});
19081907

1909-
it('closes cursors when client is closed even if it has not been exhausted', async function () {
1910-
await client
1911-
.db()
1912-
.dropCollection('test_cleanup_tailable')
1913-
.catch(() => null);
1908+
it('should close dead tailable cursors', {
1909+
metadata: {
1910+
os: '!win32' // NODE-2943: timeout on windows
1911+
},
19141912

1915-
const collection = await client
1916-
.db()
1917-
.createCollection('test_cleanup_tailable', { capped: true, size: 1000, max: 3 });
1913+
test: function (done) {
1914+
// http://www.mongodb.org/display/DOCS/Tailable+Cursors
19181915

1919-
// insert only 2 docs in capped coll of 3
1920-
await collection.insertMany([{ a: 1 }, { a: 1 }]);
1916+
const configuration = this.configuration;
1917+
client.connect((err, client) => {
1918+
expect(err).to.not.exist;
1919+
this.defer(() => client.close());
19211920

1922-
const cursor = collection.find({}, { tailable: true, awaitData: true, maxAwaitTimeMS: 2000 });
1921+
const db = client.db(configuration.db);
1922+
const options = { capped: true, size: 10000000 };
1923+
db.createCollection(
1924+
'test_if_dead_tailable_cursors_close',
1925+
options,
1926+
function (err, collection) {
1927+
expect(err).to.not.exist;
19231928

1924-
await cursor.next();
1925-
await cursor.next();
1926-
// will block for maxAwaitTimeMS (except we are closing the client)
1927-
const rejectedEarlyBecauseClientClosed = cursor.next().catch(error => error);
1929+
let closeCount = 0;
1930+
const docs = Array.from({ length: 100 }).map(() => ({ a: 1 }));
1931+
collection.insertMany(docs, { w: 'majority', wtimeoutMS: 5000 }, err => {
1932+
expect(err).to.not.exist;
19281933

1929-
await client.close();
1930-
expect(cursor).to.have.property('killed', true);
1934+
const cursor = collection.find({}, { tailable: true, awaitData: true });
1935+
const stream = cursor.stream();
1936+
1937+
stream.resume();
1938+
1939+
var validator = () => {
1940+
closeCount++;
1941+
if (closeCount === 2) {
1942+
done();
1943+
}
1944+
};
1945+
1946+
// we validate that the stream "ends" either cleanly or with an error
1947+
stream.on('end', validator);
1948+
stream.on('error', validator);
1949+
1950+
cursor.on('close', validator);
19311951

1932-
const error = await rejectedEarlyBecauseClientClosed;
1933-
expect(error).to.be.instanceOf(MongoExpiredSessionError);
1952+
const docs = Array.from({ length: 100 }).map(() => ({ a: 1 }));
1953+
collection.insertMany(docs, err => {
1954+
expect(err).to.not.exist;
1955+
1956+
setTimeout(() => client.close());
1957+
});
1958+
});
1959+
}
1960+
);
1961+
});
1962+
}
19341963
});
19351964

19361965
it('shouldAwaitData', {

‎test/integration/node-specific/topology.test.js

+5-13
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,12 @@ describe('Topology', function () {
1010
const states = [];
1111
topology.on('stateChanged', (_, newState) => states.push(newState));
1212
topology.connect(err => {
13-
try {
13+
expect(err).to.not.exist;
14+
topology.close(err => {
1415
expect(err).to.not.exist;
15-
} catch (error) {
16-
done(error);
17-
}
18-
topology.close({}, err => {
19-
try {
20-
expect(err).to.not.exist;
21-
expect(topology.isDestroyed()).to.be.true;
22-
expect(states).to.eql(['connecting', 'connected', 'closing', 'closed']);
23-
done();
24-
} catch (error) {
25-
done(error);
26-
}
16+
expect(topology.isDestroyed()).to.be.true;
17+
expect(states).to.eql(['connecting', 'connected', 'closing', 'closed']);
18+
done();
2719
});
2820
});
2921
}

‎test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('Polling Srv Records for Mongos Discovery', () => {
9797

9898
afterEach(function (done) {
9999
if (context.topology) {
100-
context.topology.close({}, done);
100+
context.topology.close(done);
101101
} else {
102102
done();
103103
}

‎test/unit/assorted/server_selection_spec_helper.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function executeServerSelectionTest(testDefinition, testDone) {
109109
});
110110

111111
function done(err) {
112-
topology.close({}, e => testDone(e || err));
112+
topology.close(e => testDone(e || err));
113113
}
114114

115115
topology.connect(err => {

‎test/unit/cmap/connection.test.ts

+5-204
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const connectionOptionsDefaults = {
2626

2727
/** The absolute minimum socket API needed by Connection as of writing this test */
2828
class FakeSocket extends EventEmitter {
29-
writableEnded: boolean;
3029
address() {
3130
// is never called
3231
}
@@ -35,14 +34,6 @@ class FakeSocket extends EventEmitter {
3534
}
3635
destroy() {
3736
// is called, has no side effects
38-
this.writableEnded = true;
39-
}
40-
end(cb) {
41-
this.writableEnded = true;
42-
// nextTick to simulate I/O delay
43-
if (typeof cb === 'function') {
44-
process.nextTick(cb);
45-
}
4637
}
4738
get remoteAddress() {
4839
return 'iLoveJavaScript';
@@ -52,20 +43,6 @@ class FakeSocket extends EventEmitter {
5243
}
5344
}
5445

55-
class InputStream extends Readable {
56-
writableEnded: boolean;
57-
constructor(options?) {
58-
super(options);
59-
}
60-
61-
end(cb) {
62-
this.writableEnded = true;
63-
if (typeof cb === 'function') {
64-
process.nextTick(cb);
65-
}
66-
}
67-
}
68-
6946
describe('new Connection()', function () {
7047
let server;
7148
after(() => mock.cleanup());
@@ -124,7 +101,7 @@ describe('new Connection()', function () {
124101
expect(err).to.be.instanceOf(MongoNetworkTimeoutError);
125102
expect(result).to.not.exist;
126103

127-
expect(conn).property('stream').property('writableEnded', true);
104+
expect(conn).property('stream').property('destroyed', true);
128105

129106
done();
130107
});
@@ -193,7 +170,7 @@ describe('new Connection()', function () {
193170

194171
context('when multiple hellos exist on the stream', function () {
195172
let callbackSpy;
196-
const inputStream = new InputStream();
173+
const inputStream = new Readable();
197174
const document = { ok: 1 };
198175
const last = { isWritablePrimary: true };
199176

@@ -412,7 +389,7 @@ describe('new Connection()', function () {
412389
connection = sinon.spy(new Connection(driverSocket, connectionOptionsDefaults));
413390
const messageStreamSymbol = getSymbolFrom(connection, 'messageStream');
414391
kDelayedTimeoutId = getSymbolFrom(connection, 'delayedTimeoutId');
415-
messageStream = sinon.spy(connection[messageStreamSymbol]);
392+
messageStream = connection[messageStreamSymbol];
416393
});
417394

418395
afterEach(() => {
@@ -425,15 +402,13 @@ describe('new Connection()', function () {
425402

426403
driverSocket.emit('timeout');
427404
expect(connection.onTimeout).to.have.been.calledOnce;
428-
expect(connection.destroy).to.not.have.been.called;
429405
expect(connection).to.have.property(kDelayedTimeoutId).that.is.instanceOf(NodeJSTimeoutClass);
430406
expect(connection).to.have.property('closed', false);
431-
expect(driverSocket.end).to.not.have.been.called;
407+
expect(driverSocket.destroy).to.not.have.been.called;
432408

433409
clock.tick(1);
434410

435-
expect(driverSocket.end).to.have.been.calledOnce;
436-
expect(connection.destroy).to.have.been.calledOnce;
411+
expect(driverSocket.destroy).to.have.been.calledOnce;
437412
expect(connection).to.have.property('closed', true);
438413
});
439414

@@ -458,88 +433,6 @@ describe('new Connection()', function () {
458433
expect(connection).to.have.property('closed', false);
459434
expect(connection).to.have.property(kDelayedTimeoutId, null);
460435
});
461-
462-
it('destroys the message stream and socket', () => {
463-
expect(connection).to.have.property(kDelayedTimeoutId, null);
464-
465-
driverSocket.emit('timeout');
466-
467-
clock.tick(1);
468-
469-
expect(connection.onTimeout).to.have.been.calledOnce;
470-
expect(connection).to.have.property(kDelayedTimeoutId).that.is.instanceOf(NodeJSTimeoutClass);
471-
472-
expect(messageStream.destroy).to.have.been.calledOnce;
473-
expect(driverSocket.destroy).to.not.have.been.called;
474-
expect(driverSocket.end).to.have.been.calledOnce;
475-
});
476-
});
477-
478-
describe('onError()', () => {
479-
let connection: sinon.SinonSpiedInstance<Connection>;
480-
let clock: sinon.SinonFakeTimers;
481-
let timerSandbox: sinon.SinonFakeTimers;
482-
let driverSocket: sinon.SinonSpiedInstance<FakeSocket>;
483-
let messageStream: MessageStream;
484-
beforeEach(() => {
485-
timerSandbox = createTimerSandbox();
486-
clock = sinon.useFakeTimers();
487-
driverSocket = sinon.spy(new FakeSocket());
488-
// @ts-expect-error: driverSocket does not fully satisfy the stream type, but that's okay
489-
connection = sinon.spy(new Connection(driverSocket, connectionOptionsDefaults));
490-
const messageStreamSymbol = getSymbolFrom(connection, 'messageStream');
491-
messageStream = sinon.spy(connection[messageStreamSymbol]);
492-
});
493-
494-
afterEach(() => {
495-
timerSandbox.restore();
496-
clock.restore();
497-
});
498-
499-
it('destroys the message stream and socket', () => {
500-
messageStream.emit('error');
501-
clock.tick(1);
502-
expect(connection.onError).to.have.been.calledOnce;
503-
connection.destroy({ force: false });
504-
clock.tick(1);
505-
expect(messageStream.destroy).to.have.been.called;
506-
expect(driverSocket.destroy).to.not.have.been.called;
507-
expect(driverSocket.end).to.have.been.calledOnce;
508-
});
509-
});
510-
511-
describe('onClose()', () => {
512-
let connection: sinon.SinonSpiedInstance<Connection>;
513-
let clock: sinon.SinonFakeTimers;
514-
let timerSandbox: sinon.SinonFakeTimers;
515-
let driverSocket: sinon.SinonSpiedInstance<FakeSocket>;
516-
let messageStream: MessageStream;
517-
beforeEach(() => {
518-
timerSandbox = createTimerSandbox();
519-
clock = sinon.useFakeTimers();
520-
521-
driverSocket = sinon.spy(new FakeSocket());
522-
// @ts-expect-error: driverSocket does not fully satisfy the stream type, but that's okay
523-
connection = sinon.spy(new Connection(driverSocket, connectionOptionsDefaults));
524-
const messageStreamSymbol = getSymbolFrom(connection, 'messageStream');
525-
messageStream = sinon.spy(connection[messageStreamSymbol]);
526-
});
527-
528-
afterEach(() => {
529-
timerSandbox.restore();
530-
clock.restore();
531-
});
532-
533-
it('destroys the message stream and socket', () => {
534-
driverSocket.emit('close');
535-
clock.tick(1);
536-
expect(connection.onClose).to.have.been.calledOnce;
537-
connection.destroy({ force: false });
538-
clock.tick(1);
539-
expect(messageStream.destroy).to.have.been.called;
540-
expect(driverSocket.destroy).to.not.have.been.called;
541-
expect(driverSocket.end).to.have.been.calledOnce;
542-
});
543436
});
544437

545438
describe('.hasSessionSupport', function () {
@@ -593,96 +486,4 @@ describe('new Connection()', function () {
593486
});
594487
});
595488
});
596-
597-
describe('destroy()', () => {
598-
let connection: sinon.SinonSpiedInstance<Connection>;
599-
let clock: sinon.SinonFakeTimers;
600-
let timerSandbox: sinon.SinonFakeTimers;
601-
let driverSocket: sinon.SinonSpiedInstance<FakeSocket>;
602-
let messageStream: MessageStream;
603-
beforeEach(() => {
604-
timerSandbox = createTimerSandbox();
605-
clock = sinon.useFakeTimers();
606-
607-
driverSocket = sinon.spy(new FakeSocket());
608-
// @ts-expect-error: driverSocket does not fully satisfy the stream type, but that's okay
609-
connection = sinon.spy(new Connection(driverSocket, connectionOptionsDefaults));
610-
const messageStreamSymbol = getSymbolFrom(connection, 'messageStream');
611-
messageStream = sinon.spy(connection[messageStreamSymbol]);
612-
});
613-
614-
afterEach(() => {
615-
timerSandbox.restore();
616-
clock.restore();
617-
});
618-
619-
context('when options.force == true', function () {
620-
it('calls stream.destroy', () => {
621-
connection.destroy({ force: true });
622-
clock.tick(1);
623-
expect(driverSocket.destroy).to.have.been.calledOnce;
624-
});
625-
626-
it('does not call stream.end', () => {
627-
connection.destroy({ force: true });
628-
clock.tick(1);
629-
expect(driverSocket.end).to.not.have.been.called;
630-
});
631-
632-
it('destroys the tcp socket', () => {
633-
connection.destroy({ force: true });
634-
clock.tick(1);
635-
expect(driverSocket.destroy).to.have.been.calledOnce;
636-
});
637-
638-
it('destroys the messageStream', () => {
639-
connection.destroy({ force: true });
640-
clock.tick(1);
641-
expect(messageStream.destroy).to.have.been.calledOnce;
642-
});
643-
644-
it('calls stream.destroy whenever destroy is called ', () => {
645-
connection.destroy({ force: true });
646-
connection.destroy({ force: true });
647-
connection.destroy({ force: true });
648-
clock.tick(1);
649-
expect(driverSocket.destroy).to.have.been.calledThrice;
650-
});
651-
});
652-
653-
context('when options.force == false', function () {
654-
it('calls stream.end', () => {
655-
connection.destroy({ force: false });
656-
clock.tick(1);
657-
expect(driverSocket.end).to.have.been.calledOnce;
658-
});
659-
660-
it('does not call stream.destroy', () => {
661-
connection.destroy({ force: false });
662-
clock.tick(1);
663-
expect(driverSocket.destroy).to.not.have.been.called;
664-
});
665-
666-
it('ends the tcp socket', () => {
667-
connection.destroy({ force: false });
668-
clock.tick(1);
669-
expect(driverSocket.end).to.have.been.calledOnce;
670-
});
671-
672-
it('destroys the messageStream', () => {
673-
connection.destroy({ force: false });
674-
clock.tick(1);
675-
expect(messageStream.destroy).to.have.been.calledOnce;
676-
});
677-
678-
it('calls stream.end exactly once when destroy is called multiple times', () => {
679-
connection.destroy({ force: false });
680-
connection.destroy({ force: false });
681-
connection.destroy({ force: false });
682-
connection.destroy({ force: false });
683-
clock.tick(1);
684-
expect(driverSocket.end).to.have.been.calledOnce;
685-
});
686-
});
687-
});
688489
});

‎test/unit/error.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ describe('MongoErrors', () => {
379379

380380
makeAndConnectReplSet((err, topology) => {
381381
// cleanup the server before calling done
382-
const cleanup = err => topology.close({}, err2 => done(err || err2));
382+
const cleanup = err => topology.close(err2 => done(err || err2));
383383

384384
if (err) {
385385
return cleanup(err);

‎test/unit/sdam/monitor.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('monitoring', function () {
5252
const serverDescription = Array.from(topology.description.servers.values())[0];
5353
expect(serverDescription).property('roundTripTime').to.be.greaterThan(0);
5454

55-
topology.close({}, done as any);
55+
topology.close(done as any);
5656
}, 500);
5757
});
5858
}).skipReason = 'TODO(NODE-3819): Unskip flaky tests';
@@ -92,7 +92,7 @@ describe('monitoring', function () {
9292
const serverDescription = Array.from(topology.description.servers.values())[0];
9393
expect(serverDescription).property('roundTripTime').to.be.greaterThan(0);
9494

95-
topology.close({}, done);
95+
topology.close(done);
9696
});
9797
}).skipReason = 'TODO(NODE-3600): Unskip flaky tests';
9898

‎test/unit/sdam/topology.test.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('Topology (unit)', function () {
2626
}
2727

2828
if (topology) {
29-
topology.close({});
29+
topology.close();
3030
}
3131
});
3232

@@ -107,7 +107,7 @@ describe('Topology (unit)', function () {
107107

108108
topology.connect(() => {
109109
expect(topology.shouldCheckForSessionSupport()).to.be.true;
110-
topology.close({}, done);
110+
topology.close(done);
111111
});
112112
});
113113

@@ -127,7 +127,7 @@ describe('Topology (unit)', function () {
127127

128128
topology.connect(() => {
129129
expect(topology.shouldCheckForSessionSupport()).to.be.false;
130-
topology.close({}, done);
130+
topology.close(done);
131131
});
132132
});
133133

@@ -147,7 +147,7 @@ describe('Topology (unit)', function () {
147147

148148
topology.connect(() => {
149149
expect(topology.shouldCheckForSessionSupport()).to.be.false;
150-
topology.close({}, done);
150+
topology.close(done);
151151
});
152152
});
153153
});
@@ -182,7 +182,7 @@ describe('Topology (unit)', function () {
182182
expect(err).to.exist;
183183
expect(err).to.match(/timed out/);
184184

185-
topology.close({}, done);
185+
topology.close(done);
186186
});
187187
});
188188
});
@@ -325,7 +325,7 @@ describe('Topology (unit)', function () {
325325
expect(err).to.exist;
326326
expect(err).to.eql(serverDescription.error);
327327
expect(poolCleared).to.be.false;
328-
topology.close({}, done);
328+
topology.close(done);
329329
});
330330
});
331331
});
@@ -467,7 +467,7 @@ describe('Topology (unit)', function () {
467467

468468
it('should clean up listeners on close', function (done) {
469469
topology.s.state = 'connected'; // fake state to test clean up logic
470-
topology.close({}, e => {
470+
topology.close(e => {
471471
const srvPollerListeners = topology.s.srvPoller.listeners(
472472
SrvPoller.SRV_RECORD_DISCOVERY
473473
);
@@ -547,7 +547,7 @@ describe('Topology (unit)', function () {
547547
// occurs `requestCheck` will be called for an immediate check.
548548
expect(requestCheck).property('callCount').to.equal(1);
549549

550-
topology.close({}, done);
550+
topology.close(done);
551551
});
552552
});
553553
});
@@ -559,7 +559,7 @@ describe('Topology (unit)', function () {
559559
this.emit('connect');
560560
});
561561

562-
topology.close({}, () => {
562+
topology.close(() => {
563563
topology.selectServer(ReadPreference.primary, { serverSelectionTimeoutMS: 2000 }, err => {
564564
expect(err).to.exist;
565565
expect(err).to.match(/Topology is closed/);

0 commit comments

Comments
 (0)
Please sign in to comment.