| 'use strict'; |
| const common = require('../common'); |
| const assert = require('assert'); |
| const child_process = require('child_process'); |
| |
| // Test that workers fail with meaningful error message |
| // when their initialization fails. |
| |
| if (common.isWindows) { |
| common.skip('ulimit does not work on Windows.'); |
| } |
| |
| if (process.config.variables.node_builtin_modules_path) { |
| common.skip('this test cannot pass when Node.js is built with --node-builtin-modules-path'); |
| } |
| |
| // A reasonably low fd count. An empty node process |
| // creates around 30 fds for its internal purposes, |
| // so making it too low will crash the process early, |
| // making it too high will cause too much resource use. |
| const OPENFILES = 128; |
| |
| // Double the open files - so that some workers fail for sure. |
| const WORKERCOUNT = 256; |
| |
| if (process.argv[2] === 'child') { |
| const { Worker } = require('worker_threads'); |
| for (let i = 0; i < WORKERCOUNT; ++i) { |
| const worker = new Worker( |
| 'require(\'worker_threads\').parentPort.postMessage(2 + 2)', |
| { eval: true }); |
| worker.on('message', (result) => { |
| assert.strictEqual(result, 4); |
| }); |
| |
| // We want to test that if there is an error in a constrained running |
| // environment, it will be one of `ENFILE`, `EMFILE`, 'ENOENT', or |
| // `ERR_WORKER_INIT_FAILED`. |
| const expected = ['ERR_WORKER_INIT_FAILED', 'EMFILE', 'ENFILE', 'ENOENT']; |
| |
| // `common.mustCall*` cannot be used here as in some environments |
| // (i.e. single cpu) `ulimit` may not lead to such an error. |
| worker.on('error', (e) => { |
| assert.ok(expected.includes(e.code), `${e.code} not expected`); |
| }); |
| } |
| |
| } else { |
| // Limit the number of open files, to force workers to fail. |
| let testCmd = `ulimit -n ${OPENFILES} && `; |
| testCmd += `${process.execPath} ${__filename} child`; |
| const cp = child_process.exec(testCmd); |
| |
| // Turn on the child streams for debugging purposes. |
| let stdout = ''; |
| cp.stdout.setEncoding('utf8'); |
| cp.stdout.on('data', (chunk) => { |
| stdout += chunk; |
| }); |
| let stderr = ''; |
| cp.stderr.setEncoding('utf8'); |
| cp.stderr.on('data', (chunk) => { |
| stderr += chunk; |
| }); |
| |
| cp.on('exit', common.mustCall((code, signal) => { |
| console.log(`child stdout: ${stdout}\n`); |
| console.log(`child stderr: ${stderr}\n`); |
| assert.strictEqual(code, 0); |
| assert.strictEqual(signal, null); |
| })); |
| } |