11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Flags: --expose-gc
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_cicommon.skipIfInspectorDisabled();
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst assert = require('assert');
91cb0ef41Sopenharmony_ciconst vm = require('vm');
101cb0ef41Sopenharmony_ciconst { Session } = require('inspector');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst session = new Session();
131cb0ef41Sopenharmony_cisession.connect();
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cifunction notificationPromise(method) {
161cb0ef41Sopenharmony_ci  return new Promise((resolve) => session.once(method, resolve));
171cb0ef41Sopenharmony_ci}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciasync function testContextCreatedAndDestroyed() {
201cb0ef41Sopenharmony_ci  console.log('Testing context created/destroyed notifications');
211cb0ef41Sopenharmony_ci  {
221cb0ef41Sopenharmony_ci    const mainContextPromise =
231cb0ef41Sopenharmony_ci        notificationPromise('Runtime.executionContextCreated');
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci    session.post('Runtime.enable', assert.ifError);
261cb0ef41Sopenharmony_ci    const contextCreated = await mainContextPromise;
271cb0ef41Sopenharmony_ci    const { name, origin, auxData } = contextCreated.params.context;
281cb0ef41Sopenharmony_ci    if (common.isSunOS || common.isWindows || common.isIBMi) {
291cb0ef41Sopenharmony_ci      // uv_get_process_title() is unimplemented on Solaris-likes and IBMi,
301cb0ef41Sopenharmony_ci      // it returns an empty string.  On the Windows CI buildbots it returns
311cb0ef41Sopenharmony_ci      // "Administrator: Windows PowerShell[42]" because of a GetConsoleTitle()
321cb0ef41Sopenharmony_ci      // quirk. Not much we can do about either, just verify that it contains
331cb0ef41Sopenharmony_ci      // the PID.
341cb0ef41Sopenharmony_ci      assert.strictEqual(name.includes(`[${process.pid}]`), true);
351cb0ef41Sopenharmony_ci    } else {
361cb0ef41Sopenharmony_ci      let expects = `${process.argv0}[${process.pid}]`;
371cb0ef41Sopenharmony_ci      if (!common.isMainThread) {
381cb0ef41Sopenharmony_ci        expects = `Worker[${require('worker_threads').threadId}]`;
391cb0ef41Sopenharmony_ci      }
401cb0ef41Sopenharmony_ci      assert.strictEqual(expects, name);
411cb0ef41Sopenharmony_ci    }
421cb0ef41Sopenharmony_ci    assert.strictEqual(origin, '',
431cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
441cb0ef41Sopenharmony_ci    assert.strictEqual(auxData.isDefault, true,
451cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  {
491cb0ef41Sopenharmony_ci    const vmContextCreatedPromise =
501cb0ef41Sopenharmony_ci        notificationPromise('Runtime.executionContextCreated');
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci    let contextDestroyed = null;
531cb0ef41Sopenharmony_ci    session.once('Runtime.executionContextDestroyed',
541cb0ef41Sopenharmony_ci                 (notification) => contextDestroyed = notification);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci    vm.runInNewContext('1 + 1');
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    const contextCreated = await vmContextCreatedPromise;
591cb0ef41Sopenharmony_ci    const { id, name, origin, auxData } = contextCreated.params.context;
601cb0ef41Sopenharmony_ci    assert.strictEqual(name, 'VM Context 1',
611cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
621cb0ef41Sopenharmony_ci    assert.strictEqual(origin, '',
631cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
641cb0ef41Sopenharmony_ci    assert.strictEqual(auxData.isDefault, false,
651cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    // GC is unpredictable...
681cb0ef41Sopenharmony_ci    console.log('Checking/waiting for GC.');
691cb0ef41Sopenharmony_ci    while (!contextDestroyed)
701cb0ef41Sopenharmony_ci      global.gc();
711cb0ef41Sopenharmony_ci    console.log('Context destroyed.');
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci    assert.strictEqual(contextDestroyed.params.executionContextId, id,
741cb0ef41Sopenharmony_ci                       JSON.stringify(contextDestroyed));
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  {
781cb0ef41Sopenharmony_ci    const vmContextCreatedPromise =
791cb0ef41Sopenharmony_ci        notificationPromise('Runtime.executionContextCreated');
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    let contextDestroyed = null;
821cb0ef41Sopenharmony_ci    session.once('Runtime.executionContextDestroyed',
831cb0ef41Sopenharmony_ci                 (notification) => contextDestroyed = notification);
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci    vm.runInNewContext('1 + 1', {}, {
861cb0ef41Sopenharmony_ci      contextName: 'Custom context',
871cb0ef41Sopenharmony_ci      contextOrigin: 'https://origin.example'
881cb0ef41Sopenharmony_ci    });
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci    const contextCreated = await vmContextCreatedPromise;
911cb0ef41Sopenharmony_ci    const { name, origin, auxData } = contextCreated.params.context;
921cb0ef41Sopenharmony_ci    assert.strictEqual(name, 'Custom context',
931cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
941cb0ef41Sopenharmony_ci    assert.strictEqual(origin, 'https://origin.example',
951cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
961cb0ef41Sopenharmony_ci    assert.strictEqual(auxData.isDefault, false,
971cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci    // GC is unpredictable...
1001cb0ef41Sopenharmony_ci    console.log('Checking/waiting for GC again.');
1011cb0ef41Sopenharmony_ci    while (!contextDestroyed)
1021cb0ef41Sopenharmony_ci      global.gc();
1031cb0ef41Sopenharmony_ci    console.log('Other context destroyed.');
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  {
1071cb0ef41Sopenharmony_ci    const vmContextCreatedPromise =
1081cb0ef41Sopenharmony_ci        notificationPromise('Runtime.executionContextCreated');
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci    let contextDestroyed = null;
1111cb0ef41Sopenharmony_ci    session.once('Runtime.executionContextDestroyed',
1121cb0ef41Sopenharmony_ci                 (notification) => contextDestroyed = notification);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci    vm.createContext({}, { origin: 'https://nodejs.org' });
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci    const contextCreated = await vmContextCreatedPromise;
1171cb0ef41Sopenharmony_ci    const { name, origin, auxData } = contextCreated.params.context;
1181cb0ef41Sopenharmony_ci    assert.strictEqual(name, 'VM Context 2',
1191cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
1201cb0ef41Sopenharmony_ci    assert.strictEqual(origin, 'https://nodejs.org',
1211cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
1221cb0ef41Sopenharmony_ci    assert.strictEqual(auxData.isDefault, false,
1231cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci    // GC is unpredictable...
1261cb0ef41Sopenharmony_ci    console.log('Checking/waiting for GC a third time.');
1271cb0ef41Sopenharmony_ci    while (!contextDestroyed)
1281cb0ef41Sopenharmony_ci      global.gc();
1291cb0ef41Sopenharmony_ci    console.log('Context destroyed once again.');
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  {
1331cb0ef41Sopenharmony_ci    const vmContextCreatedPromise =
1341cb0ef41Sopenharmony_ci        notificationPromise('Runtime.executionContextCreated');
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci    let contextDestroyed = null;
1371cb0ef41Sopenharmony_ci    session.once('Runtime.executionContextDestroyed',
1381cb0ef41Sopenharmony_ci                 (notification) => contextDestroyed = notification);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci    vm.createContext({}, { name: 'Custom context 2' });
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci    const contextCreated = await vmContextCreatedPromise;
1431cb0ef41Sopenharmony_ci    const { name, auxData } = contextCreated.params.context;
1441cb0ef41Sopenharmony_ci    assert.strictEqual(name, 'Custom context 2',
1451cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
1461cb0ef41Sopenharmony_ci    assert.strictEqual(auxData.isDefault, false,
1471cb0ef41Sopenharmony_ci                       JSON.stringify(contextCreated));
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci    // GC is unpredictable...
1501cb0ef41Sopenharmony_ci    console.log('Checking/waiting for GC a fourth time.');
1511cb0ef41Sopenharmony_ci    while (!contextDestroyed)
1521cb0ef41Sopenharmony_ci      global.gc();
1531cb0ef41Sopenharmony_ci    console.log('Context destroyed a fourth time.');
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ciasync function testBreakpointHit() {
1581cb0ef41Sopenharmony_ci  console.log('Testing breakpoint is hit in a new context');
1591cb0ef41Sopenharmony_ci  session.post('Debugger.enable', assert.ifError);
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  const pausedPromise = notificationPromise('Debugger.paused');
1621cb0ef41Sopenharmony_ci  vm.runInNewContext('debugger', {});
1631cb0ef41Sopenharmony_ci  await pausedPromise;
1641cb0ef41Sopenharmony_ci}
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci(async function() {
1671cb0ef41Sopenharmony_ci  await testContextCreatedAndDestroyed();
1681cb0ef41Sopenharmony_ci  await testBreakpointHit();
1691cb0ef41Sopenharmony_ci})().then(common.mustCall());
170