fune/devtools/shared/test-helpers/browser_allocation_tracker.js
Alexandre Poirot c69fc70787 Bug 1730507 - [devtools] Track globals of panel's documents from the leak scripts. r=jdescottes
We were correctly tracking the top toolbox document, while ignoring any of its children document,
which are all having about:blank location when processed by the allocation tracker.

While I can't easily add coverage for this particular code,
I'm adding some more coverage around the leak scripts.

Differential Revision: https://phabricator.services.mozilla.com/D125413
2021-09-14 12:18:27 +00:00

152 lines
4.3 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Load the tracker in a dedicated loader using invisibleToDebugger and freshCompartment
// so that it can inspect any other module/compartment, even DevTools, chrome,
// and this script!
const { DevToolsLoader } = ChromeUtils.import(
"resource://devtools/shared/Loader.jsm"
);
const loader = new DevToolsLoader({
invisibleToDebugger: true,
freshCompartment: true,
});
const { allocationTracker } = loader.require(
"chrome://mochitests/content/browser/devtools/shared/test-helpers/allocation-tracker"
);
const TrackedObjects = loader.require(
"devtools/shared/test-helpers/tracked-objects.jsm"
);
add_task(async function() {
// Use a sandbox to allocate test javascript object in order to avoid any
// external noise
const global = Cu.Sandbox("http://example.com");
const tracker = allocationTracker({ watchGlobal: global });
const before = tracker.stillAllocatedObjects();
/* eslint-disable no-undef */
// This will allocation 1001 objects. The array and 1000 elements in it.
Cu.evalInSandbox(
"let list; new " +
function() {
list = [];
for (let i = 0; i < 1000; i++) {
list.push({});
}
},
global,
undefined,
"test-file.js",
1,
/* enforceFilenameRestrictions */ false
);
/* eslint-enable no-undef */
const allocations = tracker.countAllocations();
ok(
allocations >= 1001,
`At least 1001 objects are reported as created (${allocations})`
);
// Uncomment this and comment the call to `countAllocations` to debug the allocations.
// The call to `countAllocations` will reset the allocation record.
// tracker.logAllocationSites();
const afterCreation = tracker.stillAllocatedObjects();
is(
afterCreation.objectsWithStack - before.objectsWithStack,
1001,
"We got exactly the expected number of objects recorded with an allocation site"
);
ok(
afterCreation.objectsWithStack > before.objectsWithStack,
"We got some random number of objects without an allocation site"
);
Cu.evalInSandbox(
"list = null;",
global,
undefined,
"test-file.js",
7,
/* enforceFilenameRestrictions */ false
);
Cu.forceGC();
Cu.forceCC();
const afterGC = tracker.stillAllocatedObjects();
is(
afterCreation.objectsWithStack - afterGC.objectsWithStack,
1001,
"All the expected objects were reported freed in the count with allocation sites"
);
ok(
afterGC.objectsWithoutStack < afterCreation.objectsWithoutStack,
"And we released some random number of objects without an allocation site"
);
tracker.stop();
});
add_task(async function() {
const leaked = {};
TrackedObjects.track(leaked);
let transient = {};
TrackedObjects.track(transient);
is(TrackedObjects.getAllNodeIds().length, 2, "The two objects are reported");
info("Free the transient object");
transient = null;
Cu.forceGC();
is(
TrackedObjects.getAllNodeIds().length,
1,
"We now only have the leaked object"
);
TrackedObjects.clear();
});
add_task(async function() {
info("Test start and stop recording without any debug mode");
const tracker = allocationTracker({ watchDevToolsGlobals: true });
await tracker.startRecordingAllocations();
await tracker.stopRecordingAllocations();
tracker.stop();
});
add_task(async function() {
info("Test start and stop recording with 'allocations' debug mode");
const tracker = allocationTracker({ watchDevToolsGlobals: true });
await tracker.startRecordingAllocations("allocations");
await tracker.stopRecordingAllocations("allocations");
tracker.stop();
});
add_task(async function() {
info("Test start and stop recording with 'leaks' debug mode");
const tracker = allocationTracker({ watchDevToolsGlobals: true });
await tracker.startRecordingAllocations("leaks");
await tracker.stopRecordingAllocations("leaks");
tracker.stop();
});
add_task(async function() {
info("Test start and stop recording with tracked objects");
const leaked = {};
TrackedObjects.track(leaked);
const tracker = allocationTracker({ watchAllGlobals: true });
await tracker.startRecordingAllocations();
await tracker.stopRecordingAllocations();
tracker.stop();
TrackedObjects.clear();
});