1'use strict';
2
3const common = require('../common');
4
5common.skipIfInspectorDisabled();
6common.skipIfWorker(); // https://github.com/nodejs/node/issues/22767
7
8const assert = require('assert');
9const { Session } = require('inspector');
10
11const session = new Session();
12
13function post(message, data) {
14  return new Promise((resolve, reject) => {
15    session.post(message, data, (err, result) => {
16      if (err)
17        reject(new Error(JSON.stringify(err)));
18      else
19        resolve(result);
20    });
21  });
22}
23
24function generateTrace() {
25  return new Promise((resolve) => setTimeout(() => {
26    for (let i = 0; i < 1000000; i++) {
27      'test' + i; // eslint-disable-line no-unused-expressions
28    }
29    resolve();
30  }, 1));
31}
32
33async function test() {
34  // This interval ensures Node does not terminate till the test is finished.
35  // Inspector session does not keep the node process running (e.g. it does not
36  // have async handles on the main event loop). It is debatable whether this
37  // should be considered a bug, and there are no plans to fix it atm.
38  const interval = setInterval(() => {}, 5000);
39  session.connect();
40  let traceNotification = null;
41  let tracingComplete = false;
42  session.on('NodeTracing.dataCollected', (n) => traceNotification = n);
43  session.on('NodeTracing.tracingComplete', () => tracingComplete = true);
44  const { categories } = await post('NodeTracing.getCategories');
45  const expectedCategories = [
46    'node',
47    'node.async_hooks',
48    'node.bootstrap',
49    'node.console',
50    'node.dns.native',
51    'node.environment',
52    'node.fs.async',
53    'node.fs.sync',
54    'node.fs_dir.async',
55    'node.fs_dir.sync',
56    'node.http',
57    'node.net.native',
58    'node.perf',
59    'node.perf.timerify',
60    'node.perf.usertiming',
61    'node.promises.rejections',
62    'node.threadpoolwork.async',
63    'node.threadpoolwork.sync',
64    'node.vm.script',
65    'v8',
66  ].sort();
67  assert.ok(categories.length === expectedCategories.length);
68  categories.forEach((category, index) => {
69    const value = expectedCategories[index];
70    assert.ok(category === value, `${category} is out of order, expect ${value}`);
71  });
72
73  const traceConfig = { includedCategories: ['v8'] };
74  await post('NodeTracing.start', { traceConfig });
75
76  for (let i = 0; i < 5; i++)
77    await generateTrace();
78  JSON.stringify(await post('NodeTracing.stop', { traceConfig }));
79  session.disconnect();
80  assert(traceNotification.params.value.length > 0);
81  assert(tracingComplete);
82  clearInterval(interval);
83  console.log('Success');
84}
85
86test().then(common.mustCall());
87