/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { ProfilerTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/ProfilerTestUtils.sys.mjs"
);
async
function addTab() {
const tab = BrowserTestUtils.addTab(gBrowser,
"https://example.com/browser", {
forceNewProcess:
true,
});
const browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
return tab;
}
const sandboxSettingsEnabled = {
entries: 8 * 1024 * 1024,
// 8M entries = 64MB
interval: 1,
// ms
features: [
"stackwalk",
"sandbox"],
threads: [
"SandboxProfilerEmitter"],
};
const sandboxSettingsDisabled = {
entries: 8 * 1024 * 1024,
// 8M entries = 64MB
interval: 1,
// ms
features: [
"stackwalk"],
threads: [
"SandboxProfilerEmitter"],
};
const kNewProcesses = 2;
async
function waitForMaybeSandboxProfilerData(
threadName,
name1,
withStacks,
enabled
) {
let tabs = [];
for (let i = 0; i < kNewProcesses; ++i) {
tabs.push(await addTab());
}
let profile;
let intercepted = undefined;
try {
await TestUtils.waitForCondition(
async () => {
profile = await Services.profiler.getProfileDataAsync();
intercepted = profile.processes
.flatMap(ps => {
let sandboxThreads = ps.threads.filter(
th => th.name === threadName
);
return sandboxThreads.flatMap(th => {
let markersData = th.markers.data;
return markersData.flatMap(d => {
let [, , , , , o] = d;
return o;
});
});
})
.filter(x =>
"name1" in x && name1.includes(x.name1) >= 0);
return !!intercepted.length;
},
`Wait
for some samples from ${threadName}`,
/* interval*/ 100,
/* maxTries */ 25
);
Assert.greater(
intercepted.length,
0,
`Should have collected some data from ${threadName}`
);
}
catch (ex) {
if (!enabled && ex.includes(`Wait
for some samples from ${threadName}`)) {
Assert.equal(
intercepted.length,
0,
`Should have NOT collected data from ${threadName}`
);
}
else {
throw ex;
}
}
if (withStacks) {
let stacks = profile.processes.flatMap(ps => {
let sandboxThreads = ps.threads.filter(th => th.name === threadName);
return sandboxThreads.flatMap(th => {
let stackTableData = th.stackTable.data;
return stackTableData.flatMap(d => {
return [d];
});
});
});
if (enabled) {
Assert.greater(stacks.length, 0,
"Should have some stack as well");
}
else {
Assert.equal(stacks.length, 0,
"Should have NO stack as well");
}
}
for (let tab of tabs) {
await BrowserTestUtils.removeTab(tab);
}
}
add_task(async () => {
await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterSyscalls",
[
"id",
"init"],
/* withStacks */ true,
/* enabled */ true
);
await Services.profiler.StopProfiler();
});
add_task(async () => {
await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterLogs",
[
"log"],
/* withStacks */ false,
/* enabled */ true
);
await Services.profiler.StopProfiler();
});
add_task(async () => {
await ProfilerTestUtils.startProfiler(sandboxSettingsDisabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterSyscalls",
[
"id",
"init"],
/* withStacks */ true,
/* enabled */ false
);
await Services.profiler.StopProfiler();
});
add_task(async () => {
await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterLogs",
[
"log"],
/* withStacks */ false,
/* enabled */ false
);
await Services.profiler.StopProfiler();
});