From 6a5a48616b72363c248cc799cdcf719157bfa816 Mon Sep 17 00:00:00 2001 From: Lucas Hrabovsky Date: Wed, 16 Jan 2019 12:09:21 -0500 Subject: [PATCH] chore: We can now upgrade to mocha@5 :taco: ## Symptoms Upgrading to `mocha@5` now causes my tests to hang without any context. [See this Travis build as an example](https://travis-ci.org/mongodb-js/index-model/builds/451375910) ## Resolution We were *not* explicitly closing driver connections after tests that needed it finished which kept the driver's underlying sockets to remain open. These `after(client.close)` blocks have been added in this PR. ## Root Cause `mocha@4` introduced a reenforcement for better testing and quality with the removal of mocha killing its process when it *thinks* the tests complete. [See release notes](https://boneskull.com/mocha-v4-nears-release/#mochawontforceexit) For us, this is a huge win. `mocha` has always included its own process management which allowed us to play fast and loose releasing fds/sockets/timeouts/etc properly. ## Diagnosis Googling lead me to [this mocha issue](https://github.com/mochajs/mocha/issues/3044) where the maintainer provides several solutions to debug this and make your tests even *more* correct. Here's what worked for me: ```bash npm i -g wtfnode; wtfnode ./node_modules/.bin/_mocha test/data-service.test.js; # Wait for hang to appear # Hit ctrl+c which produces the output below ``` ``` 34 passing (1s) ^C[WTF Node?] open handles: - File descriptors: (note: stdio always exists) - fd 1 (tty) (stdio) - fd 2 (tty) (stdio) - Sockets: - 127.0.0.1:57887 -> 127.0.0.1:27018 - 127.0.0.1:57888 -> 127.0.0.1:27018 - 127.0.0.1:57890 -> 127.0.0.1:27018 - 127.0.0.1:57891 -> 127.0.0.1:27018 - Timers: - (5000 ~ 5 s) (anonymous) @ /Users/lucas/data-service/node_modules/mongodb-core/lib/topologies/server.js:373 ``` --- package-lock.json | 103 ++++++++++------------------ package.json | 8 +-- test/data-service.test.js | 3 + test/instance-detail-helper.test.js | 3 + test/native-client.test.js | 4 ++ 5 files changed, 52 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca10963d..242bc764 100644 --- a/package-lock.json +++ b/package-lock.json @@ -774,9 +774,9 @@ } }, "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "bson": { @@ -1135,13 +1135,10 @@ } }, "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true }, "component-emitter": { "version": "1.2.1", @@ -1705,9 +1702,9 @@ } }, "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "dir-glob": { @@ -3204,9 +3201,9 @@ "dev": true }, "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "har-schema": { @@ -3242,9 +3239,9 @@ } }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-symbol-support-x": { @@ -3936,12 +3933,6 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -4112,12 +4103,6 @@ "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, "lodash._basedifference": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash._basedifference/-/lodash._basedifference-3.0.3.tgz", @@ -4402,17 +4387,6 @@ "lodash.keys": "^3.0.0" } }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "^3.0.0", - "lodash._basecreate": "^3.0.0", - "lodash._isiterateecall": "^3.0.0" - } - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -5213,55 +5187,54 @@ } }, "mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "dev": true, "requires": { - "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", + "glob": "7.1.2", + "growl": "1.10.5", "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "3.1.1", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "3.1.2" + "supports-color": "5.4.0" }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" } }, "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "^3.0.0" } } } diff --git a/package.json b/package.json index a2c1f291..b055255d 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ "mongodb-js" ], "scripts": { - "pretest": "mongodb-runner start --port=27018", - "test": "mocha", - "posttest": "mongodb-runner stop --port 27018", + "pretest": "wtfnode ./node_modules/.bin/mongodb-runner start --port=27018", + "test": "wtfnode ./node_modules/.bin/_mocha", + "posttest": "wtfnode ./node_modules/.bin/mongodb-runner stop --port 27018", "check": "mongodb-js-precommit" }, "precommit": [ @@ -52,7 +52,7 @@ "devDependencies": { "chai": "^3.4.1", "eslint-config-mongodb-js": "^3.0.1", - "mocha": "^3.1.2", + "mocha": "^5.2.0", "mock-require": "^2.0.1", "mongodb-js-precommit": "^1.1.0", "mongodb-runner": "^4.6.0", diff --git a/test/data-service.test.js b/test/data-service.test.js index a4b50efe..20bd06d8 100644 --- a/test/data-service.test.js +++ b/test/data-service.test.js @@ -15,6 +15,9 @@ describe('DataService', function() { before(function(done) { service.connect(done); }); + after(function(done) { + service.disconnect(done); + }); describe('#deleteOne', function() { it('deletes the document from the collection', function(done) { diff --git a/test/instance-detail-helper.test.js b/test/instance-detail-helper.test.js index 0225f7ad..48e7e9eb 100644 --- a/test/instance-detail-helper.test.js +++ b/test/instance-detail-helper.test.js @@ -8,6 +8,9 @@ describe('mongodb-data-service#instance', function() { describe('local', function() { let client; let db; + after(function(done) { + client.close(done); + }); it('should connect to `localhost:27018`', function(done) { const model = Connection.from('mongodb://localhost:27018/data-service'); connect( diff --git a/test/native-client.test.js b/test/native-client.test.js index 2e8426c4..88e98006 100644 --- a/test/native-client.test.js +++ b/test/native-client.test.js @@ -22,6 +22,10 @@ describe('NativeClient', function() { client.connect(callback); }); + after(function(done) { + client.disconnect(done); + }); + describe('#connect', function() { context('when mocking connection-model', function() { /*