browser_sandbox_profiler.js (4036B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { ProfilerTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/ProfilerTestUtils.sys.mjs" 8 ); 9 10 async function addTab() { 11 const tab = BrowserTestUtils.addTab(gBrowser, "https://example.com/browser", { 12 forceNewProcess: true, 13 }); 14 const browser = gBrowser.getBrowserForTab(tab); 15 await BrowserTestUtils.browserLoaded(browser); 16 return tab; 17 } 18 19 const sandboxSettingsEnabled = { 20 entries: 8 * 1024 * 1024, // 8M entries = 64MB 21 interval: 1, // ms 22 features: ["stackwalk", "sandbox"], 23 threads: ["SandboxProfilerEmitter"], 24 }; 25 26 const sandboxSettingsDisabled = { 27 entries: 8 * 1024 * 1024, // 8M entries = 64MB 28 interval: 1, // ms 29 features: ["stackwalk"], 30 threads: ["SandboxProfilerEmitter"], 31 }; 32 33 const kNewProcesses = 2; 34 35 async function waitForMaybeSandboxProfilerData( 36 threadName, 37 name1, 38 withStacks, 39 enabled 40 ) { 41 let tabs = []; 42 for (let i = 0; i < kNewProcesses; ++i) { 43 tabs.push(await addTab()); 44 } 45 46 let profile; 47 let intercepted = undefined; 48 try { 49 await TestUtils.waitForCondition( 50 async () => { 51 profile = await Services.profiler.getProfileDataAsync(); 52 intercepted = profile.processes 53 .flatMap(ps => { 54 let sandboxThreads = ps.threads.filter( 55 th => th.name === threadName 56 ); 57 return sandboxThreads.flatMap(th => { 58 let markersData = th.markers.data; 59 return markersData.flatMap(d => { 60 let [, , , , , o] = d; 61 return o; 62 }); 63 }); 64 }) 65 .filter(x => "name1" in x && name1.includes(x.name1) >= 0); 66 return !!intercepted.length; 67 }, 68 `Wait for some samples from ${threadName}`, 69 /* interval*/ 100, 70 /* maxTries */ 25 71 ); 72 Assert.greater( 73 intercepted.length, 74 0, 75 `Should have collected some data from ${threadName}` 76 ); 77 } catch (ex) { 78 if (!enabled && ex.includes(`Wait for some samples from ${threadName}`)) { 79 Assert.equal( 80 intercepted.length, 81 0, 82 `Should have NOT collected data from ${threadName}` 83 ); 84 } else { 85 throw ex; 86 } 87 } 88 89 if (withStacks) { 90 let stacks = profile.processes.flatMap(ps => { 91 let sandboxThreads = ps.threads.filter(th => th.name === threadName); 92 return sandboxThreads.flatMap(th => { 93 let stackTableData = th.stackTable.data; 94 return stackTableData.flatMap(d => { 95 return [d]; 96 }); 97 }); 98 }); 99 if (enabled) { 100 Assert.greater(stacks.length, 0, "Should have some stack as well"); 101 } else { 102 Assert.equal(stacks.length, 0, "Should have NO stack as well"); 103 } 104 } 105 106 for (let tab of tabs) { 107 await BrowserTestUtils.removeTab(tab); 108 } 109 } 110 111 add_task(async () => { 112 await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled); 113 await waitForMaybeSandboxProfilerData( 114 "SandboxProfilerEmitterSyscalls", 115 ["id", "init"], 116 /* withStacks */ true, 117 /* enabled */ true 118 ); 119 await Services.profiler.StopProfiler(); 120 }); 121 122 add_task(async () => { 123 await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled); 124 await waitForMaybeSandboxProfilerData( 125 "SandboxProfilerEmitterLogs", 126 ["log"], 127 /* withStacks */ false, 128 /* enabled */ true 129 ); 130 await Services.profiler.StopProfiler(); 131 }); 132 133 add_task(async () => { 134 await ProfilerTestUtils.startProfiler(sandboxSettingsDisabled); 135 await waitForMaybeSandboxProfilerData( 136 "SandboxProfilerEmitterSyscalls", 137 ["id", "init"], 138 /* withStacks */ true, 139 /* enabled */ false 140 ); 141 await Services.profiler.StopProfiler(); 142 }); 143 144 add_task(async () => { 145 await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled); 146 await waitForMaybeSandboxProfilerData( 147 "SandboxProfilerEmitterLogs", 148 ["log"], 149 /* withStacks */ false, 150 /* enabled */ false 151 ); 152 await Services.profiler.StopProfiler(); 153 });