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