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.
126 lines (109 loc) • 3.41 kB
Flow
/* @flow */
import fs from 'fs';
import os from 'os';
import path from 'path';
import LockFile from 'lockfile';
import mkdirp from 'mkdirp';
import findCacheDir from 'find-cache-dir';
import MongoBinaryDownload from './MongoBinaryDownload';
export type MongoBinaryCache = {
[version: string]: string,
};
export type MongoBinaryOpts = {
version?: string,
downloadDir?: string,
platform?: string,
arch?: string,
debug?: boolean | Function,
};
export default class MongoBinary {
static cache: MongoBinaryCache = {};
static async getPath(opts?: MongoBinaryOpts = {}): Promise<string> {
const legacyDLDir = path.resolve(os.homedir(), '.mongodb-binaries');
const defaultOptions = {
downloadDir:
process.env?.MONGOMS_DOWNLOAD_DIR ||
(fs.existsSync(legacyDLDir)
? legacyDLDir
: path.resolve(findCacheDir({ name: 'mongodb-memory-server' }), 'mongodb-binaries')),
platform: process.env?.MONGOMS_PLATFORM || os.platform(),
arch: process.env?.MONGOMS_ARCH || os.arch(),
version: process.env?.MONGOMS_VERSION || 'latest',
debug:
typeof process.env.MONGOMS_DEBUG === 'string'
? ['1', 'on', 'yes', 'true'].indexOf(process.env.MONGOMS_DEBUG.toLowerCase()) !== -1
: false,
};
let debug;
if (opts.debug) {
if (opts.debug.call && typeof opts.debug === 'function' && opts.debug.apply) {
debug = opts.debug;
} else {
debug = console.log.bind(null);
}
} else {
debug = (msg: string) => {}; // eslint-disable-line
}
const options = { ...defaultOptions, ...opts };
debug(`MongoBinary options: ${JSON.stringify(options)}`);
const { downloadDir, platform, arch, version } = options;
if (this.cache[version]) {
debug(`MongoBinary: found cached binary path for ${version}`);
} else {
// create downloadDir if not exists
await new Promise((resolve, reject) => {
mkdirp(downloadDir, err => {
if (err) reject(err);
else resolve();
});
});
const lockfile = path.resolve(downloadDir, `${version}.lock`);
// wait lock
await new Promise((resolve, reject) => {
LockFile.lock(
lockfile,
{
wait: 120000,
pollPeriod: 100,
stale: 110000,
retries: 3,
retryWait: 100,
},
err => {
if (err) reject(err);
else resolve();
}
);
});
// again check cache, maybe other instance resolve it
if (!this.cache[version]) {
const downloader = new MongoBinaryDownload({
downloadDir,
platform,
arch,
version,
});
downloader.debug = debug;
this.cache[version] = await downloader.getMongodPath();
}
// remove lock
LockFile.unlock(lockfile, err => {
debug(
err
? `MongoBinary: Error when removing download lock ${err}`
: `MongoBinary: Download lock removed`
);
});
}
debug(`MongoBinary: Mongod binary path: ${this.cache[version]}`);
return this.cache[version];
}
static hasValidBinPath(files: string[]): boolean {
if (files.length === 1) {
return true;
} else if (files.length > 1) {
return false;
}
return false;
}
}