Skip to content

Commit 17b2526

Browse files
HarshithaKPtargos
authored andcommitted
test: add Worker initialization failure test case
Cover the scenario fixed through #31621 Unfortunately there is no easy way to test this, in a cross-platform manner. So the approach is: - open a child process with ulimit restriction on file descriptors - in the child process, start few workers - more than the fd limit - make sure some workers fail, with the expected error type. - skip the test in windows, as there is no ulimit there. Refs: #31621 PR-URL: #31929 Reviewed-By: Denys Otrishko <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent ed89863 commit 17b2526

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
6+
// Test that workers fail with meaningful error message
7+
// when their initialization fails.
8+
9+
if (common.isWindows) {
10+
common.skip('ulimit does not work on Windows.');
11+
}
12+
13+
// A reasonably low fd count. An empty node process
14+
// creates around 30 fds for its internal purposes,
15+
// so making it too low will crash the process early,
16+
// making it too high will cause too much resource use.
17+
const OPENFILES = 128;
18+
19+
// Double the open files - so that some workers fail for sure.
20+
const WORKERCOUNT = 256;
21+
22+
if (process.argv[2] === 'child') {
23+
const { Worker } = require('worker_threads');
24+
for (let i = 0; i < WORKERCOUNT; ++i) {
25+
const worker = new Worker(
26+
'require(\'worker_threads\').parentPort.postMessage(2 + 2)',
27+
{ eval: true });
28+
worker.on('message', (result) => {
29+
assert.strictEqual(result, 4);
30+
});
31+
32+
// We want to test that if there is an error in a constrained running
33+
// environment, it will be one of `EMFILE` or `ERR_WORKER_INIT_FAILED`.
34+
// `common.mustCall*` cannot be used here as in some environments
35+
// (i.e. single cpu) `ulimit` may not lead to such an error.
36+
37+
worker.on('error', (e) => {
38+
assert.match(e.message, /EMFILE/);
39+
assert.ok(e.code === 'ERR_WORKER_INIT_FAILED' || e.code === 'EMFILE');
40+
});
41+
}
42+
43+
} else {
44+
// Limit the number of open files, to force workers to fail.
45+
let testCmd = `ulimit -n ${OPENFILES} && `;
46+
testCmd += `${process.execPath} ${__filename} child`;
47+
const cp = child_process.exec(testCmd);
48+
49+
// Turn on the child streams for debugging purposes.
50+
let stdout = '';
51+
cp.stdout.setEncoding('utf8');
52+
cp.stdout.on('data', (chunk) => {
53+
stdout += chunk;
54+
});
55+
let stderr = '';
56+
cp.stderr.setEncoding('utf8');
57+
cp.stderr.on('data', (chunk) => {
58+
stderr += chunk;
59+
});
60+
61+
cp.on('exit', common.mustCall((code, signal) => {
62+
console.log(`child stdout: ${stdout}\n`);
63+
console.log(`child stderr: ${stderr}\n`);
64+
assert.strictEqual(code, 0);
65+
assert.strictEqual(signal, null);
66+
}));
67+
}

0 commit comments

Comments
 (0)