2017-04-24 17:06:17 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
// Flags: --expose-gc
|
|
|
|
|
|
|
|
const common = require('../common');
|
|
|
|
common.skipIfInspectorDisabled();
|
|
|
|
|
2019-11-26 06:54:47 +00:00
|
|
|
const assert = require('assert');
|
|
|
|
const vm = require('vm');
|
2017-04-24 17:06:17 +00:00
|
|
|
const { Session } = require('inspector');
|
|
|
|
|
|
|
|
const session = new Session();
|
|
|
|
session.connect();
|
|
|
|
|
|
|
|
function notificationPromise(method) {
|
|
|
|
return new Promise((resolve) => session.once(method, resolve));
|
|
|
|
}
|
|
|
|
|
|
|
|
async function testContextCreatedAndDestroyed() {
|
|
|
|
console.log('Testing context created/destroyed notifications');
|
2017-11-20 22:37:50 +00:00
|
|
|
{
|
2017-12-17 21:38:15 +00:00
|
|
|
const mainContextPromise =
|
|
|
|
notificationPromise('Runtime.executionContextCreated');
|
|
|
|
|
2019-11-26 06:22:54 +00:00
|
|
|
session.post('Runtime.enable', assert.ifError);
|
2017-12-17 21:38:15 +00:00
|
|
|
const contextCreated = await mainContextPromise;
|
|
|
|
const { name, origin, auxData } = contextCreated.params.context;
|
2019-12-06 07:08:57 +00:00
|
|
|
if (common.isSunOS || common.isWindows || common.isIBMi) {
|
|
|
|
// uv_get_process_title() is unimplemented on Solaris-likes and IBMi,
|
|
|
|
// it returns an empty string. On the Windows CI buildbots it returns
|
2018-01-06 18:34:27 +00:00
|
|
|
// "Administrator: Windows PowerShell[42]" because of a GetConsoleTitle()
|
|
|
|
// quirk. Not much we can do about either, just verify that it contains
|
|
|
|
// the PID.
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(name.includes(`[${process.pid}]`), true);
|
2017-11-20 22:37:50 +00:00
|
|
|
} else {
|
2018-09-09 02:45:10 +00:00
|
|
|
let expects = `${process.argv0}[${process.pid}]`;
|
|
|
|
if (!common.isMainThread) {
|
|
|
|
expects = `Worker[${require('worker_threads').threadId}]`;
|
|
|
|
}
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(expects, name);
|
2017-11-20 22:37:50 +00:00
|
|
|
}
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(origin, '',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(auxData.isDefault, true,
|
|
|
|
JSON.stringify(contextCreated));
|
2017-12-17 21:38:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const vmContextCreatedPromise =
|
|
|
|
notificationPromise('Runtime.executionContextCreated');
|
|
|
|
|
|
|
|
let contextDestroyed = null;
|
|
|
|
session.once('Runtime.executionContextDestroyed',
|
|
|
|
(notification) => contextDestroyed = notification);
|
|
|
|
|
2019-11-26 06:54:47 +00:00
|
|
|
vm.runInNewContext('1 + 1');
|
2017-12-17 21:38:15 +00:00
|
|
|
|
|
|
|
const contextCreated = await vmContextCreatedPromise;
|
|
|
|
const { id, name, origin, auxData } = contextCreated.params.context;
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(name, 'VM Context 1',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(origin, '',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(auxData.isDefault, false,
|
|
|
|
JSON.stringify(contextCreated));
|
2017-12-17 21:38:15 +00:00
|
|
|
|
|
|
|
// GC is unpredictable...
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Checking/waiting for GC.');
|
2017-12-17 21:38:15 +00:00
|
|
|
while (!contextDestroyed)
|
|
|
|
global.gc();
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Context destroyed.');
|
2017-12-17 21:38:15 +00:00
|
|
|
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(contextDestroyed.params.executionContextId, id,
|
|
|
|
JSON.stringify(contextDestroyed));
|
2017-12-17 21:38:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const vmContextCreatedPromise =
|
|
|
|
notificationPromise('Runtime.executionContextCreated');
|
|
|
|
|
|
|
|
let contextDestroyed = null;
|
|
|
|
session.once('Runtime.executionContextDestroyed',
|
|
|
|
(notification) => contextDestroyed = notification);
|
|
|
|
|
2019-11-26 06:54:47 +00:00
|
|
|
vm.runInNewContext('1 + 1', {}, {
|
2017-12-17 21:38:15 +00:00
|
|
|
contextName: 'Custom context',
|
|
|
|
contextOrigin: 'https://origin.example'
|
|
|
|
});
|
|
|
|
|
|
|
|
const contextCreated = await vmContextCreatedPromise;
|
|
|
|
const { name, origin, auxData } = contextCreated.params.context;
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(name, 'Custom context',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(origin, 'https://origin.example',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(auxData.isDefault, false,
|
|
|
|
JSON.stringify(contextCreated));
|
2017-12-17 21:38:15 +00:00
|
|
|
|
|
|
|
// GC is unpredictable...
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Checking/waiting for GC again.');
|
2017-12-17 21:38:15 +00:00
|
|
|
while (!contextDestroyed)
|
|
|
|
global.gc();
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Other context destroyed.');
|
2017-11-20 22:37:50 +00:00
|
|
|
}
|
2017-04-24 17:06:17 +00:00
|
|
|
|
2017-12-17 21:38:15 +00:00
|
|
|
{
|
|
|
|
const vmContextCreatedPromise =
|
|
|
|
notificationPromise('Runtime.executionContextCreated');
|
|
|
|
|
|
|
|
let contextDestroyed = null;
|
|
|
|
session.once('Runtime.executionContextDestroyed',
|
|
|
|
(notification) => contextDestroyed = notification);
|
|
|
|
|
2019-11-26 06:54:47 +00:00
|
|
|
vm.createContext({}, { origin: 'https://nodejs.org' });
|
2017-12-17 21:38:15 +00:00
|
|
|
|
|
|
|
const contextCreated = await vmContextCreatedPromise;
|
|
|
|
const { name, origin, auxData } = contextCreated.params.context;
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(name, 'VM Context 2',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(origin, 'https://nodejs.org',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(auxData.isDefault, false,
|
|
|
|
JSON.stringify(contextCreated));
|
2017-12-17 21:38:15 +00:00
|
|
|
|
|
|
|
// GC is unpredictable...
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Checking/waiting for GC a third time.');
|
2017-12-17 21:38:15 +00:00
|
|
|
while (!contextDestroyed)
|
|
|
|
global.gc();
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Context destroyed once again.');
|
2017-12-17 21:38:15 +00:00
|
|
|
}
|
2017-04-24 17:06:17 +00:00
|
|
|
|
2017-12-17 21:38:15 +00:00
|
|
|
{
|
|
|
|
const vmContextCreatedPromise =
|
|
|
|
notificationPromise('Runtime.executionContextCreated');
|
2017-04-24 17:06:17 +00:00
|
|
|
|
2017-12-17 21:38:15 +00:00
|
|
|
let contextDestroyed = null;
|
|
|
|
session.once('Runtime.executionContextDestroyed',
|
|
|
|
(notification) => contextDestroyed = notification);
|
2017-04-24 17:06:17 +00:00
|
|
|
|
2019-11-26 06:54:47 +00:00
|
|
|
vm.createContext({}, { name: 'Custom context 2' });
|
2017-04-24 17:06:17 +00:00
|
|
|
|
2017-12-17 21:38:15 +00:00
|
|
|
const contextCreated = await vmContextCreatedPromise;
|
|
|
|
const { name, auxData } = contextCreated.params.context;
|
2019-11-26 06:54:47 +00:00
|
|
|
assert.strictEqual(name, 'Custom context 2',
|
|
|
|
JSON.stringify(contextCreated));
|
|
|
|
assert.strictEqual(auxData.isDefault, false,
|
|
|
|
JSON.stringify(contextCreated));
|
2017-04-24 17:06:17 +00:00
|
|
|
|
2017-12-17 21:38:15 +00:00
|
|
|
// GC is unpredictable...
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Checking/waiting for GC a fourth time.');
|
2017-12-17 21:38:15 +00:00
|
|
|
while (!contextDestroyed)
|
|
|
|
global.gc();
|
2019-11-26 07:02:24 +00:00
|
|
|
console.log('Context destroyed a fourth time.');
|
2017-12-17 21:38:15 +00:00
|
|
|
}
|
2017-04-24 17:06:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function testBreakpointHit() {
|
|
|
|
console.log('Testing breakpoint is hit in a new context');
|
2019-11-26 06:22:54 +00:00
|
|
|
session.post('Debugger.enable', assert.ifError);
|
2017-04-24 17:06:17 +00:00
|
|
|
|
|
|
|
const pausedPromise = notificationPromise('Debugger.paused');
|
2019-11-26 06:54:47 +00:00
|
|
|
vm.runInNewContext('debugger', {});
|
2017-04-24 17:06:17 +00:00
|
|
|
await pausedPromise;
|
|
|
|
}
|
|
|
|
|
2020-04-05 20:27:46 +00:00
|
|
|
(async function() {
|
|
|
|
await testContextCreatedAndDestroyed();
|
|
|
|
await testBreakpointHit();
|
|
|
|
})().then(common.mustCall());
|