11cb0ef41Sopenharmony_ci// Flags: --expose-internals
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_cicommon.skipIfInspectorDisabled();
51cb0ef41Sopenharmony_cicommon.skipIf32Bits();
61cb0ef41Sopenharmony_ciconst { NodeInstance } = require('../common/inspector-helper.js');
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cicommon.skipIfWorker(); // Signal starts a server for a main thread inspector
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciconst script = `
121cb0ef41Sopenharmony_ciprocess._rawDebug('Waiting until a signal enables the inspector...');
131cb0ef41Sopenharmony_cilet waiting = setInterval(waitUntilDebugged, 50);
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cifunction waitUntilDebugged() {
161cb0ef41Sopenharmony_ci  const { internalBinding } = require('internal/test/binding');
171cb0ef41Sopenharmony_ci  if (!internalBinding('inspector').isEnabled()) return;
181cb0ef41Sopenharmony_ci  clearInterval(waiting);
191cb0ef41Sopenharmony_ci  // At this point, even though the Inspector is enabled, the default async
201cb0ef41Sopenharmony_ci  // call stack depth is 0. We need a chance to call
211cb0ef41Sopenharmony_ci  // Debugger.setAsyncCallStackDepth *before* activating the actual timer for
221cb0ef41Sopenharmony_ci  // async stack traces to work. Directly using a debugger statement would be
231cb0ef41Sopenharmony_ci  // too brittle, and using a longer timeout would unnecessarily slow down the
241cb0ef41Sopenharmony_ci  // test on most machines. Triggering a debugger break through an interval is
251cb0ef41Sopenharmony_ci  // a faster and more reliable way.
261cb0ef41Sopenharmony_ci  process._rawDebug('Signal received, waiting for debugger setup');
271cb0ef41Sopenharmony_ci  waiting = setInterval(() => { debugger; }, 50);
281cb0ef41Sopenharmony_ci}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci// This function is called by the inspector client (session)
311cb0ef41Sopenharmony_cifunction setupTimeoutWithBreak() {
321cb0ef41Sopenharmony_ci  clearInterval(waiting);
331cb0ef41Sopenharmony_ci  process._rawDebug('Debugger ready, setting up timeout with a break');
341cb0ef41Sopenharmony_ci  setTimeout(() => { debugger; }, 50);
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci`;
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciasync function waitForInitialSetup(session) {
391cb0ef41Sopenharmony_ci  console.error('[test]', 'Waiting for initial setup');
401cb0ef41Sopenharmony_ci  await session.waitForBreakOnLine(16, '[eval]');
411cb0ef41Sopenharmony_ci}
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciasync function setupTimeoutForStackTrace(session) {
441cb0ef41Sopenharmony_ci  console.error('[test]', 'Setting up timeout for async stack trace');
451cb0ef41Sopenharmony_ci  await session.send([
461cb0ef41Sopenharmony_ci    { 'method': 'Runtime.evaluate',
471cb0ef41Sopenharmony_ci      'params': { expression: 'setupTimeoutWithBreak()' } },
481cb0ef41Sopenharmony_ci    { 'method': 'Debugger.resume' },
491cb0ef41Sopenharmony_ci  ]);
501cb0ef41Sopenharmony_ci}
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciasync function checkAsyncStackTrace(session) {
531cb0ef41Sopenharmony_ci  console.error('[test]', 'Verify basic properties of asyncStackTrace');
541cb0ef41Sopenharmony_ci  const paused = await session.waitForBreakOnLine(23, '[eval]');
551cb0ef41Sopenharmony_ci  assert(paused.params.asyncStackTrace,
561cb0ef41Sopenharmony_ci         `${Object.keys(paused.params)} contains "asyncStackTrace" property`);
571cb0ef41Sopenharmony_ci  assert(paused.params.asyncStackTrace.description, 'Timeout');
581cb0ef41Sopenharmony_ci  assert(paused.params.asyncStackTrace.callFrames
591cb0ef41Sopenharmony_ci           .some((frame) => frame.functionName === 'setupTimeoutWithBreak'));
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ciasync function runTests() {
631cb0ef41Sopenharmony_ci  const instance = await NodeInstance.startViaSignal(script);
641cb0ef41Sopenharmony_ci  const session = await instance.connectInspectorSession();
651cb0ef41Sopenharmony_ci  await session.send([
661cb0ef41Sopenharmony_ci    { 'method': 'Runtime.enable' },
671cb0ef41Sopenharmony_ci    { 'method': 'Debugger.enable' },
681cb0ef41Sopenharmony_ci    { 'method': 'Debugger.setAsyncCallStackDepth',
691cb0ef41Sopenharmony_ci      'params': { 'maxDepth': 10 } },
701cb0ef41Sopenharmony_ci    { 'method': 'Debugger.setBlackboxPatterns',
711cb0ef41Sopenharmony_ci      'params': { 'patterns': [] } },
721cb0ef41Sopenharmony_ci    { 'method': 'Runtime.runIfWaitingForDebugger' },
731cb0ef41Sopenharmony_ci  ]);
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  await waitForInitialSetup(session);
761cb0ef41Sopenharmony_ci  await setupTimeoutForStackTrace(session);
771cb0ef41Sopenharmony_ci  await checkAsyncStackTrace(session);
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  console.error('[test]', 'Stopping child instance');
801cb0ef41Sopenharmony_ci  session.disconnect();
811cb0ef41Sopenharmony_ci  instance.kill();
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_cirunTests().then(common.mustCall());
85