head.js (5068B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 // shared-head.js handles imports, constants, and utility functions 5 Services.scriptloader.loadSubScript( 6 "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js", 7 this 8 ); 9 10 // So that PERFHERDER data can be extracted from the logs. 11 SimpleTest.requestCompleteLog(); 12 13 function getFilteredModules(filters, loaders) { 14 let modules = []; 15 for (const l of loaders) { 16 const loaderModulesMap = l.modules; 17 const loaderModulesPaths = Object.keys(loaderModulesMap); 18 modules = modules.concat(loaderModulesPaths); 19 } 20 return modules.filter(url => filters.some(filter => url.includes(filter))); 21 } 22 23 function countCharsInModules(modules) { 24 return modules.reduce((sum, uri) => { 25 try { 26 return sum + require("raw!" + uri).length; 27 } catch (e) { 28 // Ignore failures 29 return sum; 30 } 31 }, 0); 32 } 33 34 /** 35 * Record module loading data. 36 * 37 * @param {object} 38 * - filterString {String} path to use to filter modules specific to the current panel 39 * - loaders {Array} Array of Loaders to check for modules 40 * - panelName {String} reused in identifiers for perfherder data 41 */ 42 function runMetricsTest({ filterString, loaders, panelName }) { 43 const allModules = getFilteredModules([""], loaders); 44 const panelModules = getFilteredModules([filterString], loaders); 45 const vendoredModules = getFilteredModules( 46 ["devtools/client/debugger/dist/vendors", "devtools/client/shared/vendor/"], 47 loaders 48 ); 49 50 const allModulesCount = allModules.length; 51 const panelModulesCount = panelModules.length; 52 const vendoredModulesCount = vendoredModules.length; 53 54 const allModulesChars = countCharsInModules(allModules); 55 const panelModulesChars = countCharsInModules(panelModules); 56 const vendoredModulesChars = countCharsInModules(vendoredModules); 57 58 const PERFHERDER_DATA = { 59 framework: { 60 name: "devtools", 61 }, 62 suites: [ 63 { 64 name: panelName + "-metrics", 65 value: allModulesChars, 66 subtests: [ 67 { 68 name: panelName + "-modules", 69 value: panelModulesCount, 70 }, 71 { 72 name: panelName + "-chars", 73 value: panelModulesChars, 74 }, 75 { 76 name: "all-modules", 77 value: allModulesCount, 78 }, 79 { 80 name: "all-chars", 81 value: allModulesChars, 82 }, 83 { 84 name: "vendored-modules", 85 value: vendoredModulesCount, 86 }, 87 { 88 name: "vendored-chars", 89 value: vendoredModulesChars, 90 }, 91 ], 92 }, 93 ], 94 }; 95 info("PERFHERDER_DATA: " + JSON.stringify(PERFHERDER_DATA)); 96 97 // Simply check that we found valid values. 98 ok( 99 allModulesCount > panelModulesCount && panelModulesCount > 0, 100 "Successfully recorded module count for " + panelName 101 ); 102 ok( 103 allModulesChars > panelModulesChars && panelModulesChars > 0, 104 "Successfully recorded char count for " + panelName 105 ); 106 107 // Easy way to check how many vendored chars we have for a given panel. 108 const percentage = ((100 * vendoredModulesChars) / allModulesChars).toFixed( 109 1 110 ); 111 info(`Percentage of vendored chars for ${panelName}: ${percentage}%`); 112 } 113 114 function getDuplicatedModules(loaders) { 115 const allModules = getFilteredModules([""], loaders); 116 117 const uniqueModules = new Set(); 118 const duplicatedModules = new Set(); 119 for (const mod of allModules) { 120 if (uniqueModules.has(mod)) { 121 duplicatedModules.add(mod); 122 } 123 124 uniqueModules.add(mod); 125 } 126 127 return duplicatedModules; 128 } 129 130 /** 131 * Check that modules are only loaded once in a given set of loaders. 132 * Panels might load the same module twice by mistake if they are both using 133 * a BrowserLoader and the regular DevTools Loader. 134 * 135 * @param {Array} loaders 136 * Array of Loader instances. 137 * @param {Array} allowedDupes 138 * Array of Strings which are paths to known duplicated modules. 139 * The test will also fail if a allowedDupesed module is not found in the 140 * duplicated modules. 141 */ 142 function runDuplicatedModulesTest(loaders, allowedDupes) { 143 const duplicatedModules = getDuplicatedModules(loaders); 144 145 // Remove allowedDupes entries, and fail if an allowed entry is not found. 146 for (const mod of allowedDupes) { 147 const deleted = duplicatedModules.delete(mod); 148 if (!deleted) { 149 ok( 150 false, 151 "module not found in the duplicated modules: [" + 152 mod + 153 "]. The allowedDupes array should be updated to remove it." 154 ); 155 } 156 } 157 158 // Prepare a log string with the paths of all duplicated modules. 159 let duplicatedModulesLog = ""; 160 for (const mod of duplicatedModules) { 161 duplicatedModulesLog += ` [duplicated module] ${mod}\n`; 162 } 163 164 // Check that duplicatedModules Set is empty. 165 is( 166 duplicatedModules.size, 167 0, 168 "Duplicated module load detected. List of duplicated modules:\n" + 169 duplicatedModulesLog 170 ); 171 }