UNPKG

mongodb-memory-server

Version:

In-memory MongoDB Server. Designed with testing in mind, the server will allow you to connect your favourite ODM or client library to the MongoDB Server and run integration tests isolated from each other.

250 lines (187 loc) 7.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _tmp = _interopRequireDefault(require("tmp")); var _getPort = _interopRequireDefault(require("get-port")); var _debug = _interopRequireDefault(require("debug")); var _db_util = require("./util/db_util"); var _MongoInstance = _interopRequireDefault(require("./util/MongoInstance")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } _tmp.default.setGracefulCleanup(); function generateConnectionString(_x, _x2) { return _generateConnectionString.apply(this, arguments); } function _generateConnectionString() { _generateConnectionString = _asyncToGenerator(function* (port, dbName) { return `mongodb://127.0.0.1:${port}/${dbName}`; }); return _generateConnectionString.apply(this, arguments); } class MongoMemoryServer { constructor(opts = {}) { _defineProperty(this, "isRunning", false); _defineProperty(this, "runningInstance", void 0); _defineProperty(this, "opts", void 0); _defineProperty(this, "debug", void 0); this.opts = opts; if (!this.opts.instance) this.opts.instance = {}; if (!this.opts.binary) this.opts.binary = {}; this.debug = msg => { if (this.opts.debug) { console.log(msg); } }; // autoStart by default if (!opts.hasOwnProperty('autoStart') || opts.autoStart) { this.debug('Autostarting MongoDB instance...'); this.start(); } } start() { var _this = this; return _asyncToGenerator(function* () { if (_this.runningInstance) { throw new Error('MongoDB instance already in status startup/running/error. Use opts.debug = true for more info.'); } _this.runningInstance = _this._startUpInstance().catch(err => { if (err.message === 'Mongod shutting down' || err === 'Mongod shutting down') { _this.debug(`Mongodb does not started. Trying to start on another port one more time...`); _this.opts.instance.port = null; return _this._startUpInstance(); } throw err; }).catch(err => { if (!_this.opts.debug) { throw new Error(`${err.message}\n\nUse debug option for more info: ` + `new MongoMemoryServer({ debug: true })`); } throw err; }); return _this.runningInstance.then(() => true); })(); } _startUpInstance() { var _this2 = this; return _asyncToGenerator(function* () { const data = {}; let tmpDir; const instOpts = _this2.opts.instance; data.port = yield (0, _getPort.default)({ port: instOpts.port }); _this2.debug = (0, _debug.default)(`Mongo[${data.port}]`); _this2.debug.enabled = !!_this2.opts.debug; data.dbName = (0, _db_util.generateDbName)(instOpts.dbName); data.uri = yield generateConnectionString(data.port, data.dbName); data.storageEngine = instOpts.storageEngine || 'ephemeralForTest'; data.replSet = instOpts.replSet; if (instOpts.dbPath) { data.dbPath = instOpts.dbPath; } else { tmpDir = _tmp.default.dirSync({ prefix: 'mongo-mem-', unsafeCleanup: true, discardDescriptor: true, mode: '0755' }); data.dbPath = tmpDir.name; } _this2.debug(`Starting MongoDB instance with following options: ${JSON.stringify(data)}`); // Download if not exists mongo binaries in ~/.mongodb-prebuilt // After that startup MongoDB instance const instance = yield _MongoInstance.default.run({ instance: { port: data.port, storageEngine: data.storageEngine, dbPath: data.dbPath, debug: _this2.opts.instance.debug, replSet: data.replSet, args: _this2.opts.instance.args, auth: _this2.opts.instance.auth }, binary: _this2.opts.binary, spawn: _this2.opts.spawn, debug: _this2.debug }); data.instance = instance; data.childProcess = instance.childProcess; data.tmpDir = tmpDir; return data; })(); } stop() { var _this3 = this; return _asyncToGenerator(function* () { const _ref = yield _this3.getInstanceData(), instance = _ref.instance, port = _ref.port, tmpDir = _ref.tmpDir; _this3.debug(`Shutdown MongoDB server on port ${port} with pid ${instance.getPid() || ''}`); yield instance.kill(); if (tmpDir) { _this3.debug(`Removing tmpDir ${tmpDir.name}`); tmpDir.removeCallback(); } _this3.runningInstance = null; return true; })(); } getInstanceData() { var _this4 = this; return _asyncToGenerator(function* () { if (_this4.runningInstance) { return _this4.runningInstance; } throw new Error('Database instance is not running. You should start database by calling start() method. BTW it should start automatically if opts.autoStart!=false. Also you may provide opts.debug=true for more info.'); })(); } getUri(otherDbName = false) { var _this5 = this; return _asyncToGenerator(function* () { const _ref2 = yield _this5.getInstanceData(), uri = _ref2.uri, port = _ref2.port; // IF true OR string if (otherDbName) { if (typeof otherDbName === 'string') { // generate uri with provided DB name on existed DB instance return generateConnectionString(port, otherDbName); } // generate new random db name return generateConnectionString(port, (0, _db_util.generateDbName)()); } return uri; })(); } getConnectionString(otherDbName = false) { var _this6 = this; return _asyncToGenerator(function* () { return _this6.getUri(otherDbName); })(); } getPort() { var _this7 = this; return _asyncToGenerator(function* () { const _ref3 = yield _this7.getInstanceData(), port = _ref3.port; return port; })(); } getDbPath() { var _this8 = this; return _asyncToGenerator(function* () { const _ref4 = yield _this8.getInstanceData(), dbPath = _ref4.dbPath; return dbPath; })(); } getDbName() { var _this9 = this; return _asyncToGenerator(function* () { const _ref5 = yield _this9.getInstanceData(), dbName = _ref5.dbName; return dbName; })(); } } exports.default = MongoMemoryServer;