Bug 1436851 - Add test for enterprise policy to disable system addon updates draft
authorKirk Steuber <ksteuber@mozilla.com>
Wed, 14 Feb 2018 15:15:02 -0800
changeset 763860 e962f9118262c1b1d93f13817415e264c5cf08ab
parent 763859 49a49423b2f0e168b280ace047877768030574da
push id101569
push userksteuber@mozilla.com
push dateTue, 06 Mar 2018 19:27:32 +0000
bugs1436851
milestone60.0a1
Bug 1436851 - Add test for enterprise policy to disable system addon updates MozReview-Commit-ID: K3NtpeVLFf4
browser/components/enterprisepolicies/tests/EnterprisePolicyTesting.jsm
browser/components/enterprisepolicies/tests/browser/head.js
browser/components/enterprisepolicies/tests/moz.build
toolkit/mozapps/extensions/test/xpcshell/test_system_update_enterprisepolicy.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/EnterprisePolicyTesting.jsm
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/osfile.jsm");
+ChromeUtils.defineModuleGetter(this, "FileTestUtils",
+                               "resource://testing-common/FileTestUtils.jsm");
+
+this.EXPORTED_SYMBOLS = ["EnterprisePolicyTesting"];
+
+this.EnterprisePolicyTesting = {
+  // |json| must be an object representing the desired policy configuration, OR a
+  // path to the JSON file containing the policy configuration.
+  setupPolicyEngineWithJson: async function setupPolicyEngineWithJson(json, customSchema) {
+    let filePath;
+    if (typeof(json) == "object") {
+      filePath = FileTestUtils.getTempFile("policies.json").path;
+
+      // This file gets automatically deleted by FileTestUtils
+      // at the end of the test run.
+      await OS.File.writeAtomic(filePath, JSON.stringify(json), {
+        encoding: "utf-8",
+      });
+    } else {
+      filePath = json;
+    }
+
+    Services.prefs.setStringPref("browser.policies.alternatePath", filePath);
+
+    let promise = new Promise(resolve => {
+      Services.obs.addObserver(function observer() {
+        Services.obs.removeObserver(observer, "EnterprisePolicies:AllPoliciesApplied");
+        dump(`bytesized: setupPolicyEngineWithJson resolving`);
+        resolve();
+      }, "EnterprisePolicies:AllPoliciesApplied");
+    });
+
+    // Clear any previously used custom schema
+    Cu.unload("resource:///modules/policies/schema.jsm");
+
+    if (customSchema) {
+      let schemaModule = ChromeUtils.import("resource:///modules/policies/schema.jsm", {});
+      schemaModule.schema = customSchema;
+    }
+
+    Services.obs.notifyObservers(null, "EnterprisePolicies:Restart");
+    return promise;
+  },
+};
--- a/browser/components/enterprisepolicies/tests/browser/head.js
+++ b/browser/components/enterprisepolicies/tests/browser/head.js
@@ -1,51 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-ChromeUtils.defineModuleGetter(this, "FileTestUtils",
-                               "resource://testing-common/FileTestUtils.jsm");
+const {EnterprisePolicyTesting} = ChromeUtils.import("resource://testing-common/EnterprisePolicyTesting.jsm", {});
 
 async function setupPolicyEngineWithJson(json, customSchema) {
-  let filePath;
-  if (typeof(json) == "object") {
-    filePath = FileTestUtils.getTempFile("policies.json").path;
-
-    // This file gets automatically deleted by FileTestUtils
-    // at the end of the test run.
-    await OS.File.writeAtomic(filePath, JSON.stringify(json), {
-      encoding: "utf-8",
-    });
-  } else {
-    filePath = getTestFilePath(json ? json : "non-existing-file.json");
+  if (typeof(json) != "object") {
+    let filePath = getTestFilePath(json ? json : "non-existing-file.json");
+    return EnterprisePolicyTesting.setupPolicyEngineWithJson(filePath, customSchema);
   }
-
-  Services.prefs.setStringPref("browser.policies.alternatePath", filePath);
-
-  let resolve = null;
-  let promise = new Promise((r) => resolve = r);
-
-  Services.obs.addObserver(function observer() {
-    Services.obs.removeObserver(observer, "EnterprisePolicies:AllPoliciesApplied");
-    resolve();
-  }, "EnterprisePolicies:AllPoliciesApplied");
-
-  // Clear any previously used custom schema
-  Cu.unload("resource:///modules/policies/schema.jsm");
-
-  if (customSchema) {
-    let schemaModule = ChromeUtils.import("resource:///modules/policies/schema.jsm", {});
-    schemaModule.schema = customSchema;
-  }
-
-  Services.obs.notifyObservers(null, "EnterprisePolicies:Restart");
-  return promise;
+  return EnterprisePolicyTesting.setupPolicyEngineWithJson(json, customSchema);
 }
 
 add_task(async function policies_headjs_startWithCleanSlate() {
   if (Services.policies.status != Ci.nsIEnterprisePolicies.INACTIVE) {
     await setupPolicyEngineWithJson("");
   }
   is(Services.policies.status, Ci.nsIEnterprisePolicies.INACTIVE, "Engine is inactive at the start of the test");
 });
--- a/browser/components/enterprisepolicies/tests/moz.build
+++ b/browser/components/enterprisepolicies/tests/moz.build
@@ -7,8 +7,12 @@
 with Files("**"):
     BUG_COMPONENT = ("Firefox", "General")
 
 BROWSER_CHROME_MANIFESTS += [
     'browser/browser.ini',
     'browser/disable_app_update/browser.ini',
     'browser/disable_developer_tools/browser.ini',
 ]
+
+TESTING_JS_MODULES += [
+    'EnterprisePolicyTesting.jsm',
+]
copy from toolkit/mozapps/extensions/test/xpcshell/test_system_update_custom.js
copy to toolkit/mozapps/extensions/test/xpcshell/test_system_update_enterprisepolicy.js
--- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_custom.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_enterprisepolicy.js
@@ -1,11 +1,28 @@
-// Tests that system add-on upgrades work.
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// This test verifies that system addon updates are correctly blocked by the
+// DisableSysAddonUpdate enterprise policy.
 
 ChromeUtils.import("resource://testing-common/httpd.js");
+ChromeUtils.import("resource://testing-common/EnterprisePolicyTesting.jsm");
+
+// Setting PREF_DISABLE_SECURITY tells the policy engine that we are in testing
+// mode and enables restarting the policy engine without restarting the browser.
+Services.prefs.setBoolPref(PREF_DISABLE_SECURITY, true);
+Services.prefs.setBoolPref("browser.policies.enabled", true);
+registerCleanupFunction(() => {
+  Services.prefs.clearUserPref(PREF_DISABLE_SECURITY);
+  Services.prefs.clearUserPref("browser.policies.enabled");
+});
+
+Services.policies; // Load policy engine
 
 BootstrapMonitor.init();
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2");
 
 var testserver = new HttpServer();
 testserver.registerDirectory("/data/", do_get_file("data/system_addons"));
 testserver.start();
@@ -14,257 +31,48 @@ var root = testserver.identity.primarySc
            testserver.identity.primaryPort + "/data/";
 Services.prefs.setCharPref(PREF_SYSTEM_ADDON_UPDATE_URL, root + "update.xml");
 
 let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"], true);
 registerDirectory("XREAppFeat", distroDir);
 initSystemAddonDirs();
 
 /**
- * Defines the set of initial conditions to run each test against. Each should
- * define the following properties:
+ * Defines the set of initial conditions to run the test against.
  *
  * setup:        A task to setup the profile into the initial state.
  * initialState: The initial expected system add-on state after setup has run.
+ *
+ * These conditions run tests with no updated or default system add-ons
+ * initially installed
  */
 const TEST_CONDITIONS = {
-  // Runs tests with no updated or default system add-ons initially installed
-  blank: {
-    setup() {
-      clearSystemAddonUpdatesDir();
-      distroDir.leafName = "empty";
-    },
-    initialState: [
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null}
-    ],
-  },
-  // Runs tests with default system add-ons installed
-  withAppSet: {
-    setup() {
-      clearSystemAddonUpdatesDir();
-      distroDir.leafName = "prefilled";
-    },
-    initialState: [
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: "2.0"},
-      { isUpgrade: false, version: "2.0"},
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null}
-    ]
+  setup() {
+    clearSystemAddonUpdatesDir();
+    distroDir.leafName = "empty";
   },
