diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8edfff05c8c..6d68b4400d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,14 +41,10 @@ jobs: matrix: node: [12, 14, 16, 18] os: [ubuntu-18.04, ubuntu-20.04] - mongodb: [4.0.2, 5.0.2, 6.0.0] + mongodb: [4.0.28, 5.0.8, 6.0.0] include: - - os: ubuntu-18.04 - mongodb-os: ubuntu1804 - - os: ubuntu-20.04 - mongodb-os: ubuntu2004 - os: ubuntu-20.04 # customize on which matrix the coverage will be collected on - mongodb: 5.0.2 + mongodb: 5.0.11 node: 16 coverage: true exclude: @@ -59,6 +55,9 @@ jobs: - os: ubuntu-20.04 # exclude because there are no <4.4 mongodb builds for 2004 mongodb: 4.0.2 name: Node ${{ matrix.node }} MongoDB ${{ matrix.mongodb }} OS ${{ matrix.os }} + env: + MONGOMS_VERSION: ${{ matrix.mongodb }} + MONGOMS_PREFER_GLOBAL_PATH: 1 steps: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2 @@ -67,18 +66,14 @@ jobs: with: node-version: ${{ matrix.node }} - - run: npm install + - name: Load MongoDB binary cache + id: cache-mongodb-binaries + uses: actions/cache@v3 + with: + path: ~/.cache/mongodb-binaries + key: ${{ matrix.os }}-${{ matrix.mongodb }} - - name: Setup - run: | - wget -q https://downloads.mongodb.org/linux/mongodb-linux-x86_64-${{ matrix.mongodb-os }}-${{ matrix.mongodb }}.tgz - tar xf mongodb-linux-x86_64-${{ matrix.mongodb-os }}-${{ matrix.mongodb }}.tgz - mkdir -p ./data/db/27017 ./data/db/27000 - printf "\ntimeout: 8000" >> ./.mocharc.yml - ./mongodb-linux-x86_64-${{ matrix.mongodb-os }}-${{ matrix.mongodb }}/bin/mongod --setParameter ttlMonitorSleepSecs=1 --fork --dbpath ./data/db/27017 --syslog --port 27017 - sleep 2 - mongod --version - echo `pwd`/mongodb-linux-x86_64-${{ matrix.mongodb-os }}-${{ matrix.mongodb }}/bin >> $GITHUB_PATH + - run: npm install - name: NPM Test without Coverage run: npm test if: matrix.coverage != true diff --git a/.mocharc.yml b/.mocharc.yml index 1810d04bb59..efa9bf8a87b 100644 --- a/.mocharc.yml +++ b/.mocharc.yml @@ -1,2 +1,4 @@ reporter: spec # better to identify failing / slow tests than "dot" ui: bdd # explicitly setting, even though it is mocha default +require: + - test/mocha-fixtures.js diff --git a/package.json b/package.json index 5a2fc5d5a64..55701e9f481 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "mkdirp": "^1.0.4", "mocha": "10.0.0", "moment": "2.x", - "mongodb-memory-server": "8.9.1", + "mongodb-memory-server": "8.9.3", "ncp": "^2.0.0", "nyc": "15.1.0", "pug": "3.0.2", diff --git a/test/common.js b/test/common.js index 932ca2d1b37..6e036983c91 100644 --- a/test/common.js +++ b/test/common.js @@ -114,11 +114,15 @@ module.exports = function(options) { return conn; }; -function getUri(env, default_uri, db) { +function getUri(default_uri, db) { + const env = process.env.START_REPLICA_SET ? process.env.MONGOOSE_REPLSET_URI : process.env.MONGOOSE_TEST_URI; const use = env ? env : default_uri; const lastIndex = use.lastIndexOf('/'); + const dbQueryString = use.slice(lastIndex); + const queryIndex = dbQueryString.indexOf('?'); + const query = queryIndex === -1 ? '' : '?' + dbQueryString.slice(queryIndex + 1); // use length if lastIndex is 9 or lower, because that would mean it found the last character of "mongodb://" - return use.slice(0, lastIndex <= 9 ? use.length : lastIndex) + `/${db}`; + return use.slice(0, lastIndex <= 9 ? use.length : lastIndex) + `/${db}` + query; } /** @@ -134,13 +138,18 @@ const databases = module.exports.databases = [ * testing uri */ -module.exports.uri = getUri(process.env.MONGOOSE_TEST_URI, 'mongodb://127.0.0.1:27017/', databases[0]); +// the following has to be done, otherwise mocha will evaluate this before running the global-setup, where it becomes the default +Object.defineProperty(module.exports, 'uri', { + get: () => getUri('mongodb://127.0.0.1:27017/', databases[0]) +}); /** * testing uri for 2nd db */ -module.exports.uri2 = getUri(process.env.MONGOOSE_TEST_URI, 'mongodb://127.0.0.1:27017/', databases[1]); +Object.defineProperty(module.exports, 'uri2', { + get: () => getUri('mongodb://127.0.0.1:27017/', databases[1]) +}); /** * expose mongoose @@ -177,28 +186,13 @@ module.exports.mongodVersion = async function() { }; async function dropDBs() { + this.timeout(60000); + const db = await module.exports({ noErrorListener: true }).asPromise(); await db.dropDatabase(); await db.close(); } -before(async function() { - this.timeout(60000); - if (process.env.START_REPLICA_SET) { - const uri = await startReplicaSet(); - - module.exports.uri = uri; - module.exports.uri2 = uri.replace(databases[0], databases[1]); - - process.env.REPLICA_SET = 'rs0'; - - const conn = mongoose.createConnection(uri); - await conn.asPromise(); - await conn.db.collection('test').findOne(); - await conn.close(); - } -}); - before(dropDBs); after(dropDBs); @@ -212,34 +206,3 @@ process.on('unhandledRejection', function(error, promise) { } throw error; }); - -async function startReplicaSet() { - const ReplSet = require('mongodb-memory-server').MongoMemoryReplSet; - - // Create new instance - const replSet = new ReplSet({ - binary: { - version: '5.0.4' - }, - instanceOpts: [ - // Set the expiry job in MongoDB to run every second - { - port: 27017, - args: ['--setParameter', 'ttlMonitorSleepSecs=1'] - } - ], - dbName: databases[0], - replSet: { - name: 'rs0', - count: 2, - storageEngine: 'wiredTiger' - } - }); - - await replSet.start(); - await replSet.waitUntilRunning(); - - await new Promise(resolve => setTimeout(resolve, 10000)); - - return replSet.getUri(databases[0]); -} diff --git a/test/index.test.js b/test/index.test.js index b67aee31763..49ae3c65242 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -717,13 +717,12 @@ describe('mongoose module:', function() { it('with replica set', async function() { const mong = new Mongoose(); - const uri = process.env.MONGOOSE_SET_TEST_URI; - if (!uri) { - return; + if (!start.uri) { + return this.skip(); } - await mong.connect(uri, options); + await mong.connect(start.uri, options); await mong.connection.close(); }); diff --git a/test/mocha-fixtures.js b/test/mocha-fixtures.js new file mode 100644 index 00000000000..2e537071c52 --- /dev/null +++ b/test/mocha-fixtures.js @@ -0,0 +1,56 @@ +'use strict'; + +const mms = require('mongodb-memory-server'); + +/* + * Default MMS mongodb version is used, unless MONGOMS_VERSION is set (which is set with the matrix in test.yml for CI) + */ + +// a single-instance running for single-instance tests +let mongoinstance; + +// a replset-instance for running repl-set tests +let mongorreplset; + +// decide wheter to start a in-memory or not +const startMemoryInstance = !process.env.MONGOOSE_TEST_URI; +const startMemoryReplset = !process.env.MONGOOSE_REPLSET_URI; + +module.exports.mochaGlobalSetup = async function mochaGlobalSetup() { + let instanceuri; + let replseturi; + + process.env.RUNTIME_DOWNLOAD = '1'; // ensure MMS is able to download binaries in this context + + // set some options when running in a CI + if (process.env.CI) { + process.env.MONGOMS_PREFER_GLOBAL_PATH = '1'; // set MMS to use "~/.cache/mongodb-binaries" even when the path does not yet exist + } + + if (startMemoryInstance) { // Config to decided if an mongodb-memory-server instance should be used + // it's needed in global space, because we don't want to create a new instance every test-suite + mongoinstance = await mms.MongoMemoryServer.create({ instance: { args: ['--setParameter', 'ttlMonitorSleepSecs=1'], storageEngine: 'wiredTiger' } }); + instanceuri = mongoinstance.getUri(); + } else { + instanceuri = process.env.MONGOOSE_TEST_URI; + } + + if (startMemoryReplset) { + mongorreplset = await mms.MongoMemoryReplSet.create({ replSet: { count: 3, args: ['--setParameter', 'ttlMonitorSleepSecs=1'], storageEngine: 'wiredTiger' } }); // using 3 because even numbers can lead to vote problems + replseturi = mongorreplset.getUri(); + } else { + replseturi = ''; + } + + process.env.MONGOOSE_TEST_URI = instanceuri; + process.env.MONGOOSE_REPLSET_URI = replseturi; +}; + +module.exports.mochaGlobalTeardown = async function mochaGlobalTeardown() { + if (mongoinstance) { // Config to decided if an mongodb-memory-server instance should be used + await mongoinstance.stop(); + } + if (mongorreplset) { + await mongorreplset.stop(); + } +};