test: replace jest workers past 200 MB so they exit in time (closes #766)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

On a starved CPU, jest force-stopped worker processes that could not exit
within the 500 ms it allows, and script/lib/jest.js failed the run although
every test passed. No test leaks a handle; exit time grows with what a
worker holds, 380 to 970 MB at the end of the run.

workerIdleMemoryLimit in package.json replaces a worker whose heap is over
200 MB after a test file with a fresh one.

tests/jestRunner.test.js runs script/lib/jest.js on a fixture that leaves
an interval running and expects the force-stop to fail the run.

Model: opus-5-5
This commit was merged in pull request #774.
This commit is contained in:
clawbot committed 2026-11-11 09:37:12 +01:00
1 parent b77b04b714
commit 3a8b309d7e
4 files changed
+45 -3

No files matched your search

+7 -2
View File
@@ -135,9 +135,14 @@ module.exports = [
}, },
}, },
// Unit tests, and the helpers they require: jest on node. // Unit tests, the helpers they require, and the test files they hand to
// jest: jest on node.
{ {
files: ["tests/**/*.test.js", "tests/support/**/*.js"], files: [
"tests/**/*.test.js",
"tests/support/**/*.js",
"tests/fixtures/**/*.js",
],
languageOptions: { languageOptions: {
...commonjs, ...commonjs,
globals: { ...globals.node, ...globals.jest }, globals: { ...globals.node, ...globals.jest },
+2 -1
View File
@@ -16,7 +16,8 @@
"jest": { "jest": {
"setupFiles": [ "setupFiles": [
"<rootDir>/tests/support/navigatorLocks.js" "<rootDir>/tests/support/navigatorLocks.js"
] ],
"workerIdleMemoryLimit": "200MB"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "10.0.1", "@eslint/js": "10.0.1",
+7
View File
@@ -0,0 +1,7 @@
// A test file that starts an interval and never clears it.
// tests/jestRunner.test.js runs script/lib/jest.js on this file alone. The
// name does not end in .test.js, so the normal run never picks it up.
test("starts an interval and never clears it", () => {
setInterval(() => {}, 1000);
});
+29
View File
@@ -0,0 +1,29 @@
// script/lib/jest.js, which package.json's test scripts run, fails a run in
// which jest force-stopped a worker process because a test left an open
// handle.
const { spawnSync } = require("child_process");
const path = require("path");
const root = path.join(__dirname, "..");
test("a test that leaves an interval running fails the run", () => {
// The memory limit in package.json makes jest run even this one file in a
// worker process. The interval keeps that worker from exiting, so jest
// force-stops it after the run.
const result = spawnSync(
process.execPath,
[
"script/lib/jest.js",
"--maxWorkers=1",
"--testMatch",
"<rootDir>/tests/fixtures/leavesIntervalRunning.js",
],
{ cwd: root, encoding: "utf8", timeout: 20000 },
);
expect(result.signal).toBeNull();
expect(result.status).toBe(1);
expect(result.stderr).toContain("1 passed");
expect(result.stderr).toContain("jest force-stopped a worker process");
});