summaryrefslogtreecommitdiffstats
path: root/devtools/client/framework/test/metrics/head.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/framework/test/metrics/head.js')
-rw-r--r--devtools/client/framework/test/metrics/head.js171
1 files changed, 171 insertions, 0 deletions
diff --git a/devtools/client/framework/test/metrics/head.js b/devtools/client/framework/test/metrics/head.js
new file mode 100644
index 0000000000..0246190b31
--- /dev/null
+++ b/devtools/client/framework/test/metrics/head.js
@@ -0,0 +1,171 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// shared-head.js handles imports, constants, and utility functions
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
+ this
+);
+
+// So that PERFHERDER data can be extracted from the logs.
+SimpleTest.requestCompleteLog();
+
+function getFilteredModules(filters, loaders) {
+ let modules = [];
+ for (const l of loaders) {
+ const loaderModulesMap = l.modules;
+ const loaderModulesPaths = Object.keys(loaderModulesMap);
+ modules = modules.concat(loaderModulesPaths);
+ }
+ return modules.filter(url => filters.some(filter => url.includes(filter)));
+}
+
+function countCharsInModules(modules) {
+ return modules.reduce((sum, uri) => {
+ try {
+ return sum + require("raw!" + uri).length;
+ } catch (e) {
+ // Ignore failures
+ return sum;
+ }
+ }, 0);
+}
+
+/**
+ * Record module loading data.
+ *
+ * @param {Object}
+ * - filterString {String} path to use to filter modules specific to the current panel
+ * - loaders {Array} Array of Loaders to check for modules
+ * - panelName {String} reused in identifiers for perfherder data
+ */
+function runMetricsTest({ filterString, loaders, panelName }) {
+ const allModules = getFilteredModules([""], loaders);
+ const panelModules = getFilteredModules([filterString], loaders);
+ const vendoredModules = getFilteredModules(
+ ["devtools/client/debugger/dist/vendors", "devtools/client/shared/vendor/"],
+ loaders
+ );
+
+ const allModulesCount = allModules.length;
+ const panelModulesCount = panelModules.length;
+ const vendoredModulesCount = vendoredModules.length;
+
+ const allModulesChars = countCharsInModules(allModules);
+ const panelModulesChars = countCharsInModules(panelModules);
+ const vendoredModulesChars = countCharsInModules(vendoredModules);
+
+ const PERFHERDER_DATA = {
+ framework: {
+ name: "devtools",
+ },
+ suites: [
+ {
+ name: panelName + "-metrics",
+ value: allModulesChars,
+ subtests: [
+ {
+ name: panelName + "-modules",
+ value: panelModulesCount,
+ },
+ {
+ name: panelName + "-chars",
+ value: panelModulesChars,
+ },
+ {
+ name: "all-modules",
+ value: allModulesCount,
+ },
+ {
+ name: "all-chars",
+ value: allModulesChars,
+ },
+ {
+ name: "vendored-modules",
+ value: vendoredModulesCount,
+ },
+ {
+ name: "vendored-chars",
+ value: vendoredModulesChars,
+ },
+ ],
+ },
+ ],
+ };
+ info("PERFHERDER_DATA: " + JSON.stringify(PERFHERDER_DATA));
+
+ // Simply check that we found valid values.
+ ok(
+ allModulesCount > panelModulesCount && panelModulesCount > 0,
+ "Successfully recorded module count for " + panelName
+ );
+ ok(
+ allModulesChars > panelModulesChars && panelModulesChars > 0,
+ "Successfully recorded char count for " + panelName
+ );
+
+ // Easy way to check how many vendored chars we have for a given panel.
+ const percentage = ((100 * vendoredModulesChars) / allModulesChars).toFixed(
+ 1
+ );
+ info(`Percentage of vendored chars for ${panelName}: ${percentage}%`);
+}
+
+function getDuplicatedModules(loaders) {
+ const allModules = getFilteredModules([""], loaders);
+
+ const uniqueModules = new Set();
+ const duplicatedModules = new Set();
+ for (const mod of allModules) {
+ if (uniqueModules.has(mod)) {
+ duplicatedModules.add(mod);
+ }
+
+ uniqueModules.add(mod);
+ }
+
+ return duplicatedModules;
+}
+
+/**
+ * Check that modules are only loaded once in a given set of loaders.
+ * Panels might load the same module twice by mistake if they are both using
+ * a BrowserLoader and the regular DevTools Loader.
+ *
+ * @param {Array} loaders
+ * Array of Loader instances.
+ * @param {Array} allowedDupes
+ * Array of Strings which are paths to known duplicated modules.
+ * The test will also fail if a allowedDupesed module is not found in the
+ * duplicated modules.
+ */
+function runDuplicatedModulesTest(loaders, allowedDupes) {
+ const duplicatedModules = getDuplicatedModules(loaders);
+
+ // Remove allowedDupes entries, and fail if an allowed entry is not found.
+ for (const mod of allowedDupes) {
+ const deleted = duplicatedModules.delete(mod);
+ if (!deleted) {
+ ok(
+ false,
+ "module not found in the duplicated modules: [" +
+ mod +
+ "]. The allowedDupes array should be updated to remove it."
+ );
+ }
+ }
+
+ // Prepare a log string with the paths of all duplicated modules.
+ let duplicatedModulesLog = "";
+ for (const mod of duplicatedModules) {
+ duplicatedModulesLog += ` [duplicated module] ${mod}\n`;
+ }
+
+ // Check that duplicatedModules Set is empty.
+ is(
+ duplicatedModules.size,
+ 0,
+ "Duplicated module load detected. List of duplicated modules:\n" +
+ duplicatedModulesLog
+ );
+}