head.js (3843B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 /* exported timeThis */ 8 9 // Load the shared-head file first. 10 Services.scriptloader.loadSubScript( 11 "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js", 12 this 13 ); 14 15 // Load common.js and promisified-events.js from accessible/tests/mochitest/ for 16 // all tests. 17 loadScripts( 18 { name: "common.js", dir: MOCHITESTS_DIR }, 19 { name: "promisified-events.js", dir: MOCHITESTS_DIR } 20 ); 21 22 // All the A11Y metrics in tools/performance/PerfStats.h. 23 const ALL_A11Y_PERFSTATS_FEATURES = [ 24 "A11Y_DoInitialUpdate", 25 "A11Y_ProcessQueuedCacheUpdate", 26 "A11Y_ContentRemovedNode", 27 "A11Y_ContentRemovedAcc", 28 "A11Y_PruneOrInsertSubtree", 29 "A11Y_ShutdownChildrenInSubtree", 30 "A11Y_ShowEvent", 31 "A11Y_RecvCache", 32 "A11Y_ProcessShowEvent", 33 "A11Y_CoalesceEvents", 34 "A11Y_CoalesceMutationEvents", 35 "A11Y_ProcessHideEvent", 36 "A11Y_SendCache", 37 "A11Y_WillRefresh", 38 "A11Y_AccessibilityServiceInit", 39 "A11Y_PlatformShowHideEvent", 40 ]; 41 42 const LOG_PREFIX = "perfMetrics"; 43 44 function logToPerfMetrics(stat) { 45 info(`${LOG_PREFIX} | ${JSON.stringify(stat)}`); 46 } 47 48 /** 49 * Time a function and log how long it took. The given name is included in log 50 * messages. All accessibility PerfStats metrics are also captured and logged. 51 * This function may only be called once per task, and we are limited to one 52 * task per file. 53 */ 54 async function timeThis(func) { 55 const start = performance.now(); 56 ChromeUtils.setPerfStatsFeatures(ALL_A11Y_PERFSTATS_FEATURES); 57 const journal = {}; 58 59 // Run the specified testing task 60 await func(); 61 62 // Log our total elapsed time 63 journal.A11Y_TotalTime = performance.now() - start; 64 65 const stats = JSON.parse(await ChromeUtils.collectPerfStats()); 66 ChromeUtils.setPerfStatsFeatures([]); 67 // Filter stuff out of stats that we don't care about. 68 // Filter out the GPU process, since accessibility doesn't do anything there. 69 stats.processes = stats.processes.filter(process => process.type != "gpu"); 70 for (const process of stats.processes) { 71 // Because of weird JS -> WebIDL 64 bit number issues, we get metrics here 72 // that aren't for accessibility. For example, 1 << 32 also gets us 1 << 0. 73 // Filter those out. Also, filter out any metrics with a count of 0. 74 process.perfstats.metrics = process.perfstats.metrics.filter( 75 metric => metric.metric.startsWith("A11Y_") && metric.count > 0 76 ); 77 } 78 // Now that we've filtered metrics, remove any processes that have no metrics left. 79 stats.processes = stats.processes.filter( 80 process => !!process.perfstats.metrics.length 81 ); 82 // Also, filter out readings for the blank new tab that gets opened before the 83 // tab with our test content opens. 84 // We may get a reading that isn't attached to any URL; this contains 85 // the startup time for the Accessibility Service which we should keep. 86 // Our parent process readings have no URL field. 87 stats.processes = stats.processes.filter( 88 process => 89 process.type == "parent" || 90 !process.urls.length || 91 !process.urls.includes("about:newtab") 92 ); 93 94 // Because our perfstats measure both occurances and timing, log values separately 95 // under different probe names with different units. 96 // Also, as the same probes can be triggered in content and parent, append a process 97 // indicator to the end of each probe name. 98 for (const process of stats.processes) { 99 for (const stat of process.perfstats.metrics) { 100 journal[stat.metric + "_" + process.type] = stat.time; 101 if (stat.count) { 102 journal[stat.metric + "_Count_" + process.type] = stat.count; 103 } 104 } 105 } 106 107 logToPerfMetrics(journal); 108 }