• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3// Flags: --expose-gc
4
5const common = require('../common');
6common.skipIfInspectorDisabled();
7
8const assert = require('assert');
9const vm = require('vm');
10const { Session } = require('inspector');
11
12const session = new Session();
13session.connect();
14
15function notificationPromise(method) {
16  return new Promise((resolve) => session.once(method, resolve));
17}
18
19async function testContextCreatedAndDestroyed() {
20  console.log('Testing context created/destroyed notifications');
21  {
22    const mainContextPromise =
23        notificationPromise('Runtime.executionContextCreated');
24
25    session.post('Runtime.enable', assert.ifError);
26    const contextCreated = await mainContextPromise;
27    const { name, origin, auxData } = contextCreated.params.context;
28    if (common.isSunOS || common.isWindows || common.isIBMi) {
29      // uv_get_process_title() is unimplemented on Solaris-likes and IBMi,
30      // it returns an empty string.  On the Windows CI buildbots it returns
31      // "Administrator: Windows PowerShell[42]" because of a GetConsoleTitle()
32      // quirk. Not much we can do about either, just verify that it contains
33      // the PID.
34      assert.strictEqual(name.includes(`[${process.pid}]`), true);
35    } else {
36      let expects = `${process.argv0}[${process.pid}]`;
37      if (!common.isMainThread) {
38        expects = `Worker[${require('worker_threads').threadId}]`;
39      }
40      assert.strictEqual(expects, name);
41    }
42    assert.strictEqual(origin, '',
43                       JSON.stringify(contextCreated));
44    assert.strictEqual(auxData.isDefault, true,
45                       JSON.stringify(contextCreated));
46  }
47
48  {
49    const vmContextCreatedPromise =
50        notificationPromise('Runtime.executionContextCreated');
51
52    let contextDestroyed = null;
53    session.once('Runtime.executionContextDestroyed',
54                 (notification) => contextDestroyed = notification);
55
56    vm.runInNewContext('1 + 1');
57
58    const contextCreated = await vmContextCreatedPromise;
59    const { id, name, origin, auxData } = contextCreated.params.context;
60    assert.strictEqual(name, 'VM Context 1',
61                       JSON.stringify(contextCreated));
62    assert.strictEqual(origin, '',
63                       JSON.stringify(contextCreated));
64    assert.strictEqual(auxData.isDefault, false,
65                       JSON.stringify(contextCreated));
66
67    // GC is unpredictable...
68    console.log('Checking/waiting for GC.');
69    while (!contextDestroyed)
70      global.gc();
71    console.log('Context destroyed.');
72
73    assert.strictEqual(contextDestroyed.params.executionContextId, id,
74                       JSON.stringify(contextDestroyed));
75  }
76
77  {
78    const vmContextCreatedPromise =
79        notificationPromise('Runtime.executionContextCreated');
80
81    let contextDestroyed = null;
82    session.once('Runtime.executionContextDestroyed',
83                 (notification) => contextDestroyed = notification);
84
85    vm.runInNewContext('1 + 1', {}, {
86      contextName: 'Custom context',
87      contextOrigin: 'https://origin.example'
88    });
89
90    const contextCreated = await vmContextCreatedPromise;
91    const { name, origin, auxData } = contextCreated.params.context;
92    assert.strictEqual(name, 'Custom context',
93                       JSON.stringify(contextCreated));
94    assert.strictEqual(origin, 'https://origin.example',
95                       JSON.stringify(contextCreated));
96    assert.strictEqual(auxData.isDefault, false,
97                       JSON.stringify(contextCreated));
98
99    // GC is unpredictable...
100    console.log('Checking/waiting for GC again.');
101    while (!contextDestroyed)
102      global.gc();
103    console.log('Other context destroyed.');
104  }
105
106  {
107    const vmContextCreatedPromise =
108        notificationPromise('Runtime.executionContextCreated');
109
110    let contextDestroyed = null;
111    session.once('Runtime.executionContextDestroyed',
112                 (notification) => contextDestroyed = notification);
113
114    vm.createContext({}, { origin: 'https://nodejs.org' });
115
116    const contextCreated = await vmContextCreatedPromise;
117    const { name, origin, auxData } = contextCreated.params.context;
118    assert.strictEqual(name, 'VM Context 2',
119                       JSON.stringify(contextCreated));
120    assert.strictEqual(origin, 'https://nodejs.org',
121                       JSON.stringify(contextCreated));
122    assert.strictEqual(auxData.isDefault, false,
123                       JSON.stringify(contextCreated));
124
125    // GC is unpredictable...
126    console.log('Checking/waiting for GC a third time.');
127    while (!contextDestroyed)
128      global.gc();
129    console.log('Context destroyed once again.');
130  }
131
132  {
133    const vmContextCreatedPromise =
134        notificationPromise('Runtime.executionContextCreated');
135
136    let contextDestroyed = null;
137    session.once('Runtime.executionContextDestroyed',
138                 (notification) => contextDestroyed = notification);
139
140    vm.createContext({}, { name: 'Custom context 2' });
141
142    const contextCreated = await vmContextCreatedPromise;
143    const { name, auxData } = contextCreated.params.context;
144    assert.strictEqual(name, 'Custom context 2',
145                       JSON.stringify(contextCreated));
146    assert.strictEqual(auxData.isDefault, false,
147                       JSON.stringify(contextCreated));
148
149    // GC is unpredictable...
150    console.log('Checking/waiting for GC a fourth time.');
151    while (!contextDestroyed)
152      global.gc();
153    console.log('Context destroyed a fourth time.');
154  }
155}
156
157async function testBreakpointHit() {
158  console.log('Testing breakpoint is hit in a new context');
159  session.post('Debugger.enable', assert.ifError);
160
161  const pausedPromise = notificationPromise('Debugger.paused');
162  vm.runInNewContext('debugger', {});
163  await pausedPromise;
164}
165
166(async function() {
167  await testContextCreatedAndDestroyed();
168  await testBreakpointHit();
169})().then(common.mustCall());
170