Skip to content

Commit 3c46471

Browse files
committed
test_runner: fix wrong signal exit codes
The test runner was exiting with a generic error code when interrupted by signals such as SIGINT, instead of using the standard signal-based exit codes. This change ensures the runner returns the correct signal exit code (e.g., 130 for SIGINT) rather than 1. Fixes: #62037
1 parent 76215dc commit 3c46471

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

lib/internal/test_runner/harness.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const {
2020
ERR_TEST_FAILURE,
2121
},
2222
} = require('internal/errors');
23-
const { exitCodes: { kGenericUserError } } = internalBinding('errors');
23+
const { exitCodes: { kGenericUserError, kSigInt, kSigTerm } } = internalBinding('errors');
2424
const { kCancelledByParent, Test, Suite } = require('internal/test_runner/test');
2525
const {
2626
parseCommandLine,
@@ -285,8 +285,8 @@ function setupProcessState(root, globalOptions) {
285285
process.removeListener('unhandledRejection', rejectionHandler);
286286
process.removeListener('beforeExit', exitHandler);
287287
if (globalOptions.isTestRunner) {
288-
process.removeListener('SIGINT', terminationHandler);
289-
process.removeListener('SIGTERM', terminationHandler);
288+
process.removeListener('SIGINT', () => terminationHandler(kSigInt));
289+
process.removeListener('SIGTERM', () => terminationHandler(kSigTerm));
290290
}
291291
};
292292

@@ -310,24 +310,24 @@ function setupProcessState(root, globalOptions) {
310310
return running;
311311
};
312312

313-
const terminationHandler = async () => {
313+
const terminationHandler = async (exitCode) => {
314314
const runningTests = findRunningTests(root);
315315
if (runningTests.length > 0) {
316316
root.reporter.interrupted(runningTests);
317317
// Allow the reporter stream to process the interrupted event
318318
await new Promise((resolve) => setImmediate(resolve));
319319
}
320320
await exitHandler(true);
321-
process.exit();
321+
process.exit(exitCode);
322322
};
323323

324324
process.on('uncaughtException', exceptionHandler);
325325
process.on('unhandledRejection', rejectionHandler);
326326
process.on('beforeExit', exitHandler);
327327
// TODO(MoLow): Make it configurable to hook when isTestRunner === false.
328328
if (globalOptions.isTestRunner) {
329-
process.on('SIGINT', terminationHandler);
330-
process.on('SIGTERM', terminationHandler);
329+
process.on('SIGINT', () => terminationHandler(kSigInt));
330+
process.on('SIGTERM', () => terminationHandler(kSigTerm));
331331
}
332332

333333
root.harness.coverage = FunctionPrototypeBind(collectCoverage, null, root, coverage);

src/node_exit_code.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ namespace node {
3333
/* typically the exit codes are 128 + signal number. We also exit with */ \
3434
/* certain error codes directly for legacy reasons. Here we define those */ \
3535
/* that are used to normalize the exit code on Windows. */ \
36-
V(Abort, 134)
36+
V(Abort, 134) \
37+
V(SigInt, 130) \
38+
V(SigTerm, 143)
3739

3840
// TODO(joyeecheung): expose this to user land when the codes are stable.
3941
// The underlying type should be an int, or we can get undefined behavior when

0 commit comments

Comments
 (0)