Bug 1447903: Part 20a - Refactor test_update.js to be less insane. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 25 Mar 2018 18:34:27 -0700
changeset 772398 a847a38ad672c0fed033f2b10621a12138a22212
parent 772397 4504718fb08e54c5557a5a3fc9c7c293ee538dc8
child 772399 37a536a81b06789828c675feeb080097deeebc05
push id103898
push usermaglione.k@gmail.com
push dateMon, 26 Mar 2018 01:36:14 +0000
reviewersaswan
bugs1447903
milestone61.0a1
Bug 1447903: Part 20a - Refactor test_update.js to be less insane. r?aswan MozReview-Commit-ID: 9y7GczOSS3T
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/test/xpcshell/data/test_update.json
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/mozapps/extensions/test/xpcshell/test_update.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -1252,26 +1252,28 @@ var AddonTestUtils = {
       files,
       file => this.promiseInstallFile(file, ignoreIncompatible)));
   },
 
   promiseCompleteAllInstalls(installs) {
     return Promise.all(Array.from(installs, this.promiseCompleteInstall));
   },
 
+  updateReason: AddonManager.UPDATE_WHEN_PERIODIC_UPDATE,
+
   /**
    * Returns a promise that will be resolved when an add-on update check is
    * complete. The value resolved will be an AddonInstall if a new version was
    * found.
    *
    * @param {object} addon The add-on to find updates for.
    * @param {integer} reason The type of update to find.
    * @return {Promise<object>} an object containing information about the update.
    */
