From 1695bb51d048b8443f8181f074d1b486c92b5b32 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Mon, 17 Dec 2018 13:13:14 -0700 Subject: [PATCH 01/11] test on CI --- package.json | 1 + src/util/MongoBinary.js | 26 +++++++++++++++++++++- src/util/__tests__/MongoBinary-test.js | 30 +++++++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 2db90e3d0..4b0d34738 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@babel/runtime": "^7.1.2", "debug": "^4.1.0", "decompress": "^4.2.0", + "dedent": "^0.7.0", "find-cache-dir": "^2.0.0", "get-port": "^4.0.0", "getos": "^3.1.1", diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index 5bcdd5333..a7b7b8f65 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -6,6 +6,8 @@ import path from 'path'; import LockFile from 'lockfile'; import mkdirp from 'mkdirp'; import findCacheDir from 'find-cache-dir'; +import { execSync } from 'child_process'; +import dedent from 'dedent'; import MongoBinaryDownload from './MongoBinaryDownload'; export type MongoBinaryCache = { @@ -43,6 +45,7 @@ export default class MongoBinary { platform: process.env?.MONGOMS_PLATFORM || os.platform(), arch: process.env?.MONGOMS_ARCH || os.arch(), version: process.env?.MONGOMS_VERSION || 'latest', + systemBinary: process.env?.MONGOMMS_SYSTEM_BINARY, debug: typeof process.env.MONGOMS_DEBUG === 'string' ? ['1', 'on', 'yes', 'true'].indexOf(process.env.MONGOMS_DEBUG.toLowerCase()) !== -1 @@ -63,7 +66,18 @@ export default class MongoBinary { const options = { ...defaultOptions, ...opts }; debug(`MongoBinary options: ${JSON.stringify(options)}`); - const { downloadDir, platform, arch, version } = options; + const { downloadDir, platform, arch, version, systemBinary } = options; + + if (systemBinary) { + try { + await fs.access(systemBinary); + + debug(`MongoBinary: found sytem binary path at ${systemBinary}`); + this.cache[version] = systemBinary; + } catch (err) { + debug(`MongoBinary: can't find system binary at ${systemBinary}`); + } + } if (this.cache[version]) { debug(`MongoBinary: found cached binary path for ${version}`); @@ -119,6 +133,16 @@ export default class MongoBinary { }); } + if (version && systemBinary) { + console.log(dedent` + MongoMemoryServer: Possible version conflict + SystemBinary version: ${execSync('mongod --version')} + Requested version: ${version} + + Using SystemBinary! + `); + } + debug(`MongoBinary: Mongod binary path: ${this.cache[version]}`); return this.cache[version]; } diff --git a/src/util/__tests__/MongoBinary-test.js b/src/util/__tests__/MongoBinary-test.js index 01431e25b..ed96e27dd 100644 --- a/src/util/__tests__/MongoBinary-test.js +++ b/src/util/__tests__/MongoBinary-test.js @@ -7,9 +7,18 @@ tmp.setGracefulCleanup(); jasmine.DEFAULT_TIMEOUT_INTERVAL = 160000; describe('MongoBinary', () => { - it('should download binary and keep it in cache', async () => { - const tmpDir = tmp.dirSync({ prefix: 'mongo-mem-bin-', unsafeCleanup: true }); + let tmpDir + + beforeEach(() => { + tmpDir = tmp.dirSync({ prefix: 'mongo-mem-bin-', unsafeCleanup: true }); + }) + + afterEach(() => { + // cleanup + tmpDir.removeCallback(); + }) + it('should download binary and keep it in cache', async () => { // download const version = 'latest'; const binPath = await MongoBinary.getPath({ @@ -27,13 +36,24 @@ describe('MongoBinary', () => { version, }); expect(binPathAgain).toEqual(binPath); - - // cleanup - tmpDir.removeCallback(); }); it('should use cache', async () => { MongoBinary.cache['3.4.2'] = '/bin/mongod'; await expect(MongoBinary.getPath({ version: '3.4.2' })).resolves.toEqual('/bin/mongod'); }); + + it('should use system binary if option is passed.', async () => { + const binPath = await MongoBinary.getPath({ + systemBinary: '/usr/bin/mongod', + }); + + expect(binPath).toEqual('/usr/bin/mongod'); + }); + + it('should get system binary from the environment', async () => { + process.env.MONGOMMS_SYSTEM_BINARY = '/usr/local/bin/mongod'; + + await expect(MongoBinary.getPath()).resolves.toEqual('/usr/local/bin/mongod'); + }); }); From 9e29683c4bbc04758e4e8114222d9147b93aa3d7 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Mon, 17 Dec 2018 13:20:15 -0700 Subject: [PATCH 02/11] fix unit test --- src/util/MongoBinary.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index a7b7b8f65..e8145f75b 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -69,14 +69,8 @@ export default class MongoBinary { const { downloadDir, platform, arch, version, systemBinary } = options; if (systemBinary) { - try { - await fs.access(systemBinary); - - debug(`MongoBinary: found sytem binary path at ${systemBinary}`); - this.cache[version] = systemBinary; - } catch (err) { - debug(`MongoBinary: can't find system binary at ${systemBinary}`); - } + debug(`MongoBinary: found sytem binary path at ${systemBinary}`); + this.cache[version] = systemBinary; } if (this.cache[version]) { From b9df877ca212415080f3f1a14542e3c22f2a3d7a Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Mon, 17 Dec 2018 13:30:39 -0700 Subject: [PATCH 03/11] fix prettier --- src/util/__tests__/MongoBinary-test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/__tests__/MongoBinary-test.js b/src/util/__tests__/MongoBinary-test.js index ed96e27dd..3086a694f 100644 --- a/src/util/__tests__/MongoBinary-test.js +++ b/src/util/__tests__/MongoBinary-test.js @@ -7,16 +7,16 @@ tmp.setGracefulCleanup(); jasmine.DEFAULT_TIMEOUT_INTERVAL = 160000; describe('MongoBinary', () => { - let tmpDir + let tmpDir; beforeEach(() => { tmpDir = tmp.dirSync({ prefix: 'mongo-mem-bin-', unsafeCleanup: true }); - }) + }); afterEach(() => { // cleanup tmpDir.removeCallback(); - }) + }); it('should download binary and keep it in cache', async () => { // download From 9f773af49fd22f71d0bba1a7af13b044cbe13e80 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Mon, 17 Dec 2018 14:51:36 -0700 Subject: [PATCH 04/11] check that system binary exists --- src/util/MongoBinary.js | 19 +++++++++++++---- src/util/__tests__/MongoBinary-test.js | 28 ++++++++++++++++++-------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index e8145f75b..59152d9cc 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -45,7 +45,7 @@ export default class MongoBinary { platform: process.env?.MONGOMS_PLATFORM || os.platform(), arch: process.env?.MONGOMS_ARCH || os.arch(), version: process.env?.MONGOMS_VERSION || 'latest', - systemBinary: process.env?.MONGOMMS_SYSTEM_BINARY, + systemBinary: process.env?.MONGOMS_SYSTEM_BINARY, debug: typeof process.env.MONGOMS_DEBUG === 'string' ? ['1', 'on', 'yes', 'true'].indexOf(process.env.MONGOMS_DEBUG.toLowerCase()) !== -1 @@ -69,8 +69,14 @@ export default class MongoBinary { const { downloadDir, platform, arch, version, systemBinary } = options; if (systemBinary) { - debug(`MongoBinary: found sytem binary path at ${systemBinary}`); - this.cache[version] = systemBinary; + try { + await fs.access(systemBinary); + + debug(`MongoBinary: found sytem binary path at ${systemBinary}`); + this.cache[version] = systemBinary; + } catch (err) { + debug(`MongoBinary: can't find system binary at ${systemBinary}`); + } } if (this.cache[version]) { @@ -130,7 +136,12 @@ export default class MongoBinary { if (version && systemBinary) { console.log(dedent` MongoMemoryServer: Possible version conflict - SystemBinary version: ${execSync('mongod --version')} + SystemBinary version: ${ + execSync('mongod --version') + .toString() + .split('\n')[0] + .split(' ')[2] + } Requested version: ${version} Using SystemBinary! diff --git a/src/util/__tests__/MongoBinary-test.js b/src/util/__tests__/MongoBinary-test.js index 3086a694f..efbc9141e 100644 --- a/src/util/__tests__/MongoBinary-test.js +++ b/src/util/__tests__/MongoBinary-test.js @@ -43,17 +43,29 @@ describe('MongoBinary', () => { await expect(MongoBinary.getPath({ version: '3.4.2' })).resolves.toEqual('/bin/mongod'); }); - it('should use system binary if option is passed.', async () => { - const binPath = await MongoBinary.getPath({ - systemBinary: '/usr/bin/mongod', + describe('System Binary', () => { + let fsMock: any; + let binPath: string; + + beforeEach(async () => { + fsMock = await jest.doMock('fs', () => ({ access: jest.fn() })); }); - expect(binPath).toEqual('/usr/bin/mongod'); - }); + afterEach(() => fsMock.access.mockReset()); - it('should get system binary from the environment', async () => { - process.env.MONGOMMS_SYSTEM_BINARY = '/usr/local/bin/mongod'; + it('should use system binary if option is passed.', async () => { + binPath = await MongoBinary.getPath({ systemBinary: '/usr/bin/mongod' }); - await expect(MongoBinary.getPath()).resolves.toEqual('/usr/local/bin/mongod'); + expect(binPath).toEqual('/usr/bin/mongod'); + expect(fsMock.access).toHaveBeenCalledWith('/usr/bin/mongod'); + }); + + it('should get system binary from the environment', async () => { + process.env.MONGOMS_SYSTEM_BINARY = '/usr/local/bin/mongod'; + binPath = await MongoBinary.getPath(); + + expect(binPath).toBe('/usr/local/bin/mongod'); + expect(fsMock.access).toHaveBeenCalledWith('/usr/local/bin/mongod'); + }); }); }); From edc536a748a6453ca6971262e3320c0ebe22c9bd Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Mon, 17 Dec 2018 15:10:29 -0700 Subject: [PATCH 05/11] fix unit tests --- src/util/MongoBinary.js | 2 +- src/util/__tests__/MongoBinary-test.js | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index 59152d9cc..dcb878dd7 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -133,7 +133,7 @@ export default class MongoBinary { }); } - if (version && systemBinary) { + if (version !== 'latest' && systemBinary) { console.log(dedent` MongoMemoryServer: Possible version conflict SystemBinary version: ${ diff --git a/src/util/__tests__/MongoBinary-test.js b/src/util/__tests__/MongoBinary-test.js index efbc9141e..ec4c1641b 100644 --- a/src/util/__tests__/MongoBinary-test.js +++ b/src/util/__tests__/MongoBinary-test.js @@ -1,6 +1,7 @@ /* @flow */ import tmp from 'tmp'; +import fs from 'fs'; import MongoBinary from '../MongoBinary'; tmp.setGracefulCleanup(); @@ -44,28 +45,25 @@ describe('MongoBinary', () => { }); describe('System Binary', () => { - let fsMock: any; - let binPath: string; + let accessSpy: any; - beforeEach(async () => { - fsMock = await jest.doMock('fs', () => ({ access: jest.fn() })); + beforeEach(() => { + accessSpy = jest.spyOn(fs, 'access'); }); - afterEach(() => fsMock.access.mockReset()); + afterEach(() => accessSpy.mockClear()); it('should use system binary if option is passed.', async () => { - binPath = await MongoBinary.getPath({ systemBinary: '/usr/bin/mongod' }); + await MongoBinary.getPath({ systemBinary: '/usr/bin/mongod' }); - expect(binPath).toEqual('/usr/bin/mongod'); - expect(fsMock.access).toHaveBeenCalledWith('/usr/bin/mongod'); + expect(accessSpy).toHaveBeenCalledWith('/usr/bin/mongod'); }); it('should get system binary from the environment', async () => { process.env.MONGOMS_SYSTEM_BINARY = '/usr/local/bin/mongod'; - binPath = await MongoBinary.getPath(); + await MongoBinary.getPath(); - expect(binPath).toBe('/usr/local/bin/mongod'); - expect(fsMock.access).toHaveBeenCalledWith('/usr/local/bin/mongod'); + expect(accessSpy).toHaveBeenCalledWith('/usr/local/bin/mongod'); }); }); }); From 262482691cee2a44ce5c7e7f74805a614f37249b Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Tue, 18 Dec 2018 14:49:40 -0700 Subject: [PATCH 06/11] refactor getPath method to consume several smaller methods --- src/util/MongoBinary.js | 162 +++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 68 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index dcb878dd7..775baed72 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -24,6 +24,83 @@ export type MongoBinaryOpts = { export default class MongoBinary { static cache: MongoBinaryCache = {}; + static debug: Function; + + static async getSystemPath(systemBinary: string): Promise { + let binaryPath: string = ''; + + try { + await fs.access(systemBinary); + + this.debug(`MongoBinary: found sytem binary path at ${systemBinary}`); + binaryPath = systemBinary; + } catch (err) { + this.debug(`MongoBinary: can't find system binary at ${systemBinary}`); + } + + return binaryPath; + } + + static async getCachePath(version: string) { + this.debug(`MongoBinary: found cached binary path for ${version}`); + return this.cache[version]; + } + + static async getDownloadPath(options: MongoBinaryOpts): Promise { + const { downloadDir, platform, arch, version } = options; + + // 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 = this.debug; + this.cache[version] = await downloader.getMongodPath(); + } + + // remove lock + LockFile.unlock(lockfile, err => { + this.debug( + err + ? `MongoBinary: Error when removing download lock ${err}` + : `MongoBinary: Download lock removed` + ); + }); + + return this.cache[version]; + } static async getPath(opts?: MongoBinaryOpts = {}): Promise { const legacyDLDir = path.resolve(os.homedir(), '.mongodb-binaries'); @@ -52,89 +129,38 @@ export default class MongoBinary { : false, }; - let debug; if (opts.debug) { if (opts.debug.call && typeof opts.debug === 'function' && opts.debug.apply) { - debug = opts.debug; + this.debug = opts.debug; } else { - debug = console.log.bind(null); + this.debug = console.log.bind(null); } } else { - debug = (msg: string) => {}; // eslint-disable-line + this.debug = (msg: string) => {}; // eslint-disable-line } const options = { ...defaultOptions, ...opts }; - debug(`MongoBinary options: ${JSON.stringify(options)}`); + this.debug(`MongoBinary options: ${JSON.stringify(options)}`); - const { downloadDir, platform, arch, version, systemBinary } = options; + const { version, systemBinary } = options; - if (systemBinary) { - try { - await fs.access(systemBinary); + let binaryPath: string = ''; - debug(`MongoBinary: found sytem binary path at ${systemBinary}`); - this.cache[version] = systemBinary; - } catch (err) { - debug(`MongoBinary: can't find system binary at ${systemBinary}`); - } + if (systemBinary) { + binaryPath = await this.getSystemPath(systemBinary); } - 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(); - } + if (!binaryPath) { + binaryPath = await this.getCachePath(version); + } - // remove lock - LockFile.unlock(lockfile, err => { - debug( - err - ? `MongoBinary: Error when removing download lock ${err}` - : `MongoBinary: Download lock removed` - ); - }); + if (!binaryPath) { + binaryPath = await this.getDownloadPath(options); } if (version !== 'latest' && systemBinary) { - console.log(dedent` + // we will log the version number of the system binary and the version requested so the user can see the difference + this.debug(dedent` MongoMemoryServer: Possible version conflict SystemBinary version: ${ execSync('mongod --version') @@ -148,8 +174,8 @@ export default class MongoBinary { `); } - debug(`MongoBinary: Mongod binary path: ${this.cache[version]}`); - return this.cache[version]; + this.debug(`MongoBinary: Mongod binary path: ${binaryPath}`); + return binaryPath; } static hasValidBinPath(files: string[]): boolean { From 5d52125f32995de176d09822a6317b25217a8f76 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Tue, 18 Dec 2018 14:52:33 -0700 Subject: [PATCH 07/11] update tests to excersize each smaller method individually this also updates tests to use a mocked version of the MongoBinaryDownloader so that we have a truelly issolated unit test... --- src/util/__tests__/MongoBinary-test.js | 89 ++++++++++++++++---------- 1 file changed, 55 insertions(+), 34 deletions(-) diff --git a/src/util/__tests__/MongoBinary-test.js b/src/util/__tests__/MongoBinary-test.js index ec4c1641b..00056240d 100644 --- a/src/util/__tests__/MongoBinary-test.js +++ b/src/util/__tests__/MongoBinary-test.js @@ -2,11 +2,23 @@ import tmp from 'tmp'; import fs from 'fs'; +import os from 'os'; import MongoBinary from '../MongoBinary'; +import MongoBinaryDownload from '../MongoBinaryDownload'; + +// const { MongoBinaryDownload } = require.requireMock('../MongoBinaryDownload') tmp.setGracefulCleanup(); jasmine.DEFAULT_TIMEOUT_INTERVAL = 160000; +const mockGetMongodPath = jest.fn().mockResolvedValue('/temp/path'); + +jest.mock('../MongoBinaryDownload', () => { + return jest.fn().mockImplementation(() => { + return { getMongodPath: mockGetMongodPath }; + }); +}); + describe('MongoBinary', () => { let tmpDir; @@ -14,56 +26,65 @@ describe('MongoBinary', () => { tmpDir = tmp.dirSync({ prefix: 'mongo-mem-bin-', unsafeCleanup: true }); }); + // cleanup afterEach(() => { - // cleanup tmpDir.removeCallback(); + MongoBinaryDownload.mockClear(); + mockGetMongodPath.mockClear(); + MongoBinary.cache = {}; }); - it('should download binary and keep it in cache', async () => { - // download - const version = 'latest'; - const binPath = await MongoBinary.getPath({ - downloadDir: tmpDir.name, - version, - }); - // eg. /tmp/mongo-mem-bin-33990ScJTSRNSsFYf/mongodb-download/a811facba94753a2eba574f446561b7e/mongodb-macOS-x86_64-3.5.5-13-g00ee4f5/ - expect(binPath).toMatch(/mongo-mem-bin-.*\/.*\/mongod$/); - - // reuse cache - expect(MongoBinary.cache[version]).toBeDefined(); - expect(MongoBinary.cache[version]).toEqual(binPath); - const binPathAgain = await MongoBinary.getPath({ - downloadDir: tmpDir.name, - version, + describe('getPath', () => { + it('should get system binary from the environment', async () => { + const accessSpy = jest.spyOn(fs, 'access'); + process.env.MONGOMS_SYSTEM_BINARY = '/usr/local/bin/mongod'; + await MongoBinary.getPath(); + + expect(accessSpy).toHaveBeenCalledWith('/usr/local/bin/mongod'); + + accessSpy.mockClear(); }); - expect(binPathAgain).toEqual(binPath); }); - it('should use cache', async () => { - MongoBinary.cache['3.4.2'] = '/bin/mongod'; - await expect(MongoBinary.getPath({ version: '3.4.2' })).resolves.toEqual('/bin/mongod'); - }); + describe('getDownloadPath', () => { + it('should download binary and keep it in cache', async () => { + // download + const version = 'latest'; + const binPath = await MongoBinary.getPath({ + downloadDir: tmpDir.name, + version, + }); + + // eg. /tmp/mongo-mem-bin-33990ScJTSRNSsFYf/mongodb-download/a811facba94753a2eba574f446561b7e/mongodb-macOS-x86_64-3.5.5-13-g00ee4f5/ + expect(MongoBinaryDownload).toHaveBeenCalledWith({ + downloadDir: tmpDir.name, + platform: os.platform(), + arch: os.arch(), + version, + }); - describe('System Binary', () => { - let accessSpy: any; + expect(mockGetMongodPath).toHaveBeenCalledTimes(1); - beforeEach(() => { - accessSpy = jest.spyOn(fs, 'access'); + expect(MongoBinary.cache[version]).toBeDefined(); + expect(MongoBinary.cache[version]).toEqual(binPath); }); + }); - afterEach(() => accessSpy.mockClear()); + describe('getCachePath', () => { + it('should get the cache', async () => { + MongoBinary.cache['3.4.2'] = '/bin/mongod'; + await expect(MongoBinary.getCachePath('3.4.2')).resolves.toEqual('/bin/mongod'); + }); + }); + describe('getSystemPath', () => { it('should use system binary if option is passed.', async () => { - await MongoBinary.getPath({ systemBinary: '/usr/bin/mongod' }); + const accessSpy = jest.spyOn(fs, 'access'); + await MongoBinary.getSystemPath('/usr/bin/mongod'); expect(accessSpy).toHaveBeenCalledWith('/usr/bin/mongod'); - }); - it('should get system binary from the environment', async () => { - process.env.MONGOMS_SYSTEM_BINARY = '/usr/local/bin/mongod'; - await MongoBinary.getPath(); - - expect(accessSpy).toHaveBeenCalledWith('/usr/local/bin/mongod'); + accessSpy.mockClear(); }); }); }); From c0f2bf0f2953340253dd45d5cfcab69c9c278303 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Tue, 18 Dec 2018 15:08:08 -0700 Subject: [PATCH 08/11] fix flow typing issues --- src/util/MongoBinary.js | 2 +- src/util/__tests__/MongoBinary-test.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index 775baed72..470f808af 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -46,7 +46,7 @@ export default class MongoBinary { return this.cache[version]; } - static async getDownloadPath(options: MongoBinaryOpts): Promise { + static async getDownloadPath(options: any): Promise { const { downloadDir, platform, arch, version } = options; // create downloadDir if not exists diff --git a/src/util/__tests__/MongoBinary-test.js b/src/util/__tests__/MongoBinary-test.js index 00056240d..b96773bcf 100644 --- a/src/util/__tests__/MongoBinary-test.js +++ b/src/util/__tests__/MongoBinary-test.js @@ -4,9 +4,8 @@ import tmp from 'tmp'; import fs from 'fs'; import os from 'os'; import MongoBinary from '../MongoBinary'; -import MongoBinaryDownload from '../MongoBinaryDownload'; -// const { MongoBinaryDownload } = require.requireMock('../MongoBinaryDownload') +const MongoBinaryDownload: any = require('../MongoBinaryDownload'); tmp.setGracefulCleanup(); jasmine.DEFAULT_TIMEOUT_INTERVAL = 160000; From 7c95849070fcaa60b039c5d9096910f2c7e5c729 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Wed, 19 Dec 2018 10:23:52 -0700 Subject: [PATCH 09/11] check system binary version against requested version this is a fairly simple check and doesn't attempt to do any complex version matching or resolution. It simply takes the value provided by the system and checks strict equality with the version requested. --- src/util/MongoBinary.js | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index 470f808af..6e774482a 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -148,6 +148,21 @@ export default class MongoBinary { if (systemBinary) { binaryPath = await this.getSystemPath(systemBinary); + const binaryVersion = execSync('mongod --version') + .toString() + .split('\n')[0] + .split(' ')[2]; + + if (version !== 'latest' && version !== binaryVersion) { + // we will log the version number of the system binary and the version requested so the user can see the difference + this.debug(dedent` + MongoMemoryServer: Possible version conflict + SystemBinary version: ${binaryVersion} + Requested version: ${version} + + Using SystemBinary! + `); + } } if (!binaryPath) { @@ -158,22 +173,6 @@ export default class MongoBinary { binaryPath = await this.getDownloadPath(options); } - if (version !== 'latest' && systemBinary) { - // we will log the version number of the system binary and the version requested so the user can see the difference - this.debug(dedent` - MongoMemoryServer: Possible version conflict - SystemBinary version: ${ - execSync('mongod --version') - .toString() - .split('\n')[0] - .split(' ')[2] - } - Requested version: ${version} - - Using SystemBinary! - `); - } - this.debug(`MongoBinary: Mongod binary path: ${binaryPath}`); return binaryPath; } From ffde32026ded446321d3b4ac1d236c1d0f55fdf5 Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Wed, 19 Dec 2018 10:25:03 -0700 Subject: [PATCH 10/11] update the README.md to include new option also added a section explaining how to use mongodb-memory-server on a system not officially supported by mongodb --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 0d48fd092..ae5dff60f 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ const mongod = new MongoMemoryServer({ arch?: string, // by default os.arch() debug?: boolean, // by default false skipMD5?: boolean, // by default false OR process.env.MONGOMS_SKIP_MD5_CHECK + systemBinary?: string, // by default undefined or process.env.MONGOMS_SYSTEM_BINARY }, debug?: boolean, // by default false autoStart?: boolean, // by default true @@ -77,6 +78,7 @@ MONGOMS_VERSION=3 MONGOMS_DEBUG=1 # also available case-insensitive values: "on" "yes" "true" MONGOMS_DOWNLOAD_MIRROR=url # your mirror url to download the mongodb binary MONGOMS_DISABLE_POSTINSTALL=1 # if you want to skip download binaries on `npm i` command +MONGOMS_SYSTEM_BINARY=/usr/local/bin/mongod # if you want to use an existing binary already on your system. MONGOMS_SKIP_MD5_CHECK=1 # if you want to skip MD5 check of downloaded binary. # Passed constructor parameter `binary.skipMD5` has higher priority. ``` @@ -333,6 +335,11 @@ Additional examples of Jest tests: ### AVA test runner For AVA written [detailed tutorial](https://github.com/zellwk/ava/blob/8b7ccba1d80258b272ae7cae6ba4967cd1c13030/docs/recipes/endpoint-testing-with-mongoose.md) how to test mongoose models by @zellwk. +### Docker Alpine +There isn't currently an official MongoDB release for alpine linux. This means that we can't pull binaries for Alpine +(or any other platform that isn't officially supported by MongoDB), but you can use a Docker image that already has mongod +built in and then set the MONGOMS_SYSTEM_BINARY variable to point at that binary. This should allow you to use +mongodb-memory-server on any system on which you can install mongod. ## Travis From f7e93fee8f1c1c9df4d2c79ffad2eaecf3e973ba Mon Sep 17 00:00:00 2001 From: Jonathan Baird Date: Wed, 19 Dec 2018 10:43:48 -0700 Subject: [PATCH 11/11] check that systemBinary exists before checking versions --- src/util/MongoBinary.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/util/MongoBinary.js b/src/util/MongoBinary.js index 6d40147da..da2fe9984 100644 --- a/src/util/MongoBinary.js +++ b/src/util/MongoBinary.js @@ -148,20 +148,22 @@ export default class MongoBinary { if (systemBinary) { binaryPath = await this.getSystemPath(systemBinary); - const binaryVersion = execSync('mongod --version') - .toString() - .split('\n')[0] - .split(' ')[2]; - - if (version !== 'latest' && version !== binaryVersion) { - // we will log the version number of the system binary and the version requested so the user can see the difference - this.debug(dedent` - MongoMemoryServer: Possible version conflict - SystemBinary version: ${binaryVersion} - Requested version: ${version} - - Using SystemBinary! - `); + if (binaryPath) { + const binaryVersion = execSync('mongod --version') + .toString() + .split('\n')[0] + .split(' ')[2]; + + if (version !== 'latest' && version !== binaryVersion) { + // we will log the version number of the system binary and the version requested so the user can see the difference + this.debug(dedent` + MongoMemoryServer: Possible version conflict + SystemBinary version: ${binaryVersion} + Requested version: ${version} + + Using SystemBinary! + `); + } } }