Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: ccov OR os == 'linux' && (asan || tsan)
- Manifest: security/sandbox/test/browser_profiler.toml
/* Any copyright is dedicated to the Public Domain.
"use strict";
/* import-globals-from /tools/profiler/tests/shared-head.js */
Services.scriptloader.loadSubScript(
this
);
// Test verifies absence of data by relying on timeout
requestLongerTimeout(2);
async function addTab() {
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*/ 250,
/* maxTries */ 75
);
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 startProfiler(sandboxSettingsEnabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterSyscalls",
["id", "init"],
/* withStacks */ true,
/* enabled */ true
);
await Services.profiler.StopProfiler();
});
add_task(async () => {
await startProfiler(sandboxSettingsEnabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterLogs",
["log"],
/* withStacks */ false,
/* enabled */ true
);
await Services.profiler.StopProfiler();
});
add_task(async () => {
await startProfiler(sandboxSettingsDisabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterSyscalls",
["id", "init"],
/* withStacks */ true,
/* enabled */ false
);
await Services.profiler.StopProfiler();
});
add_task(async () => {
await startProfiler(sandboxSettingsEnabled);
await waitForMaybeSandboxProfilerData(
"SandboxProfilerEmitterLogs",
["log"],
/* withStacks */ false,
/* enabled */ false
);
await Services.profiler.StopProfiler();
});