-  promiseFindAddonUpdates(addon, reason = AddonManager.UPDATE_WHEN_PERIODIC_UPDATE) {
+  promiseFindAddonUpdates(addon, reason = AddonTestUtils.updateReason, ...args) {
     let equal = this.testScope.equal;
     return new Promise((resolve, reject) => {
       let result = {};
       addon.findUpdates({
         onNoCompatibilityUpdateAvailable(addon2) {
           if ("compatibilityUpdate" in result) {
             throw new Error("Saw multiple compatibility update events");
           }
@@ -1307,17 +1309,17 @@ var AddonTestUtils = {
           equal(addon, addon2, "onUpdateFinished");
           if (error == AddonManager.UPDATE_STATUS_NO_ERROR) {
             resolve(result);
           } else {
             result.error = error;
             reject(result);
           }
         }
-      }, reason);
+      }, reason, ...args);
     });
   },
 
   /**
    * Monitors console output for the duration of a task, and returns a promise
    * which resolves to a tuple containing a list of all console messages
    * generated during the task's execution, and the result of the task itself.
    *
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_update.json
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_update.json
@@ -17,17 +17,17 @@
             "gecko": {
               "strict_min_version": "2",
               "strict_min_version": "2"
             }
           }
         },
         {
           "version": "2.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update.xpi",
+          "update_link": "http://example.com/addons/test_update.xpi",
           "update_info_url": "http://example.com/updateInfo.xhtml",
           "applications": {
             "gecko": {
               "strict_min_version": "1",
               "strict_min_version": "1"
             }
           }
         }
@@ -103,110 +103,110 @@
         }
       ]
     },
 
     "addon8@tests.mozilla.org": {
       "updates": [
         {
           "version": "2.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update8.xpi",
+          "update_link": "http://example.com/addons/test_update8.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "1",
               "advisory_max_version": "1"
             }
           }
         }
       ]
     },
 
     "addon9@tests.mozilla.org": {
       "updates": [
         {
           "version": "2.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update9_2.xpi",
+          "update_link": "http://example.com/addons/test_update9_2.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "1",
               "advisory_max_version": "1"
             }
           }
         },
         {
           "_comment_": "Incompatible when strict compatibility is enabled",
           "version": "3.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update9_3.xpi",
+          "update_link": "http://example.com/addons/test_update9_3.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "0.9",
               "advisory_max_version": "0.9"
             }
           }
         },
         {
           "_comment_": "Incompatible due to compatibility override",
           "version": "4.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update9_4.xpi",
+          "update_link": "http://example.com/addons/test_update9_4.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "0.9",
               "advisory_max_version": "0.9"
             }
           }
         },
         {
           "_comment_": "Addon for future version of app",
           "version": "4.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update9_5.xpi",
+          "update_link": "http://example.com/addons/test_update9_5.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "5",
               "advisory_max_version": "6"
             }
           }
         }
       ]
     },
 
     "addon10@tests.mozilla.org": {
       "updates": [
         {
           "version": "1.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update10.xpi",
+          "update_link": "http://example.com/addons/test_update10.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "0.1",
               "advisory_max_version": "0.4"
             }
           }
         }
       ]
     },
 
     "addon11@tests.mozilla.org": {
       "updates": [
         {
           "version": "2.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update11.xpi",
+          "update_link": "http://example.com/addons/test_update11.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "0.1",
               "strict_max_version": "0.2"
             }
           }
         }
       ]
     },
 
     "addon12@tests.mozilla.org": {
       "updates": [
         {
           "version": "2.0",
-          "update_link": "http://localhost:%PORT%/addons/test_update12.xpi",
+          "update_link": "http://example.com/addons/test_update12.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "1",
               "advisory_max_version": "1"
             }
           }
         }
       ]
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -66,16 +66,17 @@ ChromeUtils.defineModuleGetter(this, "Mo
 
 XPCOMUtils.defineLazyServiceGetter(this, "aomStartup",
                                    "@mozilla.org/addons/addon-manager-startup;1",
                                    "amIAddonManagerStartup");
 
 // Whitelist existing tests that still use non-restartless extensions.
 const LEGACY_NON_RESTARTLESS_TESTS = new Set([
   "test_bug455906.js",
+  "test_update.js",
 ]);
 
 if (LEGACY_NON_RESTARTLESS_TESTS.has(_TEST_FILE[0].replace(/.*\//, ""))) {
   Services.prefs.setBoolPref("extensions.legacy.non-restartless.enabled", true);
 }
 
 const {
   awaitPromise,
--- a/toolkit/mozapps/extensions/test/xpcshell/test_update.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_update.js
@@ -10,1388 +10,1298 @@ const PREF_GETADDONS_CACHE_ENABLED = "ex
 Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
 Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
 // This test requires lightweight themes update to be enabled even if the app
 // doesn't support lightweight themes.
 Services.prefs.setBoolPref("lightweightThemes.update.enabled", true);
 
 ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm");
 
-const PARAMS = "?%REQ_VERSION%/%ITEM_ID%/%ITEM_VERSION%/%ITEM_MAXAPPVERSION%/" +
-               "%ITEM_STATUS%/%APP_ID%/%APP_VERSION%/%CURRENT_APP_VERSION%/" +
-               "%APP_OS%/%APP_ABI%/%APP_LOCALE%/%UPDATE_TYPE%";
+Cu.importGlobalProperties(["URLSearchParams"]);
 
 var gInstallDate;
 
-var testserver = createHttpServer();
-gPort = testserver.identity.primaryPort;
-mapFile("/data/test_update.json", testserver);
-mapFile("/data/test_update_addons.json", testserver);
-mapFile("/data/test_update_compat.json", testserver);
-testserver.registerDirectory("/addons/", do_get_file("addons"));
+const updateFile = "test_update.json";
+const appId = "toolkit@mozilla.org";
 
 const profileDir = gProfD.clone();
 profileDir.append("extensions");
 
 var originalSyncGUID;
 
-function run_test() {
+const ADDONS = {
+  test_update: {
+    "install.rdf": {
+      id: "addon1@tests.mozilla.org",
+      version: "2.0",
+      name: "Test 1",
+      description: "Test Description",
+
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1"}],
+    },
+  },
+  test_update8: {
+    "install.rdf": {
+      id: "addon8@tests.mozilla.org",
+      version: "2.0",
+      name: "Test 8",
+      description: "Test Description",
+
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1"}],
+    },
+  },
+  test_update12: {
+    "install.rdf": {
+      id: "addon12@tests.mozilla.org",
+      version: "2.0",
+      name: "Test 12",
+      description: "Test Description",
+
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1"}],
+    },
+  },
+  test_install2_1: {
+    "install.rdf": {
+      id: "addon2@tests.mozilla.org",
+      version: "2.0",
+      name: "Real Test 2",
+      description: "Test Description",
+
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1"}],
+    },
+  },
+  test_install2_2: {
+    "install.rdf": {
+      id: "addon2@tests.mozilla.org",
+      version: "3.0",
+      name: "Real Test 3",
+      description: "Test Description",
+
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1"}],
+    },
+  },
+};
+
+var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]});
+testserver.registerDirectory("/data/", do_get_file("data"));
+
+const XPIS = {};
+for (let [name, addon] of Object.entries(ADDONS)) {
+  XPIS[name] = AddonTestUtils.createTempXPIFile(addon);
+  testserver.registerFile(`/addons/${name}.xpi`, XPIS[name]);
+}
+
+add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
 
   Services.locale.setRequestedLocales(["fr-FR"]);
-
-  run_next_test();
-}
+});
 
-const updateFile = "test_update.json";
-const appId = "toolkit@mozilla.org";
+add_task(async function() {
+  AddonTestUtils.updateReason = AddonManager.UPDATE_WHEN_USER_REQUESTED;
 
-add_test(function() {
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon1@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 1",
   }, profileDir);
 
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon2@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "0",
       maxVersion: "0"
     }],
     name: "Test Addon 2",
   }, profileDir);
 
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon3@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "5",
       maxVersion: "5"
     }],
     name: "Test Addon 3",
   }, profileDir);
 
-  startupManager();
-
-  run_next_test();
+  await promiseStartupManager();
 });
 
 // Verify that an update is available and can be installed.
-let check_test_1;
-add_test(function run_test_1() {
-  AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
-    Assert.notEqual(a1, null);
-    Assert.equal(a1.version, "1.0");
-    Assert.equal(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
-    Assert.equal(a1.releaseNotesURI, null);
-    Assert.ok(a1.foreignInstall);
-    Assert.notEqual(a1.syncGUID, null);
+add_task(async function test_1() {
+  let a1 = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
+  notEqual(a1, null);
+  equal(a1.version, "1.0");
+  equal(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
+  equal(a1.releaseNotesURI, null);
+  ok(a1.foreignInstall);
+  notEqual(a1.syncGUID, null);
+
+  originalSyncGUID = a1.syncGUID;
+  a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
+
+  prepare_test({
+    "addon1@tests.mozilla.org": [
+      ["onPropertyChanged", ["applyBackgroundUpdates"]]
+    ]
+  });
+  a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
+  check_test_completed();
+
+  a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
+
+  prepare_test({}, [
+    "onNewInstall",
+  ]);
+
+  let {updateAvailable: install} = await AddonTestUtils.promiseFindAddonUpdates(a1);
+
+  ensure_test_completed();
+
+  let installs = await AddonManager.getAllInstalls();
+  equal(installs.length, 1);
+  equal(installs[0], install);
 
-    originalSyncGUID = a1.syncGUID;
-    a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
+  equal(install.name, a1.name);
+  equal(install.version, "2.0");
+  equal(install.state, AddonManager.STATE_AVAILABLE);
+  equal(install.existingAddon, a1);
+  equal(install.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+
+  // Verify that another update check returns the same AddonInstall
+  let {updateAvailable: install2} = await AddonTestUtils.promiseFindAddonUpdates(a1);
+
+  installs = await AddonManager.getAllInstalls();
+  equal(installs.length, 1);
+  equal(installs[0], install);
+  equal(install2, install);
 
+  await new Promise(resolve => {
+    prepare_test({}, [
+      "onDownloadStarted",
+      "onDownloadEnded",
+    ], () => {
+      resolve();
+      return false;
+    });
+    install.install();
+  });
+
+  ensure_test_completed();
+  equal(install.state, AddonManager.STATE_DOWNLOADED);
+
+  // Continue installing the update.
+  // Verify that another update check returns no new update
+  let {updateAvailable} = await AddonTestUtils.promiseFindAddonUpdates(install.existingAddon);
+
+  ok(!updateAvailable, "Should find no available updates when one is already downloading");
+
+  installs = await AddonManager.getAllInstalls();
+  equal(installs.length, 1);
+  equal(installs[0], install);
+
+  await new Promise(resolve => {
     prepare_test({
       "addon1@tests.mozilla.org": [
-        ["onPropertyChanged", ["applyBackgroundUpdates"]]
+        "onInstalling"
       ]
-    });
-    a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
-    check_test_completed();
-
-    a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
-
-    prepare_test({}, [
-      "onNewInstall",
-    ]);
+    }, [
+      "onInstallStarted",
+      "onInstallEnded",
+    ], resolve);
+    install.install();
+  });
 
-    a1.findUpdates({
-      onNoCompatibilityUpdateAvailable(addon) {
-        ok(false, "Should not have seen onNoCompatibilityUpdateAvailable notification");
-      },
+  ensure_test_completed();
 
-      onUpdateAvailable(addon, install) {
-        ensure_test_completed();
+  let olda1 = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
+  await AddonTestUtils.loadAddonsList(true);
 
-        AddonManager.getAllInstalls(function(aInstalls) {
-          Assert.equal(aInstalls.length, 1);
-          Assert.equal(aInstalls[0], install);
+  notEqual(olda1, null);
+  equal(olda1.version, "1.0");
+  ok(isExtensionInAddonsList(profileDir, olda1.id));
 
-          Assert.equal(addon, a1);
-          Assert.equal(install.name, addon.name);
-          Assert.equal(install.version, "2.0");
-          Assert.equal(install.state, AddonManager.STATE_AVAILABLE);
-          Assert.equal(install.existingAddon, addon);
-          Assert.equal(install.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+  await promiseRestartManager();
 
-          // Verify that another update check returns the same AddonInstall
-          a1.findUpdates({
-            onNoCompatibilityUpdateAvailable() {
-              ok(false, "Should not have seen onNoCompatibilityUpdateAvailable notification");
-            },
+  // Grab the current time so we can check the mtime of the add-on below
+  // without worrying too much about how long other tests take.
+  let startupTime = Date.now();
 
-            onUpdateAvailable(newAddon, newInstall) {
-              AddonManager.getAllInstalls(function(aInstalls2) {
-                Assert.equal(aInstalls2.length, 1);
-                Assert.equal(aInstalls2[0], install);
-                Assert.equal(newAddon, addon);
-                Assert.equal(newInstall, install);
+  ok(isExtensionInAddonsList(profileDir, "addon1@tests.mozilla.org"));
 
-                prepare_test({}, [
-                  "onDownloadStarted",
-                  "onDownloadEnded",
-                ], check_test_1);
-                install.install();
-              });
-            },
+  a1 = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
+  notEqual(a1, null);
+  equal(a1.version, "2.0");
+  ok(isExtensionInAddonsList(profileDir, a1.id));
+  equal(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
+  equal(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+  ok(a1.foreignInstall);
+  notEqual(a1.syncGUID, null);
+  equal(originalSyncGUID, a1.syncGUID);
 
-            onNoUpdateAvailable() {
-              ok(false, "Should not have seen onNoUpdateAvailable notification");
-            }
-          }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-        });
-      },
+  // Make sure that the extension lastModifiedTime was updated.
+  let testURI = a1.getResourceURI(TEST_UNPACKED ? "install.rdf" : "");
+  let testFile = testURI.QueryInterface(Ci.nsIFileURL).file;
+  let difference = testFile.lastModifiedTime - startupTime;
+  ok(Math.abs(difference) < MAX_TIME_DIFFERENCE);
 
-      onNoUpdateAvailable(addon) {
-        ok(false, "Should not have seen onNoUpdateAvailable notification");
-      }
-    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-  });
+  a1.uninstall();
 });
 
-let run_test_2;
-check_test_1 = (install) => {
-  ensure_test_completed();
-  Assert.equal(install.state, AddonManager.STATE_DOWNLOADED);
-  run_test_2(install);
-  return false;
-};
-
-// Continue installing the update.
-let check_test_2;
-run_test_2 = (install) => {
-  // Verify that another update check returns no new update
-  install.existingAddon.findUpdates({
-    onNoCompatibilityUpdateAvailable(addon) {
-      ok(false, "Should not have seen onNoCompatibilityUpdateAvailable notification");
-    },
-
-    onUpdateAvailable() {
-      ok(false, "Should find no available update when one is already downloading");
-    },
-
-    onNoUpdateAvailable(addon) {
-      AddonManager.getAllInstalls(function(aInstalls) {
-        Assert.equal(aInstalls.length, 1);
-        Assert.equal(aInstalls[0], install);
+// Check that an update check finds compatibility updates and applies them
+add_task(async function test_3() {
+  await promiseRestartManager();
 
-        prepare_test({
-          "addon1@tests.mozilla.org": [
-            "onInstalling"
-          ]
-        }, [
-          "onInstallStarted",
-          "onInstallEnded",
-        ], check_test_2);
-        install.install();
-      });
-    }
-  }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-};
-
-check_test_2 = () => {
-  ensure_test_completed();
-
-  AddonManager.getAddonByID("addon1@tests.mozilla.org", callback_soon(async function(olda1) {
-    await AddonTestUtils.loadAddonsList(true);
-
-    Assert.notEqual(olda1, null);
-    Assert.equal(olda1.version, "1.0");
-    Assert.ok(isExtensionInAddonsList(profileDir, olda1.id));
-
-    shutdownManager();
-
-    await promiseStartupManager();
+  let a2 = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
+  notEqual(a2, null);
+  ok(a2.isActive);
+  ok(a2.isCompatible);
+  ok(!a2.appDisabled);
+  ok(a2.isCompatibleWith("0", "0"));
 
-    // Grab the current time so we can check the mtime of the add-on below
-    // without worrying too much about how long other tests take.
-    let startupTime = Date.now();
-
-    Assert.ok(isExtensionInAddonsList(profileDir, "addon1@tests.mozilla.org"));
+  let result = await AddonTestUtils.promiseFindAddonUpdates(a2);
+  ok(result.compatibilityUpdate, "Should have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
 
-    AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
-      Assert.notEqual(a1, null);
-      Assert.equal(a1.version, "2.0");
-      Assert.ok(isExtensionInAddonsList(profileDir, a1.id));
-      Assert.equal(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
-      Assert.equal(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
-      Assert.ok(a1.foreignInstall);
-      Assert.notEqual(a1.syncGUID, null);
-      Assert.equal(originalSyncGUID, a1.syncGUID);
-
-      // Make sure that the extension lastModifiedTime was updated.
-      let testURI = a1.getResourceURI(TEST_UNPACKED ? "install.rdf" : "");
-      let testFile = testURI.QueryInterface(Ci.nsIFileURL).file;
-      let difference = testFile.lastModifiedTime - startupTime;
-      Assert.ok(Math.abs(difference) < MAX_TIME_DIFFERENCE);
-
-      a1.uninstall();
-      run_next_test();
-    });
-  }));
-};
+  ok(a2.isCompatible);
+  ok(!a2.appDisabled);
+  ok(a2.isActive);
 
-// Check that an update check finds compatibility updates and applies them
-let check_test_3;
-add_test(function run_test_3() {
-  restartManager();
-
-  AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
-    Assert.notEqual(a2, null);
-    Assert.ok(a2.isActive);
-    Assert.ok(a2.isCompatible);
-    Assert.ok(!a2.appDisabled);
-    Assert.ok(a2.isCompatibleWith("0", "0"));
+  await promiseRestartManager();
 
-    a2.findUpdates({
-      onCompatibilityUpdateAvailable(addon) {
-        Assert.ok(a2.isCompatible);
-        Assert.ok(!a2.appDisabled);
-        Assert.ok(a2.isActive);
-      },
-
-      onUpdateAvailable(addon, install) {
-        ok(false, "Should not have seen an available update");
-      },
-
-      onNoUpdateAvailable(addon) {
-        Assert.equal(addon, a2);
-        executeSoon(check_test_3);
-      }
-    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-  });
+  a2 = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
+  notEqual(a2, null);
+  ok(a2.isActive);
+  ok(a2.isCompatible);
+  ok(!a2.appDisabled);
+  a2.uninstall();
 });
 
-check_test_3 = () => {
-  restartManager();
-  AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
-    Assert.notEqual(a2, null);
-    Assert.ok(a2.isActive);
-    Assert.ok(a2.isCompatible);
-    Assert.ok(!a2.appDisabled);
-    a2.uninstall();
-
-    run_next_test();
-  });
-};
+// Checks that we see no compatibility information when there is none.
+add_task(async function test_4() {
+  let a3 = await AddonManager.getAddonByID("addon3@tests.mozilla.org");
+  notEqual(a3, null);
+  ok(!a3.isActive);
+  ok(!a3.isCompatible);
+  ok(a3.appDisabled);
+  ok(a3.isCompatibleWith("5", "5"));
+  ok(!a3.isCompatibleWith("2", "2"));
 
-// Checks that we see no compatibility information when there is none.
-add_test(function run_test_4() {
-  AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
-    Assert.notEqual(a3, null);
-    Assert.ok(!a3.isActive);
-    Assert.ok(!a3.isCompatible);
-    Assert.ok(a3.appDisabled);
-    Assert.ok(a3.isCompatibleWith("5", "5"));
-    Assert.ok(!a3.isCompatibleWith("2", "2"));
-
-    a3.findUpdates({
-      sawUpdate: false,
-      onCompatibilityUpdateAvailable(addon) {
-        ok(false, "Should not have seen compatibility information");
-      },
-
-      onNoCompatibilityUpdateAvailable(addon) {
-        this.sawUpdate = true;
-      },
-
-      onUpdateAvailable(addon, install) {
-        ok(false, "Should not have seen an available update");
-      },
-
-      onNoUpdateAvailable(addon) {
-        Assert.ok(this.sawUpdate);
-        run_next_test();
-      }
-    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-  });
+  let result = await AddonTestUtils.promiseFindAddonUpdates(a3);
+  ok(!result.compatibilityUpdate, "Should not have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
 });
 
 // Checks that compatibility info for future apps are detected but don't make
 // the item compatibile.
-let check_test_5;
-add_test(function run_test_5() {
-  AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
-    Assert.notEqual(a3, null);
-    Assert.ok(!a3.isActive);
-    Assert.ok(!a3.isCompatible);
-    Assert.ok(a3.appDisabled);
-    Assert.ok(a3.isCompatibleWith("5", "5"));
-    Assert.ok(!a3.isCompatibleWith("2", "2"));
+add_task(async function test_5() {
+  let a3 = await AddonManager.getAddonByID("addon3@tests.mozilla.org");
+  notEqual(a3, null);
+  ok(!a3.isActive);
+  ok(!a3.isCompatible);
+  ok(a3.appDisabled);
+  ok(a3.isCompatibleWith("5", "5"));
+  ok(!a3.isCompatibleWith("2", "2"));
+
+  let result = await AddonTestUtils.promiseFindAddonUpdates(a3, undefined, "3.0", "3.0");
+  ok(result.compatibilityUpdate, "Should have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
 
-    a3.findUpdates({
-      sawUpdate: false,
-      onCompatibilityUpdateAvailable(addon) {
-        Assert.ok(!a3.isCompatible);
-        Assert.ok(a3.appDisabled);
-        Assert.ok(!a3.isActive);
-        this.sawUpdate = true;
-      },
+  ok(!a3.isActive);
+  ok(!a3.isCompatible);
+  ok(a3.appDisabled);
+
+  await promiseRestartManager();
 
-      onNoCompatibilityUpdateAvailable(addon) {
-        ok(false, "Should have seen some compatibility information");
-      },
+  a3 = await AddonManager.getAddonByID("addon3@tests.mozilla.org");
+  notEqual(a3, null);
+  ok(!a3.isActive);
+  ok(!a3.isCompatible);
+  ok(a3.appDisabled);
 
-      onUpdateAvailable(addon, install) {
-        ok(false, "Should not have seen an available update");
-      },
-
-      onNoUpdateAvailable(addon) {
-        Assert.ok(this.sawUpdate);
-        executeSoon(check_test_5);
-      }
-    }, AddonManager.UPDATE_WHEN_USER_REQUESTED, "3.0", "3.0");
-  });
+  a3.uninstall();
+  await promiseRestartManager();
 });
 
-check_test_5 = () => {
-  restartManager();
-  AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
-    Assert.notEqual(a3, null);
-    Assert.ok(!a3.isActive);
-    Assert.ok(!a3.isCompatible);
-    Assert.ok(a3.appDisabled);
-
-    a3.uninstall();
-    run_next_test();
-  });
-};
-
 // Test that background update checks work
-let continue_test_6;
-add_test(function run_test_6() {
-  restartManager();
-
-  writeInstallRDFForExtension({
+add_task(async function test_6() {
+  await promiseWriteInstallRDFForExtension({
     id: "addon1@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 1",
   }, profileDir);
-  restartManager();
+
+  await promiseRestartManager();
+
+  let install = await new Promise(resolve => {
+    prepare_test({}, [
+      "onNewInstall",
+      "onDownloadStarted",
+      "onDownloadEnded"
+    ], resolve);
+
+    AddonManagerInternal.backgroundUpdateCheck();
+  });
+
+  notEqual(install.existingAddon, null);
+  equal(install.existingAddon.id, "addon1@tests.mozilla.org");
 
-  prepare_test({}, [
-    "onNewInstall",
-    "onDownloadStarted",
-    "onDownloadEnded"
-  ], continue_test_6);
+  await new Promise(resolve => {
+    prepare_test({
+      "addon1@tests.mozilla.org": [
+        "onInstalling"
+      ]
+    }, [
+      "onInstallStarted",
+      "onInstallEnded",
+    ], resolve);
+  });
 
-  AddonManagerInternal.backgroundUpdateCheck();
+  equal(install.existingAddon.pendingUpgrade.install, install);
+
+  await promiseRestartManager();
+
+  let a1 = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
+  notEqual(a1, null);
+  equal(a1.version, "2.0");
+  equal(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+  a1.uninstall();
+
+  await promiseRestartManager();
 });
 
-let check_test_6;
-continue_test_6 = (install) => {
-  Assert.notEqual(install.existingAddon, null);
-  Assert.equal(install.existingAddon.id, "addon1@tests.mozilla.org");
+const PARAMS = "?" + [
+  "req_version=%REQ_VERSION%",
+  "item_id=%ITEM_ID%",
+  "item_version=%ITEM_VERSION%",
+  "item_maxappversion=%ITEM_MAXAPPVERSION%",
+  "item_status=%ITEM_STATUS%",
+  "app_id=%APP_ID%",
+  "app_version=%APP_VERSION%",
+  "current_app_version=%CURRENT_APP_VERSION%",
+  "app_os=%APP_OS%",
+  "app_abi=%APP_ABI%",
+  "app_locale=%APP_LOCALE%",
+  "update_type=%UPDATE_TYPE%",
+].join("&");
+
+const PARAM_ADDONS = {
+  "addon1@tests.mozilla.org": {
+    "install.rdf": {
+      id: "addon1@tests.mozilla.org",
+      version: "5.0",
+      updateURL: "http://example.com/data/param_test.json" + PARAMS,
+      targetApplications: [{
+        id: appId,
+        minVersion: "1",
+        maxVersion: "2"
+      }],
+      name: "Test Addon 1",
+    },
+    params: {
+      item_version: "5.0",
+      item_maxappversion: "2",
+      item_status: "userEnabled",
+      app_version: "1",
+      update_type: "97",
+    },
+    updateType: [AddonManager.UPDATE_WHEN_USER_REQUESTED],
+  },
+
+  "addon2@tests.mozilla.org": {
+    "install.rdf": {
+      id: "addon2@tests.mozilla.org",
+      version: "67.0.5b1",
+      updateURL: "http://example.com/data/param_test.json" + PARAMS,
+      targetApplications: [{
+        id: "toolkit@mozilla.org",
+        minVersion: "0",
+        maxVersion: "3"
+      }],
+      name: "Test Addon 2",
+    },
+    initialState: {
+      userDisabled: true,
+    },
+    params: {
+      item_version: "67.0.5b1",
+      item_maxappversion: "3",
+      item_status: "userDisabled",
+      app_version: "1",
+      update_type: "49",
+    },
+    updateType: [AddonManager.UPDATE_WHEN_ADDON_INSTALLED],
+    compatOnly: true,
+  },
 
-  prepare_test({
-    "addon1@tests.mozilla.org": [
-      "onInstalling"
-    ]
-  }, [
-    "onInstallStarted",
-    "onInstallEnded",
-  ], callback_soon(check_test_6));
+  "addon3@tests.mozilla.org": {
+    "install.rdf": {
+      id: "addon3@tests.mozilla.org",
+      version: "1.3+",
+      updateURL: "http://example.com/data/param_test.json" + PARAMS,
+      targetApplications: [{
+        id: appId,
+        minVersion: "0",
+        maxVersion: "0"
+      }, {
+        id: "toolkit@mozilla.org",
+        minVersion: "0",
+        maxVersion: "3"
+      }],
+      name: "Test Addon 3",
+    },
+    params: {
+      item_version: "1.3+",
+      item_maxappversion: "0",
+      item_status: "userEnabled",
+      app_version: "1",
+      update_type: "112",
+    },
+    updateType: [AddonManager.UPDATE_WHEN_PERIODIC_UPDATE],
+  },
+
+  "addon4@tests.mozilla.org": {
+    "install.rdf": {
+      id: "addon4@tests.mozilla.org",
+      version: "0.5ab6",
+      updateURL: "http://example.com/data/param_test.json" + PARAMS,
+      targetApplications: [{
+        id: appId,
+        minVersion: "1",
+        maxVersion: "5"
+      }],
+      name: "Test Addon 4",
+    },
+    params: {
+      item_version: "0.5ab6",
+      item_maxappversion: "5",
+      item_status: "userEnabled",
+      app_version: "2",
+      update_type: "98",
+    },
+    updateType: [AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, "2"],
+  },
+
+  "addon5@tests.mozilla.org": {
+    "install.rdf": {
+      id: "addon5@tests.mozilla.org",
+      version: "1.0",
+      updateURL: "http://example.com/data/param_test.json" + PARAMS,
+      targetApplications: [{
+        id: appId,
+        minVersion: "1",
+        maxVersion: "1"
+      }],
+      name: "Test Addon 5",
+    },
+    params: {
+      item_version: "1.0",
+      item_maxappversion: "1",
+      item_status: "userEnabled",
+      app_version: "1",
+      update_type: "35",
+    },
+    updateType: [AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED],
+    compatOnly: true,
+  },
+
+  "addon6@tests.mozilla.org": {
+    "install.rdf": {
+      id: "addon6@tests.mozilla.org",
+      version: "1.0",
+      updateURL: "http://example.com/data/param_test.json" + PARAMS,
+      targetApplications: [{
+        id: appId,
+        minVersion: "1",
+        maxVersion: "1"
+      }],
+      name: "Test Addon 6",
+    },
+    params: {
+      item_version: "1.0",
+      item_maxappversion: "1",
+      item_status: "userEnabled",
+      app_version: "1",
+      update_type: "99",
+    },
+    updateType: [AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED],
+  },
 };
 
-check_test_6 = (install) => {
-  Assert.equal(install.existingAddon.pendingUpgrade.install, install);
-
-  restartManager();
-  AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
-    Assert.notEqual(a1, null);
-    Assert.equal(a1.version, "2.0");
-    Assert.equal(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
-    a1.uninstall();
-    run_next_test();
-  });
-};
+const PARAM_IDS = Object.keys(PARAM_ADDONS);
 
 // Verify the parameter escaping in update urls.
-add_test(function run_test_8() {
-  restartManager();
+add_task(async function test_8() {
+  await promiseShutdownManager();
 
-  writeInstallRDFForExtension({
-    id: "addon1@tests.mozilla.org",
-    version: "5.0",
-    updateURL: "http://localhost:" + gPort + "/data/param_test.json" + PARAMS,
-    targetApplications: [{
-      id: appId,
-      minVersion: "1",
-      maxVersion: "2"
-    }],
-    name: "Test Addon 1",
-  }, profileDir);
+  for (let addon of Object.values(PARAM_ADDONS)) {
+    await promiseWriteInstallRDFForExtension(addon["install.rdf"], profileDir);
+  }
 
-  writeInstallRDFForExtension({
-    id: "addon2@tests.mozilla.org",
-    version: "67.0.5b1",
-    updateURL: "http://localhost:" + gPort + "/data/param_test.json" + PARAMS,
-    targetApplications: [{
-      id: "toolkit@mozilla.org",
-      minVersion: "0",
-      maxVersion: "3"
-    }],
-    name: "Test Addon 2",
-  }, profileDir);
+  await promiseStartupManager();
 
-  writeInstallRDFForExtension({
-    id: "addon3@tests.mozilla.org",
-    version: "1.3+",
-    updateURL: "http://localhost:" + gPort + "/data/param_test.json" + PARAMS,
-    targetApplications: [{
-      id: appId,
-      minVersion: "0",
-      maxVersion: "0"
-    }, {
-      id: "toolkit@mozilla.org",
-      minVersion: "0",
-      maxVersion: "3"
-    }],
-    name: "Test Addon 3",
-  }, profileDir);
-
-  writeInstallRDFForExtension({
-    id: "addon4@tests.mozilla.org",
-    version: "0.5ab6",
-    updateURL: "http://localhost:" + gPort + "/data/param_test.json" + PARAMS,
-    targetApplications: [{
-      id: appId,
-      minVersion: "1",
-      maxVersion: "5"
-    }],
-    name: "Test Addon 4",
-  }, profileDir);
+  for (let [id, options] of Object.entries(PARAM_ADDONS)) {
+    if (options.initialState) {
+      let addon = await AddonManager.getAddonByID(id);
+      Object.assign(addon, options.initialState);
+    }
+  }
 
-  writeInstallRDFForExtension({
-    id: "addon5@tests.mozilla.org",
-    version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/param_test.json" + PARAMS,
-    targetApplications: [{
-      id: appId,
-      minVersion: "1",
-      maxVersion: "1"
-    }],
-    name: "Test Addon 5",
-  }, profileDir);
+  await promiseRestartManager();
 
-  writeInstallRDFForExtension({
-    id: "addon6@tests.mozilla.org",
-    version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/param_test.json" + PARAMS,
-    targetApplications: [{
-      id: appId,
-      minVersion: "1",
-      maxVersion: "1"
-    }],
-    name: "Test Addon 6",
-  }, profileDir);
-
-  restartManager();
-
-  AddonManager.getAddonByID("addon2@tests.mozilla.org", callback_soon(function(a2) {
-    a2.userDisabled = true;
-    restartManager();
+  let resultsPromise = new Promise(resolve => {
+    let results = new Map();
 
     testserver.registerPathHandler("/data/param_test.json", function(request, response) {
-      Assert.notEqual(request.queryString, "");
-      let [req_version, item_id, item_version,
-           item_maxappversion, item_status,
-           app_id, app_version, current_app_version,
-           app_os, app_abi, app_locale, update_type] =
-           request.queryString.split("/").map(a => decodeURIComponent(a));
-
-      Assert.equal(req_version, "2");
+      let params = new URLSearchParams(request.queryString);
+      let itemId = params.get("item_id");
+      ok(!results.has(itemId), `Should not see a duplicate request for item ${itemId}`);
 
-      switch (item_id) {
-      case "addon1@tests.mozilla.org":
-        Assert.equal(item_version, "5.0");
-        Assert.equal(item_maxappversion, "2");
-        Assert.equal(item_status, "userEnabled");
-        Assert.equal(app_version, "1");
-        Assert.equal(update_type, "97");
-        break;
-      case "addon2@tests.mozilla.org":
-        Assert.equal(item_version, "67.0.5b1");
-        Assert.equal(item_maxappversion, "3");
-        Assert.equal(item_status, "userDisabled");
-        Assert.equal(app_version, "1");
-        Assert.equal(update_type, "49");
-        break;
-      case "addon3@tests.mozilla.org":
-        Assert.equal(item_version, "1.3+");
-        Assert.equal(item_maxappversion, "0");
-        Assert.equal(item_status, "userEnabled");
-        Assert.equal(app_version, "1");
-        Assert.equal(update_type, "112");
-        break;
-      case "addon4@tests.mozilla.org":
-        Assert.equal(item_version, "0.5ab6");
-        Assert.equal(item_maxappversion, "5");
-        Assert.equal(item_status, "userEnabled");
-        Assert.equal(app_version, "2");
-        Assert.equal(update_type, "98");
-        break;
-      case "addon5@tests.mozilla.org":
-        Assert.equal(item_version, "1.0");
-        Assert.equal(item_maxappversion, "1");
-        Assert.equal(item_status, "userEnabled");
-        Assert.equal(app_version, "1");
-        Assert.equal(update_type, "35");
-        break;
-      case "addon6@tests.mozilla.org":
-        Assert.equal(item_version, "1.0");
-        Assert.equal(item_maxappversion, "1");
-        Assert.equal(item_status, "userEnabled");
-        Assert.equal(app_version, "1");
-        Assert.equal(update_type, "99");
-        break;
-      default:
-        ok(false, "Update request for unexpected add-on " + item_id);
+      results.set(itemId, params);
+
+      if (results.size === PARAM_IDS.length) {
+        resolve(results);
       }
 
-      Assert.equal(app_id, "xpcshell@tests.mozilla.org");
-      Assert.equal(current_app_version, "1");
-      Assert.equal(app_os, "XPCShell");
-      Assert.equal(app_abi, "noarch-spidermonkey");
-      Assert.equal(app_locale, "fr-FR");
-
       request.setStatusLine(null, 500, "Server Error");
     });
-
-    AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                                 "addon2@tests.mozilla.org",
-                                 "addon3@tests.mozilla.org",
-                                 "addon4@tests.mozilla.org",
-                                 "addon5@tests.mozilla.org",
-                                 "addon6@tests.mozilla.org"],
-                                 function([a1_2, a2_2, a3_2, a4_2, a5_2, a6_2]) {
-      let count = 6;
+  });
 
-      function next_test() {
-        a1_2.uninstall();
-        a2_2.uninstall();
-        a3_2.uninstall();
-        a4_2.uninstall();
-        a5_2.uninstall();
-        a6_2.uninstall();
+  let addons = await getAddons(PARAM_IDS);
+  for (let [id, options] of Object.entries(PARAM_ADDONS)) {
+    // Having an onUpdateAvailable callback in the listener automagically adds
+    // UPDATE_TYPE_NEWVERSION to the update type flags in the request.
+    let listener = options.compatOnly ? {} : {onUpdateAvailable() {}};
 
-        restartManager();
-        run_next_test();
-      }
+    addons.get(id).findUpdates(listener, ...options.updateType);
+  }
 
-      let compatListener = {
-        onUpdateFinished(addon, error) {
-          if (--count == 0)
-            executeSoon(next_test);
-        }
-      };
+  let baseParams = {
+    req_version: "2",
+    app_id: "xpcshell@tests.mozilla.org",
+    current_app_version: "1",
+    app_os: "XPCShell",
+    app_abi: "noarch-spidermonkey",
+    app_locale: "fr-FR",
+  };
 
-      let updateListener = {
-        onUpdateAvailable(addon, update) {
-          // Dummy so the update checker knows we care about new versions
-        },
+  let results = await resultsPromise;
+  for (let [id, options] of Object.entries(PARAM_ADDONS)) {
+    info(`Checking update params for ${id}`);
 
-        onUpdateFinished(addon, error) {
-          if (--count == 0)
-            executeSoon(next_test);
-        }
-      };
+    let expected = Object.assign({}, baseParams, options.params);
+    let params = results.get(id);
 
-      a1_2.findUpdates(updateListener, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-      a2_2.findUpdates(compatListener, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
-      a3_2.findUpdates(updateListener, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
-      a4_2.findUpdates(updateListener, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, "2");
-      a5_2.findUpdates(compatListener, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
-      a6_2.findUpdates(updateListener, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
-    });
-  }));
+    for (let [prop, value] of Object.entries(expected)) {
+      equal(params.get(prop), value, `Expected value for ${prop}`);
+    }
+  }
+
+  for (let [, addon] of await getAddons(PARAM_IDS)) {
+    addon.uninstall();
+  }
+  await promiseRestartManager();
 });
 
 // Tests that if an install.rdf claims compatibility then the add-on will be
 // seen as compatible regardless of what the update.rdf says.
-add_test(function run_test_9() {
-  writeInstallRDFForExtension({
+add_task(async function test_9() {
+  await promiseWriteInstallRDFForExtension({
     id: "addon4@tests.mozilla.org",
     version: "5.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "0",
       maxVersion: "1"
     }],
     name: "Test Addon 1",
   }, profileDir);
 
-  restartManager();
+  await promiseRestartManager();
 
-  AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
-    Assert.ok(a4.isActive, "addon4 is active");
-    Assert.ok(a4.isCompatible, "addon4 is compatible");
-
-    run_next_test();
-  });
+  let a4 = await AddonManager.getAddonByID("addon4@tests.mozilla.org");
+  ok(a4.isActive, "addon4 is active");
+  ok(a4.isCompatible, "addon4 is compatible");
 });
 
 // Tests that a normal update check won't decrease a targetApplication's
 // maxVersion.
-add_test(function run_test_10() {
-  AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
-    a4.findUpdates({
-      onUpdateFinished(addon) {
-        Assert.ok(addon.isCompatible, "addon4 is compatible");
-
-        run_next_test();
-      }
-    }, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
-  });
+add_task(async function test_10() {
+  let a4 = await AddonManager.getAddonByID("addon4@tests.mozilla.org");
+  await AddonTestUtils.promiseFindAddonUpdates(
+    a4, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
+  ok(a4.isCompatible, "addon4 is compatible");
 });
 
 // Tests that an update check for a new application will decrease a
 // targetApplication's maxVersion.
-add_test(function run_test_11() {
-  AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
-    a4.findUpdates({
-      onUpdateFinished(addon) {
-        Assert.ok(addon.isCompatible, "addon4 is not compatible");
-
-        run_next_test();
-      }
-    }, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
-  });
+add_task(async function test_11() {
+  let a4 = await AddonManager.getAddonByID("addon4@tests.mozilla.org");
+  await AddonTestUtils.promiseFindAddonUpdates(
+    a4, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
+  ok(a4.isCompatible, "addon4 is not compatible");
 });
 
 // Check that the decreased maxVersion applied and disables the add-on
-add_test(function run_test_12() {
-  restartManager();
+add_task(async function test_12() {
+  await promiseRestartManager();
 
-  AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
-    Assert.ok(a4.isActive);
-    Assert.ok(a4.isCompatible);
+  let a4 = await AddonManager.getAddonByID("addon4@tests.mozilla.org");
+  ok(a4.isActive);
+  ok(a4.isCompatible);
 
-    a4.uninstall();
-    run_next_test();
-  });
+  a4.uninstall();
+  await promiseRestartManager();
 });
 
 // Tests that a compatibility update is passed to the listener when there is
 // compatibility info for the current version of the app but not for the
 // version of the app that the caller requested an update check for, when
 // strict compatibility checking is disabled.
-let check_test_13;
-add_test(function run_test_13() {
-  restartManager();
-
+add_task(async function test_13() {
   // Not initially compatible but the update check will make it compatible
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon7@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "0",
       maxVersion: "0"
     }],
     name: "Test Addon 7",
   }, profileDir);
-  restartManager();
 
-  AddonManager.getAddonByID("addon7@tests.mozilla.org", function(a7) {
-    Assert.notEqual(a7, null);
-    Assert.ok(a7.isActive);
-    Assert.ok(a7.isCompatible);
-    Assert.ok(!a7.appDisabled);
-    Assert.ok(a7.isCompatibleWith("0", "0"));
+  await promiseRestartManager();
 
-    a7.findUpdates({
-      sawUpdate: false,
-      onNoCompatibilityUpdateAvailable(addon) {
-        ok(false, "Should have seen compatibility information");
-      },
-
-      onUpdateAvailable(addon, install) {
-        ok(false, "Should not have seen an available update");
-      },
+  let a7 = await AddonManager.getAddonByID("addon7@tests.mozilla.org");
+  notEqual(a7, null);
+  ok(a7.isActive);
+  ok(a7.isCompatible);
+  ok(!a7.appDisabled);
+  ok(a7.isCompatibleWith("0", "0"));
 
-      onUpdateFinished(addon) {
-        Assert.ok(addon.isCompatible);
-        executeSoon(check_test_13);
-      }
-    }, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, "3.0", "3.0");
-  });
-});
+  let result = await AddonTestUtils.promiseFindAddonUpdates(
+    a7, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, "3.0", "3.0");
+  ok(result.compatibilityUpdate, "Should have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
+
+  ok(a7.isCompatible);
+
+  await promiseRestartManager();
 
-check_test_13 = () => {
-  restartManager();
-  AddonManager.getAddonByID("addon7@tests.mozilla.org", function(a7) {
-    Assert.notEqual(a7, null);
-    Assert.ok(a7.isActive);
-    Assert.ok(a7.isCompatible);
-    Assert.ok(!a7.appDisabled);
+  a7 = await AddonManager.getAddonByID("addon7@tests.mozilla.org");
+  notEqual(a7, null);
+  ok(a7.isActive);
+  ok(a7.isCompatible);
+  ok(!a7.appDisabled);
 
-    a7.uninstall();
-    run_next_test();
-  });
-};
+  a7.uninstall();
+  await promiseRestartManager();
+});
 
 // Test that background update checks doesn't update an add-on that isn't
 // allowed to update automatically.
-let check_test_14;
-add_test(function run_test_14() {
-  restartManager();
-
+add_task(async function test_14() {
   // Have an add-on there that will be updated so we see some events from it
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon1@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 1",
   }, profileDir);
 
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon8@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 8",
   }, profileDir);
-  restartManager();
+
+  await promiseRestartManager();
+
+  let a8 = await AddonManager.getAddonByID("addon8@tests.mozilla.org");
+  a8.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
 
-  AddonManager.getAddonByID("addon8@tests.mozilla.org", function(a8) {
-    a8.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
-
-    // The background update check will find updates for both add-ons but only
-    // proceed to install one of them.
-    AddonManager.addInstallListener({
+  // The background update check will find updates for both add-ons but only
+  // proceed to install one of them.
+  let listener;
+  await new Promise(resolve => {
+    listener = {
       onNewInstall(aInstall) {
         let id = aInstall.existingAddon.id;
         ok((id == "addon1@tests.mozilla.org" || id == "addon8@tests.mozilla.org"),
            "Saw unexpected onNewInstall for " + id);
       },
 
       onDownloadStarted(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
       },
 
       onDownloadEnded(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
       },
 
       onDownloadFailed(aInstall) {
         ok(false, "Should not have seen onDownloadFailed event");
       },
 
       onDownloadCancelled(aInstall) {
         ok(false, "Should not have seen onDownloadCancelled event");
       },
 
       onInstallStarted(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
       },
 
       onInstallEnded(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
-        Assert.equal(aInstall.existingAddon.pendingUpgrade.install, aInstall);
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.pendingUpgrade.install, aInstall);
 
-        executeSoon(check_test_14);
+        resolve();
       },
 
       onInstallFailed(aInstall) {
         ok(false, "Should not have seen onInstallFailed event");
       },
 
       onInstallCancelled(aInstall) {
         ok(false, "Should not have seen onInstallCancelled event");
       },
-    });
-
+    };
+    AddonManager.addInstallListener(listener);
     AddonManagerInternal.backgroundUpdateCheck();
   });
-});
+  AddonManager.removeInstallListener(listener);
+
+  await promiseRestartManager();
 
-check_test_14 = () => {
-  restartManager();
-  AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                               "addon8@tests.mozilla.org"], function([a1, a8]) {
-    Assert.notEqual(a1, null);
-    Assert.equal(a1.version, "2.0");
-    a1.uninstall();
+  let a1;
+  [a1, a8] = await AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                                                   "addon8@tests.mozilla.org"]);
+  notEqual(a1, null);
+  equal(a1.version, "2.0");
+  a1.uninstall();
 
-    Assert.notEqual(a8, null);
-    Assert.equal(a8.version, "1.0");
-    a8.uninstall();
-
-    run_next_test();
-  });
-};
+  notEqual(a8, null);
+  equal(a8.version, "1.0");
+  a8.uninstall();
+  await promiseRestartManager();
+});
 
 // Test that background update checks doesn't update an add-on that is
 // pending uninstall
-let check_test_15;
-add_test(function run_test_15() {
-  restartManager();
-
+add_task(async function test_15() {
   // Have an add-on there that will be updated so we see some events from it
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon1@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 1",
   }, profileDir);
 
-  writeInstallRDFForExtension({
+  await promiseWriteInstallRDFForExtension({
     id: "addon8@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 8",
   }, profileDir);
-  restartManager();
+
+  await promiseRestartManager();
 
-  AddonManager.getAddonByID("addon8@tests.mozilla.org", function(a8) {
-    a8.uninstall();
-    Assert.ok(!hasFlag(a8.permissions, AddonManager.PERM_CAN_UPGRADE));
+  let a8 = await AddonManager.getAddonByID("addon8@tests.mozilla.org");
+  a8.uninstall();
+  ok(!hasFlag(a8.permissions, AddonManager.PERM_CAN_UPGRADE));
 
-    // The background update check will find updates for both add-ons but only
-    // proceed to install one of them.
-    AddonManager.addInstallListener({
+  // The background update check will find updates for both add-ons but only
+  // proceed to install one of them.
+  let listener;
+  await new Promise(resolve => {
+    listener = {
       onNewInstall(aInstall) {
         let id = aInstall.existingAddon.id;
         ok((id == "addon1@tests.mozilla.org" || id == "addon8@tests.mozilla.org"),
            "Saw unexpected onNewInstall for " + id);
       },
 
       onDownloadStarted(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
       },
 
       onDownloadEnded(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
       },
 
       onDownloadFailed(aInstall) {
         ok(false, "Should not have seen onDownloadFailed event");
       },
 
       onDownloadCancelled(aInstall) {
         ok(false, "Should not have seen onDownloadCancelled event");
       },
 
       onInstallStarted(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
       },
 
       onInstallEnded(aInstall) {
-        Assert.equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
-        executeSoon(check_test_15);
+        equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
+        resolve();
       },
 
       onInstallFailed(aInstall) {
         ok(false, "Should not have seen onInstallFailed event");
       },
 
       onInstallCancelled(aInstall) {
         ok(false, "Should not have seen onInstallCancelled event");
       },
-    });
-
+    };
+    AddonManager.addInstallListener(listener);
     AddonManagerInternal.backgroundUpdateCheck();
   });
+  AddonManager.removeInstallListener(listener);
+
+  await promiseRestartManager();
+
+  let a1;
+  [a1, a8] = await AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                                                "addon8@tests.mozilla.org"]);
+  notEqual(a1, null);
+  equal(a1.version, "2.0");
+  a1.uninstall();
+
+  equal(a8, null);
+  await promiseRestartManager();
 });
 
-check_test_15 = () => {
-  restartManager();
-  AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                               "addon8@tests.mozilla.org"], function([a1, a8]) {
-    Assert.notEqual(a1, null);
-    Assert.equal(a1.version, "2.0");
-    a1.uninstall();
-
-    Assert.equal(a8, null);
+add_task(async function test_16() {
+  await promiseRestartManager();
 
-    run_next_test();
-  });
-};
-
-add_test(function run_test_16() {
-  restartManager();
+  let url = "http://example.com/addons/test_install2_1.xpi";
+  let install = await AddonManager.getInstallForURL(url, null, "application/x-xpinstall");
+  await promiseCompleteInstall(install);
 
-  restartManager();
+  await promiseRestartManager();
 
-  let url = "http://localhost:" + gPort + "/addons/test_install2_1.xpi";
-  AddonManager.getInstallForURL(url, function(aInstall) {
-    aInstall.addListener({
-      onInstallEnded() {
-       executeSoon(function install_2_1_ended() {
-        restartManager();
+  let a1 = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
+  notEqual(a1.syncGUID, null);
+  let oldGUID = a1.syncGUID;
 
-        AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a1) {
-          Assert.notEqual(a1.syncGUID, null);
-          let oldGUID = a1.syncGUID;
+  let url_2 = "http://example.com/addons/test_install2_2.xpi";
+  let install_2 = await AddonManager.getInstallForURL(url_2, null, "application/x-xpinstall");
+  await promiseCompleteInstall(install_2);
 
-          let url_2 = "http://localhost:" + gPort + "/addons/test_install2_2.xpi";
-          AddonManager.getInstallForURL(url_2, function(aInstall_2) {
-            aInstall_2.addListener({
-              onInstallEnded() {
-               executeSoon(function install_2_2_ended() {
-                restartManager();
-
-                AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
-                  Assert.notEqual(a2.syncGUID, null);
-                  Assert.equal(oldGUID, a2.syncGUID);
+  await promiseRestartManager();
 
-                  a2.uninstall();
-                  run_next_test();
-                });
-               });
-              }
-            });
-            aInstall_2.install();
-          }, "application/x-xpinstall");
-        });
-       });
-      }
-    });
-    aInstall.install();
-  }, "application/x-xpinstall");
+  let a2 = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
+  notEqual(a2.syncGUID, null);
+  equal(oldGUID, a2.syncGUID);
+
+  a2.uninstall();
+  await promiseRestartManager();
 });
 
 // Test that the update check correctly observes the
 // extensions.strictCompatibility pref and compatibility overrides.
-add_test(function run_test_17() {
-  restartManager();
-
-  writeInstallRDFForExtension({
+add_task(async function test_17() {
+  await promiseWriteInstallRDFForExtension({
     id: "addon9@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "0.1",
       maxVersion: "0.2"
     }],
     name: "Test Addon 9",
   }, profileDir);
-  restartManager();
+
+  await promiseRestartManager();
 
-  AddonManager.addInstallListener({
-    onNewInstall(aInstall) {
-      equal(aInstall.existingAddon.id, "addon9@tests.mozilla.org",
-            "Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
-      Assert.equal(aInstall.version, "3.0");
-    },
-    onDownloadFailed(aInstall) {
-      AddonManager.getAddonByID("addon9@tests.mozilla.org", function(a9) {
-        a9.uninstall();
-        run_next_test();
-      });
-    }
+  let listener;
+  await new Promise(resolve => {
+    listener = {
+      onNewInstall(aInstall) {
+        equal(aInstall.existingAddon.id, "addon9@tests.mozilla.org",
+              "Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
+        equal(aInstall.version, "3.0");
+      },
+      onDownloadFailed(aInstall) {
+        resolve();
+      }
+    };
+    AddonManager.addInstallListener(listener);
+
+    Services.prefs.setCharPref(PREF_GETADDONS_BYIDS,
+                               `http://example.com/data/test_update_addons.json`);
+    Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES,
+                               `http://example.com/data/test_update_compat.json`);
+    Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
+
+    AddonManagerInternal.backgroundUpdateCheck();
   });
 
-  Services.prefs.setCharPref(PREF_GETADDONS_BYIDS,
-                             `http://localhost:${gPort}/data/test_update_addons.json`);
-  Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES,
-                             `http://localhost:${gPort}/data/test_update_compat.json`);
-  Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
+  AddonManager.removeInstallListener(listener);
 
-  AddonManagerInternal.backgroundUpdateCheck();
+  let a9 = await AddonManager.getAddonByID("addon9@tests.mozilla.org");
+  a9.uninstall();
+  await promiseRestartManager();
 });
 
 // Tests that compatibility updates are applied to addons when the updated
 // compatibility data wouldn't match with strict compatibility enabled.
-add_test(function run_test_18() {
-  restartManager();
-  writeInstallRDFForExtension({
+add_task(async function test_18() {
+  await promiseWriteInstallRDFForExtension({
     id: "addon10@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "0.1",
       maxVersion: "0.2"
     }],
     name: "Test Addon 10",
   }, profileDir);
-  restartManager();
 
-  AddonManager.getAddonByID("addon10@tests.mozilla.org", function(a10) {
-    Assert.notEqual(a10, null);
+  await promiseRestartManager();
 
-    a10.findUpdates({
-      onNoCompatibilityUpdateAvailable() {
-        ok(false, "Should have seen compatibility information");
-      },
+  let a10 = await AddonManager.getAddonByID("addon10@tests.mozilla.org");
+  notEqual(a10, null);
 
-      onUpdateAvailable() {
-        ok(false, "Should not have seen an available update");
-      },
+  let result = await AddonTestUtils.promiseFindAddonUpdates(a10);
+  ok(result.compatibilityUpdate, "Should have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
 
-      onUpdateFinished() {
-        a10.uninstall();
-        run_next_test();
-      }
-    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-  });
+  a10.uninstall();
+  await promiseRestartManager();
 });
 
 // Test that the update check correctly observes when an addon opts-in to
 // strict compatibility checking.
-add_test(function run_test_19() {
-  restartManager();
-  writeInstallRDFForExtension({
+add_task(async function test_19() {
+  await promiseWriteInstallRDFForExtension({
     id: "addon11@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "0.1",
       maxVersion: "0.2"
     }],
     name: "Test Addon 11",
   }, profileDir);
-  restartManager();
 
-  AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
-    Assert.notEqual(a11, null);
+  await promiseRestartManager();
 
-    a11.findUpdates({
-      onCompatibilityUpdateAvailable() {
-        ok(false, "Should have not have seen compatibility information");
-      },
+  let a11 = await AddonManager.getAddonByID("addon11@tests.mozilla.org");
+  notEqual(a11, null);
 
-      onUpdateAvailable() {
-        ok(false, "Should not have seen an available update");
-      },
+  let result = await AddonTestUtils.promiseFindAddonUpdates(a11);
+  ok(!result.compatibilityUpdate, "Should not have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
 
-      onUpdateFinished() {
-        a11.uninstall();
-        run_next_test();
-      }
-   }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-  });
+  a11.uninstall();
+  await promiseRestartManager();
 });
 
 // Test that the update succeeds when the update.rdf URN contains a type prefix
 // different from the add-on type
-let continue_test_20;
-add_test(function run_test_20() {
-  restartManager();
-  writeInstallRDFForExtension({
+add_task(async function test_20() {
+  await promiseWriteInstallRDFForExtension({
     id: "addon12@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
+    updateURL: "http://example.com/data/" + updateFile,
     targetApplications: [{
       id: appId,
       minVersion: "1",
       maxVersion: "1"
     }],
     name: "Test Addon 12",
   }, profileDir);
-  restartManager();
 
-  prepare_test({}, [
-    "onNewInstall",
-    "onDownloadStarted",
-    "onDownloadEnded"
-  ], continue_test_20);
+  await promiseRestartManager();
 
-  AddonManagerPrivate.backgroundUpdateCheck();
-});
+  let install = await new Promise(resolve => {
+    prepare_test({}, [
+      "onNewInstall",
+      "onDownloadStarted",
+      "onDownloadEnded"
+    ], resolve);
 
-let check_test_20;
-continue_test_20 = (install) => {
-  Assert.notEqual(install.existingAddon, null);
-  Assert.equal(install.existingAddon.id, "addon12@tests.mozilla.org");
+    AddonManagerPrivate.backgroundUpdateCheck();
+  });
+
+  notEqual(install.existingAddon, null);
+  equal(install.existingAddon.id, "addon12@tests.mozilla.org");
 
-  prepare_test({
-    "addon12@tests.mozilla.org": [
-      "onInstalling"
-    ]
-  }, [
-    "onInstallStarted",
-    "onInstallEnded",
-  ], callback_soon(check_test_20));
-};
-
-check_test_20 = (install) => {
-  Assert.equal(install.existingAddon.pendingUpgrade.install, install);
+  await new Promise(resolve => {
+    prepare_test({
+      "addon12@tests.mozilla.org": [
+        "onInstalling"
+      ]
+    }, [
+      "onInstallStarted",
+      "onInstallEnded",
+    ], resolve);
+  });
 
-  restartManager();
-  AddonManager.getAddonByID("addon12@tests.mozilla.org", function(a12) {
-    Assert.notEqual(a12, null);
-    Assert.equal(a12.version, "2.0");
-    Assert.equal(a12.type, "extension");
-    a12.uninstall();
+  equal(install.existingAddon.pendingUpgrade.install, install);
 
-    executeSoon(() => {
-      restartManager();
-      run_next_test();
-    });
-  });
-};
+  await promiseRestartManager();
+  let a12 = await AddonManager.getAddonByID("addon12@tests.mozilla.org");
+  notEqual(a12, null);
+  equal(a12.version, "2.0");
+  equal(a12.type, "extension");
+  a12.uninstall();
+  await promiseRestartManager();
+});
 
 add_task(async function cleanup() {
   let addons = await AddonManager.getAddonsByTypes(["extension"]);
 
   for (let addon of addons)
     addon.uninstall();
 
   await promiseRestartManager();
-
-  shutdownManager();
-
-  await new Promise(executeSoon);
 });
 
 // Test that background update checks work for lightweight themes
-add_test(function run_test_7() {
-  startupManager();
-
+add_task(async function test_7() {
   LightweightThemeManager.currentTheme = {
     id: "1",
     version: "1",
     name: "Test LW Theme",
     description: "A test theme",
     author: "Mozilla",
-    homepageURL: "http://localhost:" + gPort + "/data/index.html",
-    headerURL: "http://localhost:" + gPort + "/data/header.png",
-    footerURL: "http://localhost:" + gPort + "/data/footer.png",
-    previewURL: "http://localhost:" + gPort + "/data/preview.png",
-    iconURL: "http://localhost:" + gPort + "/data/icon.png",
-    updateURL: "http://localhost:" + gPort + "/data/lwtheme.js"
+    homepageURL: "http://example.com/data/index.html",
+    headerURL: "http://example.com/data/header.png",
+    footerURL: "http://example.com/data/footer.png",
+    previewURL: "http://example.com/data/preview.png",
+    iconURL: "http://example.com/data/icon.png",
+    updateURL: "http://example.com/data/lwtheme.js"
   };
 
   // XXX The lightweight theme manager strips non-https updateURLs so hack it
   // back in.
   let themes = JSON.parse(Services.prefs.getCharPref("lightweightThemes.usedThemes"));
-  Assert.equal(themes.length, 1);
-  themes[0].updateURL = "http://localhost:" + gPort + "/data/lwtheme.js";
+  equal(themes.length, 1);
+  themes[0].updateURL = "http://example.com/data/lwtheme.js";
   Services.prefs.setCharPref("lightweightThemes.usedThemes", JSON.stringify(themes));
 
   testserver.registerPathHandler("/data/lwtheme.js", function(request, response) {
     // Server will specify an expiry in one year.
     let expiry = new Date();
     expiry.setFullYear(expiry.getFullYear() + 1);
     response.setHeader("Expires", expiry.toUTCString(), false);
     response.write(JSON.stringify({
       id: "1",
       version: "2",
       name: "Updated Theme",
       description: "A test theme",
       author: "Mozilla",
-      homepageURL: "http://localhost:" + gPort + "/data/index2.html",
-      headerURL: "http://localhost:" + gPort + "/data/header.png",
-      footerURL: "http://localhost:" + gPort + "/data/footer.png",
-      previewURL: "http://localhost:" + gPort + "/data/preview.png",
-      iconURL: "http://localhost:" + gPort + "/data/icon2.png",
-      updateURL: "http://localhost:" + gPort + "/data/lwtheme.js"
+      homepageURL: "http://example.com/data/index2.html",
+      headerURL: "http://example.com/data/header.png",
+      footerURL: "http://example.com/data/footer.png",
+      previewURL: "http://example.com/data/preview.png",
+      iconURL: "http://example.com/data/icon2.png",
+      updateURL: "http://example.com/data/lwtheme.js"
     }));
   });
 
-  AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
-    Assert.notEqual(p1, null);
-    Assert.equal(p1.version, "1");
-    Assert.equal(p1.name, "Test LW Theme");
-    Assert.ok(p1.isActive);
-    Assert.equal(p1.installDate.getTime(), p1.updateDate.getTime());
+  let p1 = await AddonManager.getAddonByID("1@personas.mozilla.org");
+  notEqual(p1, null);
+  equal(p1.version, "1");
+  equal(p1.name, "Test LW Theme");
+  ok(p1.isActive);
+  equal(p1.installDate.getTime(), p1.updateDate.getTime());
 
-    // 5 seconds leeway seems like a lot, but tests can run slow and really if
-    // this is within 5 seconds it is fine. If it is going to be wrong then it
-    // is likely to be hours out at least
-    Assert.ok((Date.now() - p1.installDate.getTime()) < 5000);
+  // 5 seconds leeway seems like a lot, but tests can run slow and really if
+  // this is within 5 seconds it is fine. If it is going to be wrong then it
+  // is likely to be hours out at least
+  ok((Date.now() - p1.installDate.getTime()) < 5000);
 
-    gInstallDate = p1.installDate.getTime();
+  gInstallDate = p1.installDate.getTime();
 
+  await new Promise(resolve => {
     prepare_test({
       "1@personas.mozilla.org": [
         ["onInstalling", false],
         "onInstalled"
       ]
     }, [
       "onExternalInstall"
-    ], check_test_7);
+    ], resolve);
 
     AddonManagerInternal.backgroundUpdateCheck();
   });
-});
 
-function check_test_7() {
-  AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
-    Assert.notEqual(p1, null);
-    Assert.equal(p1.version, "2");
-    Assert.equal(p1.name, "Updated Theme");
-    Assert.equal(p1.installDate.getTime(), gInstallDate);
-    Assert.ok(p1.installDate.getTime() < p1.updateDate.getTime());
+  p1 = await AddonManager.getAddonByID("1@personas.mozilla.org");
+  notEqual(p1, null);
+  equal(p1.version, "2");
+  equal(p1.name, "Updated Theme");
+  equal(p1.installDate.getTime(), gInstallDate);
+  ok(p1.installDate.getTime() < p1.updateDate.getTime());
 
-    // 5 seconds leeway seems like a lot, but tests can run slow and really if
-    // this is within 5 seconds it is fine. If it is going to be wrong then it
-    // is likely to be hours out at least
-    Assert.ok((Date.now() - p1.updateDate.getTime()) < 5000);
+  // 5 seconds leeway seems like a lot, but tests can run slow and really if
+  // this is within 5 seconds it is fine. If it is going to be wrong then it
+  // is likely to be hours out at least
+  ok((Date.now() - p1.updateDate.getTime()) < 5000);
 
-    gInstallDate = p1.installDate.getTime();
-
-    run_next_test();
-  });
-}
+  gInstallDate = p1.installDate.getTime();
+});
 
 // Test that background update checks for lightweight themes do not use the cache
 // The update body from test 7 shouldn't be used since the cache should be bypassed.
-add_test(function() {
+add_task(async function() {
   // XXX The lightweight theme manager strips non-https updateURLs so hack it
   // back in.
   let themes = JSON.parse(Services.prefs.getCharPref("lightweightThemes.usedThemes"));
-  Assert.equal(themes.length, 1);
-  themes[0].updateURL = "http://localhost:" + gPort + "/data/lwtheme.js";
+  equal(themes.length, 1);
+  themes[0].updateURL = "http://example.com/data/lwtheme.js";
   Services.prefs.setCharPref("lightweightThemes.usedThemes", JSON.stringify(themes));
 
   testserver.registerPathHandler("/data/lwtheme.js", function(request, response) {
     response.write(JSON.stringify({
       id: "1",
       version: "3",
       name: "Updated Theme v.3",
       description: "A test theme v.3",
       author: "John Smith",
-      homepageURL: "http://localhost:" + gPort + "/data/index3.html?v=3",
-      headerURL: "http://localhost:" + gPort + "/data/header.png?v=3",
-      footerURL: "http://localhost:" + gPort + "/data/footer.png?v=3",
-      previewURL: "http://localhost:" + gPort + "/data/preview.png?v=3",
-      iconURL: "http://localhost:" + gPort + "/data/icon2.png?v=3",
-      updateURL: "https://localhost:" + gPort + "/data/lwtheme.js?v=3"
+      homepageURL: "http://example.com/data/index3.html?v=3",
+      headerURL: "http://example.com/data/header.png?v=3",
+      footerURL: "http://example.com/data/footer.png?v=3",
+      previewURL: "http://example.com/data/preview.png?v=3",
+      iconURL: "http://example.com/data/icon2.png?v=3",
+      updateURL: "https://example.com/data/lwtheme.js?v=3"
     }));
   });
 
-  AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
-    Assert.notEqual(p1, null);
-    Assert.equal(p1.version, "2");
-    Assert.equal(p1.name, "Updated Theme");
-    Assert.ok(p1.isActive);
-    Assert.equal(p1.installDate.getTime(), gInstallDate);
-    Assert.ok(p1.installDate.getTime() < p1.updateDate.getTime());
+  let p1 = await AddonManager.getAddonByID("1@personas.mozilla.org");
+  notEqual(p1, null);
+  equal(p1.version, "2");
+  equal(p1.name, "Updated Theme");
+  ok(p1.isActive);
+  equal(p1.installDate.getTime(), gInstallDate);
+  ok(p1.installDate.getTime() < p1.updateDate.getTime());
 
+  await new Promise(resolve => {
     prepare_test({
       "1@personas.mozilla.org": [
         ["onInstalling", false],
         "onInstalled"
       ]
     }, [
       "onExternalInstall"
-    ], check_test_7_cache);
+    ], resolve);
 
     AddonManagerInternal.backgroundUpdateCheck();
   });
-});
 
-function check_test_7_cache() {
-  AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
-    let currentTheme = LightweightThemeManager.currentTheme;
-    Assert.notEqual(p1, null);
-    Assert.equal(p1.version, "3");
-    Assert.equal(p1.name, "Updated Theme v.3");
-    Assert.equal(p1.description, "A test theme v.3");
-    info(JSON.stringify(p1));
-    Assert.equal(p1.creator.name, "John Smith");
-    Assert.equal(p1.homepageURL, "http://localhost:" + gPort + "/data/index3.html?v=3");
-    Assert.equal(p1.screenshots[0].url, "http://localhost:" + gPort + "/data/preview.png?v=3");
-    Assert.equal(p1.iconURL, "http://localhost:" + gPort + "/data/icon2.png?v=3");
-    Assert.equal(currentTheme.headerURL, "http://localhost:" + gPort + "/data/header.png?v=3");
-    Assert.equal(currentTheme.footerURL, "http://localhost:" + gPort + "/data/footer.png?v=3");
-    Assert.equal(currentTheme.updateURL, "https://localhost:" + gPort + "/data/lwtheme.js?v=3");
+  p1 = await AddonManager.getAddonByID("1@personas.mozilla.org");
+  let currentTheme = LightweightThemeManager.currentTheme;
+  notEqual(p1, null);
+  equal(p1.version, "3");
+  equal(p1.name, "Updated Theme v.3");
+  equal(p1.description, "A test theme v.3");
+  info(JSON.stringify(p1));
+  equal(p1.creator.name, "John Smith");
+  equal(p1.homepageURL, "http://example.com/data/index3.html?v=3");
+  equal(p1.screenshots[0].url, "http://example.com/data/preview.png?v=3");
+  equal(p1.iconURL, "http://example.com/data/icon2.png?v=3");
+  equal(currentTheme.headerURL, "http://example.com/data/header.png?v=3");
+  equal(currentTheme.footerURL, "http://example.com/data/footer.png?v=3");
+  equal(currentTheme.updateURL, "https://example.com/data/lwtheme.js?v=3");
 
-    Assert.equal(p1.installDate.getTime(), gInstallDate);
-    Assert.ok(p1.installDate.getTime() < p1.updateDate.getTime());
-
-    run_next_test();
-  });
-}
+  equal(p1.installDate.getTime(), gInstallDate);
+  ok(p1.installDate.getTime() < p1.updateDate.getTime());
+});
 
 // Test that the update check returns nothing for addons in locked install
 // locations.
-add_test(async function run_test_locked_install() {
+add_task(async function run_test_locked_install() {
   const lockedDir = gProfD.clone();
   lockedDir.append("locked_extensions");
   registerDirectory("XREAppFeat", lockedDir);
 
   await promiseShutdownManager();
 
-  writeInstallRDFToXPI({
+  await promiseWriteInstallRDFToXPI({
     id: "addon13@tests.mozilla.org",
     version: "1.0",
-    updateURL: "http://localhost:" + gPort + "/data/test_update.json",
+    updateURL: "http://example.com/data/test_update.json",
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "0.1",
       maxVersion: "0.2"
     }],
     name: "Test Addon 13",
   }, lockedDir);
 
   let validAddons = { "system": ["addon13@tests.mozilla.org"] };
   await overrideBuiltIns(validAddons);
 
   await promiseStartupManager();
 
-  AddonManager.getAddonByID("addon13@tests.mozilla.org", function(a13) {
-    Assert.notEqual(a13, null);
-
-    a13.findUpdates({
-      onCompatibilityUpdateAvailable() {
-        ok(false, "Should have not have seen compatibility information");
-      },
-
-      onUpdateAvailable() {
-        ok(false, "Should not have seen an available update");
-      },
+  let a13 = await AddonManager.getAddonByID("addon13@tests.mozilla.org");
+  notEqual(a13, null);
 
-      onUpdateFinished() {
-        ok(true, "Should have seen an onUpdateFinished");
-      }
-    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-  });
+  let result = await AddonTestUtils.promiseFindAddonUpdates(a13);
+  ok(!result.compatibilityUpdate, "Should not have seen a compatibility update");
+  ok(!result.updateAvailable, "Should not have seen a version update");
 
-  AddonManager.getAllInstalls(aInstalls => {
-    Assert.equal(aInstalls.length, 0);
-  });
-  run_next_test();
+  let installs = await AddonManager.getAllInstalls();
+  equal(installs.length, 0);
 });
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -264,17 +264,17 @@ run-if = addon_signing
 fail-if = os == "android"
 [test_syncGUID.js]
 [test_strictcompatibility.js]
 [test_types.js]
 [test_undouninstall.js]
 skip-if = os == "win" # Bug 1358846
 [test_update.js]
 # Bug 676992: test consistently hangs on Android; bug 1330227 - linux
-skip-if = os == "android" || os == "linux"
+skip-if = os == "android"
 [test_update_rdf.js]
 [test_update_webextensions.js]
 tags = webextensions
 [test_updateCancel.js]
 [test_update_ignorecompat.js]
 skip-if = true # Bug 676922 Bug 1437697
 [test_updatecheck.js]
 # Bug 676992: test consistently hangs on Android