// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // TODO(kozyatinskiy): fix or remove it later. let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we trim async call chains correctly.'); Protocol.Debugger.enable(); InspectorTest.log('set async chain depth to 8'); Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 8}); InspectorTest.runAsyncTestSuite([ async function testDebuggerPaused() { runWithAsyncChain(4, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithAsyncChain(8, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithAsyncChain(9, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithAsyncChain(32, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); }, async function testConsoleTrace() { Protocol.Runtime.enable(); runWithAsyncChain(4, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithAsyncChain(8, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithAsyncChain(9, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithAsyncChain(32, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); }, async function testDebuggerPausedSetTimeout() { runWithAsyncChainSetTimeout(4, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithAsyncChainSetTimeout(8, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithAsyncChainSetTimeout(9, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithAsyncChainSetTimeout(32, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); }, async function testConsoleTraceSetTimeout() { runWithAsyncChainSetTimeout(4, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithAsyncChainSetTimeout(8, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithAsyncChainSetTimeout(9, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithAsyncChainSetTimeout(32, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); }, async function testConsoleTraceWithEmptySync() { Protocol.Runtime.evaluate({ expression: 'new Promise(resolve => setTimeout(resolve, 0)).then(() => console.trace(42))' }); InspectorTest.logMessage((await Protocol.Runtime.onceConsoleAPICalled()).params.stackTrace); }, async function testDebuggerPausedThenableJob() { runWithThenableJob(4, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithThenableJob(8, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithThenableJob(9, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); runWithThenableJob(32, 'debugger;'); dumpAsyncChainLength(await Protocol.Debugger.oncePaused()); await Protocol.Debugger.resume(); }, async function testConsoleTraceThenableJob() { runWithThenableJob(4, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithThenableJob(8, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithThenableJob(9, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); runWithThenableJob(32, 'console.trace(42);'); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); }, async function twoConsoleAssert() { Protocol.Runtime.evaluate({ expression: 'setTimeout(' + 'setTimeout.bind(null, ' + 'setTimeout.bind(null, () => { console.assert(); setTimeout(console.assert, 0) }, 0), 0), 0)' }); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled()); } ]); function runWithAsyncChain(len, source) { InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`); let then = '.then(() => 1)'; let pause = `.then(() => { ${source} })`; Protocol.Runtime.evaluate({ expression: `Promise.resolve()${then.repeat(len - 1)}${pause}` }); } function runWithAsyncChainSetTimeout(len, source) { InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`); let setTimeout = 'setTimeout(() => {'; let suffix = '}, 0)'; Protocol.Runtime.evaluate({ expression: `${setTimeout.repeat(len)}${source}${suffix.repeat(len)}` }); } function runWithThenableJob(len, source) { InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`); let then = '.then(Promise.resolve.bind(Promise, 0))'; let pause = `.then(() => { ${source} })`; Protocol.Runtime.evaluate({ expression: `Promise.resolve()${then.repeat(len - 1)}${pause}` }); } function dumpAsyncChainLength(message) { let stackTrace = message.params.asyncStackTrace || message.params.stackTrace.parent; let asyncChainCount = 0; while (stackTrace) { ++asyncChainCount; stackTrace = stackTrace.parent; } InspectorTest.log(`actual async chain len: ${asyncChainCount}`); }