• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3common.skipIfInspectorDisabled();
4
5// Test inspector open()/close()/url() API. It uses ephemeral ports so can be
6// run safely in parallel.
7
8const assert = require('assert');
9const fork = require('child_process').fork;
10const net = require('net');
11const url = require('url');
12
13const kFirstOpen = 0;
14const kOpenWhileOpen = 1;
15const kReOpen = 2;
16
17if (process.env.BE_CHILD)
18  return beChild();
19
20const child = fork(__filename,
21                   { env: { ...process.env, BE_CHILD: 1 } });
22
23child.once('message', common.mustCall((msg) => {
24  assert.strictEqual(msg.cmd, 'started');
25
26  child.send({ cmd: 'open', args: [kFirstOpen] });
27  child.once('message', common.mustCall(firstOpen));
28}));
29
30let firstPort;
31
32function firstOpen(msg) {
33  assert.strictEqual(msg.cmd, 'url');
34  const port = url.parse(msg.url).port;
35  ping(port, (err) => {
36    assert.ifError(err);
37    // Inspector is already open, and won't be reopened, so args don't matter.
38    child.send({ cmd: 'open', args: [kOpenWhileOpen] });
39    child.once('message', common.mustCall(tryToOpenWhenOpen));
40    firstPort = port;
41  });
42}
43
44function tryToOpenWhenOpen(msg) {
45  assert.strictEqual(msg.cmd, 'url');
46  const port = url.parse(msg.url).port;
47  // Reopen didn't do anything, the port was already open, and has not changed.
48  assert.strictEqual(port, firstPort);
49  ping(port, (err) => {
50    assert.ifError(err);
51    child.send({ cmd: 'close' });
52    child.once('message', common.mustCall(closeWhenOpen));
53  });
54}
55
56function closeWhenOpen(msg) {
57  assert.strictEqual(msg.cmd, 'url');
58  assert.strictEqual(msg.url, undefined);
59  ping(firstPort, (err) => {
60    assert(err);
61    child.send({ cmd: 'close' });
62    child.once('message', common.mustCall(tryToCloseWhenClosed));
63  });
64}
65
66function tryToCloseWhenClosed(msg) {
67  assert.strictEqual(msg.cmd, 'url');
68  assert.strictEqual(msg.url, undefined);
69  child.send({ cmd: 'open', args: [kReOpen] });
70  child.once('message', common.mustCall(reopenAfterClose));
71}
72
73function reopenAfterClose(msg) {
74  assert.strictEqual(msg.cmd, 'url');
75  const port = url.parse(msg.url).port;
76  ping(port, (err) => {
77    assert.ifError(err);
78    process.exit();
79  });
80}
81
82function ping(port, callback) {
83  net.connect(port)
84    .on('connect', function() { close(this); })
85    .on('error', function(err) { close(this, err); });
86
87  function close(self, err) {
88    self.end();
89    self.on('close', () => callback(err));
90  }
91}
92
93function beChild() {
94  const inspector = require('inspector');
95
96  process.send({ cmd: 'started' });
97
98  process.on('message', (msg) => {
99    if (msg.cmd === 'open') {
100      if (msg.args[0] === kFirstOpen) {
101        inspector.open(0, false, undefined);
102      } else if (msg.args[0] === kOpenWhileOpen) {
103        assert.throws(() => {
104          inspector.open(0, false, undefined);
105        }, {
106          code: 'ERR_INSPECTOR_ALREADY_ACTIVATED'
107        });
108      } else if (msg.args[0] === kReOpen) {
109        inspector.open(0, false, undefined);
110      }
111    }
112    if (msg.cmd === 'close') {
113      inspector.close();
114    }
115    process.send({ cmd: 'url', url: inspector.url() });
116  });
117}
118