зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1875502 - Fix tests broken by the previous patch stack that standardizes update initialization r=nalexander,application-update-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D204129
This commit is contained in:
Родитель
c9a19be7fa
Коммит
c288841e23
|
@ -286,18 +286,6 @@ const startupPhases = {
|
|||
// We reach this phase right after showing the first browser window.
|
||||
// This means that any I/O at this point delayed first paint.
|
||||
"before first paint": [
|
||||
{
|
||||
// bug 1545119
|
||||
path: "OldUpdRootD:",
|
||||
condition: WIN,
|
||||
stat: 1,
|
||||
},
|
||||
{
|
||||
// bug 1446012
|
||||
path: "UpdRootD:updates/0/update.status",
|
||||
condition: WIN,
|
||||
stat: 1,
|
||||
},
|
||||
{
|
||||
path: "XREAppFeat:formautofill@mozilla.org.xpi",
|
||||
condition: !WIN,
|
||||
|
|
|
@ -39,7 +39,8 @@ add_task(async function test_override_postupdate_page() {
|
|||
reloadUpdateManagerData(true);
|
||||
});
|
||||
|
||||
writeUpdatesToXMLFile(XML_UPDATE);
|
||||
writeFile(XML_UPDATE, getActiveUpdateFile());
|
||||
writeSuccessUpdateStatusFile();
|
||||
reloadUpdateManagerData(false);
|
||||
|
||||
is(
|
||||
|
@ -105,27 +106,41 @@ function reloadUpdateManagerData(skipFiles = false) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Writes the updates specified to the active-update.xml file.
|
||||
* Writes the specified text to the specified file.
|
||||
*
|
||||
* @param {string} aText
|
||||
* The updates represented as a string to write to the active-update.xml file.
|
||||
* The string to write to the file.
|
||||
* @param {nsIFile} aFile
|
||||
* The file to write to.
|
||||
*/
|
||||
function writeUpdatesToXMLFile(aText) {
|
||||
function writeFile(aText, aFile) {
|
||||
const PERMS_FILE = 0o644;
|
||||
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
|
||||
let activeUpdateFile = getActiveUpdateFile();
|
||||
if (!activeUpdateFile.exists()) {
|
||||
activeUpdateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
if (!aFile.exists()) {
|
||||
aFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
}
|
||||
let fos = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
let flags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
|
||||
fos.init(activeUpdateFile, flags, PERMS_FILE, 0);
|
||||
fos.init(aFile, flags, PERMS_FILE, 0);
|
||||
fos.write(aText, aText.length);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* If we want the update system to treat the update we wrote out as one that it
|
||||
* just installed, we need to make it think that the update state is
|
||||
* "succeeded".
|
||||
*/
|
||||
function writeSuccessUpdateStatusFile() {
|
||||
const statusFile = Services.dirsvc.get("UpdRootD", Ci.nsIFile);
|
||||
statusFile.append("updates");
|
||||
statusFile.append("0");
|
||||
statusFile.append("update.status");
|
||||
writeFile("succeeded", statusFile);
|
||||
}
|
||||
|
|
|
@ -120,10 +120,11 @@ add_task(async function test_bug538331() {
|
|||
if (testCase.openURL) {
|
||||
actionsXML += ' openURL="' + testCase.openURL + '"';
|
||||
}
|
||||
writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
|
||||
writeFile(XML_PREFIX + actionsXML + XML_SUFFIX, getActiveUpdateFile());
|
||||
} else {
|
||||
writeUpdatesToXMLFile(XML_EMPTY);
|
||||
writeFile(XML_EMPTY, getActiveUpdateFile());
|
||||
}
|
||||
writeSuccessUpdateStatusFile();
|
||||
|
||||
reloadUpdateManagerData(false);
|
||||
|
||||
|
@ -200,28 +201,41 @@ function reloadUpdateManagerData(skipFiles = false) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Writes the updates specified to the active-update.xml file.
|
||||
* Writes the specified text to the specified file.
|
||||
*
|
||||
* @param aText
|
||||
* The updates represented as a string to write to the active-update.xml
|
||||
* file.
|
||||
* @param {string} aText
|
||||
* The string to write to the file.
|
||||
* @param {nsIFile} aFile
|
||||
* The file to write to.
|
||||
*/
|
||||
function writeUpdatesToXMLFile(aText) {
|
||||
function writeFile(aText, aFile) {
|
||||
const PERMS_FILE = 0o644;
|
||||
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
|
||||
let activeUpdateFile = getActiveUpdateFile();
|
||||
if (!activeUpdateFile.exists()) {
|
||||
activeUpdateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
if (!aFile.exists()) {
|
||||
aFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
}
|
||||
let fos = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
let flags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
|
||||
fos.init(activeUpdateFile, flags, PERMS_FILE, 0);
|
||||
fos.init(aFile, flags, PERMS_FILE, 0);
|
||||
fos.write(aText, aText.length);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* If we want the update system to treat the update we wrote out as one that it
|
||||
* just installed, we need to make it think that the update state is
|
||||
* "succeeded".
|
||||
*/
|
||||
function writeSuccessUpdateStatusFile() {
|
||||
const statusFile = Services.dirsvc.get("UpdRootD", Ci.nsIFile);
|
||||
statusFile.append("updates");
|
||||
statusFile.append("0");
|
||||
statusFile.append("update.status");
|
||||
writeFile("succeeded", statusFile);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ class PurgeHTTPCacheAtShutdownTestCase(MarionetteTestCase):
|
|||
return Services.dirsvc.get("UpdRootD", Ci.nsIFile).parent.parent.path;
|
||||
"""
|
||||
)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
self.lock_dir = Path(path)
|
||||
|
||||
def assertNoLocks(self):
|
||||
|
|
|
@ -44,7 +44,8 @@ add_task(async function test_updatePing() {
|
|||
activeUpdateFile.remove(false);
|
||||
reloadUpdateManagerData(true);
|
||||
});
|
||||
writeUpdatesToXMLFile(XML_UPDATE);
|
||||
writeFile(XML_UPDATE, getActiveUpdateFile());
|
||||
writeSuccessUpdateStatusFile();
|
||||
reloadUpdateManagerData(false);
|
||||
|
||||
// Start monitoring the ping archive.
|
||||
|
@ -138,28 +139,41 @@ function reloadUpdateManagerData(skipFiles = false) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Writes the updates specified to the active-update.xml file.
|
||||
* Writes the specified text to the specified file.
|
||||
*
|
||||
* @param aText
|
||||
* The updates represented as a string to write to the active-update.xml
|
||||
* file.
|
||||
* @param {string} aText
|
||||
* The string to write to the file.
|
||||
* @param {nsIFile} aFile
|
||||
* The file to write to.
|
||||
*/
|
||||
function writeUpdatesToXMLFile(aText) {
|
||||
function writeFile(aText, aFile) {
|
||||
const PERMS_FILE = 0o644;
|
||||
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
|
||||
let activeUpdateFile = getActiveUpdateFile();
|
||||
if (!activeUpdateFile.exists()) {
|
||||
activeUpdateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
if (!aFile.exists()) {
|
||||
aFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
}
|
||||
let fos = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
let flags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
|
||||
fos.init(activeUpdateFile, flags, PERMS_FILE, 0);
|
||||
fos.init(aFile, flags, PERMS_FILE, 0);
|
||||
fos.write(aText, aText.length);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* If we want the update system to treat the update we wrote out as one that it
|
||||
* just installed, we need to make it think that the update state is
|
||||
* "succeeded".
|
||||
*/
|
||||
function writeSuccessUpdateStatusFile() {
|
||||
const statusFile = Services.dirsvc.get("UpdRootD", Ci.nsIFile);
|
||||
statusFile.append("updates");
|
||||
statusFile.append("0");
|
||||
statusFile.append("update.status");
|
||||
writeFile("succeeded", statusFile);
|
||||
}
|
||||
|
|
|
@ -1505,7 +1505,7 @@ function cleanupDownloadingUpdate() {
|
|||
if (status == STATE_DOWNLOADING) {
|
||||
let statusFile = readyUpdateDir.clone();
|
||||
statusFile.append(FILE_UPDATE_STATUS);
|
||||
statusFile.remove();
|
||||
statusFile.remove(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3409,7 +3409,11 @@ export class UpdateService {
|
|||
// update checks, because manual update checking uses a completely
|
||||
// different code path (AppUpdater.sys.mjs creates its own nsIUpdateChecker),
|
||||
// bypassing this function completely.
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_DISABLED_BY_POLICY);
|
||||
if (!this.disabledForTesting) {
|
||||
// This can cause some problems for tests that aren't setup properly for
|
||||
// this.
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_DISABLED_BY_POLICY);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,15 @@ function handleRequest(aRequest, aResponse) {
|
|||
return;
|
||||
}
|
||||
|
||||
let marBytes = readFileBytes(getTestDataFile(FILE_SIMPLE_MAR));
|
||||
if (params.firstByteEarly) {
|
||||
// Sending the first byte early causes the request's `onStartRequest`
|
||||
// to be fired before the continue file is written.
|
||||
const firstByte = marBytes[0];
|
||||
marBytes = marBytes.substring(1);
|
||||
aResponse.write(firstByte);
|
||||
}
|
||||
|
||||
let retries = 0;
|
||||
gSlowDownloadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
gSlowDownloadTimer.initWithCallback(
|
||||
|
@ -92,7 +101,7 @@ function handleRequest(aRequest, aResponse) {
|
|||
continueFile.remove(false);
|
||||
}
|
||||
gSlowDownloadTimer.cancel();
|
||||
aResponse.write(readFileBytes(getTestDataFile(FILE_SIMPLE_MAR)));
|
||||
aResponse.write(marBytes);
|
||||
aResponse.finish();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
@ -142,6 +151,9 @@ function handleRequest(aRequest, aResponse) {
|
|||
let url = "";
|
||||
if (params.useSlowDownloadMar) {
|
||||
url = URL_HTTP_UPDATE_SJS + "?slowDownloadMar=1";
|
||||
if (params.useFirstByteEarly) {
|
||||
url += "&firstByteEarly=1";
|
||||
}
|
||||
} else {
|
||||
url = params.badURL ? BAD_SERVICE_URL : SERVICE_URL;
|
||||
}
|
||||
|
|
|
@ -2286,6 +2286,11 @@ function checkSymlink() {
|
|||
* Sets the active update and related information for updater tests.
|
||||
*/
|
||||
async function setupActiveUpdate() {
|
||||
// The update system being initialized at an unexpected time could cause
|
||||
// unexpected effects in the reload process. Make sure that initialization
|
||||
// has already run first.
|
||||
await gAUS.init();
|
||||
|
||||
let pendingState = gIsServiceTest ? STATE_PENDING_SVC : STATE_PENDING;
|
||||
let patchProps = { state: pendingState };
|
||||
let patches = getLocalPatchString(patchProps);
|
||||
|
@ -3164,6 +3169,11 @@ async function setupUpdaterTest(
|
|||
{ requiresOmnijar = false } = {}
|
||||
) {
|
||||
debugDump("start - updater test setup");
|
||||
// Make sure that update has already been initialized. If post update
|
||||
// processing unexpectedly runs between this setup and when we use these
|
||||
// files, it may clean them up before we get the chance to use them.
|
||||
await gAUS.init();
|
||||
|
||||
let updatesPatchDir = getUpdateDirFile(DIR_PATCH);
|
||||
if (!updatesPatchDir.exists()) {
|
||||
updatesPatchDir.create(Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
|
||||
|
|
|
@ -137,24 +137,52 @@ class TestNoWindowUpdateRestart(MarionetteTestCase):
|
|||
)
|
||||
self.assertTrue(quit_flags_correct)
|
||||
|
||||
# Normally, the update status file would have been removed at this point by Post Update
|
||||
# Processing. But restarting resets app.update.disabledForTesting, which causes that to be
|
||||
# skipped, allowing us to look at the update status file directly.
|
||||
update_status_path = self.marionette.execute_script(
|
||||
update_status = self.marionette.execute_async_script(
|
||||
"""
|
||||
let statusFile = FileUtils.getDir("UpdRootD", ["updates", "0"]);
|
||||
statusFile.append("update.status");
|
||||
return statusFile.path;
|
||||
"""
|
||||
let [updateURLString, resolve] = arguments;
|
||||
(async () => {
|
||||
// Because post update processing happens during early startup and
|
||||
// `app.update.disabledForTesting` is also set in early startup, it isn't
|
||||
// especially well defined whether or not post update processing will have run at
|
||||
// this point. Resolve this by forcing post update processing to run. This is as
|
||||
// simple as turning off `app.update.disabledForTesting` and calling into
|
||||
// UpdateManager, since the relevant methods ensure that initialization has run
|
||||
// as long as update isn't disabled.
|
||||
|
||||
// Set the update URL to a local one first to ensure we don't hit the update server
|
||||
// when we turn off `app.update.disabledForTesting`.
|
||||
const mockAppInfo = Object.create(Services.appinfo, {
|
||||
updateURL: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: updateURLString,
|
||||
},
|
||||
});
|
||||
Services.appinfo = mockAppInfo;
|
||||
|
||||
Services.prefs.setBoolPref("app.update.disabledForTesting", false);
|
||||
|
||||
const UM =
|
||||
Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager);
|
||||
const history = await UM.getHistory();
|
||||
if (!history.length) {
|
||||
return null;
|
||||
}
|
||||
return history[0].state;
|
||||
})().then(resolve);
|
||||
""",
|
||||
script_args=(self.marionette.absolute_url("update.xml"),),
|
||||
)
|
||||
with open(update_status_path, "r") as f:
|
||||
# If Firefox was built with "--enable-unverified-updates" (or presumably if we tested
|
||||
# with an actual, signed update), the update should succeed. Otherwise, it will fail
|
||||
# with CERT_VERIFY_ERROR (error code 19). Unfortunately, there is no good way to tell
|
||||
# which of those situations we are in. Luckily, it doesn't matter, because we aren't
|
||||
# trying to test whether the update applied successfully, just whether the
|
||||
# "No Window Update Restart" feature works.
|
||||
self.assertIn(f.read().strip(), ["succeeded", "failed: 19"])
|
||||
|
||||
# If Firefox was built with "--enable-unverified-updates" (or presumably if we tested
|
||||
# with an actual, signed update), the update should succeed. Otherwise, it will fail
|
||||
# with CERT_VERIFY_ERROR (error code 19). Unfortunately, there is no good way to tell
|
||||
# which of those situations we are in. Luckily, it doesn't matter, because we aren't
|
||||
# trying to test whether the update applied successfully, just whether the
|
||||
# "No Window Update Restart" feature attempted to apply an update.
|
||||
# So both success and failure are fine. Any in-progress state is not.
|
||||
self.assertIn(update_status, ["succeeded", "failed"])
|
||||
|
||||
def resetUpdate(self):
|
||||
self.marionette.execute_script(
|
||||
|
|
|
@ -99,7 +99,7 @@ async function testCleanupSuccessLogsFIFO(
|
|||
"Last Update Elevated Log"
|
||||
);
|
||||
|
||||
await standardInit();
|
||||
await testPostUpdateProcessing();
|
||||
|
||||
Assert.ok(
|
||||
!(await gUpdateManager.getDownloadingUpdate()),
|
||||
|
|
|
@ -103,8 +103,8 @@ async function downloadUpdate(appUpdateAuto, onDownloadStartCallback) {
|
|||
await gAUS.downloadUpdate(update, true);
|
||||
}
|
||||
|
||||
await continueFileHandler(CONTINUE_DOWNLOAD);
|
||||
await waitToStartPromise;
|
||||
await continueFileHandler(CONTINUE_DOWNLOAD);
|
||||
await downloadFinishedPromise;
|
||||
// Wait an extra tick after the download has finished. If we try to check for
|
||||
// another update exactly when "update-downloaded" fires,
|
||||
|
@ -173,7 +173,7 @@ async function testUpdateCheckDoesNotStart() {
|
|||
}
|
||||
|
||||
function prepareToDownloadVersion(version, onlyCompleteMar = false) {
|
||||
let updateUrl = `${APP_UPDATE_SJS_URL}?useSlowDownloadMar=1&appVersion=${version}`;
|
||||
let updateUrl = `${APP_UPDATE_SJS_URL}?useSlowDownloadMar=1&useFirstByteEarly=1&appVersion=${version}`;
|
||||
if (onlyCompleteMar) {
|
||||
updateUrl += "&completePatchOnly=1";
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ async function run_test() {
|
|||
writeVersionFile("0.9");
|
||||
// Try to switch the application to the fake staged application.
|
||||
await runUpdateUsingApp(STATE_AFTER_STAGE);
|
||||
reloadUpdateManagerData();
|
||||
await testPostUpdateProcessing();
|
||||
checkPostUpdateRunningFile(false);
|
||||
setTestFilesAndDirsForFailure();
|
||||
|
|
Загрузка…
Ссылка в новой задаче