Bug 1526747 - Consolidate the calls to registerCleanupFunction where possible in app update's browser chrome tests. r=mhowell

Adds a common registerCleanupFunction for all tests
Moves several common test setup calls to the add_task used for common test setup
Also clean up several of the comments and formatting

Differential Revision: https://phabricator.services.mozilla.com/D19327

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Robert Strong 2019-02-11 18:17:53 +00:00
parent dcf26b19b4
commit 33b0c590c9
2 changed files with 103 additions and 106 deletions

View File

@ -11,14 +11,16 @@ ChromeUtils.defineModuleGetter(this, "UpdateListener",
"resource://gre/modules/UpdateListener.jsm");
const BIN_SUFFIX = (AppConstants.platform == "win" ? ".exe" : "");
const FILE_UPDATER_BIN = "updater" + (AppConstants.platform == "macosx" ? ".app" : BIN_SUFFIX);
const FILE_UPDATER_BIN =
"updater" + (AppConstants.platform == "macosx" ? ".app" : BIN_SUFFIX);
const FILE_UPDATER_BIN_BAK = FILE_UPDATER_BIN + ".bak";
const LOG_FUNCTION = info;
const MAX_UPDATE_COPY_ATTEMPTS = 10;
const DATA_URI_SPEC = "chrome://mochitests/content/browser/toolkit/mozapps/update/tests/browser/";
const DATA_URI_SPEC =
"chrome://mochitests/content/browser/toolkit/mozapps/update/tests/browser/";
/* import-globals-from testConstants.js */
Services.scriptloader.loadSubScript(DATA_URI_SPEC + "testConstants.js", this);
@ -35,14 +37,49 @@ let gOriginalUpdateAutoValue = null;
// the test's onload function.
gDebugTest = true;
/**
* Common tasks to perform for all tests before each one has started.
*/
add_task(async function setupTestCommon() {
await SpecialPowers.pushPrefEnv({
set: [
[PREF_APP_UPDATE_LOG, gDebugTest],
],
});
setUpdateTimerPrefs();
removeUpdateFiles(true);
// Most app update mochitest-browser-chrome tests expect auto update to be
// enabled. Those that don't will explicitly change this.
await setAppUpdateAutoEnabledHelper(true);
});
/**
* Common tasks to perform for all tests after each one has finished.
*/
registerCleanupFunction(async () => {
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "");
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "");
UpdateListener.reset();
reloadUpdateManagerData(true);
// Pass false when the log files are needed for troubleshooting the tests.
removeUpdateFiles(true);
// Always try to restore the original updater files. If none of the updater
// backup files are present then this is just a no-op.
await finishTestRestoreUpdaterBackup();
});
/**
* Creates the continue file used to signal that update staging or the mock http
* server should continue. The delay this creates allows the tests to verify the
* user interfaces before they auto advance to phases of an update. The continue
* file for staging will be deleted by the test updater and the continue file
* for update check and update download requests will be deleted by the test
* http server handler implemented in app_update.sjs. The test returns a promise
* so the test can wait on the deletion of the continue file when necessary.
* user interfaces before they auto advance to other phases of an update. The
* continue file for staging will be deleted by the test updater and the
* continue file for the update check and update download requests will be
* deleted by the test http server handler implemented in app_update.sjs. The
* test returns a promise so the test can wait on the deletion of the continue
* file when necessary. If the continue file still exists at the end of a test
* it will be removed to prevent it from affecting tests that run after the test
* that created it.
*
* @param leafName
* The leafName of the file to create. This should be one of the
@ -84,6 +121,16 @@ async function continueFileHandler(leafName) {
continueFile.path);
}
continueFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
// If for whatever reason the continue file hasn't been removed when a test
// has finished remove it during cleanup so it doesn't affect tests that run
// after the test that created it.
registerCleanupFunction(() => {
if (continueFile.exists()) {
logTestInfo("Removing continue file during test cleanup, path: " +
continueFile.path);
continueFile.remove(false);
}
});
return BrowserTestUtils.waitForCondition(() =>
(!continueFile.exists()),
"Waiting for file to be deleted, path: " + continueFile.path,
@ -120,6 +167,13 @@ function lockWriteTestFile() {
});
}
/**
* Closes the update mutex handle in nsUpdateService.js if it exists and then
* creates a new update mutex handle so the update code thinks there is another
* instance of the application handling updates.
*
* @throws If the function is called on a platform other than Windows.
*/
function setOtherInstanceHandlingUpdates() {
if (AppConstants.platform != "win") {
throw new Error("Windows only test function called");
@ -146,14 +200,6 @@ function getVersionParams(aAppVersion) {
return "&appVersion=" + (aAppVersion ? aAppVersion : appInfo.version);
}
/**
* Clean up updates list and the updates directory.
*/
function cleanUpUpdates() {
reloadUpdateManagerData(true);
removeUpdateFiles(true);
}
/**
* Prevent nsIUpdateTimerManager from notifying nsIApplicationUpdateService
* to check for updates by setting the app update last update time to the
@ -167,8 +213,11 @@ function setUpdateTimerPrefs() {
}
/*
* In addition to changing the value of the Auto Update setting, this function
* also takes care of cleaning up after itself.
* Sets the value of the App Auto Update setting and sets it back to the
* original value at the start of the test when the test finishes.
*
* @param enabled
* The value to set App Auto Update to.
*/
async function setAppUpdateAutoEnabledHelper(enabled) {
if (gOriginalUpdateAutoValue == null) {
@ -180,19 +229,6 @@ async function setAppUpdateAutoEnabledHelper(enabled) {
await UpdateUtils.setAppUpdateAutoEnabled(enabled);
}
add_task(async function setDefaults() {
await SpecialPowers.pushPrefEnv({
set: [
[PREF_APP_UPDATE_LOG, gDebugTest],
// See bug 1505790 - uses a very large value to prevent the sync code
// from running since it has nothing to do with these tests.
["services.sync.autoconnectDelay", 600000],
]});
// Most tests in this directory expect auto update to be enabled. Those that
// don't will explicitly change this.
await setAppUpdateAutoEnabledHelper(true);
});
/**
* Runs a typical update test. Will set various common prefs for using the
* updater doorhanger, runs the provided list of steps, and makes sure
@ -211,22 +247,15 @@ add_task(async function setDefaults() {
*/
function runUpdateTest(updateParams, checkAttempts, steps) {
return (async function() {
registerCleanupFunction(() => {
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "");
UpdateListener.reset();
cleanUpUpdates();
});
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1");
setUpdateTimerPrefs();
removeUpdateFiles(true);
await SpecialPowers.pushPrefEnv({
set: [
[PREF_APP_UPDATE_DOWNLOADPROMPTATTEMPTS, 0],
[PREF_APP_UPDATE_DISABLEDFORTESTING, false],
[PREF_APP_UPDATE_IDLETIME, 0],
[PREF_APP_UPDATE_URL_MANUAL, URL_MANUAL_UPDATE],
]});
],
});
await setupTestUpdater();
@ -249,8 +278,6 @@ function runUpdateTest(updateParams, checkAttempts, steps) {
for (let step of steps) {
await processStep(step);
}
await finishTestRestoreUpdaterBackup();
})();
}
@ -267,22 +294,15 @@ function runUpdateTest(updateParams, checkAttempts, steps) {
*/
function runUpdateProcessingTest(updates, steps) {
return (async function() {
registerCleanupFunction(() => {
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "");
UpdateListener.reset();
cleanUpUpdates();
});
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1");
setUpdateTimerPrefs();
removeUpdateFiles(true);
await SpecialPowers.pushPrefEnv({
set: [
[PREF_APP_UPDATE_DOWNLOADPROMPTATTEMPTS, 0],
[PREF_APP_UPDATE_DISABLEDFORTESTING, false],
[PREF_APP_UPDATE_IDLETIME, 0],
[PREF_APP_UPDATE_URL_MANUAL, URL_MANUAL_UPDATE],
]});
],
});
await setupTestUpdater();
@ -297,8 +317,6 @@ function runUpdateProcessingTest(updates, steps) {
for (let step of steps) {
await processStep(step);
}
await finishTestRestoreUpdaterBackup();
})();
}
@ -366,7 +384,8 @@ function waitForEvent(topic, status = null) {
* @return The button element.
*/
function getNotificationButton(win, notificationId, button) {
let notification = win.document.getElementById(`appMenu-${notificationId}-notification`);
let notification =
win.document.getElementById(`appMenu-${notificationId}-notification`);
is(notification.hidden, false, `${notificationId} notification is showing`);
return notification[button];
}
@ -492,9 +511,11 @@ function copyTestUpdater(attempt = 0) {
}
/**
* Restores the updater that was backed up. This is called in setupTestUpdater
* before the backup of the real updater is done in case the previous test
* failed to restore the updater when the test has finished.
* Restores the updater and updater related file that if there a backup exists.
* This is called in setupTestUpdater before the backup of the real updater is
* done in case the previous test failed to restore the file when a test has
* finished. This is also called in finishTestRestoreUpdaterBackup to restore
* the files when a test finishes.
*/
function restoreUpdaterBackup() {
let greBinDir = getGREBinDir();
@ -538,23 +559,21 @@ function restoreUpdaterBackup() {
}
/**
* When a staging test finishes this will repeatedly attempt to restore the real
* updater.
* When a test finishes this will repeatedly attempt to restore the real updater
* and the other files for the updater if a backup of the file exists.
*/
function finishTestRestoreUpdaterBackup() {
return (async function() {
if (Services.prefs.getBoolPref(PREF_APP_UPDATE_STAGING_ENABLED)) {
try {
// Windows debug builds keep the updater file in use for a short period of
// time after the updater process exits.
restoreUpdaterBackup();
} catch (e) {
logTestInfo("Attempt to restore the backed up updater failed... " +
"will try again, Exception: " + e);
try {
// Windows debug builds keep the updater file in use for a short period of
// time after the updater process exits.
restoreUpdaterBackup();
} catch (e) {
logTestInfo("Attempt to restore the backed up updater failed... " +
"will try again, Exception: " + e);
await TestUtils.waitForTick();
await finishTestRestoreUpdaterBackup();
}
await TestUtils.waitForTick();
await finishTestRestoreUpdaterBackup();
}
})();
}
@ -575,7 +594,8 @@ function waitForAboutDialog() {
async function aboutDialogOnLoad() {
domwindow.removeEventListener("load", aboutDialogOnLoad, true);
let chromeURI = "chrome://browser/content/aboutDialog.xul";
is(domwindow.document.location.href, chromeURI, "About dialog appeared");
is(domwindow.document.location.href, chromeURI,
"About dialog appeared");
resolve(domwindow);
}
@ -664,6 +684,7 @@ function runAboutDialogUpdateTest(updateParams, backgroundUpdate, steps) {
}
return (async function() {
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "1");
await SpecialPowers.pushPrefEnv({
set: [
[PREF_APP_UPDATE_SERVICE_ENABLED, false],
@ -671,20 +692,8 @@ function runAboutDialogUpdateTest(updateParams, backgroundUpdate, steps) {
[PREF_APP_UPDATE_URL_MANUAL, detailsURL],
],
});
registerCleanupFunction(() => {
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "");
UpdateListener.reset();
cleanUpUpdates();
});
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "1");
setUpdateTimerPrefs();
removeUpdateFiles(true);
await setupTestUpdater();
registerCleanupFunction(async () => {
await finishTestRestoreUpdaterBackup();
});
let updateURL = URL_HTTP_UPDATE_SJS + "?detailsURL=" + detailsURL +
updateParams + getVersionParams();
@ -694,9 +703,6 @@ function runAboutDialogUpdateTest(updateParams, backgroundUpdate, steps) {
// MOZ_TEST_SLOW_SKIP_UPDATE_STAGE in updater.cpp this removes the need
// for the continue file to continue staging the update.
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1");
registerCleanupFunction(() => {
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "");
});
}
setUpdateURL(updateURL);
gAUS.checkForBackgroundUpdates();
@ -743,7 +749,8 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
const {panelId, checkActiveUpdate, continueFile} = step;
return (async function() {
await ContentTask.spawn(tab.linkedBrowser, {panelId}, async ({panelId}) => {
await ContentTask.spawn(tab.linkedBrowser, {panelId},
async ({panelId}) => {
let updateDeck = content.document.getElementById("updateDeck");
await ContentTaskUtils.waitForCondition(() =>
(updateDeck.selectedPanel && updateDeck.selectedPanel.id == panelId),
@ -766,7 +773,8 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
await continueFileHandler(continueFile);
}
await ContentTask.spawn(tab.linkedBrowser, {panelId, detailsURL}, async ({panelId, detailsURL}) => {
await ContentTask.spawn(tab.linkedBrowser, {panelId, detailsURL},
async ({panelId, detailsURL}) => {
let linkPanels = ["downloadFailed", "manualUpdate", "unsupportedSystem"];
if (linkPanels.includes(panelId)) {
let selectedPanel =
@ -787,13 +795,14 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
let buttonPanels = ["downloadAndInstall", "apply"];
if (buttonPanels.includes(panelId)) {
let selectedPanel = content.document.getElementById("updateDeck").selectedPanel;
let selectedPanel =
content.document.getElementById("updateDeck").selectedPanel;
let buttonEl = selectedPanel.querySelector("button");
// Note: The about:preferences doesn't focus the button like the
// About Dialog does.
ok(!buttonEl.disabled, "The button should be enabled");
// Don't click the button on the apply panel since this will restart the
// application.
// Don't click the button on the apply panel since this will restart
// the application.
if (selectedPanel.id != "apply") {
buttonEl.click();
}
@ -803,6 +812,7 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
}
return (async function() {
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "1");
await SpecialPowers.pushPrefEnv({
set: [
[PREF_APP_UPDATE_SERVICE_ENABLED, false],
@ -810,20 +820,8 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
[PREF_APP_UPDATE_URL_MANUAL, detailsURL],
],
});
registerCleanupFunction(() => {
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "");
UpdateListener.reset();
cleanUpUpdates();
});
gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "1");
setUpdateTimerPrefs();
removeUpdateFiles(true);
await setupTestUpdater();
registerCleanupFunction(async () => {
await finishTestRestoreUpdaterBackup();
});
let updateURL = URL_HTTP_UPDATE_SJS + "?detailsURL=" + detailsURL +
updateParams + getVersionParams();
@ -833,9 +831,6 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
// MOZ_TEST_SLOW_SKIP_UPDATE_STAGE in updater.cpp this removes the need
// for the continue file to continue staging the update.
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1");
registerCleanupFunction(() => {
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "");
});
}
setUpdateURL(updateURL);
gAUS.checkForBackgroundUpdates();
@ -845,7 +840,8 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
setUpdateURL(updateURL);
}
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser,
"about:preferences");
registerCleanupFunction(async () => {
await BrowserTestUtils.removeTab(tab);
});

View File

@ -109,4 +109,5 @@ marSuccessCompleteSvc.js
marSuccessPartial.js
marSuccessPartialSvc.js
END