Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(kill): should not wait too much to open a connection to ReplSet #813

Merged
merged 9 commits into from
Nov 13, 2023
12 changes: 11 additions & 1 deletion packages/mongodb-memory-server-core/src/util/MongoInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import {
} from './utils';
import { lt } from 'semver';
import { EventEmitter } from 'events';
import { MongoClient, MongoClientOptions, MongoNetworkError } from 'mongodb';
import {
MongoClient,
MongoClientOptions,
MongoNetworkError,
MongoServerSelectionError,
} from 'mongodb';
import {
GenericMMSError,
KeyFileMissingError,
Expand Down Expand Up @@ -445,6 +450,7 @@ export class MongoInstance extends EventEmitter implements ManagerBase {
con = await MongoClient.connect(uriTemplate(ip, port, 'admin'), {
...this.extraConnectionOptions,
directConnection: true,
serverSelectionTimeoutMS: 500,
hasezoey marked this conversation as resolved.
Show resolved Hide resolved
});

const admin = con.db('admin'); // just to ensure it is actually the "admin" database
Expand All @@ -460,6 +466,10 @@ export class MongoInstance extends EventEmitter implements ManagerBase {
!(
err instanceof MongoNetworkError &&
/^connection \d+ to [\d.]+:\d+ closed$/i.test(err.message)
) &&
!(
err instanceof MongoServerSelectionError &&
/^Server selection timed out after \d+ ms$/i.test(err.message)
)
) {
console.warn(err);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ describe('MongodbInstance', () => {
expect(dbUtil.killProcess).not.toBeCalled();
});

it('"kill" should not try to open a connection to a not running ReplSet', async () => {
it('"kill" should not try to open a connection to a not running instance', async () => {
hasezoey marked this conversation as resolved.
Show resolved Hide resolved
const gotPort = await getFreePort();
const mongod = new MongodbInstance({
instance: {
Expand All @@ -292,12 +292,31 @@ describe('MongodbInstance', () => {
await mongod.start();
jest.spyOn(MongoClient, 'connect');
process.kill(mongod.mongodProcess!.pid, 'SIGKILL');
await new Promise<void>((resolve) => setTimeout(resolve, 100));
while (dbUtil.isAlive(mongod.mongodProcess!.pid)) {
await new Promise<void>((resolve) => setTimeout(resolve, 5));
}
await mongod.stop();

expect(MongoClient.connect).not.toBeCalled();
});

test('"kill" should not wait too much to open a connection', async () => {
hasezoey marked this conversation as resolved.
Show resolved Hide resolved
const gotPort = await getFreePort();
const mongod = new MongodbInstance({
instance: {
replSet: 'testset',
ip: '127.0.0.1',
port: gotPort,
dbPath: tmpDir,
},
});
await mongod.start();
jest.spyOn(MongoClient, 'connect');
arthursimas1 marked this conversation as resolved.
Show resolved Hide resolved
process.kill(mongod.mongodProcess!.pid, 'SIGKILL');
await mongod.stop();
expect(MongoClient.connect).toBeCalled();
hasezoey marked this conversation as resolved.
Show resolved Hide resolved
}, 8000); // the default serverSelectionTimeoutMS is 10s, so waiting for 8s seems ok to catch it
hasezoey marked this conversation as resolved.
Show resolved Hide resolved

it('"_launchMongod" should throw an error if "mongodProcess.pid" is undefined', () => {
const mongod = new MongodbInstance({ instance: { port: 0, dbPath: '' } }); // dummy values - they shouldnt matter
const mockBinary = '/tmp/thisShouldNotExist';
Expand Down