Skip to content

Commit

Permalink
Merge pull request #11 from zendesk/dderidder/fix-exit-codes-pr-update
Browse files Browse the repository at this point in the history
Support posix-exit-codes for child and in-process modes
  • Loading branch information
73rhodes authored Aug 2, 2024
2 parents 1809576 + df38431 commit 9ee844a
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 19 deletions.
2 changes: 1 addition & 1 deletion bin/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const mochaArgs = {};
const nodeArgs = {};
const EXIT_SUCCESS = 0;
const EXIT_FAILURE = 1;
const SIGNAL_OFFSET= 128;
const SIGNAL_OFFSET = 128;
let hasInspect = false;

const opts = loadOptions(process.argv.slice(2));
Expand Down
10 changes: 8 additions & 2 deletions lib/cli/run-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const {format} = require('util');
const {createInvalidLegacyPluginError} = require('../errors');
const {requireOrImport} = require('../nodejs/esm-utils');
const PluginLoader = require('../plugin-loader');
const EXIT_FAILURE = 1;

/**
* Exits Mocha when tests + code under test has finished execution (default)
Expand All @@ -25,7 +26,10 @@ const PluginLoader = require('../plugin-loader');
*/
const exitMochaLater = code => {
process.on('exit', () => {
process.exitCode = Math.min(code, 255);
const usePosixExitCodes = process.argv.includes('--posix-exit-codes');
const exitCode =
usePosixExitCodes && code > 0 ? EXIT_FAILURE : Math.min(code, 255);
process.exitCode = exitCode;
});
};

Expand All @@ -37,7 +41,9 @@ const exitMochaLater = code => {
* @private
*/
const exitMocha = code => {
const clampedCode = Math.min(code, 255);
const usePosixExitCodes = process.argv.includes('--posix-exit-codes');
const clampedCode =
usePosixExitCodes && code > 0 ? EXIT_FAILURE : Math.min(code, 255);
let draining = 0;

// Eagerly set the process's exit code in case stream.write doesn't
Expand Down
13 changes: 13 additions & 0 deletions test/integration/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {format} = require('util');
const path = require('path');
const Base = require('../../lib/reporters/base');
const debug = require('debug')('mocha:test:integration:helpers');
const SIGNAL_OFFSET = 128;

/**
* Path to `mocha` executable
Expand Down Expand Up @@ -357,6 +358,18 @@ function createSubprocess(args, done, opts = {}) {
});
});

/**
* Emulate node's exit code for fatal signal. Allows tests to see the same
* exit code as the mocha cli.
*/
mocha.on('exit', (code, signal) => {
if (signal) {
mocha.exitCode =
SIGNAL_OFFSET +
(typeof signal == 'string' ? os.constants.signals[signal] : signal);
}
});

return mocha;
}

Expand Down
185 changes: 169 additions & 16 deletions test/integration/options/posixExitCodes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,96 @@ const EXIT_FAILURE = 1;
const SIGNAL_OFFSET = 128;

describe('--posix-exit-codes', function () {
if (os.platform() !== 'win32') { // SIGTERM is not supported on Windows
describe('when enabled, and with node options', function () {
var args = ['--no-warnings', '--posix-exit-codes'];
describe('when enabled', function () {
describe('when mocha is run as a child process', () => {
// 'no-warnings' node option makes mocha run as a child process
const args = ['--no-warnings', '--posix-exit-codes'];

it('should exit with correct POSIX shell code on SIGABRT', function (done) {
var fixture = 'signals-sigabrt.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(res.code, 'to be', SIGNAL_OFFSET + os.constants.signals.SIGABRT);
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGABRT
);
done();
});
});

it('should exit with correct POSIX shell code on SIGTERM', function (done) {
var fixture = 'signals-sigterm.fixture.js';
// SIGTERM is not supported on Windows
if (os.platform() !== 'win32') {
var fixture = 'signals-sigterm.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGTERM
);
done();
});
} else {
done();
}
});

it('should exit with code 1 if there are test failures', function (done) {
var fixture = 'failing.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(res.code, 'to be', SIGNAL_OFFSET + os.constants.signals.SIGTERM);
expect(res.code, 'to be', EXIT_FAILURE);
done();
});
});
});

describe('when mocha is run in-process', () => {
// Without node-specific cli options, mocha runs in-process
const args = ['--posix-exit-codes'];

it('should exit with the correct POSIX shell code on SIGABRT', function (done) {
var fixture = 'signals-sigabrt.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGABRT
);
done();
});
});

it('should exit with the correct POSIX shell code on SIGTERM', function (done) {
// SIGTERM is not supported on Windows
if (os.platform() !== 'win32') {
var fixture = 'signals-sigterm.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGTERM
);
done();
});
} else {
done();
}
});

it('should exit with code 1 if there are test failures', function (done) {
var fixture = 'failing.fixture.js';
Expand All @@ -46,19 +111,107 @@ describe('--posix-exit-codes', function () {
});
});
});
}
});

describe('when not enabled, and with node options', function () {
it('should exit with the number of failed tests', function (done) {
var fixture = 'failing.fixture.js'; // contains three failing tests
var numFailures = 3;
describe('when not enabled', function () {
const fixture = 'failing.fixture.js'; // contains three failing tests
const numFailures = 3;

describe('when mocha is run as a child process', () => {
// 'no-warnings' node option makes mocha run as a child process
var args = ['--no-warnings'];
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);

it('should exit with the correct POSIX shell code on SIGABRT', function (done) {
var fixture = 'signals-sigabrt.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGABRT
);
done();
});
});

it('should exit with the correct POSIX shell code on SIGTERM', function (done) {
// SIGTERM is not supported on Windows
if (os.platform() !== 'win32') {
var fixture = 'signals-sigterm.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGTERM
);
done();
});
} else {
done();
}
});

it('should exit with the number of failed tests', function (done) {
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(res.code, 'to be', numFailures);
done();
});
});
});

describe('when mocha is run in-process', () => {
var args = [];
it('should exit with the correct POSIX shell code on SIGABRT', function (done) {
var fixture = 'signals-sigabrt.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGABRT
);
done();
});
});

it('should exit with the correct POSIX shell code on SIGTERM', function (done) {
// SIGTERM is not supported on Windows
if (os.platform() !== 'win32') {
var fixture = 'signals-sigterm.fixture.js';
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(
res.code,
'to be',
SIGNAL_OFFSET + os.constants.signals.SIGTERM
);
done();
});
} else {
done();
}
expect(res.code, 'to be', numFailures);
done();
});

it('should exit with the number of failed tests', function (done) {
runMocha(fixture, args, function postmortem(err, res) {
if (err) {
return done(err);
}
expect(res.code, 'to be', numFailures);
done();
});
});
});
});
Expand Down

0 comments on commit 9ee844a

Please sign in to comment.