• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3// Flags: --expose-internals
4
5const common = require('../common');
6
7common.skipIfInspectorDisabled();
8
9const assert = require('assert');
10const cluster = require('cluster');
11
12const debuggerPort = common.PORT;
13const childProcess = require('child_process');
14
15let offset = 0;
16
17/*
18 * This test suite checks that inspector port in cluster is incremented
19 * for different execArgv combinations
20 */
21
22function testRunnerMain() {
23  let defaultPortCase = spawnMaster({
24    execArgv: ['--inspect'],
25    workers: [{ expectedPort: 9230 }]
26  });
27
28  spawnMaster({
29    execArgv: ['--inspect=65534'],
30    workers: [
31      { expectedPort: 65535 },
32      { expectedPort: 1024 },
33      { expectedPort: 1025 },
34      { expectedPort: 1026 }
35    ]
36  });
37
38  let port = debuggerPort + offset++ * 5;
39
40  spawnMaster({
41    execArgv: [`--inspect=${port}`],
42    workers: [
43      { expectedPort: port + 1 },
44      { expectedPort: port + 2 },
45      { expectedPort: port + 3 }
46    ]
47  });
48
49  port = debuggerPort + offset++ * 5;
50
51  spawnMaster({
52    execArgv: ['--inspect', `--inspect-port=${port}`],
53    workers: [{ expectedPort: port + 1 }]
54  });
55
56  port = debuggerPort + offset++ * 5;
57
58  spawnMaster({
59    execArgv: ['--inspect', `--debug-port=${port}`],
60    workers: [{ expectedPort: port + 1 }]
61  });
62
63  port = debuggerPort + offset++ * 5;
64
65  spawnMaster({
66    execArgv: [`--inspect=0.0.0.0:${port}`],
67    workers: [{ expectedPort: port + 1, expectedHost: '0.0.0.0' }]
68  });
69
70  port = debuggerPort + offset++ * 5;
71
72  spawnMaster({
73    execArgv: [`--inspect=127.0.0.1:${port}`],
74    workers: [{ expectedPort: port + 1, expectedHost: '127.0.0.1' }]
75  });
76
77  if (common.hasIPv6) {
78    port = debuggerPort + offset++ * 5;
79
80    spawnMaster({
81      execArgv: [`--inspect=[::]:${port}`],
82      workers: [{ expectedPort: port + 1, expectedHost: '::' }]
83    });
84
85    port = debuggerPort + offset++ * 5;
86
87    spawnMaster({
88      execArgv: [`--inspect=[::1]:${port}`],
89      workers: [{ expectedPort: port + 1, expectedHost: '::1' }]
90    });
91  }
92
93  // These tests check that setting inspectPort in cluster.settings
94  // would take effect and override port incrementing behavior
95
96  port = debuggerPort + offset++ * 5;
97
98  spawnMaster({
99    execArgv: [`--inspect=${port}`],
100    clusterSettings: { inspectPort: port + 2 },
101    workers: [{ expectedPort: port + 2 }]
102  });
103
104  port = debuggerPort + offset++ * 5;
105
106  spawnMaster({
107    execArgv: [`--inspect=${port}`],
108    clusterSettings: { inspectPort: 'addTwo' },
109    workers: [
110      { expectedPort: port + 2 },
111      { expectedPort: port + 4 }
112    ]
113  });
114
115  port = debuggerPort + offset++ * 5;
116
117  spawnMaster({
118    execArgv: [`--inspect=${port}`],
119    clusterSettings: { inspectPort: 'string' },
120    workers: [{}]
121  });
122
123  port = debuggerPort + offset++ * 5;
124
125  spawnMaster({
126    execArgv: [`--inspect=${port}`],
127    clusterSettings: { inspectPort: 'null' },
128    workers: [{}]
129  });
130
131  port = debuggerPort + offset++ * 5;
132
133  spawnMaster({
134    execArgv: [`--inspect=${port}`],
135    clusterSettings: { inspectPort: 'bignumber' },
136    workers: [{}]
137  });
138
139  port = debuggerPort + offset++ * 5;
140
141  spawnMaster({
142    execArgv: [`--inspect=${port}`],
143    clusterSettings: { inspectPort: 'negativenumber' },
144    workers: [{}]
145  });
146
147  port = debuggerPort + offset++ * 5;
148
149  spawnMaster({
150    execArgv: [`--inspect=${port}`],
151    clusterSettings: { inspectPort: 'bignumberfunc' },
152    workers: [{}]
153  });
154
155  port = debuggerPort + offset++ * 5;
156
157  spawnMaster({
158    execArgv: [`--inspect=${port}`],
159    clusterSettings: { inspectPort: 'strfunc' },
160    workers: [{}]
161  });
162
163  port = debuggerPort + offset++ * 5;
164
165  spawnMaster({
166    execArgv: [],
167    clusterSettings: { inspectPort: port, execArgv: ['--inspect'] },
168    workers: [
169      { expectedPort: port }
170    ]
171  });
172
173  port = debuggerPort + offset++ * 5;
174
175  spawnMaster({
176    execArgv: [`--inspect=${port}`],
177    clusterSettings: { inspectPort: 0 },
178    workers: [
179      { expectedInitialPort: 0 },
180      { expectedInitialPort: 0 },
181      { expectedInitialPort: 0 }
182    ]
183  });
184
185  port = debuggerPort + offset++ * 5;
186
187  spawnMaster({
188    execArgv: [],
189    clusterSettings: { inspectPort: 0 },
190    workers: [
191      { expectedInitialPort: 0 },
192      { expectedInitialPort: 0 },
193      { expectedInitialPort: 0 }
194    ]
195  });
196
197  defaultPortCase.then(() => {
198    port = debuggerPort + offset++ * 5;
199    defaultPortCase = spawnMaster({
200      execArgv: ['--inspect'],
201      clusterSettings: { inspectPort: port + 2 },
202      workers: [
203        { expectedInitialPort: port + 2 }
204      ]
205    });
206  });
207}
208
209function masterProcessMain() {
210  const workers = JSON.parse(process.env.workers);
211  const clusterSettings = JSON.parse(process.env.clusterSettings) || {};
212  const badPortError = { name: 'RangeError', code: 'ERR_SOCKET_BAD_PORT' };
213  let debugPort = process.debugPort;
214
215  for (const worker of workers) {
216    const params = {};
217
218    if (worker.expectedPort) {
219      params.expectedPort = worker.expectedPort;
220    }
221
222    if (worker.expectedInitialPort) {
223      params.expectedInitialPort = worker.expectedInitialPort;
224    }
225
226    if (worker.expectedHost) {
227      params.expectedHost = worker.expectedHost;
228    }
229
230    clusterSettings.execArgv = clusterSettings.execArgv ?
231      clusterSettings.execArgv.concat(['--expose-internals']) :
232      process.execArgv.concat(['--expose-internals']);
233
234    if (clusterSettings.inspectPort === 'addTwo') {
235      clusterSettings.inspectPort = common.mustCall(
236        () => { return debugPort += 2; },
237        workers.length
238      );
239    } else if (clusterSettings.inspectPort === 'string') {
240      clusterSettings.inspectPort = 'string';
241      cluster.setupMaster(clusterSettings);
242
243      assert.throws(() => {
244        cluster.fork(params).on('exit', common.mustCall(checkExitCode));
245      }, badPortError);
246
247      return;
248    } else if (clusterSettings.inspectPort === 'null') {
249      clusterSettings.inspectPort = null;
250      cluster.setupMaster(clusterSettings);
251
252      assert.throws(() => {
253        cluster.fork(params).on('exit', common.mustCall(checkExitCode));
254      }, badPortError);
255
256      return;
257    } else if (clusterSettings.inspectPort === 'bignumber') {
258      clusterSettings.inspectPort = 1293812;
259      cluster.setupMaster(clusterSettings);
260
261      assert.throws(() => {
262        cluster.fork(params).on('exit', common.mustCall(checkExitCode));
263      }, badPortError);
264
265      return;
266    } else if (clusterSettings.inspectPort === 'negativenumber') {
267      clusterSettings.inspectPort = -9776;
268      cluster.setupMaster(clusterSettings);
269
270      assert.throws(() => {
271        cluster.fork(params).on('exit', common.mustCall(checkExitCode));
272      }, badPortError);
273
274      return;
275    } else if (clusterSettings.inspectPort === 'bignumberfunc') {
276      clusterSettings.inspectPort = common.mustCall(
277        () => 123121,
278        workers.length
279      );
280
281      cluster.setupMaster(clusterSettings);
282
283      assert.throws(() => {
284        cluster.fork(params).on('exit', common.mustCall(checkExitCode));
285      }, badPortError);
286
287      return;
288    } else if (clusterSettings.inspectPort === 'strfunc') {
289      clusterSettings.inspectPort = common.mustCall(
290        () => 'invalidPort',
291        workers.length
292      );
293
294      cluster.setupMaster(clusterSettings);
295
296      assert.throws(() => {
297        cluster.fork(params).on('exit', common.mustCall(checkExitCode));
298      }, badPortError);
299
300      return;
301    }
302
303    cluster.setupMaster(clusterSettings);
304
305    cluster.fork(params).on('exit', common.mustCall(checkExitCode));
306  }
307}
308
309function workerProcessMain() {
310  const { expectedPort, expectedInitialPort, expectedHost } = process.env;
311  const debugOptions =
312    require('internal/options').getOptionValue('--inspect-port');
313
314  if ('expectedPort' in process.env) {
315    assert.strictEqual(process.debugPort, +expectedPort);
316  }
317
318  if ('expectedInitialPort' in process.env) {
319    assert.strictEqual(debugOptions.port, +expectedInitialPort);
320  }
321
322  if ('expectedHost' in process.env) {
323    assert.strictEqual(debugOptions.host, expectedHost);
324  }
325
326  process.exit();
327}
328
329function spawnMaster({ execArgv, workers, clusterSettings = {} }) {
330  return new Promise((resolve) => {
331    childProcess.fork(__filename, {
332      env: { ...process.env,
333             workers: JSON.stringify(workers),
334             clusterSettings: JSON.stringify(clusterSettings),
335             testProcess: true
336      },
337      execArgv: execArgv.concat(['--expose-internals'])
338    }).on('exit', common.mustCall((code, signal) => {
339      checkExitCode(code, signal);
340      resolve();
341    }));
342  });
343}
344
345function checkExitCode(code, signal) {
346  assert.strictEqual(code, 0);
347  assert.strictEqual(signal, null);
348}
349
350if (!process.env.testProcess) {
351  testRunnerMain();
352} else if (cluster.isMaster) {
353  masterProcessMain();
354} else {
355  workerProcessMain();
356}
357