From 8999b7b787a95b3d447df0daf025fd0d7c5d02ea Mon Sep 17 00:00:00 2001 From: Darren DeRidder Date: Tue, 23 May 2023 17:53:18 -0400 Subject: [PATCH] Option to use posix exit code upon fatal signal --- bin/mocha.js | 10 ++++-- lib/cli/run-option-metadata.js | 1 + lib/cli/run.js | 4 +++ .../fixtures/posix-exit-codes.fixture.js | 7 ++++ .../options/posixExitCodes.spec.js | 36 +++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) mode change 100644 => 100755 bin/mocha.js create mode 100644 test/integration/fixtures/posix-exit-codes.fixture.js create mode 100644 test/integration/options/posixExitCodes.spec.js diff --git a/bin/mocha.js b/bin/mocha.js old mode 100644 new mode 100755 index fb58e65fcd..735bc42e95 --- a/bin/mocha.js +++ b/bin/mocha.js @@ -10,6 +10,7 @@ * @private */ +const os = require('os'); const {loadOptions} = require('../lib/cli/options'); const { unparseNodeFlags, @@ -109,7 +110,12 @@ if (mochaArgs['node-option'] || Object.keys(nodeArgs).length || hasInspect) { proc.on('exit', (code, signal) => { process.on('exit', () => { if (signal) { - process.kill(process.pid, signal); + if (mochaArgs['posix-exit-codes'] === true) { + process.exitCode = 128 + os.constants.signals[signal]; + process.exit(process.exitCode); + } else { + process.kill(process.pid, signal); + } } else { process.exit(code); } @@ -126,7 +132,7 @@ if (mochaArgs['node-option'] || Object.keys(nodeArgs).length || hasInspect) { // be needed. if (!args.parallel || args.jobs < 2) { // win32 does not support SIGTERM, so use next best thing. - if (require('os').platform() === 'win32') { + if (os.platform() === 'win32') { proc.kill('SIGKILL'); } else { // using SIGKILL won't cleanly close the output streams, which can result diff --git a/lib/cli/run-option-metadata.js b/lib/cli/run-option-metadata.js index 492608fbdd..91a0282e7b 100644 --- a/lib/cli/run-option-metadata.js +++ b/lib/cli/run-option-metadata.js @@ -45,6 +45,7 @@ const TYPES = (exports.types = { 'list-reporters', 'no-colors', 'parallel', + 'posix-exit-codes', 'recursive', 'sort', 'watch' diff --git a/lib/cli/run.js b/lib/cli/run.js index fbbe510e94..a4830e97e6 100644 --- a/lib/cli/run.js +++ b/lib/cli/run.js @@ -190,6 +190,10 @@ exports.builder = yargs => description: 'Run tests in parallel', group: GROUPS.RULES }, + 'posix-exit-codes': { + description: 'Use posix exit codes for fatal signals', + group: GROUPS.RULES + }, recursive: { description: 'Look for tests in subdirectories', group: GROUPS.FILES diff --git a/test/integration/fixtures/posix-exit-codes.fixture.js b/test/integration/fixtures/posix-exit-codes.fixture.js new file mode 100644 index 0000000000..037111097b --- /dev/null +++ b/test/integration/fixtures/posix-exit-codes.fixture.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('signal suite', function () { + it('test SIGABRT', function () { + process.kill(process.pid, 'SIGABRT'); + }); +}); diff --git a/test/integration/options/posixExitCodes.spec.js b/test/integration/options/posixExitCodes.spec.js new file mode 100644 index 0000000000..63fa8c9726 --- /dev/null +++ b/test/integration/options/posixExitCodes.spec.js @@ -0,0 +1,36 @@ +'use strict'; + +var helpers = require('../helpers'); +var runMocha = helpers.runMocha; + +describe('--posix-exit-codes', function () { + // subprocess + var mocha; + + function killSubprocess() { + mocha.kill('SIGKILL'); + } + + // these two handlers deal with a ctrl-c on command-line + before(function () { + process.on('SIGINT', killSubprocess); + }); + + after(function () { + process.removeListener('SIGINT', killSubprocess); + }); + + describe('when enabled with node options', function () { + it('should exit with code 134 on SIGABRT', function (done) { + var fixture = 'posix-exit-codes.fixture.js'; + var args = ['--no-warnings', '--posix-exit-codes']; + mocha = runMocha(fixture, args, function postmortem(err, res) { + if (err) { + return done(err); + } + expect(res.code, 'to be', 134); + done(); + }); + }); + }); +});