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