summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/update/tests/unit_background_update/test_backgroundupdate_reason_update.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/update/tests/unit_background_update/test_backgroundupdate_reason_update.js')
-rw-r--r--toolkit/mozapps/update/tests/unit_background_update/test_backgroundupdate_reason_update.js321
1 files changed, 321 insertions, 0 deletions
diff --git a/toolkit/mozapps/update/tests/unit_background_update/test_backgroundupdate_reason_update.js b/toolkit/mozapps/update/tests/unit_background_update/test_backgroundupdate_reason_update.js
new file mode 100644
index 0000000000..c5349f5a06
--- /dev/null
+++ b/toolkit/mozapps/update/tests/unit_background_update/test_backgroundupdate_reason_update.js
@@ -0,0 +1,321 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * vim: sw=4 ts=4 sts=4 et
+ * 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";
+
+const { BackgroundUpdate } = ChromeUtils.importESModule(
+ "resource://gre/modules/BackgroundUpdate.sys.mjs"
+);
+let reasons = () => BackgroundUpdate._reasonsToNotUpdateInstallation();
+let REASON = BackgroundUpdate.REASON;
+const { EnterprisePolicyTesting } = ChromeUtils.importESModule(
+ "resource://testing-common/EnterprisePolicyTesting.sys.mjs"
+);
+const { UpdateService } = ChromeUtils.importESModule(
+ "resource://gre/modules/UpdateService.sys.mjs"
+);
+
+const { sinon } = ChromeUtils.importESModule(
+ "resource://testing-common/Sinon.sys.mjs"
+);
+
+// We can't reasonably check NO_MOZ_BACKGROUNDTASKS, nor NO_OMNIJAR.
+
+// These tests use per-installation prefs, and those are a shared resource, so
+// they require some non-trivial setup.
+setupTestCommon(null);
+standardInit();
+
+function setup_enterprise_policy_testing() {
+ // This initializes the policy engine for xpcshell tests
+ let policies = Cc["@mozilla.org/enterprisepolicies;1"].getService(
+ Ci.nsIObserver
+ );
+ policies.observe(null, "policies-startup", null);
+}
+setup_enterprise_policy_testing();
+
+async function setupPolicyEngineWithJson(json, customSchema) {
+ if (typeof json != "object") {
+ let filePath = do_get_file(json ? json : "non-existing-file.json").path;
+ return EnterprisePolicyTesting.setupPolicyEngineWithJson(
+ filePath,
+ customSchema
+ );
+ }
+ return EnterprisePolicyTesting.setupPolicyEngineWithJson(json, customSchema);
+}
+
+add_setup(function test_setup() {
+ // FOG needs a profile directory to put its data in.
+ do_get_profile();
+
+ // We need to initialize it once, otherwise operations will be stuck in the pre-init queue.
+ Services.fog.initializeFOG();
+
+ setupProfileService();
+});
+
+add_task(async function test_reasons_update_no_app_update_auto() {
+ let prev = await UpdateUtils.getAppUpdateAutoEnabled();
+ try {
+ await UpdateUtils.setAppUpdateAutoEnabled(false);
+ let result = await reasons();
+ Assert.ok(result.includes(REASON.NO_APP_UPDATE_AUTO));
+ result = await checkGleanPing();
+ Assert.ok(result.includes(REASON.NO_APP_UPDATE_AUTO));
+
+ await UpdateUtils.setAppUpdateAutoEnabled(true);
+ result = await reasons();
+ Assert.ok(!result.includes(REASON.NO_APP_UPDATE_AUTO));
+
+ result = await checkGleanPing();
+ Assert.ok(!result.includes(REASON.NO_APP_UPDATE_AUTO));
+ } finally {
+ await UpdateUtils.setAppUpdateAutoEnabled(prev);
+ }
+});
+
+add_task(async function test_reasons_update_no_app_update_background_enabled() {
+ let prev = await UpdateUtils.readUpdateConfigSetting(
+ "app.update.background.enabled"
+ );
+ try {
+ await UpdateUtils.writeUpdateConfigSetting(
+ "app.update.background.enabled",
+ false
+ );
+ let result = await reasons();
+ Assert.ok(result.includes(REASON.NO_APP_UPDATE_BACKGROUND_ENABLED));
+ result = await checkGleanPing();
+ Assert.ok(result.includes(REASON.NO_APP_UPDATE_BACKGROUND_ENABLED));
+
+ await UpdateUtils.writeUpdateConfigSetting(
+ "app.update.background.enabled",
+ true
+ );
+ result = await reasons();
+ Assert.ok(!result.includes(REASON.NO_APP_UPDATE_BACKGROUND_ENABLED));
+ result = await checkGleanPing();
+ Assert.ok(!result.includes(REASON.NO_APP_UPDATE_BACKGROUND_ENABLED));
+ } finally {
+ await UpdateUtils.writeUpdateConfigSetting(
+ "app.update.background.enabled",
+ prev
+ );
+ }
+});
+
+add_task(async function test_reasons_update_cannot_usually_check() {
+ // It's difficult to arrange the conditions in a testing environment, so
+ // we'll use mocks to get a little assurance.
+ let result = await reasons();
+ Assert.ok(!result.includes(REASON.CANNOT_USUALLY_CHECK));
+
+ let sandbox = sinon.createSandbox();
+ try {
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyCheckForUpdates")
+ .get(() => false);
+ result = await reasons();
+ Assert.ok(result.includes(REASON.CANNOT_USUALLY_CHECK));
+ result = await checkGleanPing();
+ Assert.ok(result.includes(REASON.CANNOT_USUALLY_CHECK));
+ } finally {
+ sandbox.restore();
+ }
+});
+
+add_task(async function test_reasons_update_can_usually_stage_or_appl() {
+ // It's difficult to arrange the conditions in a testing environment, so
+ // we'll use mocks to get a little assurance.
+ let sandbox = sinon.createSandbox();
+ try {
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyStageUpdates")
+ .get(() => true);
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyApplyUpdates")
+ .get(() => true);
+ let result = await reasons();
+ Assert.ok(
+ !result.includes(REASON.CANNOT_USUALLY_STAGE_AND_CANNOT_USUALLY_APPLY)
+ );
+ result = await checkGleanPing();
+ Assert.ok(
+ !result.includes(REASON.CANNOT_USUALLY_STAGE_AND_CANNOT_USUALLY_APPLY)
+ );
+
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyStageUpdates")
+ .get(() => false);
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyApplyUpdates")
+ .get(() => false);
+ result = await reasons();
+ Assert.ok(
+ result.includes(REASON.CANNOT_USUALLY_STAGE_AND_CANNOT_USUALLY_APPLY)
+ );
+ result = await checkGleanPing();
+ Assert.ok(
+ result.includes(REASON.CANNOT_USUALLY_STAGE_AND_CANNOT_USUALLY_APPLY)
+ );
+ } finally {
+ sandbox.restore();
+ }
+});
+
+add_task(
+ {
+ skip_if: () =>
+ !AppConstants.MOZ_BITS_DOWNLOAD || AppConstants.platform != "win",
+ },
+ async function test_reasons_update_can_usually_use_bits() {
+ let prev = Services.prefs.getBoolPref("app.update.BITS.enabled");
+
+ // Here we use mocks to "get by" preconditions that are not
+ // satisfied in the testing environment.
+ let sandbox = sinon.createSandbox();
+ try {
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyStageUpdates")
+ .get(() => true);
+ sandbox
+ .stub(UpdateService.prototype, "canUsuallyApplyUpdates")
+ .get(() => true);
+
+ Services.prefs.setBoolPref("app.update.BITS.enabled", false);
+ let result = await reasons();
+ Assert.ok(result.includes(REASON.WINDOWS_CANNOT_USUALLY_USE_BITS));
+ result = await checkGleanPing();
+ Assert.ok(
+ result.includes(REASON.WINDOWS_CANNOT_USUALLY_USE_BITS),
+ "result : " + result.join("', '") + "']"
+ );
+
+ Services.prefs.setBoolPref("app.update.BITS.enabled", true);
+ result = await reasons();
+ Assert.ok(!result.includes(REASON.WINDOWS_CANNOT_USUALLY_USE_BITS));
+ result = await checkGleanPing();
+ Assert.ok(!result.includes(REASON.WINDOWS_CANNOT_USUALLY_USE_BITS));
+ } finally {
+ sandbox.restore();
+ Services.prefs.setBoolPref("app.update.BITS.enabled", prev);
+ }
+ }
+);
+
+add_task(async function test_reasons_update_manual_update_only() {
+ await setupPolicyEngineWithJson({
+ policies: {
+ ManualAppUpdateOnly: true,
+ },
+ });
+ Assert.equal(
+ Services.policies.status,
+ Ci.nsIEnterprisePolicies.ACTIVE,
+ "Engine is active"
+ );
+
+ let result = await reasons();
+ Assert.ok(result.includes(REASON.MANUAL_UPDATE_ONLY));
+ result = await checkGleanPing();
+ Assert.ok(result.includes(REASON.MANUAL_UPDATE_ONLY));
+
+ await setupPolicyEngineWithJson({});
+
+ result = await reasons();
+ Assert.ok(!result.includes(REASON.MANUAL_UPDATE_ONLY));
+ result = await checkGleanPing();
+ Assert.ok(!result.includes(REASON.MANUAL_UPDATE_ONLY));
+});
+
+add_task(
+ {
+ skip_if: () => AppConstants.platform != "win",
+ },
+ async function test_unelevated_nimbus_enabled() {
+ // Enable feature.
+ Services.prefs.setBoolPref(
+ "app.update.background.allowUpdatesForUnelevatedInstallations",
+ true
+ );
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref(
+ "app.update.background.allowUpdatesForUnelevatedInstallations"
+ );
+ });
+
+ // execute!
+ let r = await reasons();
+ Assert.ok(
+ !r.includes(BackgroundUpdate.REASON.SERVICE_REGISTRY_KEY_MISSING),
+ `no SERVICE_REGISTRY_KEY_MISSING in ${JSON.stringify(r)}`
+ );
+ Assert.ok(
+ !r.includes(BackgroundUpdate.REASON.APPBASEDIR_NOT_WRITABLE),
+ `no APPBASEDIR_NOT_WRITABLE in ${JSON.stringify(r)}`
+ );
+
+ // the test directory usually is writable, but we now create a file and keep
+ // it open, so that the test file can neither be deleted nor recreated and
+ // appears to be locked. With that we re-execute the test and expect to find
+ // APPBASEDIR_NOT_WRITABLE in the telemetry data.
+ let appDirTestFile = Services.dirsvc.get(
+ XRE_EXECUTABLE_FILE,
+ Ci.nsIFile
+ ).parent;
+ appDirTestFile.append(FILE_UPDATE_TEST);
+ appDirTestFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+
+ var outputStream = Cc[
+ "@mozilla.org/network/file-output-stream;1"
+ ].createInstance(Ci.nsIFileOutputStream);
+ // WR_ONLY|CREATE|TRUNC
+ outputStream.init(appDirTestFile, 0x02 | 0x08 | 0x20, 0o644, null);
+ registerCleanupFunction(() => {
+ outputStream.close();
+ appDirTestFile.remove(false);
+ });
+ // after the preperation: execute again!
+ r = await reasons();
+ Assert.ok(
+ r.includes(BackgroundUpdate.REASON.APPBASEDIR_NOT_WRITABLE),
+ `no APPBASEDIR_NOT_WRITABLE in ${JSON.stringify(r)}`
+ );
+ }
+);
+
+add_task(
+ {
+ skip_if: () => AppConstants.platform != "win",
+ },
+ async function test_unelevated_nimbus_disabled() {
+ // Disable feature.
+ Services.prefs.setBoolPref(
+ "app.update.background.allowUpdatesForUnelevatedInstallations",
+ false
+ );
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref(
+ "app.update.background.allowUpdatesForUnelevatedInstallations"
+ );
+ });
+
+ let r = await reasons();
+ Assert.ok(
+ r.includes(BackgroundUpdate.REASON.SERVICE_REGISTRY_KEY_MISSING),
+ `SERVICE_REGISTRY_KEY_MISSING in ${JSON.stringify(r)}`
+ );
+ }
+);
+
+add_task(() => {
+ // `setupTestCommon()` calls `do_test_pending()`; this calls
+ // `do_test_finish()`. The `add_task` schedules this to run after all the
+ // other tests have completed.
+ doTestFinish();
+});