1// Flags: --inspect=0 2'use strict'; 3const common = require('../common'); 4const assert = require('assert'); 5 6// With the current behavior of Node.js (at least as late as 8.1.0), this 7// test fails with the following error: 8// `AssertionError [ERR_ASSERTION]: worker 2 failed to bind port` 9// Ideally, there would be a way for the user to opt out of sequential port 10// assignment. 11// 12// Refs: https://github.com/nodejs/node/issues/13343 13 14// This following check should be replaced by common.skipIfInspectorDisabled() 15// if moved out of the known_issues directory. 16if (!process.features.inspector) { 17 // When the V8 inspector is disabled, using either --without-inspector or 18 // --without-ssl, this test will not fail which it is expected to do. 19 // The following fail will allow this test to be skipped by failing it. 20 assert.fail('skipping as V8 inspector is disabled'); 21} 22 23const cluster = require('cluster'); 24const net = require('net'); 25 26const ports = [process.debugPort]; 27const clashPort = process.debugPort + 2; 28function serialFork() { 29 return new Promise((res) => { 30 const worker = cluster.fork(); 31 worker.on('error', (err) => assert.fail(err)); 32 // No common.mustCall since 1 out of 3 should fail. 33 worker.on('online', () => { 34 worker.on('message', common.mustCall((message) => { 35 ports.push(message.debugPort); 36 })); 37 }); 38 worker.on('exit', common.mustCall((code, signal) => { 39 assert.strictEqual(signal, null); 40 // worker 2 should fail because of port clash with `server` 41 if (code === 12) { 42 return assert.fail(`worker ${worker.id} failed to bind port`); 43 } 44 assert.strictEqual(code, 0); 45 })); 46 worker.on('disconnect', common.mustCall(res)); 47 }); 48} 49 50if (cluster.isPrimary) { 51 cluster.on('online', common.mustCall((worker) => worker.send('dbgport'), 2)); 52 53 // Block one of the ports with a listening socket. 54 const server = net.createServer(); 55 server.listen(clashPort, common.localhostIPv4, common.mustCall(() => { 56 // Try to fork 3 workers. No.2 should fail. 57 Promise.all([serialFork(), serialFork(), serialFork()]) 58 .then(common.mustNotCall()) 59 .catch((err) => console.error(err)); 60 })); 61 server.unref(); 62} else { 63 const sentinel = common.mustCall(); 64 process.on('message', (message) => { 65 if (message !== 'dbgport') return; 66 process.send({ debugPort: process.debugPort }); 67 sentinel(); 68 process.disconnect(); 69 }); 70} 71