@@ -10,7 +10,7 @@ import {
1010 UnexpectedCloseError ,
1111} from '../errors' ;
1212import { assertIsError } from '../../__tests__/testUtils/test_utils' ;
13- import { MongoClient } from 'mongodb' ;
13+ import { MongoClient , MongoServerSelectionError } from 'mongodb' ;
1414
1515jest . setTimeout ( 100000 ) ; // 10s
1616
@@ -279,7 +279,7 @@ describe('MongodbInstance', () => {
279279 expect ( dbUtil . killProcess ) . not . toBeCalled ( ) ;
280280 } ) ;
281281
282- it ( '"kill" should not try to open a connection to a not running ReplSet' , async ( ) => {
282+ it ( '"kill" should not try to open a connection to a not running ReplSet instance ' , async ( ) => {
283283 const gotPort = await getFreePort ( ) ;
284284 const mongod = new MongodbInstance ( {
285285 instance : {
@@ -292,12 +292,57 @@ describe('MongodbInstance', () => {
292292 await mongod . start ( ) ;
293293 jest . spyOn ( MongoClient , 'connect' ) ;
294294 process . kill ( mongod . mongodProcess ! . pid , 'SIGKILL' ) ;
295- await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
295+ // loop until the mongod process actually exits
296+ while ( dbUtil . isAlive ( mongod . mongodProcess ! . pid ) ) {
297+ await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 5 ) ) ;
298+ }
296299 await mongod . stop ( ) ;
297300
298301 expect ( MongoClient . connect ) . not . toBeCalled ( ) ;
299302 } ) ;
300303
304+ test ( '"kill" should not wait too much to open a connection to a ReplSet instance' , async ( ) => {
305+ const gotPort = await getFreePort ( ) ;
306+
307+ // mock indicating some kind of server selection problem (undetected shutdown / unresponsive)
308+ // so that the ".stop" function does not exit too early
309+ jest . spyOn ( MongodbInstance . prototype , 'closeHandler' ) . mockImplementationOnce ( ( ) => void 0 ) ;
310+
311+ const mongod = new MongodbInstance ( {
312+ instance : {
313+ replSet : 'testset' ,
314+ ip : '127.0.0.1' ,
315+ port : gotPort ,
316+ dbPath : tmpDir ,
317+ } ,
318+ } ) ;
319+ await mongod . start ( ) ;
320+ mongod . extraConnectionOptions = {
321+ // the following is set to 1s to speed-up the test, instead of the set default of 5s (or the 30s of mongodb default)
322+ serverSelectionTimeoutMS : 1000 , // 1 second
323+ } ;
324+ jest . spyOn ( MongoClient , 'connect' ) ;
325+ jest . spyOn ( MongoClient . prototype , 'db' ) ;
326+ jest . spyOn ( console , 'warn' ) . mockImplementationOnce ( ( ) => void 0 ) ;
327+ process . kill ( mongod . mongodProcess ! . pid , 'SIGKILL' ) ;
328+ // loop until the mongod process actually exits
329+ while ( dbUtil . isAlive ( mongod . mongodProcess ! . pid ) ) {
330+ await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 5 ) ) ;
331+ }
332+
333+ // mock indicating some kind of server selection problem (undetected shutdown / unresponsive)
334+ // so that the ".stop" function does not exit too early
335+ jest . spyOn ( dbUtil , 'isAlive' ) . mockImplementationOnce ( ( ) => true ) ;
336+
337+ await mongod . stop ( ) ;
338+ // connect should be called, but never beyond that (con.db is called next)
339+ expect ( MongoClient . connect ) . toHaveBeenCalledTimes ( 1 ) ;
340+ expect ( MongoClient . prototype . db ) . not . toHaveBeenCalled ( ) ;
341+ // should print a warning about "ECONREFUSED" or "Server selection timed-out"
342+ expect ( console . warn ) . toHaveBeenCalledTimes ( 1 ) ;
343+ expect ( console . warn ) . toHaveBeenCalledWith ( expect . any ( MongoServerSelectionError ) ) ;
344+ } , 8000 ) ; // the default serverSelectionTimeoutMS is 30s, the overwritten config is 5s, so waiting 8s should be fine
345+
301346 it ( '"_launchMongod" should throw an error if "mongodProcess.pid" is undefined' , ( ) => {
302347 const mongod = new MongodbInstance ( { instance : { port : 0 , dbPath : '' } } ) ; // dummy values - they shouldnt matter
303348 const mockBinary = '/tmp/thisShouldNotExist' ;
0 commit comments