test: run jest in one process, fail on an open handle (closes #766)
Jest force-stopped worker processes that could not exit within 500 ms on a starved CPU, failing runs where every test passed. The test scripts now pass --runInBand. script/lib/jest.js fails the run at once when jest warns that it did not exit one second after the run, instead of hanging. The Dockerfile test stage drops its 90-second timeout. tests/jestRunner.test.js runs the runner on a fixture that leaves an interval running and expects exit status 1. Model: opus-5-5
This commit is contained in:
1 parent
d909567ab9
commit
4cb61d1a10
7 files changed
+72
-39
No files matched your search
+17
-25
@@ -1,8 +1,8 @@
|
||||
// Runs jest with the arguments it is given, and fails the run when jest had to
|
||||
// force-stop the worker process that ran a test file. Jest itself only prints a
|
||||
// warning when that happens, and its run still passes. The warning means a test
|
||||
// left a timer or another open handle running. The test scripts in package.json
|
||||
// run jest through this file.
|
||||
// Runs jest with the arguments it is given, and fails the run at once when a
|
||||
// test left a timer or another open handle running. Such a handle keeps this
|
||||
// process alive after the last test, so the run would hang. Jest itself only
|
||||
// prints a warning one second after the run, and then keeps waiting. The test
|
||||
// scripts in package.json run jest through this file, in this one process.
|
||||
//
|
||||
// Jest runs inside this process and writes to the terminal directly, so its
|
||||
// output looks the same as a plain jest run. This file only checks each write
|
||||
@@ -10,31 +10,23 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// The start of the warning that jest prints on stderr after it force-stops a
|
||||
// worker process.
|
||||
const WORKER_WARNING = "A worker process has failed to exit gracefully";
|
||||
|
||||
let forceStopped = false;
|
||||
// The start of the warning that jest prints on stderr when the process has not
|
||||
// exited one second after the test run.
|
||||
const OPEN_HANDLE_WARNING =
|
||||
"Jest did not exit one second after the test run has completed.";
|
||||
|
||||
const writeStderr = process.stderr.write.bind(process.stderr);
|
||||
process.stderr.write = (chunk, ...rest) => {
|
||||
if (String(chunk).includes(WORKER_WARNING)) {
|
||||
forceStopped = true;
|
||||
}
|
||||
return writeStderr(chunk, ...rest);
|
||||
};
|
||||
|
||||
// Runs after jest has finished, as the process exits.
|
||||
process.on("exit", () => {
|
||||
if (forceStopped) {
|
||||
console.error(
|
||||
"script/lib/jest.js: failing the run, because jest force-stopped " +
|
||||
"a worker process. A test left a timer or another open " +
|
||||
"handle running.",
|
||||
const written = writeStderr(chunk, ...rest);
|
||||
if (String(chunk).includes(OPEN_HANDLE_WARNING)) {
|
||||
writeStderr(
|
||||
"script/lib/jest.js: failing the run, because a test left a " +
|
||||
"timer or another open handle running.\n",
|
||||
);
|
||||
process.exitCode = 1;
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
return written;
|
||||
};
|
||||
|
||||
// Jest's own command-line program. It reads its arguments from process.argv.
|
||||
require("jest/bin/jest");
|
||||
Reference in new issue
Block a user