commit 1346bd8346bccbccc64e48d89aeade48d27b9e2f
parent 2db2ad618c5d8148357fdd8d720f8c2225dfdc79
Author: Cristina Horotan <chorotan@mozilla.com>
Date: Thu, 9 Oct 2025 02:08:24 +0300
Revert "Bug 1984458 - Add tests that `UpdateService` notices when `update.status` is inaccessible r=cdupuis,nrishel" for causing xpcshell failures on accessAndLockout.js
This reverts commit 2665adee74b624d68ed0fa0153396945b1f1a1e8.
Revert "Bug 1984458 - Add test utilities for `update.status` I/O failures r=cdupuis,nrishel"
This reverts commit ad4dbea294fbfbf7a9d5573330ad6a1d11e08846.
Revert "Bug 1984458 - Make `UpdateService` check for persistent access failures r=cdupuis,nrishel"
This reverts commit 2e959490d411967d2f1f87e272e052c8325f4dfa.
Diffstat:
9 files changed, 17 insertions(+), 483 deletions(-)
diff --git a/toolkit/mozapps/update/UpdateService.sys.mjs b/toolkit/mozapps/update/UpdateService.sys.mjs
@@ -84,11 +84,6 @@ const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
const PREF_APP_UPDATE_ELEVATE_VERSION = "app.update.elevate.version";
const PREF_APP_UPDATE_ELEVATE_ATTEMPTS = "app.update.elevate.attempts";
const PREF_APP_UPDATE_ELEVATE_MAXATTEMPTS = "app.update.elevate.maxAttempts";
-const PREF_APP_UPDATE_LOCKEDOUT_COUNT = "app.update.lockedOut.count";
-const PREF_APP_UPDATE_LOCKEDOUT_DEBOUNCETIME =
- "app.update.lockedOut.debounceTimeMs";
-const PREF_APP_UPDATE_LOCKEDOUT_MAXCOUNT = "app.update.lockedOut.maxCount";
-const PREF_APP_UPDATE_LOCKEDOUT_MAXAGE = "app.update.lockedOut.maxAgeMs";
const PREF_APP_UPDATE_LANGPACK_ENABLED = "app.update.langpack.enabled";
const PREF_APP_UPDATE_LANGPACK_TIMEOUT = "app.update.langpack.timeout";
const PREF_APP_UPDATE_NOTIFYDURINGDOWNLOAD = "app.update.notifyDuringDownload";
@@ -311,8 +306,6 @@ let gOnlyDownloadUpdatesThisSession = false;
// This will be the backing for `nsIApplicationUpdateService.currentState`
var gUpdateState = Ci.nsIApplicationUpdateService.STATE_IDLE;
-let gLastLockoutDebouncedAt = 0;
-
/**
* Simple container and constructor for a Promise and its resolve function.
*/
@@ -1050,92 +1043,6 @@ function getDownloadingUpdateDir() {
}
/**
- * If there is a problem with accessing the status file, it may be a transient
- * issue, such as another process checking for updates holding a lock,
- * or it may be a persistent problem that needs attention.
- * This function tries to determine if we should prompt the user to fix the
- * issue.
- *
- * @param file
- * An nsIFile object for the file with the issue
- * @param ex
- * The Exception object that was thrown when attempting to access the
- * file.
- */
-function onStateAccessFailure(file, ex) {
- LOG("onStateAccessFailure. Ex: " + ex);
- if (
- ex.result == Cr.NS_ERROR_FILE_ACCESS_DENIED ||
- ex.result == Cr.NS_ERROR_FILE_IS_LOCKED
- ) {
- // Looks like we can't access the file. If it hasn't changed in
- // a long time, notify the user that we are persistently unable to update.
- const oneMinMs = 60 * 1000;
- const oneDayMs = 24 * 60 * oneMinMs;
- const now = Date.now();
-
- // A single update check can attempt to read and write the update state
- // multiple times. We want `lockoutCount` to count the number of times that
- // an update check fails, not the number of times that we fail to access the
- // state. To deal with this, we will implement a debouncing period after
- // each failure.
- let debounceTimeMs = Services.prefs.getIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_DEBOUNCETIME,
- 5 * oneMinMs
- );
- debounceTimeMs = Math.min(debounceTimeMs, oneDayMs);
- const debounceEnd = gLastLockoutDebouncedAt + debounceTimeMs;
- if (now < debounceEnd) {
- LOG(`onStateAccessFailure: debounced! (${debounceEnd - now}ms left)`);
- return;
- }
- gLastLockoutDebouncedAt = now;
-
- // Not really the age, just the interval since last modified.
- const fileAgeMs = now - file.lastModifiedTime;
-
- let lockoutCount = Services.prefs.getIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_COUNT,
- 0
- );
- lockoutCount += 1;
- Services.prefs.setIntPref(PREF_APP_UPDATE_LOCKEDOUT_COUNT, lockoutCount);
-
- let maxLockoutCount = Services.prefs.getIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_MAXCOUNT,
- 4
- );
- maxLockoutCount = Math.min(maxLockoutCount, 20);
- LOG(
- `onStateAccessFailure: lockoutCount is ${lockoutCount}, maxLockoutCount is ${maxLockoutCount}`
- );
-
- let maxFileAgeMs = Services.prefs.getIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_MAXAGE,
- oneDayMs * 2
- );
- maxFileAgeMs = Math.min(maxFileAgeMs, oneDayMs * 14);
- LOG(
- `onStateAccessFailure: fileAgeMs = ${fileAgeMs} maxFileAgeMs = ${maxFileAgeMs}`
- );
-
- if (lockoutCount >= maxLockoutCount && fileAgeMs >= maxFileAgeMs) {
- Glean.update.stateWriteFailure.add();
- // Create an empty Update object for messaging.
- let update = new Update(null);
- LOG("onStateAccessFailure: reporting permission issue");
- Services.obs.notifyObservers(update, "update-error", "bad-perms");
- Services.prefs.setIntPref(PREF_APP_UPDATE_LOCKEDOUT_COUNT, 0);
- }
- }
-}
-
-function onStateAccessSuccess() {
- LOG("onStateAccessSuccess");
- Services.prefs.setIntPref(PREF_APP_UPDATE_LOCKEDOUT_COUNT, 0);
-}
-
-/**
* Reads the update state from the update.status file in the specified
* directory.
* @param dir
@@ -1154,31 +1061,16 @@ function readStatusFile(dir) {
* Writes the current update operation/state to a file in the patch
* directory, indicating to the patching system that operations need
* to be performed.
- *
- * This function does not throw on errors. It just returns the error.
- *
* @param dir
* The patch directory where the update.status file should be
* written.
* @param state
* The state value to write.
- * @returns `null` on success or a JS exception on failure.
*/
function writeStatusFile(dir, state) {
let statusFile = dir.clone();
statusFile.append(FILE_UPDATE_STATUS);
- try {
- writeStringToFile(statusFile, state);
- LOG("writeStatusFile - status: " + state + ", path: " + statusFile.path);
- try {
- onStateAccessSuccess();
- } catch {}
- } catch (ex) {
- LOG("writeStatusFile failed: " + ex);
- onStateAccessFailure(statusFile, ex);
- return ex;
- }
- return null;
+ writeStringToFile(statusFile, state);
}
/**
@@ -1189,9 +1081,6 @@ function writeStatusFile(dir, state) {
* the update should be applied. Note that this won't provide protection from
* downgrade of the application for the nightly user case where the application
* version doesn't change.
- *
- * This function fails silently.
- *
* @param dir
* The patch directory where the update.version file should be
* written.
@@ -1202,11 +1091,7 @@ function writeStatusFile(dir, state) {
function writeVersionFile(dir, version) {
let versionFile = dir.clone();
versionFile.append(FILE_UPDATE_VERSION);
- try {
- writeStringToFile(versionFile, version);
- } catch (ex) {
- LOG("writeVersionFile failed: " + ex);
- }
+ writeStringToFile(versionFile, version);
}
/**
@@ -1540,20 +1425,19 @@ async function cleanupActiveUpdates() {
* written to the file. This function only works with ASCII text.
* @param file An nsIFile indicating what file to write to.
* @param text A string containing the text to write to the file.
- * @throws Errors from file stream will be propagated.
+ * @return true on success, false on failure.
*/
function writeStringToFile(file, text) {
- let fos = FileUtils.openSafeFileOutputStream(file);
- text += "\n";
- fos.write(text, text.length);
- // Don't use `FileUtils.closeSafeFileOutputStream` because it swallows errors,
- // which we don't want to do here.
try {
- fos.QueryInterface(Ci.nsISafeOutputStream);
- fos.finish();
- } finally {
- fos.close();
+ let fos = FileUtils.openSafeFileOutputStream(file);
+ text += "\n";
+ fos.write(text, text.length);
+ FileUtils.closeSafeFileOutputStream(fos);
+ } catch (e) {
+ LOG(`writeStringToFile - Failed to write to file: "${file}". Error: ${e}"`);
+ return false;
}
+ return true;
}
function readStringFromInputStream(inputStream) {
@@ -6516,14 +6400,8 @@ class Downloader {
}
if (!lazy.UM.internal.readyUpdate) {
- const error = writeStatusFile(getReadyUpdateDir(), STATE_DOWNLOADING);
- if (error) {
- LOG("Downloader:downloadUpdate - Failed to set status to downloading");
- await cleanupActiveUpdates();
- return Ci.nsIApplicationUpdateService
- .DOWNLOAD_FAILURE_CANNOT_WRITE_STATE;
- }
- LOG("Downloader:downloadUpdate - Set status to downloading");
+ LOG("Downloader:downloadUpdate - Setting status to downloading");
+ writeStatusFile(getReadyUpdateDir(), STATE_DOWNLOADING);
}
if (this._patch.state != STATE_DOWNLOADING) {
LOG("Downloader:downloadUpdate - Setting state to downloading");
diff --git a/toolkit/mozapps/update/metrics.yaml b/toolkit/mozapps/update/metrics.yaml
@@ -467,20 +467,6 @@ update:
expires: never
telemetry_mirror: h#UPDATE_SERVICE_MANUALLY_UNINSTALLED_SUBSEQUENT
- state_write_failure:
- type: counter
- description: >
- Update: Count of the number of times we have shown a notification to the
- user that they need to manually update because we cannot write to the
- update status file.
- bugs:
- - https://bugzilla.mozilla.org/show_bug.cgi?id=1984458
- data_reviews:
- - https://bugzilla.mozilla.org/show_bug.cgi?id=1984458
- notification_emails:
- - application-update-telemetry-alerts@mozilla.com
- expires: never
-
unable_to_apply_external:
type: counter
description: >
diff --git a/toolkit/mozapps/update/nsIUpdateService.idl b/toolkit/mozapps/update/nsIUpdateService.idl
@@ -490,9 +490,6 @@ interface nsIApplicationUpdateService : nsISupports
// The update download cannot be started for a reason that doesn't have a more
// specific failure code.
const long DOWNLOAD_FAILURE_GENERIC = 3;
- // The update download cannot be started because the update state could not
- // be written to the update directory.
- const long DOWNLOAD_FAILURE_CANNOT_WRITE_STATE = 4;
/**
* Starts downloading the update passed. Once the update is downloaded, it
diff --git a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -154,7 +154,6 @@ const APP_UPDATE_SJS_HOST = "http://127.0.0.1";
const APP_UPDATE_SJS_PATH = "/" + REL_PATH_DATA + "app_update.sjs";
var gIncrementalDownloadErrorType;
-var gIncrementalDownloadCancelOk = false;
var gResponseBody;
@@ -5175,13 +5174,7 @@ IncrementalDownload.prototype = {
/* nsIRequest */
cancel(_aStatus) {
- // We aren't actually going to do anything to cancel this. The tests should
- // clean up the completed download either way, so it should never really
- // matter if we actually finish it after calling this. But we want to throw
- // an error if a test calls this unexpectedly.
- if (!gIncrementalDownloadCancelOk) {
- throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
- }
+ throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
},
suspend() {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
@@ -5704,12 +5697,6 @@ const EXIT_CODE = ${JSON.stringify(TestUpdateMutexCrossProcess.EXIT_CODE)};
* expectedDownloadResult
* This function asserts that the download should finish with this
* result. Defaults to `NS_OK`.
- * expectedDownloadStartResult
- * This function asserts that `AUS.downloadUpdate` return the
- * expected value. Defaults to
- * `Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS`. If a different
- * value is specified, later checks that the download completed
- * properly will be skipped.
* incrementalDownloadErrorType
* This can be used to specify an alternate value of
* `gIncrementalDownloadErrorType`. The default value is `3`, which
@@ -5732,7 +5719,6 @@ async function downloadUpdate({
expectDownloadRestriction,
expectedCheckResult,
expectedDownloadResult = Cr.NS_OK,
- expectedDownloadStartResult = Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS,
incrementalDownloadErrorType = 3,
onDownloadStartCallback,
slowDownload,
@@ -5750,10 +5736,7 @@ async function downloadUpdate({
"update-download-restriction-hit"
);
});
- } else if (
- expectedDownloadStartResult ==
- Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS
- ) {
+ } else {
downloadFinishedPromise = new Promise(resolve =>
gAUS.addDownloadListener({
onStartRequest: _aRequest => {},
@@ -5817,9 +5800,6 @@ async function downloadUpdate({
initMockIncrementalDownload();
gIncrementalDownloadErrorType = incrementalDownloadErrorType;
- gIncrementalDownloadCancelOk =
- expectedDownloadStartResult !=
- Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS;
update = await gAUS.selectUpdate(updates);
}
@@ -5844,12 +5824,9 @@ async function downloadUpdate({
const result = await gAUS.downloadUpdate(update);
Assert.equal(
result,
- expectedDownloadStartResult,
- "nsIApplicationUpdateService:downloadUpdate status should be correct"
+ Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS,
+ "nsIApplicationUpdateService:downloadUpdate should succeed"
);
- if (result != Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS) {
- return;
- }
}
if (waitToStartPromise) {
@@ -5879,60 +5856,3 @@ async function downloadUpdate({
await TestUtils.waitForTick();
}
}
-
-/**
- * Holds a file open until it ought to be closed.
- *
- * @param file
- * The `nsIFile` for the file to be held open
- * @param shareMode
- * Optional. The share mode (`dwShareMode`) to pass to `CreateFileW`
- * when opening the file. If provided, should be a string containing
- * a combination of 'r', 'w', and 'd' to indicate sharing for the
- * read, write, and delete permissions, respectively. The default is to
- * share nothing.
- * @return An asynchronous function taking no arguments. When it is called and
- * the returned promise resolves, the file is no longer being held open.
- */
-async function holdFileOpen(file, shareMode) {
- const testHelper = getTestDirFile("test_file_hold_open.exe", false);
-
- const args = [file.path];
- if (shareMode) {
- args.push(shareMode);
- }
-
- const proc = await Subprocess.call({
- command: testHelper.path,
- arguments: args,
- });
- const isLocked = await proc.stdout.readString();
-
- if (isLocked.trim() != "Locked") {
- throw new Error("Expected status to be Locked, found " + isLocked);
- }
-
- return async () => {
- await proc.stdin.write("q");
- const rc = await proc.wait(1000);
- Assert.equal(rc.exitCode, 0, "Expected process to have successful exit");
- };
-}
-
-async function setFileModifiedAge(outfile, ageInSeconds) {
- const outfilePath = outfile.path;
- const testHelper = getTestDirFile("test_file_update_mtime.exe");
-
- let proc = await Subprocess.call({
- command: testHelper.path,
- arguments: [outfilePath, ageInSeconds],
- });
-
- let stdout;
- while ((stdout = await proc.stdout.readString())) {
- logTestInfo(stdout);
- }
-
- const rc = await proc.wait(1000); // Wait for it to exit.
- Assert.equal(rc.exitCode, 0, "Expected process to have successful exit");
-}
diff --git a/toolkit/mozapps/update/tests/moz.build b/toolkit/mozapps/update/tests/moz.build
@@ -34,9 +34,6 @@ SimplePrograms(
]
)
-if CONFIG["OS_ARCH"] == "WINNT":
- SimplePrograms(["test_file_hold_open", "test_file_update_mtime"])
-
LOCAL_INCLUDES += [
"/toolkit/mozapps/update",
"/toolkit/mozapps/update/common",
diff --git a/toolkit/mozapps/update/tests/test_file_hold_open.cpp b/toolkit/mozapps/update/tests/test_file_hold_open.cpp
@@ -1,53 +0,0 @@
-#include <windows.h>
-#include <iostream>
-#include <string>
-
-// Opens a file and holds it open until the caller sends input.
-// Then it closes the file and exits.
-
-void usage(int argc, wchar_t** argv) {
- std::wcout << L"Usage:\n"
- << L" " << argv[0] << L" filename [sharing]\n\n"
- << L" filename\n"
- << L" The path of the file to hold open.\n"
- << L" sharing\n"
- << L" File sharing flags. 'r', 'w', and/or 'd' can be\n"
- << L" specified. Defaults to no sharing.\n\n";
-}
-
-int wmain(int argc, wchar_t** argv) {
- DWORD dwShareMode = 0;
-
- if (argc < 2 || argc > 3) {
- usage(argc, argv);
- exit(1);
- }
- if (argc >= 3) {
- for (wchar_t* curr = argv[2]; *curr; ++curr) {
- switch (*curr) {
- case L'w':
- dwShareMode |= FILE_SHARE_WRITE;
- break;
- case L'r':
- dwShareMode |= FILE_SHARE_READ;
- break;
- case L'd':
- dwShareMode |= FILE_SHARE_DELETE;
- break;
- default:
- usage(argc, argv);
- return 1;
- }
- }
- }
- HANDLE handle = CreateFileW(argv[1], GENERIC_READ, dwShareMode, nullptr,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (handle == INVALID_HANDLE_VALUE) {
- std::wcout << L"failed to open file " << argv[1] << std::endl;
- return 1;
- }
- std::wcout << "Locked" << std::endl;
- (void)std::wcin.get();
- CloseHandle(handle);
- return 0;
-}
diff --git a/toolkit/mozapps/update/tests/test_file_update_mtime.cpp b/toolkit/mozapps/update/tests/test_file_update_mtime.cpp
@@ -1,65 +0,0 @@
-#include <windows.h>
-#include <iostream>
-#include <string>
-
-void usage(int argc, wchar_t** argv) {
- std::wcout << L"Usage:\n"
- << L" " << argv[0] << L" filename age\n\n"
- << L" filename\n"
- << L" The path of the file to change.\n"
- << L" age\n"
- << L" The number of seconds in the past to set the file's \n"
- << L" modification time to.\n\n";
-}
-
-static const ULONGLONG FILETIME_TICKS_PER_SECOND = 10'000'000;
-
-static ULARGE_INTEGER secondsAgoTimestamp(ULONGLONG secondsAgo) {
- FILETIME now{};
- GetSystemTimeAsFileTime(&now);
- ULARGE_INTEGER systemTime;
- systemTime.LowPart = now.dwLowDateTime;
- systemTime.HighPart = now.dwHighDateTime;
- systemTime.QuadPart -= secondsAgo * FILETIME_TICKS_PER_SECOND;
- return systemTime;
-}
-
-int wmain(int argc, wchar_t** argv) {
- HANDLE handle;
- FILE_BASIC_INFO fileBasicInfo{};
- long ageInSeconds;
- if (argc != 3) {
- usage(argc, argv);
- return 1;
- }
- if (!swscanf(argv[2], L"%lu", &ageInSeconds)) {
- std::wcout << "Invalid seconds: " << argv[2] << std::endl;
- return 2;
- }
- if ((handle = CreateFileW(argv[1], GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, nullptr)) ==
- INVALID_HANDLE_VALUE) {
- std::wcout << "Error opening file: " << argv[1] << ", " << GetLastError()
- << std::endl;
- return 3;
- }
- if (!GetFileInformationByHandleEx(handle, FileBasicInfo, &fileBasicInfo,
- sizeof(fileBasicInfo))) {
- std::wcout << "Error getting file info: " << GetLastError() << std::endl;
- return 4;
- }
-
- ULARGE_INTEGER desiredTimestamp = secondsAgoTimestamp(ageInSeconds);
- fileBasicInfo.LastWriteTime.QuadPart = desiredTimestamp.QuadPart;
-
- if (!SetFileInformationByHandle(handle, FileBasicInfo, &fileBasicInfo,
- sizeof(fileBasicInfo))) {
- std::wcout << "Error setting file mtime: " << GetLastError() << std::endl;
- return 5;
- }
- if (!CloseHandle(handle)) {
- std::wcout << "Error closing handle: " << GetLastError() << std::endl;
- return 6;
- }
- return 0;
-}
diff --git a/toolkit/mozapps/update/tests/unit_aus_update/accessAndLockout.js b/toolkit/mozapps/update/tests/unit_aus_update/accessAndLockout.js
@@ -1,122 +0,0 @@
-/* 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/.
- */
-
-const PREF_APP_UPDATE_LOCKEDOUT_COUNT = "app.update.lockedOut.count";
-const PREF_APP_UPDATE_LOCKEDOUT_DEBOUNCETIME =
- "app.update.lockedOut.debounceTimeMs";
-const PREF_APP_UPDATE_LOCKEDOUT_MAXCOUNT = "app.update.lockedOut.maxCount";
-const PREF_APP_UPDATE_LOCKEDOUT_MAXAGE = "app.update.lockedOut.maxAgeMs";
-
-const kMaxLockedOutCount = 10;
-const kMaxStatusFileModifyAgeMs = 24 * 60 * 60 * 1000; // 1 day
-
-add_setup(async function setup() {
- setupTestCommon();
- start_httpserver();
- setUpdateURL(gURLData + gHTTPHandlerPath);
- setUpdateChannel("test_channel");
-
- // FOG needs a profile directory to put its data in.
- do_get_profile();
- Services.fog.initializeFOG();
-});
-
-async function runLockedOutTest({
- isLockedOut,
- statusFileIsOld,
- lockoutsRemaining,
-}) {
- await reloadUpdateManagerData();
- await reInitUpdateService();
- Services.fog.testResetFOG();
-
- const statusFile = getUpdateDirFile(FILE_UPDATE_STATUS);
-
- let lockoutCount = kMaxLockedOutCount - lockoutsRemaining;
- Services.prefs.setIntPref(PREF_APP_UPDATE_LOCKEDOUT_COUNT, lockoutCount);
-
- // Write an empty status file to ensure that the path exists.
- writeStatusFile("");
- if (statusFileIsOld) {
- await setFileModifiedAge(
- statusFile,
- Math.floor((2 * kMaxStatusFileModifyAgeMs) / 1000)
- );
- } else {
- await setFileModifiedAge(statusFile, 0);
- }
- let unlockStatusFile;
- if (isLockedOut) {
- unlockStatusFile = await holdFileOpen(statusFile, "r");
- } else {
- unlockStatusFile = async () => {};
- }
-
- const nextLockoutWillBeMax = lockoutsRemaining <= 1;
- const expectNotifyUser =
- isLockedOut && statusFileIsOld && nextLockoutWillBeMax;
- const badPermsObserverPromise = expectNotifyUser
- ? waitForEvent("update-error", "bad-perms")
- : Promise.resolve(true);
- const expectedDownloadStartResult = isLockedOut
- ? Ci.nsIApplicationUpdateService.DOWNLOAD_FAILURE_CANNOT_WRITE_STATE
- : Ci.nsIApplicationUpdateService.DOWNLOAD_SUCCESS;
-
- await downloadUpdate({ expectedDownloadStartResult });
-
- const badPermsObserverResult = await badPermsObserverPromise;
- Assert.ok(badPermsObserverResult);
-
- const newLockoutCount = Services.prefs.getIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_COUNT,
- -1
- );
- if (!isLockedOut || expectNotifyUser) {
- Assert.equal(newLockoutCount, 0, "lockout count should reset");
- } else {
- Assert.equal(
- newLockoutCount,
- lockoutCount + 1,
- "lockout count should incremented"
- );
- }
- if (expectNotifyUser) {
- Assert.equal(
- Glean.update.stateWriteFailure.testGetValue(),
- 1,
- "telemetry should be incremented"
- );
- } else {
- // Coerce the telemetry into an integer since this will generally return
- // `null`.
- Assert.equal(
- Number(Glean.update.stateWriteFailure.testGetValue()),
- 0,
- "telemetry should not be incremented"
- );
- }
-
- await unlockStatusFile();
-}
-
-add_task(async function testAccessAndLockout() {
- Services.prefs.setIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_MAXCOUNT,
- kMaxLockedOutCount
- );
- Services.prefs.setIntPref(PREF_APP_UPDATE_LOCKEDOUT_DEBOUNCETIME, 0);
- Services.prefs.setIntPref(
- PREF_APP_UPDATE_LOCKEDOUT_MAXAGE,
- kMaxStatusFileModifyAgeMs
- );
-
- await parameterizedTest(runLockedOutTest, {
- isLockedOut: [true, false],
- statusFileIsOld: [true, false],
- lockoutsRemaining: [1, 2],
- });
-
- await doTestFinish();
-});
diff --git a/toolkit/mozapps/update/tests/unit_aus_update/xpcshell.toml b/toolkit/mozapps/update/tests/unit_aus_update/xpcshell.toml
@@ -19,10 +19,6 @@ support-files = [
"../data/simple.mar",
]
-["accessAndLockout.js"]
-run-if = ["os == 'win'"]
-reason = "Testing mechanism is Windows-only as it relies on CreateFileW"
-
["ausReadStrings.js"]
["backgroundUpdateTaskInternalUpdater.js"]