-
-  // Runs tests with updated system add-ons installed
-  withProfileSet: {
-    setup() {
-      buildPrefilledUpdatesDir();
-      distroDir.leafName = "empty";
-    },
-    initialState: [
-      { isUpgrade: false, version: null},
-      { isUpgrade: true, version: "2.0"},
-      { isUpgrade: true, version: "2.0"},
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null}
-    ]
-  },
-
-  // Runs tests with both default and updated system add-ons installed
-  withBothSets: {
-    setup() {
-      buildPrefilledUpdatesDir();
-      distroDir.leafName = "hidden";
-    },
-    initialState: [
-      { isUpgrade: false, version: "1.0"},
-      { isUpgrade: true, version: "2.0"},
-      { isUpgrade: true, version: "2.0"},
-      { isUpgrade: false, version: null},
-      { isUpgrade: false, version: null}
-    ]
-  },
+  initialState: [
+    { isUpgrade: false, version: null},
+    { isUpgrade: false, version: null},
+    { isUpgrade: false, version: null},
+    { isUpgrade: false, version: null},
+    { isUpgrade: false, version: null}
+  ],
 };
 
-// Test that the update check is performed as part of the regular add-on update
-// check
-add_task(async function test_addon_update() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.blank, distroDir);
+add_task(async function test_update_disabled_by_policy() {
+  await setupSystemAddonConditions(TEST_CONDITIONS, distroDir);
+
+  await EnterprisePolicyTesting.setupPolicyEngineWithJson({
+    "policies": {
+      "DisableSysAddonUpdate": true
+    }
+  });
 
   await updateAllSystemAddons(await buildSystemAddonUpdates([
     { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
     { id: "system3@tests.mozilla.org", version: "2.0", path: "system3_2.xpi" }
   ], root), testserver);
 
-  await verifySystemAddonState(TEST_CONDITIONS.blank.initialState, [
-    {isUpgrade: false, version: null},
-    {isUpgrade: true, version: "2.0"},
-    {isUpgrade: true, version: "2.0"},
-    {isUpgrade: false, version: null},
-    {isUpgrade: false, version: null}
-  ], false, distroDir);
-
-  await promiseShutdownManager();
-});
-
-// Disabling app updates should block system add-on updates
-add_task(async function test_app_update_disabled() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.blank, distroDir);
-
-  Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, false);
-  await updateAllSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
-    { id: "system3@tests.mozilla.org", version: "2.0", path: "system3_2.xpi" }
-  ], root), testserver);
-  Services.prefs.clearUserPref(PREF_APP_UPDATE_ENABLED);
-
-  await verifySystemAddonState(TEST_CONDITIONS.blank.initialState, undefined, false, distroDir);
-
-  await promiseShutdownManager();
-});
-
-// Safe mode should block system add-on updates
-add_task(async function test_safe_mode() {
-  gAppInfo.inSafeMode = true;
-
-  await setupSystemAddonConditions(TEST_CONDITIONS.blank, distroDir);
-
-  Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, false);
-  await updateAllSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
-    { id: "system3@tests.mozilla.org", version: "2.0", path: "system3_2.xpi" }
-  ], root), testserver);
-  Services.prefs.clearUserPref(PREF_APP_UPDATE_ENABLED);
-
-  await verifySystemAddonState(TEST_CONDITIONS.blank.initialState, undefined, false, distroDir);
-
-  await promiseShutdownManager();
-
-  gAppInfo.inSafeMode = false;
-});
-
-// Tests that a set that matches the default set does nothing
-add_task(async function test_match_default() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.withAppSet, distroDir);
-
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
-    { id: "system3@tests.mozilla.org", version: "2.0", path: "system3_2.xpi" }
-  ], root), testserver);
-
-  // Shouldn't have installed an updated set
-  await verifySystemAddonState(TEST_CONDITIONS.withAppSet.initialState, undefined, false, distroDir);
-
-  await promiseShutdownManager();
-});
-
-// Tests that a set that matches the hidden default set works
-add_task(async function test_match_default_revert() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.withBothSets, distroDir);
-
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system1@tests.mozilla.org", version: "1.0", path: "system1_1.xpi" },
-    { id: "system2@tests.mozilla.org", version: "1.0", path: "system2_1.xpi" }
-  ], root), testserver);
-
-  // This should revert to the default set instead of installing new versions
-  // into an updated set.
-  await verifySystemAddonState(TEST_CONDITIONS.withBothSets.initialState, [
-    {isUpgrade: false, version: "1.0"},
-    {isUpgrade: false, version: "1.0"},
-    {isUpgrade: false, version: null},
-    {isUpgrade: false, version: null},
-    {isUpgrade: false, version: null}
-  ], false, distroDir);
+  await verifySystemAddonState(TEST_CONDITIONS.initialState, undefined, false, distroDir);
 
   await promiseShutdownManager();
 });
