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