Bug 857456 Part 3: Convert (non-) strict compatibility tests to use an external extension loader r=kmag
authorAndrew Swan <aswan@mozilla.com>
Sat, 24 Nov 2018 20:27:20 -0800
changeset 505277 e3b6db3b34ab06b60ab5b0f9d8d5695df754b7e1
parent 505276 061b97e02ede2133f50956feba25fd8798745347
child 505278 0c715a8f0170fd4b19c4281c269c03f872090648
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs857456
milestone65.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 857456 Part 3: Convert (non-) strict compatibility tests to use an external extension loader r=kmag The addon manager has a bunch of handling for "strict compatibility" -- an option for individual profiles and addons to control exactly how compatibility is handled. However, WebExtensions don't use or expose this feature. We want to retain this capability for other projects that use the addon manager but since it cannot be tested with WebExtensions, this patch converts its tests to use the new extension loading hook added in the previous patch.
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/internal/XPIDatabase.jsm
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/test/xpcshell/data/test_update.json
toolkit/mozapps/extensions/test/xpcshell/data/test_updatecompatmode_ignore.json
toolkit/mozapps/extensions/test/xpcshell/data/test_updatecompatmode_normal.json
toolkit/mozapps/extensions/test/xpcshell/data/test_updatecompatmode_strict.json
toolkit/mozapps/extensions/test/xpcshell/head_compat.js
toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
toolkit/mozapps/extensions/test/xpcshell/test_onPropertyChanged_appDisabled.js
toolkit/mozapps/extensions/test/xpcshell/test_strictcompatibility.js
toolkit/mozapps/extensions/test/xpcshell/test_update_compatmode.js
toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js
toolkit/mozapps/extensions/test/xpcshell/test_upgrade.js
toolkit/mozapps/extensions/test/xpcshell/test_webextension_install_syntax_error.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -667,19 +667,25 @@ var AddonTestUtils = {
   overrideCertDB() {
     let verifyCert = async (file, result, cert, callback) => {
       if (result == Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED &&
           !this.useRealCertChecks && callback.wrappedJSObject) {
         // Bypassing XPConnect allows us to create a fake x509 certificate from JS
         callback = callback.wrappedJSObject;
 
         try {
-          let manifestURI = this.getManifestURI(file);
-
-          let id = await this.getIDFromManifest(manifestURI);
+          let id;
+          try {
+            let manifestURI = this.getManifestURI(file);
+            id = await this.getIDFromManifest(manifestURI);
+          } catch (err) {
+            if (file.leafName.endsWith(".xpi")) {
+              id = file.leafName.slice(0, -4);
+            }
+          }
 
           let fakeCert = {commonName: id};
           if (this.usePrivilegedSignatures) {
             let privileged = typeof this.usePrivilegedSignatures == "function" ?
                              this.usePrivilegedSignatures(id) : this.usePrivilegedSignatures;
             if (privileged === "system") {
               fakeCert.organizationalUnit = "Mozilla Components";
             } else if (privileged) {
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -90,21 +90,16 @@ const DEFAULT_THEME_ID = "default-theme@
 
 // Properties to cache and reload when an addon installation is pending
 const PENDING_INSTALL_METADATA =
     ["syncGUID", "targetApplications", "userDisabled", "softDisabled",
      "existingAddonID", "sourceURI", "releaseNotesURI", "installDate",
      "updateDate", "applyBackgroundUpdates", "compatibilityOverrides",
      "installTelemetryInfo"];
 
-const COMPATIBLE_BY_DEFAULT_TYPES = {
-  extension: true,
-  dictionary: true,
-};
-
 // Properties to save in JSON file
 const PROP_JSON_FIELDS = ["id", "syncGUID", "version", "type",
                           "loader", "updateURL", "optionsURL",
                           "optionsType", "optionsBrowserStyle", "aboutURL",
                           "defaultLocale", "visible", "active", "userDisabled",
                           "appDisabled", "pendingUninstall", "installDate",
                           "updateDate", "applyBackgroundUpdates", "path",
                           "skinnable", "sourceURI", "releaseNotesURI",
@@ -440,20 +435,18 @@ class AddonInternal {
     if (app.id == Services.appinfo.ID)
       version = aAppVersion;
     else if (app.id == TOOLKIT_ID)
       version = aPlatformVersion;
 
     // Only extensions and dictionaries can be compatible by default; themes
     // and language packs always use strict compatibility checking.
     // Dictionaries are compatible by default unless requested by the dictinary.
-    if (this.type in COMPATIBLE_BY_DEFAULT_TYPES &&
-        !this.strictCompatibility &&
-        (!AddonManager.strictCompatibility ||
-         this.type == "dictionary")) {
+    if (!this.strictCompatibility &&
+        (!AddonManager.strictCompatibility || this.type == "dictionary")) {
 
       // The repository can specify compatibility overrides.
       // Note: For now, only blacklisting is supported by overrides.
       let overrides = AddonRepository.getCompatibilityOverridesSync(this.id);
       if (overrides) {
         let override = AddonRepository.findMatchingCompatOverride(this.version,
                                                                   overrides);
         if (override) {
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -149,21 +149,16 @@ const PREF_INSTALL_REQUIREBUILTINCERTS =
 const KEY_PROFILEDIR                  = "ProfD";
 const KEY_TEMPDIR                     = "TmpD";
 
 const KEY_APP_PROFILE                 = "app-profile";
 
 const DIR_STAGE                       = "staged";
 const DIR_TRASH                       = "trash";
 
-const COMPATIBLE_BY_DEFAULT_TYPES = {
-  extension: true,
-  dictionary: true,
-};
-
 // This is a random number array that can be used as "salt" when generating
 // an automatic ID based on the directory path of an add-on. It will prevent
 // someone from creating an ID for a permanent add-on that could be replaced
 // by a temporary add-on (because that would be confusing, I guess).
 const TEMP_INSTALL_ID_GEN_SESSION =
   new Uint8Array(Float64Array.of(Math.random()).buffer);
 
 const MSG_JAR_FLUSH = "AddonJarFlush";
@@ -2423,18 +2418,17 @@ UpdateChecker.prototype = {
     this.addon._updateCheck = null;
     let AUC = AddonUpdateChecker;
     let ignoreMaxVersion = false;
     // Ignore strict compatibility for dictionaries by default.
     let ignoreStrictCompat = (this.addon.type == "dictionary");
     if (!AddonManager.checkCompatibility) {
       ignoreMaxVersion = true;
       ignoreStrictCompat = true;
-    } else if (this.addon.type in COMPATIBLE_BY_DEFAULT_TYPES &&
-               !AddonManager.strictCompatibility &&
+    } else if (!AddonManager.strictCompatibility &&
                !this.addon.strictCompatibility) {
       ignoreMaxVersion = true;
     }
 
     // Always apply any compatibility update for the current version
     let compatUpdate = AUC.getCompatibilityUpdate(aUpdates, this.addon.version,
                                                   this.syncCompatibility,
                                                   null, null,
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_update.json
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_update.json
@@ -114,94 +114,16 @@
               "strict_min_version": "1",
               "advisory_max_version": "1"
             }
           }
         }
       ]
     },
 
-    "addon9@tests.mozilla.org": {
-      "updates": [
-        {
-          "version": "2.0",
-          "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://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://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://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://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://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://example.com/addons/test_update12.xpi",
           "applications": {
             "gecko": {
               "strict_min_version": "1",
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_updatecompatmode_ignore.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "addons": {
-    "compatmode-ignore@tests.mozilla.org": {
-      "updates": [
-        {
-          "applications": {
-            "gecko": {
-              "strict_min_version": "1",
-              "advisory_max_version": "2"
-            }
-          },
-          "version": "2.0",
-          "update_link": "https://example.com/addons/test1.xpi"
-        }
-      ]
-    }
-  }
-}
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_updatecompatmode_normal.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "addons": {
-    "compatmode-normal@tests.mozilla.org": {
-      "updates": [
-        {
-          "applications": {
-            "gecko": {
-              "strict_min_version": "1",
-              "advisory_max_version": "2"
-            }
-          },
-          "version": "2.0",
-          "update_link": "https://example.com/addons/test1.xpi"
-        }
-      ]
-    }
-  }
-}
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_updatecompatmode_strict.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "addons": {
-    "compatmode-strict@tests.mozilla.org": {
-      "updates": [
-        {
-          "applications": {
-            "gecko": {
-              "strict_min_version": "1",
-              "advisory_max_version": "2"
-            }
-          },
-          "version": "2.0",
-          "update_link": "https://example.com/addons/test1.xpi"
-        }
-      ]
-    }
-  }
-}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_compat.js
@@ -0,0 +1,48 @@
+//
+// This file provides helpers for tests of addons that use strictCompatibility.
+// Since WebExtensions cannot opt out of strictCompatibility, we add a
+// simple extension loader that lets tests directly set AddonInternal
+// properties (including strictCompatibility)
+//
+
+/* import-globals-from head_addons.js */
+
+const MANIFEST = "compat_manifest.json";
+
+AddonManager.addExternalExtensionLoader({
+  name: "compat-test",
+  manifestFile: MANIFEST,
+  async loadManifest(pkg) {
+    // XPIDatabase.jsm gets unloaded in AddonTestUtils when the
+    // addon manager is restarted.  Work around that by just importing
+    // it every time we need to create an AddonInternal.
+    ChromeUtils.import("resource://gre/modules/addons/XPIDatabase.jsm");
+    /* globals AddonInternal */
+    let addon = new AddonInternal();
+    let manifest = JSON.parse(await pkg.readString(MANIFEST));
+    Object.assign(addon, manifest);
+    return addon;
+  },
+  loadScope(addon, file) {
+    return {
+      install() {},
+      uninstall() {},
+      startup() {},
+      shutdonw() {},
+    };
+  },
+});
+
+const DEFAULTS = {
+  defaultLocale: {},
+  locales: [],
+  targetPlatforms: [],
+  type: "extension",
+  version: "1.0",
+};
+
+function createAddon(manifest) {
+  return AddonTestUtils.createTempXPIFile({
+    [MANIFEST]: Object.assign({}, DEFAULTS, manifest),
+  });
+}
--- a/toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
@@ -2,33 +2,25 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests compatibility overrides, for when strict compatibility checking is
 // disabled. See bug 693906.
 
 
 const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
 
-ChromeUtils.import("resource://testing-common/httpd.js");
-var gServer = new HttpServer();
-gServer.start(-1);
-gPort = gServer.identity.primaryPort;
-
-const PORT            = gPort;
-const BASE_URL        = "http://localhost:" + PORT;
+let testserver = createHttpServer({hosts: ["example.com"]});
 
 const GETADDONS_RESPONSE = {
   next: null,
   previous: null,
   results: [],
 };
-gServer.registerPathHandler("/addons.json", (request, response) => {
-  response.setHeader("content-type", "application/json");
-  response.write(JSON.stringify(GETADDONS_RESPONSE));
-});
+
+AddonTestUtils.registerJSON(testserver, "/addons.json", GETADDONS_RESPONSE);
 
 const COMPAT_RESPONSE = {
   next: null,
   previous: null,
   results: [
     {
       addon_guid: "addon3@tests.mozilla.org",
       version_ranges: [
@@ -175,242 +167,184 @@ const COMPAT_RESPONSE = {
               max_version: "2",
             },
           ],
         },
       ],
     },
   ],
 };
-gServer.registerPathHandler("/compat.json", (request, response) => {
-  response.setHeader("content-type", "application/json");
-  response.write(JSON.stringify(COMPAT_RESPONSE));
-});
+
+AddonTestUtils.registerJSON(testserver, "/compat.json", COMPAT_RESPONSE);
 
 Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
 Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
-Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, `${BASE_URL}/addons.json`);
-Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, `${BASE_URL}/compat.json`);
-
+Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, "http://example.com/addons.json");
+Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, "http://example.com/compat.json");
 
-// Not hosted, no overrides
-var addon1 = {
-  id: "addon1@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 1",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+const ADDONS = [
+  // Not hosted, no overrides
+  {
+    manifest:  {
+      id: "addon1@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: true,
+    overrides: 0,
+  },
 
-// Hosted, no overrides
-var addon2 = {
-  id: "addon2@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 2",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Hosted, no overrides
+  {
+    manifest: {
+      id: "addon2@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: true,
+    overrides: 0,
+  },
 
-// Hosted, matching override
-var addon3 = {
-  id: "addon3@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 3",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Hosted, matching override
+  {
+    manifest: {
+      id: "addon3@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: false,
+    overrides: 1,
+  },
 
-// Hosted, matching override, wouldn't be compatible if strict checking is enabled
-var addon4 = {
-  id: "addon4@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 4",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "0.1",
-    maxVersion: "0.2",
-  }],
-};
+  // Hosted, matching override,
+  // wouldn't be compatible if strict checking is enabled
+  {
+    manifest: {
+      id: "addon4@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "0.1",
+        maxVersion: "0.2",
+      }],
+    },
+    compatible: false,
+    overrides: 1,
+  },
 
-// Hosted, app ID doesn't match in override
-var addon5 = {
-  id: "addon5@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 5",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Hosted, app ID doesn't match in override
+  {
+    manifest: {
+      id: "addon5@tests.mozilla.org",
+      version: "1.0",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: true,
+    overrides: 0,
+  },
 
-// Hosted, addon version range doesn't match in override
-var addon6 = {
-  id: "addon6@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 6",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Hosted, addon version range doesn't match in override
+  {
+    manifest: {
+      id: "addon6@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: true,
+    overrides: 1,
+  },
 
-// Hosted, app version range doesn't match in override
-var addon7 = {
-  id: "addon7@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 7",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Hosted, app version range doesn't match in override
+  {
+    manifest: {
+      id: "addon7@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: true,
+    overrides: 1,
+  },
 
-// Hosted, multiple overrides
-var addon8 = {
-  id: "addon8@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 8",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Hosted, multiple overrides
+  {
+    manifest: {
+      id: "addon8@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: false,
+    overrides: 3,
+  },
 
-// Not hosted, matching override
-var addon9 = {
-  id: "addon9@tests.mozilla.org",
-  version: "1.0",
-  name: "Test addon 9",
-  bootstrap: true,
-  targetApplications: [{
-    id: "xpcshell@tests.mozilla.org",
-    minVersion: "1",
-    maxVersion: "1",
-  }],
-};
+  // Not hosted, matching override
+  {
+    manifest: {
+      id: "addon9@tests.mozilla.org",
+      targetApplications: [{
+        id: "xpcshell@tests.mozilla.org",
+        minVersion: "1",
+        maxVersion: "1",
+      }],
+    },
+    compatible: false,
+    overrides: 1,
+  },
+];
 
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
-
-async function run_test() {
-  do_test_pending();
+add_task(async function run_tests() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2");
 
-  await promiseWriteInstallRDFForExtension(addon1, profileDir);
-  await promiseWriteInstallRDFForExtension(addon2, profileDir);
-  await promiseWriteInstallRDFForExtension(addon3, profileDir);
-  await promiseWriteInstallRDFForExtension(addon4, profileDir);
-  await promiseWriteInstallRDFForExtension(addon5, profileDir);
-  await promiseWriteInstallRDFForExtension(addon6, profileDir);
-  await promiseWriteInstallRDFForExtension(addon7, profileDir);
-  await promiseWriteInstallRDFForExtension(addon8, profileDir);
-  await promiseWriteInstallRDFForExtension(addon9, profileDir);
-
+  for (let addon of ADDONS) {
+    let xpi = await createAddon(addon.manifest);
+    await manuallyInstall(xpi, AddonTestUtils.profileExtensions,
+                          addon.manifest.id);
+  }
   await promiseStartupManager();
 
-  AddonManagerInternal.backgroundUpdateCheck().then(run_test_1);
-}
-
-function end_test() {
-  gServer.stop(do_test_finished);
-}
-
-async function check_compat_status(aCallback) {
-  let [a1, a2, a3, a4, a5, a6, a7, a8, a9] = await 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",
-                                                                                "addon7@tests.mozilla.org",
-                                                                                "addon8@tests.mozilla.org",
-                                                                                "addon9@tests.mozilla.org"]);
-  Assert.notEqual(a1, null);
-  Assert.equal(AddonRepository.getCompatibilityOverridesSync(a1.id), null);
-  Assert.ok(a1.isCompatible);
-  Assert.ok(!a1.appDisabled);
-
-  Assert.notEqual(a2, null);
-  Assert.equal(AddonRepository.getCompatibilityOverridesSync(a2.id), null);
-  Assert.ok(a2.isCompatible);
-  Assert.ok(!a2.appDisabled);
-
-  Assert.notEqual(a3, null);
-  let overrides = AddonRepository.getCompatibilityOverridesSync(a3.id);
-  Assert.notEqual(overrides, null);
-  Assert.equal(overrides.length, 1);
-  Assert.ok(!a3.isCompatible);
-  Assert.ok(a3.appDisabled);
-
-  Assert.notEqual(a4, null);
-  overrides = AddonRepository.getCompatibilityOverridesSync(a4.id);
-  Assert.notEqual(overrides, null);
-  Assert.equal(overrides.length, 1);
-  Assert.ok(!a4.isCompatible);
-  Assert.ok(a4.appDisabled);
+  await AddonManagerInternal.backgroundUpdateCheck();
 
-  Assert.notEqual(a5, null);
-  Assert.equal(AddonRepository.getCompatibilityOverridesSync(a5.id), null);
-  Assert.ok(a5.isCompatible);
-  Assert.ok(!a5.appDisabled);
-
-  Assert.notEqual(a6, null);
-  overrides = AddonRepository.getCompatibilityOverridesSync(a6.id);
-  Assert.notEqual(overrides, null);
-  Assert.equal(overrides.length, 1);
-  Assert.ok(a6.isCompatible);
-  Assert.ok(!a6.appDisabled);
-
-  Assert.notEqual(a7, null);
-  overrides = AddonRepository.getCompatibilityOverridesSync(a7.id);
-  Assert.notEqual(overrides, null);
-  Assert.equal(overrides.length, 1);
-  Assert.ok(a7.isCompatible);
-  Assert.ok(!a7.appDisabled);
+  async function check() {
+    for (let info of ADDONS) {
+      let {id} = info.manifest;
+      let addon = await promiseAddonByID(id);
+      Assert.notEqual(addon, null, `Found ${id}`);
+      let overrides = AddonRepository.getCompatibilityOverridesSync(id);
+      if (info.overrides === 0) {
+        Assert.equal(overrides, null, `Got no overrides for ${id}`);
+      } else {
+        Assert.notEqual(overrides, null, `Got overrides for ${id}`);
+        Assert.equal(overrides.length, info.overrides,
+                     `Got right number of overrides for ${id}`);
+      }
+      Assert.equal(addon.isCompatible, info.compatible,
+                   `Got expected compatibility for ${id}`);
+      Assert.equal(addon.appDisabled, !info.compatible,
+                   `Got expected appDisabled for ${id}`);
+    }
+  }
 
-  Assert.notEqual(a8, null);
-  overrides = AddonRepository.getCompatibilityOverridesSync(a8.id);
-  Assert.notEqual(overrides, null);
-  Assert.equal(overrides.length, 3);
-  Assert.ok(!a8.isCompatible);
-  Assert.ok(a8.appDisabled);
-
-  Assert.notEqual(a9, null);
-  overrides = AddonRepository.getCompatibilityOverridesSync(a9.id);
-  Assert.notEqual(overrides, null);
-  Assert.equal(overrides.length, 1);
-  Assert.ok(!a9.isCompatible);
-  Assert.ok(a9.appDisabled);
+  await check();
 
-  executeSoon(aCallback);
-}
+  await promiseRestartManager();
 
-function run_test_1() {
-  info("Run test 1");
-  check_compat_status(run_test_2);
-}
-
-async function run_test_2() {
-  info("Run test 2");
-  await promiseRestartManager();
-  check_compat_status(end_test);
-}
+  await check();
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/test_onPropertyChanged_appDisabled.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_onPropertyChanged_appDisabled.js
@@ -1,64 +1,45 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
-
-async function run_test() {
-  do_test_pending();
+const ID = "addon1@tests.mozilla.org";
+add_task(async function run_test() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
-  await promiseWriteInstallRDFForExtension({
-    id: "addon1@tests.mozilla.org",
-    version: "1.0",
-    name: "Test 1",
-    bootstrap: true,
+  let xpi = createAddon({
+    id: ID,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "0.1",
       maxVersion: "0.2",
     }],
-  }, profileDir);
-
-  await promiseStartupManager();
+  });
+  await manuallyInstall(xpi, AddonTestUtils.profileExtensions, ID);
 
   AddonManager.strictCompatibility = false;
+  await promiseStartupManager();
 
-  let aAddon = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
-  Assert.notEqual(aAddon, null);
-  await aAddon.disable();
-  executeSoon(run_test_1);
-}
+  let addon = await AddonManager.getAddonByID(ID);
+  Assert.notEqual(addon, null);
+  await addon.disable();
 
-async function run_test_1() {
-  await promiseRestartManager();
-  let aAddon = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
-  Assert.notEqual(aAddon, null);
-  Assert.ok(aAddon.userDisabled);
-  Assert.ok(!aAddon.isActive);
-  Assert.ok(!aAddon.appDisabled);
+  Assert.ok(addon.userDisabled);
+  Assert.ok(!addon.isActive);
+  Assert.ok(!addon.appDisabled);
+
+  let promise = promiseAddonEvent("onPropertyChanged");
+  AddonManager.strictCompatibility = true;
+  let [, properties] = await promise;
 
-  prepare_test({
-    "addon1@tests.mozilla.org": [
-      ["onPropertyChanged", ["appDisabled"]],
-    ],
-  }, [], run_test_2);
-
-  AddonManager.strictCompatibility = true;
-}
+  Assert.deepEqual(properties, ["appDisabled"],
+                   "Got onPropertyChanged for appDisabled");
+  Assert.ok(addon.appDisabled);
 
-async function run_test_2() {
-  let aAddon = await AddonManager.getAddonByID("addon1@tests.mozilla.org");
-  Assert.notEqual(aAddon, null);
-  Assert.ok(aAddon.userDisabled);
-  Assert.ok(!aAddon.isActive);
-  Assert.ok(aAddon.appDisabled);
+  promise = promiseAddonEvent("onPropertyChanged");
+  AddonManager.strictCompatibility = false;
+  [, properties] = await promise;
 
-  prepare_test({
-    "addon1@tests.mozilla.org": [
-      ["onPropertyChanged", ["appDisabled"]],
-    ],
-  }, [], callback_soon(do_test_finished));
+  Assert.deepEqual(properties, ["appDisabled"],
+                   "Got onPropertyChanged for appDisabled");
+  Assert.ok(!addon.appDisabled);
+});
 
-  AddonManager.strictCompatibility = false;
-}
--- a/toolkit/mozapps/extensions/test/xpcshell/test_strictcompatibility.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_strictcompatibility.js
@@ -3,178 +3,122 @@
 
 // Tests AddonManager.strictCompatibility and it's related preference,
 // extensions.strictCompatibility, and the strictCompatibility option in
 // install.rdf
 
 
 // The `compatbile` array defines which of the tests below the add-on
 // should be compatible in. It's pretty gross.
-const ADDONS = {
+const ADDONS = [
   // Always compatible
-  "addon1@tests.mozilla.org": {
-    "install.rdf": {
+  {
+    manifest: {
       id: "addon1@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 1",
-      bootstrap: true,
       targetApplications: [{
         id: "xpcshell@tests.mozilla.org",
         minVersion: "1",
         maxVersion: "1",
       }],
     },
-    expected: {
-      strictCompatibility: false,
-    },
     compatible: {
       nonStrict: true,
       strict: true,
     },
   },
 
   // Incompatible in strict compatibility mode
-  "addon2@tests.mozilla.org": {
-    "install.rdf": {
+  {
+    manifest: {
       id: "addon2@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 2",
-      bootstrap: true,
       targetApplications: [{
         id: "xpcshell@tests.mozilla.org",
         minVersion: "0.7",
         maxVersion: "0.8",
       }],
     },
-    expected: {
-      strictCompatibility: false,
-    },
     compatible: {
       nonStrict: true,
       strict: false,
     },
   },
 
   // Opt-in to strict compatibility - always incompatible
-  "addon4@tests.mozilla.org": {
-    "install.rdf": {
-      id: "addon4@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 4",
-      bootstrap: true,
+  {
+    manifest: {
+      id: "addon3@tests.mozilla.org",
       strictCompatibility: true,
       targetApplications: [{
         id: "xpcshell@tests.mozilla.org",
         minVersion: "0.8",
         maxVersion: "0.9",
       }],
     },
-    expected: {
-      strictCompatibility: true,
-    },
     compatible: {
       nonStrict: false,
       strict: false,
     },
   },
 
   // Addon from the future - would be marked as compatibile-by-default,
   // but minVersion is higher than the app version
-  "addon5@tests.mozilla.org": {
-    "install.rdf": {
-      id: "addon5@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 5",
-      bootstrap: true,
+  {
+    manifest: {
+      id: "addon4@tests.mozilla.org",
       targetApplications: [{
         id: "xpcshell@tests.mozilla.org",
         minVersion: "3",
         maxVersion: "5",
       }],
     },
-    expected: {
-      strictCompatibility: false,
-    },
     compatible: {
       nonStrict: false,
       strict: false,
     },
   },
 
-  // Extremely old addon - maxVersion is less than the minimum compat version
-  // set in extensions.minCompatibleVersion
-  "addon6@tests.mozilla.org": {
-    "install.rdf": {
-      id: "addon6@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 6",
-      bootstrap: true,
-      targetApplications: [{
-        id: "xpcshell@tests.mozilla.org",
-        minVersion: "0.1",
-        maxVersion: "0.2",
-      }],
-    },
-    expected: {
-      strictCompatibility: false,
-    },
-    compatible: {
-      nonStrict: true,
-      strict: false,
-    },
-  },
-
   // Dictionary - compatible even in strict compatibility mode
-  "addon7@tests.mozilla.org": {
-    "install.rdf": {
-      id: "addon7@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 7",
-      type: "64",
+  {
+    manifest: {
+      id: "addon5@tests.mozilla.org",
+      type: "dictionary",
       targetApplications: [{
         id: "xpcshell@tests.mozilla.org",
         minVersion: "0.8",
         maxVersion: "0.9",
       }],
     },
-    expected: {
-      strictCompatibility: false,
-    },
     compatible: {
       nonStrict: true,
       strict: true,
     },
   },
-};
-
-const IDS = Object.keys(ADDONS);
-
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
+];
 
 async function checkCompatStatus(strict, index) {
   info(`Checking compat status for test ${index}\n`);
 
   equal(AddonManager.strictCompatibility, strict);
 
-  let addons = await getAddons(IDS);
-  for (let [id, addon] of Object.entries(ADDONS)) {
-    checkAddon(id, addons.get(id), {
-      ...addon.expected,
-      isCompatible: addon.compatible[index],
-      appDisabled: !addon.compatible[index],
+  for (let test of ADDONS) {
+    let {id} = test.manifest;
+    let addon = await promiseAddonByID(id);
+    checkAddon(id, addon, {
+      isCompatible: test.compatible[index],
+      appDisabled: !test.compatible[index],
     });
   }
 }
 
 add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
-  for (let addon of Object.values(ADDONS)) {
-    await promiseWriteInstallRDFForExtension(addon["install.rdf"], profileDir);
+  for (let addon of ADDONS) {
+    let xpi = await createAddon(addon.manifest);
+    await manuallyInstall(xpi, AddonTestUtils.profileExtensions, addon.manifest.id);
   }
 
   await promiseStartupManager();
 });
 
 add_task(async function test_1() {
   info("Test 1");
   Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
@@ -186,110 +130,99 @@ add_task(async function test_1() {
 add_task(async function test_2() {
   info("Test 2");
   Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, true);
   await checkCompatStatus(true, "strict");
   await promiseRestartManager();
   await checkCompatStatus(true, "strict");
 });
 
-const CHECK_COMPAT_ADDONS = {
-  "cc-addon1@tests.mozilla.org": {
-    "install.rdf": {
-      // Cannot be enabled as it has no target app info for the applciation
+const CHECK_COMPAT_ADDONS = [
+  // Cannot be enabled as it has no target app info for the applciation
+  {
+    manifest: {
       id: "cc-addon1@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 1",
-      bootstrap: true,
       targetApplications: [{
         id: "unknown@tests.mozilla.org",
         minVersion: "1",
         maxVersion: "1",
       }],
     },
     compatible: false,
     canOverride: false,
   },
 
-  "cc-addon2@tests.mozilla.org": {
-    "install.rdf": {
-      // Always appears incompatible but can be enabled if compatibility checking is
-      // disabled
+
+  // Always appears incompatible but can be enabled if compatibility checking is
+  // disabled
+  {
+    manifest: {
       id: "cc-addon2@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 2",
-      bootstrap: true,
       targetApplications: [{
         id: "toolkit@mozilla.org",
         minVersion: "1",
         maxVersion: "1",
       }],
     },
     compatible: false,
     canOverride: true,
   },
 
-  "cc-addon4@tests.mozilla.org": {
-    "install.rdf": {
-      // Always compatible and enabled
-      id: "cc-addon4@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 4",
-      bootstrap: true,
+  // Always compatible and enabled
+  {
+    manifest: {
+      id: "cc-addon3@tests.mozilla.org",
       targetApplications: [{
         id: "toolkit@mozilla.org",
         minVersion: "1",
         maxVersion: "2",
       }],
     },
     compatible: true,
   },
 
-  "cc-addon5@tests.mozilla.org": {
-    "install.rdf": {
-      // Always compatible and enabled
-      id: "cc-addon5@tests.mozilla.org",
-      version: "1.0",
-      name: "Test 5",
-      bootstrap: true,
+  // Always compatible and enabled
+  {
+    manifest: {
+      id: "cc-addon4@tests.mozilla.org",
       targetApplications: [{
         id: "xpcshell@tests.mozilla.org",
         minVersion: "1",
         maxVersion: "3",
       }],
     },
     compatible: true,
   },
-};
-
-const CHECK_COMPAT_IDS = Object.keys(CHECK_COMPAT_ADDONS);
+];
 
 async function checkCompatOverrides(overridden) {
-  let addons = await getAddons(CHECK_COMPAT_IDS);
-
-  for (let [id, addon] of Object.entries(CHECK_COMPAT_ADDONS)) {
-    checkAddon(id, addons.get(id), {
-      isCompatible: addon.compatible,
-      isActive: addon.compatible || (overridden && addon.canOverride),
+  for (let test of CHECK_COMPAT_ADDONS) {
+    let {id} = test.manifest;
+    let addon = await promiseAddonByID(id);
+    checkAddon(id, addon, {
+      isCompatible: test.compatible,
+      isActive: test.compatible || (overridden && test.canOverride),
     });
   }
 }
 
 var gIsNightly;
 
 add_task(async function setupCheckCompat() {
   gIsNightly = isNightlyChannel();
 
   Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, true);
 
   Object.assign(AddonTestUtils.appInfo,
                 {version: "2.2.3", platformVersion: "2"});
 
-  for (let addon of Object.values(CHECK_COMPAT_ADDONS)) {
-    await promiseWriteInstallRDFForExtension(addon["install.rdf"], profileDir);
+  for (let addon of CHECK_COMPAT_ADDONS) {
+    let {manifest} = addon;
+    let xpi = await createAddon(manifest);
+    await manuallyInstall(xpi, AddonTestUtils.profileExtensions, manifest.id);
   }
   await promiseRestartManager("2.2.3");
 });
 
 // Tests that with compatibility checking enabled we see the incompatible
 // add-ons disabled
 add_task(async function test_compat_overrides_1() {
   await checkCompatOverrides(false);
@@ -324,8 +257,9 @@ add_task(async function test_compat_over
   if (gIsNightly)
     Services.prefs.setBoolPref("extensions.checkCompatibility.nightly", true);
   else
     Services.prefs.setBoolPref("extensions.checkCompatibility.2.1a", true);
   await promiseRestartManager();
 
   await checkCompatOverrides(false);
 });
+
--- a/toolkit/mozapps/extensions/test/xpcshell/test_update_compatmode.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_compatmode.js
@@ -1,178 +1,94 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // This verifies that add-on update check correctly fills in the
 // %COMPATIBILITY_MODE% token in the update URL.
 
+Cu.importGlobalProperties(["URLSearchParams"]);
 
 // The test extension uses an insecure update url.
 Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
 
-var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]});
-testserver.registerDirectory("/data/", do_get_file("data"));
+let testserver = createHttpServer({hosts: ["example.com"]});
+
+let lastMode;
+testserver.registerPathHandler("/update.json", (request, response) => {
+  let params = new URLSearchParams(request.queryString);
+  lastMode = params.get("mode");
 
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
+  response.setHeader("content-type", "application/json", true);
+  response.write(JSON.stringify({addons: {}}));
+});
 
-async function run_test() {
-  do_test_pending();
+const ID_NORMAL = "compatmode@tests.mozilla.org";
+const ID_STRICT = "compatmode-strict@tests.mozilla.org";
+
+add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
-  await promiseWriteInstallRDFForExtension({
-    id: "compatmode-normal@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
-    updateURL: "http://example.com/data/test_updatecompatmode_%COMPATIBILITY_MODE%.json",
+  let xpi = await createAddon({
+    id: ID_NORMAL,
+    updateURL: "http://example.com/update.json?mode=%COMPATIBILITY_MODE%",
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "1",
       maxVersion: "1",
     }],
-    name: "Test Addon - normal",
-  }, profileDir);
-
-  await promiseWriteInstallRDFForExtension({
-    id: "compatmode-strict@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
-    updateURL: "http://example.com/data/test_updatecompatmode_%COMPATIBILITY_MODE%.json",
-    targetApplications: [{
-      id: "xpcshell@tests.mozilla.org",
-      minVersion: "1",
-      maxVersion: "1",
-    }],
-    name: "Test Addon - strict",
-  }, profileDir);
+  });
+  await manuallyInstall(xpi, AddonTestUtils.profileExtensions, ID_NORMAL);
 
-  await promiseWriteInstallRDFForExtension({
-    id: "compatmode-strict-optin@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
-    updateURL: "http://example.com/data/test_updatecompatmode_%COMPATIBILITY_MODE%.json",
-    targetApplications: [{
-      id: "xpcshell@tests.mozilla.org",
-      minVersion: "1",
-      maxVersion: "1",
-    }],
-    name: "Test Addon - strict opt-in",
+  xpi = await createAddon({
+    id: ID_STRICT,
+    updateURL: "http://example.com/update.json?mode=%COMPATIBILITY_MODE%",
     strictCompatibility: true,
-  }, profileDir);
-
-  await promiseWriteInstallRDFForExtension({
-    id: "compatmode-ignore@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
-    updateURL: "http://example.com/data/test_updatecompatmode_%COMPATIBILITY_MODE%.json",
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "1",
       maxVersion: "1",
     }],
-    name: "Test Addon - ignore",
-  }, profileDir);
+  });
+  await manuallyInstall(xpi, AddonTestUtils.profileExtensions, ID_STRICT);
 
   await promiseStartupManager();
-  run_test_1();
-}
-
-function end_test() {
-  do_test_finished();
-}
-
+});
 
 // Strict compatibility checking disabled.
-async function run_test_1() {
-  info("Testing with strict compatibility checking disabled");
+add_task(async function test_strict_disabled() {
   Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
-  let addon = await AddonManager.getAddonByID("compatmode-normal@tests.mozilla.org");
+  let addon = await AddonManager.getAddonByID(ID_NORMAL);
   Assert.notEqual(addon, null);
-  addon.findUpdates({
-    onCompatibilityUpdateAvailable() {
-      do_throw("Should have not have seen compatibility information");
-    },
 
-    onNoUpdateAvailable() {
-      do_throw("Should have seen an available update");
-    },
-
-    onUpdateAvailable(unused, install) {
-      Assert.equal(install.version, "2.0");
-    },
-
-    onUpdateFinished() {
-      run_test_2();
-    },
-  }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-}
+  await promiseFindAddonUpdates(addon, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+  Assert.equal(lastMode, "normal", "COMPATIBIILITY_MODE normal was set correctly");
+});
 
 // Strict compatibility checking enabled.
-async function run_test_2() {
-  info("Testing with strict compatibility checking enabled");
+add_task(async function test_strict_enabled() {
   Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, true);
-  let addon = await AddonManager.getAddonByID("compatmode-strict@tests.mozilla.org");
+  let addon = await AddonManager.getAddonByID(ID_NORMAL);
   Assert.notEqual(addon, null);
-  addon.findUpdates({
-    onCompatibilityUpdateAvailable() {
-      do_throw("Should have not have seen compatibility information");
-    },
 
-    onNoUpdateAvailable() {
-      do_throw("Should have seen an available update");
-    },
-
-    onUpdateAvailable(unused, install) {
-      Assert.equal(install.version, "2.0");
-    },
-
-    onUpdateFinished() {
-      run_test_3();
-    },
-  }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-}
+  await promiseFindAddonUpdates(addon, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+  Assert.equal(lastMode, "strict", "COMPATIBILITY_MODE strict was set correctly");
+});
 
 // Strict compatibility checking opt-in.
-async function run_test_3() {
-  info("Testing with strict compatibility disabled, but addon opt-in");
+add_task(async function test_strict_optin() {
   Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
-  let addon = await AddonManager.getAddonByID("compatmode-strict-optin@tests.mozilla.org");
+  let addon = await AddonManager.getAddonByID(ID_STRICT);
   Assert.notEqual(addon, null);
-  addon.findUpdates({
-    onCompatibilityUpdateAvailable() {
-      do_throw("Should have not have seen compatibility information");
-    },
 
-    onUpdateAvailable() {
-      do_throw("Should not have seen an available update");
-    },
-
-    onUpdateFinished() {
-      run_test_4();
-    },
-  }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-}
+  await promiseFindAddonUpdates(addon, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+  Assert.equal(lastMode, "normal", "COMPATIBILITY_MODE is normal even for an addon with strictCompatibility");
+});
 
 // Compatibility checking disabled.
-async function run_test_4() {
-  info("Testing with all compatibility checking disabled");
+add_task(async function test_compat_disabled() {
   AddonManager.checkCompatibility = false;
-  let addon = await AddonManager.getAddonByID("compatmode-ignore@tests.mozilla.org");
+  let addon = await AddonManager.getAddonByID(ID_NORMAL);
   Assert.notEqual(addon, null);
-  addon.findUpdates({
-    onCompatibilityUpdateAvailable() {
-      do_throw("Should have not have seen compatibility information");
-    },
 
-    onNoUpdateAvailable() {
-      do_throw("Should have seen an available update");
-    },
-
-    onUpdateAvailable(unused, install) {
-      Assert.equal(install.version, "2.0");
-    },
-
-    onUpdateFinished() {
-      end_test();
-    },
-  }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
-}
+  await promiseFindAddonUpdates(addon, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+  Assert.equal(lastMode, "ignore", "COMPATIBILITY_MODE ignore was set correctly");
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js
@@ -1,171 +1,215 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-// This verifies that add-on update checks work
-// This file is a placeholder for now, it holds test cases related to
-// strict compatibility to be moved or removed shortly.
+// This verifies that add-on update checks work in conjunction with
+// strict compatibility settings.
 
 const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
 
 // The test extension uses an insecure update url.
 Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
 Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
 
-const updateFile = "test_update.json";
 const appId = "toolkit@mozilla.org";
 
-const profileDir = gProfD.clone();
-profileDir.append("extensions");
-
-const ADDONS = {
-  test_update: {
-    id: "addon1@tests.mozilla.org",
-    version: "2.0",
-    name: "Test 1",
-  },
-  test_update8: {
-    id: "addon8@tests.mozilla.org",
-    version: "2.0",
-    name: "Test 8",
-  },
-  test_update12: {
-    id: "addon12@tests.mozilla.org",
-    version: "2.0",
-    name: "Test 12",
-  },
-  test_install2_1: {
-    id: "addon2@tests.mozilla.org",
-    version: "2.0",
-    name: "Real Test 2",
-  },
-  test_install2_2: {
-    id: "addon2@tests.mozilla.org",
-    version: "3.0",
-    name: "Real Test 3",
-  },
-};
-
-var testserver = createHttpServer({hosts: ["example.com"]});
+testserver = createHttpServer({hosts: ["example.com"]});
 testserver.registerDirectory("/data/", do_get_file("data"));
 
-const XPIS = {};
-
 add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
-
-  Services.locale.requestedLocales = ["fr-FR"];
-
-  for (let [name, info] of Object.entries(ADDONS)) {
-    XPIS[name] = createTempWebExtensionFile({
-      manifest: {
-        name: info.name,
-        version: info.version,
-        applications: {gecko: {id: info.id}},
-      },
-    });
-    testserver.registerFile(`/addons/${name}.xpi`, XPIS[name]);
-  }
-
   AddonTestUtils.updateReason = AddonManager.UPDATE_WHEN_USER_REQUESTED;
 
-  await promiseStartupManager();
+  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);
 });
 
 // Test that the update check correctly observes the
 // extensions.strictCompatibility pref and compatibility overrides.
-add_task(async function test_17() {
-  await promiseInstallWebExtension({
-    manifest: {
-      name: "Test Addon 9",
-      version: "1.0",
-      applications: {
-        gecko: {
-          id: "addon9@tests.mozilla.org",
-          update_url: "http://example.com/data/" + updateFile,
-        },
+add_task(async function test_update_strict() {
+  const ID = "addon9@tests.mozilla.org";
+  let xpi = await createAddon({
+    id: ID,
+    updateURL: "http://example.com/update.json",
+    targetApplications: [{
+      id: "xpcshell@tests.mozilla.org",
+      minVersion: "0.1",
+      maxVersion: "0.2",
+    }],
+  });
+  await manuallyInstall(xpi, AddonTestUtils.profileExtensions, ID);
+
+  await promiseStartupManager();
+
+  await AddonRepository.backgroundUpdateCheck();
+
+  let UPDATE = {
+    addons: {
+      [ID]: {
+        updates: [
+          {
+            version: "2.0",
+            update_link: "http://example.com/addons/test_update9_2.xpi",
+            applications: {
+              gecko: {
+                strict_min_version: "1",
+                advisory_max_version: "1",
+              },
+            },
+          },
+
+          // Incompatible when strict compatibility is enabled
+          {
+            version: "3.0",
+            update_link: "http://example.com/addons/test_update9_3.xpi",
+            applications: {
+              gecko: {
+                strict_min_version: "0.9",
+                advisory_max_version: "0.9",
+              },
+            },
+          },
+
+          // Incompatible due to compatibility override
+          {
+            version: "4.0",
+            update_link: "http://example.com/addons/test_update9_4.xpi",
+            applications: {
+              gecko: {
+                strict_min_version: "0.9",
+                advisory_max_version: "0.9",
+              },
+            },
+          },
+
+          // Addon for future version of app
+          {
+            version: "4.0",
+            update_link: "http://example.com/addons/test_update9_5.xpi",
+            applications: {
+              gecko: {
+                strict_min_version: "5",
+                advisory_max_version: "6",
+              },
+            },
+          },
+        ],
       },
     },
-  });
+  };
+
+  AddonTestUtils.registerJSON(testserver, "/update.json", UPDATE);
 
-  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);
+  let addon = await AddonManager.getAddonByID(ID);
+  let {updateAvailable} = await promiseFindAddonUpdates(addon);
 
-    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);
+  Assert.notEqual(updateAvailable, null, "Got update");
+  Assert.equal(updateAvailable.version, "3.0", "The correct update was selected");
+  await addon.uninstall();
 
-    AddonManagerInternal.backgroundUpdateCheck();
-  });
-
-  AddonManager.removeInstallListener(listener);
-
-  let a9 = await AddonManager.getAddonByID("addon9@tests.mozilla.org");
-  await a9.uninstall();
+  await promiseShutdownManager();
 });
 
 // Tests that compatibility updates are applied to addons when the updated
 // compatibility data wouldn't match with strict compatibility enabled.
-add_task(async function test_18() {
-  await promiseInstallXPI({
-    id: "addon10@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
-    updateURL: "http://example.com/data/" + updateFile,
+add_task(async function test_update_strict2() {
+  const ID = "addon10@tests.mozilla.org";
+  let xpi = createAddon({
+    id: ID,
+    updateURL: "http://example.com/update.json",
     targetApplications: [{
       id: appId,
       minVersion: "0.1",
       maxVersion: "0.2",
     }],
-    name: "Test Addon 10",
   });
+  await manuallyInstall(xpi, AddonTestUtils.profileExtensions, ID);
+
+  await promiseStartupManager();
+  await AddonRepository.backgroundUpdateCheck();
 
-  let a10 = await AddonManager.getAddonByID("addon10@tests.mozilla.org");
-  notEqual(a10, null);
+  const UPDATE = {
+    addons: {
+      [ID]: {
+        updates: [
+          {
+            version: "1.0",
+            update_link: "http://example.com/addons/test_update10.xpi",
+            applications: {
+              gecko: {
+                strict_min_version: "0.1",
+                advisory_max_version: "0.4",
+              },
+            },
+          },
+        ],
+      },
+    },
+  };
 
-  let result = await AddonTestUtils.promiseFindAddonUpdates(a10);
+  AddonTestUtils.registerJSON(testserver, "/update.json", UPDATE);
+
+  let addon = await AddonManager.getAddonByID(ID);
+  notEqual(addon, null);
+
+  let result = await promiseFindAddonUpdates(addon);
   ok(result.compatibilityUpdate, "Should have seen a compatibility update");
   ok(!result.updateAvailable, "Should not have seen a version update");
 
-  await a10.uninstall();
+  await addon.uninstall();
+  await promiseShutdownManager();
 });
 
 // Test that the update check correctly observes when an addon opts-in to
 // strict compatibility checking.
-add_task(async function test_19() {
-  await promiseInstallXPI({
-    id: "addon11@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
-    updateURL: "http://example.com/data/" + updateFile,
+add_task(async function test_update_strict_optin() {
+  const ID = "addon11@tests.mozilla.org";
+  let xpi = await createAddon({
+    id: ID,
+    updateURL: "http://example.com/update.json",
     targetApplications: [{
       id: appId,
       minVersion: "0.1",
       maxVersion: "0.2",
     }],
-    name: "Test Addon 11",
   });
+  await manuallyInstall(xpi, AddonTestUtils.profileExtensions, ID);
+
+  await promiseStartupManager();
+
+  await AddonRepository.backgroundUpdateCheck();
 
-  let a11 = await AddonManager.getAddonByID("addon11@tests.mozilla.org");
-  notEqual(a11, null);
+  const UPDATE = {
+    addons: {
+      [ID]: {
+        updates: [
+          {
+            version: "2.0",
+            update_link: "http://example.com/addons/test_update11.xpi",
+            applications: {
+              gecko: {
+                strict_min_version: "0.1",
+                strict_max_version: "0.2",
+              },
+            },
+          },
+        ],
+      },
+    },
+  };
 
-  let result = await AddonTestUtils.promiseFindAddonUpdates(a11);
+  AddonTestUtils.registerJSON(testserver, "/update.json", UPDATE);
+
+  let addon = await AddonManager.getAddonByID(ID);
+  notEqual(addon, null);
+
+  let result = await AddonTestUtils.promiseFindAddonUpdates(addon);
   ok(!result.compatibilityUpdate, "Should not have seen a compatibility update");
   ok(!result.updateAvailable, "Should not have seen a version update");
 
-  await a11.uninstall();
+  await addon.uninstall();
+  await promiseShutdownManager();
 });
-
--- a/toolkit/mozapps/extensions/test/xpcshell/test_upgrade.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_upgrade.js
@@ -16,134 +16,131 @@ const profileDir = gProfD.clone();
 profileDir.append("extensions");
 
 const globalDir = Services.dirsvc.get("XREAddonAppDir", Ci.nsIFile);
 globalDir.append("extensions");
 
 var gGlobalExisted = globalDir.exists();
 var gInstallTime = Date.now();
 
+const ID1 = "addon1@tests.mozilla.org";
+const ID2 = "addon2@tests.mozilla.org";
+const ID3 = "addon3@tests.mozilla.org";
+const ID4 = "addon4@tests.mozilla.org";
+const PATH4 = OS.Path.join(globalDir.path, `${ID4}.xpi`);
+
 add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
   // Will be compatible in the first version and incompatible in subsequent versions
-  await promiseWriteInstallRDFForExtension({
-    id: "addon1@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
+  let xpi = await createAddon({
+    id: ID1,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "1",
       maxVersion: "1",
     }],
-    name: "Test Addon 1",
     targetPlatforms: [
-      "XPCShell",
-      "WINNT_x86",
+      {os: "XPCShell"},
+      {os: "WINNT_x86"},
     ],
-  }, profileDir);
+  });
+  await manuallyInstall(xpi, profileDir, ID1);
+
 
   // Works in all tested versions
-  await promiseWriteInstallRDFForExtension({
-    id: "addon2@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
+  xpi = await createAddon({
+    id: ID2,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "1",
       maxVersion: "2",
     }],
-    name: "Test Addon 2",
     targetPlatforms: [
-      "XPCShell_noarch-spidermonkey",
+      {
+        os: "XPCShell",
+        abi: "noarch-spidermonkey",
+      },
     ],
-  }, profileDir);
+  });
+  await manuallyInstall(xpi, profileDir, ID2);
 
   // Will be disabled in the first version and enabled in the second.
-  await promiseWriteInstallRDFForExtension({
-    id: "addon3@tests.mozilla.org",
-    version: "1.0",
-    bootstrap: true,
+  xpi = createAddon({
+    id: ID3,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "2",
       maxVersion: "2",
     }],
-    name: "Test Addon 3",
-  }, profileDir);
+  });
+  await manuallyInstall(xpi, profileDir, ID3);
 
   // Will be compatible in both versions but will change version in between
-  var dest = await promiseWriteInstallRDFForExtension({
-    id: "addon4@tests.mozilla.org",
+  xpi = await createAddon({
+    id: ID4,
     version: "1.0",
-    bootstrap: true,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "1",
       maxVersion: "1",
     }],
-    name: "Test Addon 4",
-  }, globalDir);
-  setExtensionModifiedTime(dest, gInstallTime);
+  });
+  await manuallyInstall(xpi, globalDir, ID4);
+  await promiseSetExtensionModifiedTime(PATH4, gInstallTime);
 });
 
 registerCleanupFunction(function end_test() {
   if (!gGlobalExisted) {
     globalDir.remove(true);
   } else {
-    globalDir.append(do_get_expected_addon_name("addon4@tests.mozilla.org"));
+    globalDir.append(do_get_expected_addon_name(ID4));
     globalDir.remove(true);
   }
 });
 
 // Test that the test extensions are all installed
 add_task(async function test_1() {
   await promiseStartupManager();
 
-  let [a1, a2, a3, a4] = await AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                                                            "addon2@tests.mozilla.org",
-                                                            "addon3@tests.mozilla.org",
-                                                            "addon4@tests.mozilla.org"]);
-  Assert.notEqual(a1, null);
-  Assert.ok(isExtensionInBootstrappedList(profileDir, a1.id));
+  let [a1, a2, a3, a4] = await promiseAddonsByIDs([ID1, ID2, ID3, ID4]);
+  Assert.notEqual(a1, null, "Found extension 1");
+  Assert.equal(a1.isActive, true, "Extension 1 is active");
 
-  Assert.notEqual(a2, null);
-  Assert.ok(isExtensionInBootstrappedList(profileDir, a2.id));
+  Assert.notEqual(a2, null, "Found extension 2");
+  Assert.equal(a2.isActive, true, "Extension 2 is active");
 
-  Assert.notEqual(a3, null);
-  Assert.ok(!isExtensionInBootstrappedList(profileDir, a3.id));
+  Assert.notEqual(a3, null, "Found extension 3");
+  Assert.equal(a3.isActive, false, "Extension 3 is not active");
 
   Assert.notEqual(a4, null);
-  Assert.ok(isExtensionInBootstrappedList(globalDir, a4.id));
+  Assert.equal(a4.isActive, true);
   Assert.equal(a4.version, "1.0");
+
 });
 
 // Test that upgrading the application doesn't disable now incompatible add-ons
 add_task(async function test_2() {
   await promiseShutdownManager();
 
   // Upgrade the extension
-  var dest = await promiseWriteInstallRDFForExtension({
-    id: "addon4@tests.mozilla.org",
+  let xpi = createAddon({
+    id: ID4,
     version: "2.0",
-    bootstrap: true,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "2",
       maxVersion: "2",
     }],
-    name: "Test Addon 4",
-  }, globalDir);
-  setExtensionModifiedTime(dest, gInstallTime);
+  });
+  await manuallyInstall(xpi, globalDir, ID4);
+  await promiseSetExtensionModifiedTime(PATH4, gInstallTime);
 
   await promiseStartupManager("2");
-  let [a1, a2, a3, a4] = await AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                                                            "addon2@tests.mozilla.org",
-                                                            "addon3@tests.mozilla.org",
-                                                            "addon4@tests.mozilla.org"]);
+  let [a1, a2, a3, a4] = await promiseAddonsByIDs([ID1, ID2, ID3, ID4]);
   Assert.notEqual(a1, null);
   Assert.ok(isExtensionInBootstrappedList(profileDir, a1.id));
 
   Assert.notEqual(a2, null);
   Assert.ok(isExtensionInBootstrappedList(profileDir, a2.id));
 
   Assert.notEqual(a3, null);
   Assert.ok(isExtensionInBootstrappedList(profileDir, a3.id));
@@ -153,45 +150,42 @@ add_task(async function test_2() {
   Assert.equal(a4.version, "2.0");
 });
 
 // Test that nothing changes when only the build ID changes.
 add_task(async function test_3() {
   await promiseShutdownManager();
 
   // Upgrade the extension
-  var dest = await promiseWriteInstallRDFForExtension({
-    id: "addon4@tests.mozilla.org",
+  let xpi = createAddon({
+    id: ID4,
     version: "3.0",
-    bootstrap: true,
     targetApplications: [{
       id: "xpcshell@tests.mozilla.org",
       minVersion: "3",
       maxVersion: "3",
     }],
-    name: "Test Addon 4",
-  }, globalDir);
-  setExtensionModifiedTime(dest, gInstallTime);
+  });
+  await manuallyInstall(xpi, globalDir, ID4);
+  await promiseSetExtensionModifiedTime(PATH4, gInstallTime);
 
-  // Simulates a simple Build ID change, the platform deletes extensions.ini
-  // whenever the application is changed.
+  // Simulates a simple Build ID change
   gAddonStartup.remove(true);
   await promiseStartupManager();
 
-  let [a1, a2, a3, a4] = await AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                                                            "addon2@tests.mozilla.org",
-                                                            "addon3@tests.mozilla.org",
-                                                            "addon4@tests.mozilla.org"]);
+  let [a1, a2, a3, a4] = await promiseAddonsByIDs([ID1, ID2, ID3, ID4]);
+
   Assert.notEqual(a1, null);
   Assert.ok(isExtensionInBootstrappedList(profileDir, a1.id));
 
   Assert.notEqual(a2, null);
   Assert.ok(isExtensionInBootstrappedList(profileDir, a2.id));
 
   Assert.notEqual(a3, null);
   Assert.ok(isExtensionInBootstrappedList(profileDir, a3.id));
 
   Assert.notEqual(a4, null);
   Assert.ok(isExtensionInBootstrappedList(globalDir, a4.id));
   Assert.equal(a4.version, "2.0");
 
   await promiseShutdownManager();
 });
+
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install_syntax_error.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install_syntax_error.js
@@ -2,46 +2,44 @@ const ADDON_ID = "webext-test@tests.mozi
 
 add_task(async function setup() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
   await promiseStartupManager();
 });
 
 add_task(async function install_xpi() {
 
-  // Data for WebExtension with syntax error
+  // WebExtension with a JSON syntax error in manifest.json
   let xpi1 = Extension.generateXPI({
     files: {
       "manifest.json": String.raw`{
-        // This is a manifest. Intentional syntax error in next line.
         "manifest_version: 2,
         "applications": {"gecko": {"id": "${ADDON_ID}"}},
         "name": "Temp WebExt with Error",
         "version": "0.1"
       }`,
     },
   });
 
-  // Data for WebExtension without syntax error
+  // Valid WebExtension
   let xpi2 = Extension.generateXPI({
     files: {
       "manifest.json": String.raw`{
-        // This is a manifest.
         "manifest_version": 2,
         "applications": {"gecko": {"id": "${ADDON_ID}"}},
         "name": "Temp WebExt without Error",
         "version": "0.1"
       }`,
     },
   });
 
   let install1 = await AddonManager.getInstallForFile(xpi1);
   Assert.equal(install1.state, AddonManager.STATE_DOWNLOAD_FAILED);
   Assert.equal(install1.error, AddonManager.ERROR_CORRUPT_FILE);
 
   // Replace xpi1 with xpi2 to have the same filename to reproduce install error
   xpi2.moveTo(xpi1.parent, xpi1.leafName);
 
   let install2 = await AddonManager.getInstallForFile(xpi2);
-  Assert.notEqual(install2.error, AddonManager.ERROR_CORRUPT_FILE);
+  Assert.equal(install2.error, 0);
 
   xpi1.remove(false);
 });
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -66,16 +66,17 @@ tags = blocklist
 [test_bootstrap.js]
 [test_bootstrap_const.js]
 [test_bootstrap_globals.js]
 [test_bootstrapped_chrome_manifest.js]
 [test_cache_certdb.js]
 [test_cacheflush.js]
 [test_childprocess.js]
 [test_compatoverrides.js]
+head = head_addons.js head_compat.js
 [test_corrupt.js]
 [test_crash_annotation_quoting.js]
 [test_db_path.js]
 head =
 [test_delay_update_webextension.js]
 tags = webextensions
 [test_dependencies.js]
 [test_dictionary_webextension.js]
@@ -144,16 +145,17 @@ skip-if = !allow_legacy_extensions || ap
 [test_manifest_locales.js]
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_moved_extension_metadata.js]
 skip-if = true
 [test_no_addons.js]
 [test_nodisable_hidden.js]
 [test_onPropertyChanged_appDisabled.js]
+head = head_addons.js head_compat.js
 [test_overrideblocklist.js]
 run-sequentially = Uses global XCurProcD dir.
 tags = blocklist
 [test_permissions.js]
 [test_permissions_prefs.js]
 [test_pluginBlocklistCtp.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
@@ -195,16 +197,17 @@ skip-if = true
 skip-if = require_signing || !allow_legacy_extensions
 [test_signed_verify.js]
 [test_softblocked.js]
 tags = blocklist
 [test_startup.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
 [test_strictcompatibility.js]
+head = head_addons.js head_compat.js
 [test_syncGUID.js]
 [test_system_allowed.js]
 head = head_addons.js head_system_addons.js
 [test_system_delay_update.js]
 head = head_addons.js head_system_addons.js
 skip-if = true # Bug 1495021
 [test_system_repository.js]
 head = head_addons.js head_system_addons.js
@@ -240,29 +243,33 @@ skip-if = os != "win"
 [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"
 [test_updateCancel.js]
 [test_update_compatmode.js]
+head = head_addons.js head_compat.js
 [test_update_ignorecompat.js]
 skip-if = true # Bug 676922 Bug 1437697
 [test_update_rdf.js]
+[test_update_strictcompat.js]
+head = head_addons.js head_compat.js
 [test_update_webextensions.js]
 tags = webextensions
 [test_updatecheck.js]
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_updatecheck_errors.js]
 [test_updateid.js]
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_upgrade.js]
+head = head_addons.js head_compat.js
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 run-sequentially = Uses global XCurProcD dir.
 [test_upgrade_incompatible.js]
 [test_webextension.js]
 tags = webextensions
 [test_webextension_events.js]
 tags = webextensions