-
-// Tests that a set that matches the current set works
-add_task(async function test_match_current() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.withBothSets, distroDir);
-
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
-    { id: "system3@tests.mozilla.org", version: "2.0", path: "system3_2.xpi" }
-  ], root), testserver);
-
-  // This should remain with the current set instead of creating a new copy
-  let set = JSON.parse(Services.prefs.getCharPref(PREF_SYSTEM_ADDON_SET));
-  Assert.equal(set.directory, "prefilled");
-
-  await verifySystemAddonState(TEST_CONDITIONS.withBothSets.initialState, undefined, false, distroDir);
-
-  await promiseShutdownManager();
-});
-
-// Tests that a set with a minor change doesn't re-download existing files
-add_task(async function test_no_download() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.withBothSets, distroDir);
-
-  // The missing file here is unneeded since there is a local version already
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "missing.xpi" },
-    { id: "system4@tests.mozilla.org", version: "1.0", path: "system4_1.xpi" }
-  ], root), testserver);
-
-  await verifySystemAddonState(TEST_CONDITIONS.withBothSets.initialState, [
-    {isUpgrade: false, version: "1.0"},
-    {isUpgrade: true, version: "2.0"},
-    {isUpgrade: false, version: null},
-    {isUpgrade: true, version: "1.0"},
-    {isUpgrade: false, version: null}
-  ], false, distroDir);
-
-  await promiseShutdownManager();
-});
-
-// Tests that a second update before a restart works
-add_task(async function test_double_update() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.withAppSet, distroDir);
-
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
-    { id: "system3@tests.mozilla.org", version: "1.0", path: "system3_1.xpi" }
-  ], root), testserver);
-
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system3@tests.mozilla.org", version: "2.0", path: "system3_2.xpi" },
-    { id: "system4@tests.mozilla.org", version: "1.0", path: "system4_1.xpi" }
-  ], root), testserver);
-
-  await verifySystemAddonState(TEST_CONDITIONS.withAppSet.initialState, [
-    {isUpgrade: false, version: null},
-    {isUpgrade: false, version: "2.0"},
-    {isUpgrade: true, version: "2.0"},
-    {isUpgrade: true, version: "1.0"},
-    {isUpgrade: false, version: null}
-  ], true, distroDir);
-
-  await promiseShutdownManager();
-});
-
-// A second update after a restart will delete the original unused set
-add_task(async function test_update_purges() {
-  await setupSystemAddonConditions(TEST_CONDITIONS.withBothSets, distroDir);
-
-  await installSystemAddons(await buildSystemAddonUpdates([
-    { id: "system2@tests.mozilla.org", version: "2.0", path: "system2_2.xpi" },
-    { id: "system3@tests.mozilla.org", version: "1.0", path: "system3_1.xpi" }
-  ], root), testserver);
-
-  await verifySystemAddonState(TEST_CONDITIONS.withBothSets.initialState, [
-    {isUpgrade: false, version: "1.0"},
-    {isUpgrade: true, version: "2.0"},
-    {isUpgrade: true, version: "1.0"},
-    {isUpgrade: false, version: null},
-    {isUpgrade: false, version: null}
-  ], false, distroDir);
-
-  await installSystemAddons(await buildSystemAddonUpdates(null), testserver);
-
-  let dirs = await getSystemAddonDirectories();
-  Assert.equal(dirs.length, 1);
-
-  await promiseShutdownManager();
-});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -30,16 +30,17 @@ tags = blocklist
 [test_ProductAddonChecker.js]
 [test_shutdown.js]
 [test_system_update_blank.js]
 fail-if = os == 'win' && ccov
 [test_system_update_checkSizeHash.js]
 [test_system_update_custom.js]
 [test_system_update_empty.js]
 skip-if = true # Failing intermittently due to a race condition in the test, see bug 1348981
+[test_system_update_enterprisepolicy.js]
 [test_system_update_fail.js]
 [test_system_update_newset.js]
 [test_system_update_overlapping.js]
 [test_system_update_upgrades.js]
 [test_system_repository.js]
 [test_system_reset.js]
 [test_XPIcancel.js]
 [test_XPIStates.js]