-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add option to use posix exit code upon fatal signal #4989
base: main
Are you sure you want to change the base?
Conversation
This PR hasn't had any recent activity, and I'm labeling it |
We should probably disable the stale action, pending picking up reviewing PRs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice and clean implementation, thanks! ✨
Requesting changes on a few things. But let me know, please, if I'm off base here 🙂.
Note that after this lands, we'll want to file a followup issue about making this the default behavior in some future version of Mocha. |
Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
Address PR review comments mocha org
Address PR review comments mocha org
@JoshuaKGoldberg Thanks for the review! Hopefully that latest update addresses your questions, but let me know if there's anything else you'd like to see. Looking froward to not using our own fork of mocha! 😆 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Progress! Thanks for adding in the tests. I think we'll need to capture some more cases?
Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
Remove test that asserts the problematic behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Omit win32 from signals test suite
@JoshuaKGoldberg just circling back to see if there's anything you need from me to unblock this enhancement? lmk 🙏 |
Thanks for the ping! Nothing yet. The other maintainers have been swamped (so much happening in the ecosystem!) but I'm still holding onto hope someone will be able to review. I've personally time boxed this one to within June. |
Update package.json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can see this only changes the flow in this flow:
Line 80 in 2f3fedc
if (mochaArgs['node-option'] || Object.keys(nodeArgs).length || hasInspect) { |
Not in the other flow:
Lines 139 to 141 in 2f3fedc
} else { | |
debug('running Mocha in-process'); | |
require('../lib/cli/cli').main([], mochaArgs); |
Is this really the right place for this fix?
Eg: The non-standard error codes are set here:
Lines 26 to 45 in 2f3fedc
const exitMochaLater = code => { | |
process.on('exit', () => { | |
process.exitCode = Math.min(code, 255); | |
}); | |
}; | |
/** | |
* Exits Mocha when Mocha itself has finished execution, regardless of | |
* what the tests or code under test is doing. | |
* @param {number} code - Exit code; typically # of failures | |
* @ignore | |
* @private | |
*/ | |
const exitMocha = code => { | |
const clampedCode = Math.min(code, 255); | |
let draining = 0; | |
// Eagerly set the process's exit code in case stream.write doesn't | |
// execute its callback before the process terminates. | |
process.exitCode = clampedCode; |
And in the old-school case where one forces the process to be killed once all tests are done it happens within that:
Line 52 in 2f3fedc
process.exit(clampedCode); |
I overall find this PR to be a mix of two changes:
- Stop mocha from abusing the exit code as an error count reporter
- Add signal specific exit codes
The latter of the two I would want to read up on more, but the first of them should be an easier fix.
Node.js should already be setting the signal exit codes, I wonder if we can piggy back on that instead? https://nodejs.org/api/process.html#exit-codes |
@voxpelli Thanks for the review. That's right, the option only applies "when mocha is run as a child process". The reasoning was to try and be as unobtrusive as possible and address specifically the problem of fatal errors (OOM et al) getting swallowed silently in a CI/CD pipeline where mocha is spawned by something like nyc. It sounds like there's general agreement that mocha shouldn't use the exit code to report the number of errors though, so I can update this PR to support the option in both cases. As for exit codes other than 0, 1 and 128+signal - I guess we'd need to know what the exit code scheme should be and could be something for another PR.... |
@73rhodes Is there a need to handle 128+signal codes manually or is that already handled by node.js itself? Reason why I ask is since its typically not something I have seen handled manually by other CLI tools built with node.js |
…rocess modes of running mocha
Support posix-exit-codes for child and in-process modes
@voxpelli ... I just updated the PR with a commit (this PR) that adds the signal-handling behavior for both the child-process and in-process modes of running mocha, as requested. As far as piggybacking on node's signal handling, I'm just working with these inputs:
and
where, based on what I've seen and implemented in the tests, we need to check the |
Just circling back here to see if there are any specific changes being requested here to move forward. We would prefer to use the original mocha package but proper signal handling is critical for us. Please let me know if there's anything I can do to unblock this, thanks! |
Requirements
Description of the Change
Mocha uses the number of failed tests as an exit code, which is unconventional and has led to a number of issues when trying to integrate mocha into ci/cd pipelines.
To resolve these issues, this PR introduces a
--posix-exit-codes
boolean command-line option. If this option is specified, a fatal signal (eg.SIGABRT
, et al) will cause the process to consistently exit with a standard posix exit code (128 + the numeric ID of the signal) when mocha is run as a child process (which is the case when passing node options). This helps to solve issues for toolchains that expect standard posix exit codes, for example by preventing out-of-memory crashes from being silently ignored.The GNU libc manual page provides additional context on why using the number of errors as an exit status is problematic:
Providing the option to exit with standard posix shell exit codes avoids these problems and solves a number of downstream issues listed below.
Alternate Designs
The alternatives considered were not in the scope of the mocha project.
Why should this be in core?
This option is implemented in the core repository where signal handling occurs.
Benefits
This PR provides a solution for #3559 and various downstream issues reported by mocha consumers; it preserves non-zero exit codes when mocha is spawned as a child process via various CI/CD or reporting tools and prevents silently swallowing out-of-memory errors.
Possible Drawbacks
Introduces another option. Requires docs. Leaves non-standard exit code behavior to remain as the default.
Applicable issues
fixes #3559
#3893
#2445
#2438
istanbuljs/nyc#798
cypress-io/cypress#24695