Bug 1373453 Part 1 Move repeated webextension startup check to AddonTestUtils r=kmag
authorAndrew Swan <aswan@mozilla.com>
Thu, 15 Jun 2017 16:33:28 -0700
changeset 364617 91c2ce06c69b1b548762efeca93ea505a5c45d6f
parent 364616 2664a53d4c18bc4874d68bc41b13ffc8993bb27f
child 364618 26d62a1ac0e3a33ebbf9b052d40816e1fec72920
push id32049
push usercbook@mozilla.com
push dateMon, 19 Jun 2017 11:36:23 +0000
treeherdermozilla-central@26d62a1ac0e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1373453
milestone56.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 1373453 Part 1 Move repeated webextension startup check to AddonTestUtils r=kmag MozReview-Commit-ID: 5uhi7VSbZNi
toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/test_reload.js
toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
toolkit/mozapps/extensions/test/xpcshell/test_webextension_embedded.js
toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
--- a/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
@@ -1,28 +1,15 @@
 "use strict";
 
 /* globals browser */
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 
-function promiseAddonStartup() {
-  const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
-
-  return new Promise(resolve => {
-    let listener = (evt, extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 add_task(async function setup() {
   await ExtensionTestUtils.startAddonManager();
 });
 
 add_task(async function test_experiments_api() {
   let apiAddonFile = Extension.generateZipFile({
     "install.rdf": `<?xml version="1.0" encoding="UTF-8"?>
       <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
@@ -143,26 +130,25 @@ add_task(async function test_experiments
   let apiAddon = await AddonManager.installTemporaryAddon(apiAddonFile);
 
   let {ExtensionAPIs} = Cu.import("resource://gre/modules/ExtensionAPI.jsm", {});
   ok(ExtensionAPIs.apis.has("meh"), "Should have meh API.");
 
 
   // Install boring WebExtension add-on.
   let boringAddon = await AddonManager.installTemporaryAddon(boringAddonFile);
-  await promiseAddonStartup();
-
+  await AddonTestUtils.promiseWebExtensionStartup();
 
   // Install interesting WebExtension add-on.
   let promise = new Promise(resolve => {
     resolveHello = resolve;
   });
 
   let addon = await AddonManager.installTemporaryAddon(addonFile);
-  await promiseAddonStartup();
+  await AddonTestUtils.promiseWebExtensionStartup();
 
   let hello = await promise;
   equal(hello, "Here I am", "Should get hello from add-on");
 
   // Cleanup.
   apiAddon.uninstall();
 
   boringAddon.userDisabled = true;
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -23,16 +23,20 @@ Cu.import("resource://gre/modules/NetUti
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const {EventEmitter} = Cu.import("resource://gre/modules/EventEmitter.jsm", {});
 const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
 
 XPCOMUtils.defineLazyModuleGetter(this, "Extension",
                                   "resource://gre/modules/Extension.jsm");
+XPCOMUtils.defineLazyGetter(this, "Management", () => {
+  let {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
+  return Management;
+});
 
 XPCOMUtils.defineLazyServiceGetter(this, "aomStartup",
                                    "@mozilla.org/addons/addon-manager-startup;1",
                                    "amIAddonManagerStartup");
 XPCOMUtils.defineLazyServiceGetter(this, "rdfService",
                                    "@mozilla.org/rdf/rdf-service;1", "nsIRDFService");
 XPCOMUtils.defineLazyServiceGetter(this, "uuidGen",
                                    "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
@@ -1241,16 +1245,36 @@ var AddonTestUtils = {
       Services.console.logStringMessage(DONE);
       await awaitListener;
 
       return {messages, result};
     } finally {
       Services.console.unregisterListener(listener);
     }
   },
+
+  /**
+   * Helper to wait for a webextension to completely start
+   *
+   * @param {string} [id]
+   *        An optional extension id to look for.
+   *
+   * @returns {Promise<Extension>}
+   *           A promise that resolves with the extension, once it is started.
+   */
+  promiseWebExtensionStartup(id) {
+    return new Promise(resolve => {
+      Management.on("ready", function listener(event, extension) {
+        if (!id || extension.id == id) {
+          Management.off("ready", listener);
+          resolve(extension);
+        }
+      });
+    });
+  },
 };
 
 for (let [key, val] of Object.entries(AddonTestUtils)) {
   if (typeof val == "function")
     AddonTestUtils[key] = val.bind(AddonTestUtils);
 }
 
 EventEmitter.decorate(AddonTestUtils);
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -81,16 +81,17 @@ const {
   promiseConsoleOutput,
   promiseFindAddonUpdates,
   promiseInstallAllFiles,
   promiseInstallFile,
   promiseRestartManager,
   promiseSetExtensionModifiedTime,
   promiseShutdownManager,
   promiseStartupManager,
+  promiseWebExtensionStartup,
   promiseWriteProxyFileToDir,
   registerDirectory,
   setExtensionModifiedTime,
   writeFilesToZip
 } = AddonTestUtils;
 
 function manuallyInstall(...args) {
   return AddonTestUtils.awaitPromise(
@@ -1061,29 +1062,16 @@ function completeAllInstalls(aInstalls, 
 function installAllFiles(aFiles, aCallback, aIgnoreIncompatible) {
   promiseInstallAllFiles(aFiles, aIgnoreIncompatible).then(aCallback);
 }
 
 const EXTENSIONS_DB = "extensions.json";
 var gExtensionsJSON = gProfD.clone();
 gExtensionsJSON.append(EXTENSIONS_DB);
 
-function promiseWebExtensionStartup() {
-  const {Management} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-  return new Promise(resolve => {
-    let listener = (evt, extension) => {
-      Management.off("ready", listener);
-      resolve(extension);
-    };
-
-    Management.on("ready", listener);
-  });
-}
-
 function promiseInstallWebExtension(aData) {
   let addonFile = createTempWebExtensionFile(aData);
 
   return promiseInstallAllFiles([addonFile]).then(installs => {
     Services.obs.notifyObservers(addonFile, "flush-cache-entry");
     // Since themes are disabled by default, it won't start up.
     if (aData.manifest.theme)
       return installs[0].addon;
--- a/toolkit/mozapps/extensions/test/xpcshell/test_reload.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_reload.js
@@ -16,29 +16,16 @@ const manifestSample = {
   bootstrap: true,
   targetApplications: [{
     id: "xpcshell@tests.mozilla.org",
     minVersion: "1",
     maxVersion: "1"
   }],
 };
 
-const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseAddonStartup() {
-  return new Promise(resolve => {
-    let listener = (extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 async function installAddon(fixtureName, addonID) {
   await promiseInstallAllFiles([do_get_addon(fixtureName)]);
   return promiseAddonByID(addonID);
 }
 
 async function tearDownAddon(addon) {
   addon.uninstall();
   await promiseShutdownManager();
@@ -80,17 +67,17 @@ add_task(async function test_reloading_a
         resolve();
       },
     }
     AddonManager.addAddonListener(listener);
   });
 
   await Promise.all([
     addon.reload(),
-    promiseAddonStartup(),
+    promiseWebExtensionStartup(),
   ]);
   await onReload;
 
   // Make sure reload() doesn't trigger uninstall events.
   equal(receivedOnUninstalled, false, "reload should not trigger onUninstalled");
   equal(receivedOnUninstalling, false, "reload should not trigger onUninstalling");
 
   // Make sure reload() triggers install events, like an upgrade.
@@ -114,17 +101,17 @@ add_task(async function test_can_reload_
     onEnabled: (aAddon) => {
       do_check_true(disabledCalled);
       enabledCalled = true
     }
   })
 
   await Promise.all([
     addon.reload(),
-    promiseAddonStartup(),
+    promiseWebExtensionStartup(),
   ]);
 
   do_check_true(disabledCalled);
   do_check_true(enabledCalled);
 
   notEqual(addon, null);
   equal(addon.appDisabled, false);
   equal(addon.userDisabled, false);
@@ -147,17 +134,17 @@ add_task(async function test_reload_to_i
       gecko: {
         id: addonId,
       }
     },
   };
 
   let addonDir = await promiseWriteWebManifestForExtension(manifest, tempdir, "invalid_version");
   await AddonManager.installTemporaryAddon(addonDir);
-  await promiseAddonStartup();
+  await promiseWebExtensionStartup();
 
   let addon = await promiseAddonByID(addonId);
   notEqual(addon, null);
   equal(addon.id, addonId);
   equal(addon.version, "1.0");
   equal(addon.appDisabled, false);
   equal(addon.userDisabled, false);
   addonDir.remove(true);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
@@ -13,29 +13,16 @@ const sampleRDFManifest = {
     maxVersion: "1"
   }],
   name: "Test Bootstrap 1 (temporary)",
 };
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
 startupManager();
 
-const {Management} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseAddonStartup() {
-  return new Promise(resolve => {
-    let listener = (extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 BootstrapMonitor.init();
 
 // Partial list of bootstrap reasons from XPIProvider.jsm
 const BOOTSTRAP_REASONS = {
   ADDON_INSTALL: 5,
   ADDON_UPGRADE: 7,
   ADDON_DOWNGRADE: 8,
 };
@@ -260,17 +247,17 @@ add_task(async function() {
             id: ID
           }
         }
       }
     });
 
     await Promise.all([
       AddonManager.installTemporaryAddon(webext),
-      promiseAddonStartup(),
+      promiseWebExtensionStartup(),
     ]);
     addon = await promiseAddonByID(ID);
 
     // temporary add-on is installed and started
     do_check_neq(addon, null);
     do_check_eq(addon.version, "4.0");
     do_check_eq(addon.name, "Test WebExtension 1 (temporary)");
     do_check_true(addon.isCompatible);
@@ -290,17 +277,17 @@ add_task(async function() {
             id: ID
           }
         }
       }
     });
 
     await Promise.all([
       AddonManager.installTemporaryAddon(webext),
-      promiseAddonStartup(),
+      promiseWebExtensionStartup(),
     ]);
     addon = await promiseAddonByID(ID);
 
     // temporary add-on is installed and started
     do_check_neq(addon, null);
     do_check_eq(addon.version, "5.0");
     do_check_eq(addon.name, "Test WebExtension 1 (temporary)");
     do_check_true(addon.isCompatible);
@@ -322,17 +309,17 @@ add_task(async function() {
           }
         },
         theme: { images: { headerURL: "example.png" } }
       }
     });
 
     await Promise.all([
       AddonManager.installTemporaryAddon(webext),
-      promiseAddonStartup(),
+      promiseWebExtensionStartup(),
     ]);
     addon = await promiseAddonByID(ID);
 
     do_check_neq(addon, null);
     do_check_eq(addon.version, "6.0");
     do_check_eq(addon.name, "Test WebExtension 1 (temporary)");
     do_check_true(addon.isCompatible);
     do_check_false(addon.appDisabled);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_embedded.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_embedded.js
@@ -15,28 +15,16 @@ startupManager();
 // AddonManager will raise a ReferenceError exception because it tried to
 // access an undefined `Services.appinfo` object.
 const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {});
 
 const {
   EmbeddedExtensionManager,
 } = Components.utils.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
 
-// Wait the startup of the embedded webextension.
-function promiseWebExtensionStartup() {
-  return new Promise(resolve => {
-    let listener = (event, extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 function promiseWebExtensionShutdown() {
   return new Promise(resolve => {
     let listener = (event, extension) => {
       Management.off("shutdown", listener);
       resolve(extension);
     };
 
     Management.on("shutdown", listener);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_icons.js
@@ -6,35 +6,22 @@ const ID = "webextension1@tests.mozilla.
 
 const profileDir = gProfD.clone();
 profileDir.append("extensions");
 profileDir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
 startupManager();
 
-const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseAddonStartup() {
-  return new Promise(resolve => {
-    let listener = (evt, extension) => {
-      Management.off("startup", listener);
-      resolve(extension);
-    };
-
-    Management.on("startup", listener);
-  });
-}
-
 async function testSimpleIconsetParsing(manifest) {
   await promiseWriteWebManifestForExtension(manifest, profileDir);
 
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   let uri = do_get_addon_root_uri(profileDir, ID);
 
   let addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   function check_icons(addon_copy) {
@@ -58,33 +45,33 @@ async function testSimpleIconsetParsing(
     equal(AddonManager.getPreferredIconURL(addon, 128), uri + "icon64.png");
   }
 
   check_icons(addon);
 
   // check if icons are persisted through a restart
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   check_icons(addon);
 
   addon.uninstall();
 }
 
 async function testRetinaIconsetParsing(manifest) {
   await promiseWriteWebManifestForExtension(manifest, profileDir);
 
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   let addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   let uri = do_get_addon_root_uri(profileDir, ID);
 
   // AddonManager displays larger icons for higher pixel density
@@ -103,17 +90,17 @@ async function testRetinaIconsetParsing(
   addon.uninstall();
 }
 
 async function testNoIconsParsing(manifest) {
   await promiseWriteWebManifestForExtension(manifest, profileDir);
 
   await Promise.all([
     promiseRestartManager(),
-    manifest.theme || promiseAddonStartup(),
+    manifest.theme || promiseWebExtensionStartup(ID),
   ]);
 
   let addon = await promiseAddonByID(ID);
   do_check_neq(addon, null);
 
   deepEqual(addon.icons, {});
 
   equal(addon.iconURL, null);