11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_cicommon.skipIfInspectorDisabled();
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci// Test inspector open()/close()/url() API. It uses ephemeral ports so can be
61cb0ef41Sopenharmony_ci// run safely in parallel.
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst assert = require('assert');
91cb0ef41Sopenharmony_ciconst fork = require('child_process').fork;
101cb0ef41Sopenharmony_ciconst net = require('net');
111cb0ef41Sopenharmony_ciconst url = require('url');
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciconst kFirstOpen = 0;
141cb0ef41Sopenharmony_ciconst kOpenWhileOpen = 1;
151cb0ef41Sopenharmony_ciconst kReOpen = 2;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciif (process.env.BE_CHILD)
181cb0ef41Sopenharmony_ci  return beChild();
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciconst child = fork(__filename,
211cb0ef41Sopenharmony_ci                   { env: { ...process.env, BE_CHILD: 1 } });
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_cichild.once('message', common.mustCall((msg) => {
241cb0ef41Sopenharmony_ci  assert.strictEqual(msg.cmd, 'started');
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  child.send({ cmd: 'open', args: [kFirstOpen] });
271cb0ef41Sopenharmony_ci  child.once('message', common.mustCall(firstOpen));
281cb0ef41Sopenharmony_ci}));
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_cilet firstPort;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cifunction firstOpen(msg) {
331cb0ef41Sopenharmony_ci  assert.strictEqual(msg.cmd, 'url');
341cb0ef41Sopenharmony_ci  const port = url.parse(msg.url).port;
351cb0ef41Sopenharmony_ci  ping(port, common.mustSucceed(() => {
361cb0ef41Sopenharmony_ci    // Inspector is already open, and won't be reopened, so args don't matter.
371cb0ef41Sopenharmony_ci    child.send({ cmd: 'open', args: [kOpenWhileOpen] });
381cb0ef41Sopenharmony_ci    child.once('message', common.mustCall(tryToOpenWhenOpen));
391cb0ef41Sopenharmony_ci    firstPort = port;
401cb0ef41Sopenharmony_ci  }));
411cb0ef41Sopenharmony_ci}
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_cifunction tryToOpenWhenOpen(msg) {
441cb0ef41Sopenharmony_ci  assert.strictEqual(msg.cmd, 'url');
451cb0ef41Sopenharmony_ci  const port = url.parse(msg.url).port;
461cb0ef41Sopenharmony_ci  // Reopen didn't do anything, the port was already open, and has not changed.
471cb0ef41Sopenharmony_ci  assert.strictEqual(port, firstPort);
481cb0ef41Sopenharmony_ci  ping(port, common.mustSucceed(() => {
491cb0ef41Sopenharmony_ci    child.send({ cmd: 'close' });
501cb0ef41Sopenharmony_ci    child.once('message', common.mustCall(closeWhenOpen));
511cb0ef41Sopenharmony_ci  }));
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_cifunction closeWhenOpen(msg) {
551cb0ef41Sopenharmony_ci  assert.strictEqual(msg.cmd, 'url');
561cb0ef41Sopenharmony_ci  assert.strictEqual(msg.url, undefined);
571cb0ef41Sopenharmony_ci  ping(firstPort, (err) => {
581cb0ef41Sopenharmony_ci    assert(err);
591cb0ef41Sopenharmony_ci    child.send({ cmd: 'close' });
601cb0ef41Sopenharmony_ci    child.once('message', common.mustCall(tryToCloseWhenClosed));
611cb0ef41Sopenharmony_ci  });
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_cifunction tryToCloseWhenClosed(msg) {
651cb0ef41Sopenharmony_ci  assert.strictEqual(msg.cmd, 'url');
661cb0ef41Sopenharmony_ci  assert.strictEqual(msg.url, undefined);
671cb0ef41Sopenharmony_ci  child.send({ cmd: 'open', args: [kReOpen] });
681cb0ef41Sopenharmony_ci  child.once('message', common.mustCall(reopenAfterClose));
691cb0ef41Sopenharmony_ci}
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_cifunction reopenAfterClose(msg) {
721cb0ef41Sopenharmony_ci  assert.strictEqual(msg.cmd, 'url');
731cb0ef41Sopenharmony_ci  const port = url.parse(msg.url).port;
741cb0ef41Sopenharmony_ci  ping(port, common.mustSucceed(() => {
751cb0ef41Sopenharmony_ci    process.exit();
761cb0ef41Sopenharmony_ci  }));
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cifunction ping(port, callback) {
801cb0ef41Sopenharmony_ci  net.connect({ port, family: 4 })
811cb0ef41Sopenharmony_ci    .on('connect', function() { close(this); })
821cb0ef41Sopenharmony_ci    .on('error', function(err) { close(this, err); });
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  function close(self, err) {
851cb0ef41Sopenharmony_ci    self.end();
861cb0ef41Sopenharmony_ci    self.on('close', () => callback(err));
871cb0ef41Sopenharmony_ci  }
881cb0ef41Sopenharmony_ci}
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_cifunction beChild() {
911cb0ef41Sopenharmony_ci  const inspector = require('inspector');
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  process.send({ cmd: 'started' });
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  process.on('message', (msg) => {
961cb0ef41Sopenharmony_ci    if (msg.cmd === 'open') {
971cb0ef41Sopenharmony_ci      if (msg.args[0] === kFirstOpen) {
981cb0ef41Sopenharmony_ci        inspector.open(0, false, undefined);
991cb0ef41Sopenharmony_ci      } else if (msg.args[0] === kOpenWhileOpen) {
1001cb0ef41Sopenharmony_ci        assert.throws(() => {
1011cb0ef41Sopenharmony_ci          inspector.open(0, false, undefined);
1021cb0ef41Sopenharmony_ci        }, {
1031cb0ef41Sopenharmony_ci          code: 'ERR_INSPECTOR_ALREADY_ACTIVATED'
1041cb0ef41Sopenharmony_ci        });
1051cb0ef41Sopenharmony_ci      } else if (msg.args[0] === kReOpen) {
1061cb0ef41Sopenharmony_ci        inspector.open(0, false, undefined);
1071cb0ef41Sopenharmony_ci      }
1081cb0ef41Sopenharmony_ci    }
1091cb0ef41Sopenharmony_ci    if (msg.cmd === 'close') {
1101cb0ef41Sopenharmony_ci      inspector.close();
1111cb0ef41Sopenharmony_ci    }
1121cb0ef41Sopenharmony_ci    process.send({ cmd: 'url', url: inspector.url() });
1131cb0ef41Sopenharmony_ci  });
1141cb0ef41Sopenharmony_ci}
115