'use strict'; const common = require('../common'); common.skipIfInspectorDisabled(); // Test inspector open()/close()/url() API. It uses ephemeral ports so can be // run safely in parallel. const assert = require('assert'); const fork = require('child_process').fork; const net = require('net'); const url = require('url'); if (process.env.BE_CHILD) return beChild(); const child = fork(__filename, { env: { ...process.env, BE_CHILD: 1 } }); child.once('message', common.mustCall((msg) => { assert.strictEqual(msg.cmd, 'started'); child.send({ cmd: 'open', args: [0] }); child.once('message', common.mustCall(firstOpen)); })); let firstPort; function firstOpen(msg) { assert.strictEqual(msg.cmd, 'url'); const port = url.parse(msg.url).port; ping(port, (err) => { assert.ifError(err); // Inspector is already open, and won't be reopened, so args don't matter. child.send({ cmd: 'open', args: [] }); child.once('message', common.mustCall(tryToOpenWhenOpen)); firstPort = port; }); } function tryToOpenWhenOpen(msg) { assert.strictEqual(msg.cmd, 'url'); const port = url.parse(msg.url).port; // Reopen didn't do anything, the port was already open, and has not changed. assert.strictEqual(port, firstPort); ping(port, (err) => { assert.ifError(err); child.send({ cmd: 'close' }); child.once('message', common.mustCall(closeWhenOpen)); }); } function closeWhenOpen(msg) { assert.strictEqual(msg.cmd, 'url'); assert.strictEqual(msg.url, undefined); ping(firstPort, (err) => { assert(err); child.send({ cmd: 'close' }); child.once('message', common.mustCall(tryToCloseWhenClosed)); }); } function tryToCloseWhenClosed(msg) { assert.strictEqual(msg.cmd, 'url'); assert.strictEqual(msg.url, undefined); child.send({ cmd: 'open', args: [] }); child.once('message', common.mustCall(reopenAfterClose)); } function reopenAfterClose(msg) { assert.strictEqual(msg.cmd, 'url'); const port = url.parse(msg.url).port; ping(port, (err) => { assert.ifError(err); process.exit(); }); } function ping(port, callback) { net.connect(port) .on('connect', function() { close(this); }) .on('error', function(err) { close(this, err); }); function close(self, err) { self.end(); self.on('close', () => callback(err)); } } function beChild() { const inspector = require('inspector'); process.send({ cmd: 'started' }); process.on('message', (msg) => { if (msg.cmd === 'open') { inspector.open(...msg.args); } if (msg.cmd === 'close') { inspector.close(); } process.send({ cmd: 'url', url: inspector.url() }); }); }