Bug 1471066 - Convert browser_startup_content.js to a whitelist. r=florian
authorFelipe Gomes <felipc@gmail.com>
Wed, 27 Jun 2018 13:55:38 -0300
changeset 423966 2cc73c7d2c75fa46261ab18d8992181eb60d8fa1
parent 423965 cd9f6f1e04d21173b5e94b5fbc7f7c39309e2e5f
child 423967 d37a23757d2750251dea1920c8e78c2df3e8e872
push id34197
push usercsabou@mozilla.com
push dateThu, 28 Jun 2018 09:44:02 +0000
treeherdermozilla-central@db455160668d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1471066
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1471066 - Convert browser_startup_content.js to a whitelist. r=florian This should prevent new files from being added in the startup path for content processes MozReview-Commit-ID: 6hCLurrVQ67
browser/base/content/test/performance/browser_startup_content.js
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -12,35 +12,90 @@
  * handling user events.
  */
 
 "use strict";
 
 /* Set this to true only for debugging purpose; it makes the output noisy. */
 const kDumpAllStacks = false;
 
-const blacklist = {
+const whitelist = {
   components: new Set([
-    "PushComponents.js",
-    "TelemetryStartup.js",
+    "ContentProcessSingleton.js",
+    "EnterprisePoliciesContent.js", // bug 1470324
+    "extension-process-script.js",
   ]),
   modules: new Set([
-    "resource:///modules/ContentWebRTC.jsm",
-    "resource://gre/modules/InlineSpellChecker.jsm",
-    "resource://gre/modules/InlineSpellCheckerContent.jsm",
-    "resource://gre/modules/LoginHelper.jsm",
-    "resource://gre/modules/LoginManagerContent.jsm",
-    "resource://gre/modules/Promise.jsm",
-    "resource://gre/modules/Task.jsm",
-    "resource://gre/modules/osfile.jsm",
-    "resource://pdf.js/PdfJs.jsm",
-    "resource://pdf.js/PdfStreamConverter.jsm",
+    // From the test harness
+    "chrome://mochikit/content/ShutdownLeaksCollector.jsm",
+    "chrome://specialpowers/content/MockColorPicker.jsm",
+    "chrome://specialpowers/content/MockFilePicker.jsm",
+    "chrome://specialpowers/content/MockPermissionPrompt.jsm",
+
+    // General utilities
+    "resource://gre/modules/AppConstants.jsm",
+    "resource://gre/modules/AsyncShutdown.jsm",
+    "resource://gre/modules/DeferredTask.jsm",
+    "resource://gre/modules/FileUtils.jsm",
+    "resource://gre/modules/NetUtil.jsm",
+    "resource://gre/modules/PromiseUtils.jsm",
+    "resource://gre/modules/Services.jsm", // bug 1464542
+    "resource://gre/modules/Timer.jsm",
+    "resource://gre/modules/XPCOMUtils.jsm",
+
+    // Logging related
+    "resource://gre/modules/Console.jsm", // bug 1470333
+    "resource://gre/modules/Log.jsm",
+
+    // Session store
+    "resource:///modules/sessionstore/ContentRestore.jsm",
+    "resource://gre/modules/sessionstore/SessionHistory.jsm",
+
+    // Forms and passwords
+    "resource://formautofill/FormAutofillContent.jsm",
+    "resource://formautofill/FormAutofillUtils.jsm",
+
+    // Browser front-end
+    "resource:///modules/ContentLinkHandler.jsm",
+    "resource:///modules/ContentMetaHandler.jsm",
+    "resource:///modules/PageStyleHandler.jsm",
+    "resource://gre/modules/BrowserUtils.jsm",
+    "resource://gre/modules/E10SUtils.jsm",
+    "resource://gre/modules/PrivateBrowsingUtils.jsm",
+    "resource://gre/modules/ReaderMode.jsm",
+    "resource://gre/modules/RemotePageManager.jsm",
+
+    // Pocket
+    "chrome://pocket/content/AboutPocket.jsm",
+
+    // Telemetry
+    "resource://gre/modules/TelemetryController.jsm", // bug 1470339
+    "resource://gre/modules/TelemetrySession.jsm", // bug 1470339
+    "resource://gre/modules/TelemetryUtils.jsm", // bug 1470339
+
+    // PDF.js
+    "resource://pdf.js/PdfJsRegistration.jsm",
+    "resource://pdf.js/PdfjsContentUtils.jsm",
+
+    // Extensions
+    "resource://gre/modules/ExtensionUtils.jsm",
+    "resource://gre/modules/MessageChannel.jsm",
+
+    // Service workers
+    "resource://gre/modules/ServiceWorkerCleanUp.jsm",
+
+    // Shield
+    "resource://normandy-content/AboutPages.jsm",
   ]),
+};
+
+const blacklist = {
   services: new Set([
     "@mozilla.org/base/telemetry-startup;1",
+    "@mozilla.org/embedcomp/default-tooltiptextprovider;1",
     "@mozilla.org/push/Service;1",
   ])
 };
 
 add_task(async function() {
   SimpleTest.requestCompleteLog();
 
   let tab = await BrowserTestUtils.openNewForegroundTab({gBrowser,
@@ -64,35 +119,70 @@ add_task(async function() {
       components[component.replace(/.*\//, "")] =
         collectStacks ? loader.getComponentLoadStack(component) : "";
     }
     let modules = {};
     for (let module of loader.loadedModules()) {
       modules[module] = collectStacks ? loader.getModuleImportStack(module) : "";
     }
     let services = {};
-    for (let contractID in Object.keys(Cc)) {
+    for (let contractID of Object.keys(Cc)) {
       try {
-        if (Cm.isServiceInstantiatedByContractID(contractID, Ci.nsISupports))
+        if (Cm.isServiceInstantiatedByContractID(contractID, Ci.nsISupports)) {
           services[contractID] = "";
+        }
       } catch (e) {}
     }
     sendAsyncMessage("Test:LoadedScripts", {components, modules, services});
   } + ")()", false);
 
-  let loadedList = await promise;
+  let loadedInfo = await promise;
+  let loadedList = {};
+
+  for (let scriptType in whitelist) {
+    loadedList[scriptType] = Object.keys(loadedInfo[scriptType]).filter(c => {
+      if (!whitelist[scriptType].has(c))
+        return true;
+      whitelist[scriptType].delete(c);
+      return false;
+    });
+
+    is(loadedList[scriptType].length, 0,
+       `should have no unexpected ${scriptType} loaded on content process startup`);
+
+    for (let script of loadedList[scriptType]) {
+      ok(false, `Unexpected ${scriptType} loaded during content process startup: ${script}`);
+      info(`Stack that loaded ${script}:\n`);
+      info(loadedInfo[scriptType][script]);
+    }
+
+    is(whitelist[scriptType].size, 0,
+       `all ${scriptType} whitelist entries should have been used`);
+
+    for (let script of whitelist[scriptType]) {
+      ok(false, `${scriptType} is whitelisted for content process startup but wasn't used: ${script}`);
+    }
+
+    if (kDumpAllStacks) {
+      info(`Stacks for all loaded ${scriptType}:`);
+      for (let file in loadedInfo[scriptType]) {
+        if (loadedInfo[scriptType][file]) {
+          info(`${file}\n------------------------------------\n` + loadedInfo[scriptType][file] + "\n");
+        }
+      }
+    }
+  }
+
   for (let scriptType in blacklist) {
-    info(scriptType);
-    for (let file of blacklist[scriptType]) {
-      let loaded = file in loadedList[scriptType];
-      ok(!loaded, `${file} is not allowed`);
-      if (loaded && loadedList[scriptType][file])
-        info(loadedList[scriptType][file]);
-    }
-    for (let file in loadedList[scriptType]) {
-      info(file);
-      if (kDumpAllStacks && loadedList[scriptType][file])
-        info(loadedList[scriptType][file]);
+    for (let script of blacklist[scriptType]) {
+      let loaded = script in loadedInfo[scriptType];
+      if (loaded) {
+        ok(false, `Unexpected ${scriptType} loaded during content process startup: ${script}`);
+        if (loadedInfo[scriptType][script]) {
+          info(`Stack that loaded ${script}:\n`);
+          info(loadedInfo[scriptType][script]);
+        }
+      }
     }
   }
 
   BrowserTestUtils.removeTab(tab);
 });