UNPKG

nems

Version:

nodejs-embedded-mongodb-standalone is a promise based embedded mongodb distribution library that downloads a appropriate mongodb and utilizes it as standalone, e.g. for integration/functional tests.

126 lines (102 loc) 4.16 kB
'use strict'; var Ramda = require('ramda'), Promise = require('bluebird'), childProcess = require('child_process'), logger = require('npmlog'), path = require('path'), MongoError = require('../error/errors').MongoError, mongoProcess, MESSAGE_MONGO_WAITING = '[initandlisten] waiting for connections on port', MESSAGE_MONGO_KILLING_PROCESS = 'killing process with pid', MESSAGE_MONGO_INIT_EXCEPTION = '[initandlisten] exception in initAndListen', MESSAGE_MONGO_BAD_PORT = 'bad --port number', MESSAGE_MONGO_ADDR_IN_USE = 'addr already in use', MESSAGE_MONGO_UNKNOWN_DB_PATH = 'There doesn\'t seem to be a server running with dbpath', SUCCESS_MESSAGE_MONGO_SHUTDOWN = 'The mongodb instance has been shutdown!', ERROR_MESSAGE_MONGO_START_FAILED = 'could not start mongo process: ', ERROR_MESSAGE_MONGO_SHUTDOWN = 'could not create child process to stop mongo process', ERROR_MESSAGE_MONGO_INSTANCE_EXIST = 'Is a mongod instance already running?', ERROR_MESSAGE_MONGO_BAD_PORT = 'The port you used is not allowed. See mongodb docs.', ERROR_MESSAGE_MONGO_ADDR_IN_USE = 'The port you used is already in use.', ERROR_MESSAGE_MONGO_UNKNOWN_DB_PATH = 'There doesn\'t seem to be a server running with the given dbpath.'; function escapePath(dbPath) { // wrap path as string due to https://github.com/nodejs/node/issues/6803 return '"' + dbPath + '"'; } function addDbPathParameter(execCommand, dbPath, binPath) { if (!!dbPath) { execCommand = execCommand.concat(' --dbpath ', escapePath(dbPath)); } else if (!!binPath) { execCommand = execCommand.concat(' --dbpath ', escapePath(binPath)); } return execCommand; } function createMongoProcess(execCommand, resolve, reject) { if (mongoProcess) { resolve(mongoProcess.pid); } mongoProcess = childProcess.exec(execCommand); mongoProcess.stderr.on('data', function(err) { reject(new MongoError(ERROR_MESSAGE_MONGO_START_FAILED + err)); }); mongoProcess.stdout.on('data', function(data) { if (data.toString().indexOf(MESSAGE_MONGO_INIT_EXCEPTION) >= 0) { reject(new MongoError(ERROR_MESSAGE_MONGO_START_FAILED + ERROR_MESSAGE_MONGO_INSTANCE_EXIST)); } if (data.toString().indexOf(MESSAGE_MONGO_BAD_PORT) >= 0) { reject(new MongoError(ERROR_MESSAGE_MONGO_START_FAILED + ERROR_MESSAGE_MONGO_BAD_PORT)); } if (data.toString().indexOf(MESSAGE_MONGO_ADDR_IN_USE) >= 0) { reject(new MongoError(ERROR_MESSAGE_MONGO_START_FAILED + ERROR_MESSAGE_MONGO_ADDR_IN_USE)); } if (data.toString().indexOf(MESSAGE_MONGO_WAITING) >= 0) { resolve(mongoProcess.pid); } }); } function shutdownMongoProcess(execCommand, resolve, reject) { var cp = childProcess.exec(execCommand); if(!cp) { reject(new MongoError(ERROR_MESSAGE_MONGO_SHUTDOWN)); } cp.stderr.on('data', function(err) { if (err.toString().indexOf(MESSAGE_MONGO_UNKNOWN_DB_PATH) >= 0) { reject(new MongoError(ERROR_MESSAGE_MONGO_UNKNOWN_DB_PATH)); } }); cp.stdout.on('data', function(data) { if (data.toString().indexOf(MESSAGE_MONGO_KILLING_PROCESS) >= 0) { mongoProcess = undefined; resolve(SUCCESS_MESSAGE_MONGO_SHUTDOWN); } }); } function start(binPath, port, noprealloc, nojournal, dbPath) { var execCommand = 'mongod'; if (!!binPath) { execCommand = escapePath(path.join(binPath, execCommand)); } if (!!port) { execCommand = [execCommand, '--port', port].join(' '); } if (!!noprealloc) { execCommand = execCommand.concat(' --noprealloc'); } if (!!nojournal) { execCommand = execCommand.concat(' --nojournal'); } execCommand = addDbPathParameter(execCommand, dbPath, binPath); return new Promise(Ramda.partial(createMongoProcess, [execCommand])); } function stop(binPath, dbPath) { var execCommand = 'mongod'; if (!!binPath) { execCommand = escapePath(path.join(binPath, execCommand)); } execCommand = addDbPathParameter(execCommand, dbPath, binPath); execCommand += ' --shutdown'; return new Promise(Ramda.partial(shutdownMongoProcess, [execCommand])); } module.exports.start = start; module.exports.stop = stop;