|  | 
|  | 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