Bug 1529043 - Part 8 (test only) - Make the stageUpdate function async and change call sites so they use await. r=mhowell
authorRobert Strong <robert.bugzilla@gmail.com>
Fri, 22 Feb 2019 21:47:37 +0000
changeset 460682 17a347c991657ad0b01087caa9702a22d4daf777
parent 460681 0633e80e4acc19875b6573ecede25a2d1a8f70d0
child 460683 3314bffa0d510fabaa87292b0d5ef7d23c05a2a4
push id35596
push userrmaries@mozilla.com
push dateSat, 23 Feb 2019 04:13:22 +0000
treeherdermozilla-central@fdd04819e350 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell
bugs1529043
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1529043 - Part 8 (test only) - Make the stageUpdate function async and change call sites so they use await. r=mhowell Depends on D20799 Differential Revision: https://phabricator.services.mozilla.com/D20800
toolkit/mozapps/update/tests/browser/head.js
toolkit/mozapps/update/tests/data/shared.js
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js
toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js
toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTooLongFailureSvc.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTraversalFailureSvc.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathSuffixFailureSvc.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathTraversalFailureSvc.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgStageDirNotInInstallDirFailureSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathLocalUNCFailureSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathRelativeFailureSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
--- a/toolkit/mozapps/update/tests/browser/head.js
+++ b/toolkit/mozapps/update/tests/browser/head.js
@@ -356,36 +356,16 @@ function processStep(step) {
 
     if (cleanup) {
       await cleanup();
     }
   })();
 }
 
 /**
- * Waits for the specified topic and (optionally) status.
- * @param  topic
- *         String representing the topic to wait for.
- * @param  status
- *         Optional String representing the status on said topic to wait for.
- * @return A promise which will resolve the first time an event occurs on the
- *         specified topic, and (optionally) with the specified status.
- */
-function waitForEvent(topic, status = null) {
-  return new Promise(resolve => Services.obs.addObserver({
-    observe(subject, innerTopic, innerStatus) {
-      if (!status || status == innerStatus) {
-        Services.obs.removeObserver(this, topic);
-        resolve(innerStatus);
-      }
-    },
-  }, topic));
-}
-
-/**
  * Gets the specified button for the notification.
  *
  * @param  win
  *         The window to get the notification button for.
  * @param  notificationId
  *         The ID of the notification to get the button for.
  * @param  button
  *         The anonid of the button to get.
--- a/toolkit/mozapps/update/tests/data/shared.js
+++ b/toolkit/mozapps/update/tests/data/shared.js
@@ -135,16 +135,37 @@ XPCOMUtils.defineLazyGetter(this, "gDefa
 XPCOMUtils.defineLazyGetter(this, "gPrefRoot", function test_gPR() {
   return Services.prefs.getBranch(null);
 });
 
 XPCOMUtils.defineLazyServiceGetter(this, "gEnv",
                                    "@mozilla.org/process/environment;1",
                                    "nsIEnvironment");
 
+/**
+ * Waits for the specified topic and (optionally) status.
+ *
+ * @param  topic
+ *         String representing the topic to wait for.
+ * @param  status (optional)
+ *         A string representing the status on said topic to wait for.
+ * @return A promise which will resolve the first time an event occurs on the
+ *         specified topic, and (optionally) with the specified status.
+ */
+function waitForEvent(topic, status = null) {
+  return new Promise(resolve => Services.obs.addObserver({
+    observe(subject, innerTopic, innerStatus) {
+      if (!status || status == innerStatus) {
+        Services.obs.removeObserver(this, topic);
+        resolve(innerStatus);
+      }
+    },
+  }, topic));
+}
+
 /* Triggers post-update processing */
 function testPostUpdateProcessing() {
   gAUS.observe(null, "test-post-update-processing", "");
 }
 
 /* Initializes the update service stub */
 function initUpdateServiceStub() {
   Cc["@mozilla.org/updates/update-service-stub;1"].
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -152,21 +152,16 @@ var gGREBinDirOrig;
 
 var gPIDPersistProcess;
 
 // Variables are used instead of contants so tests can override these values if
 // necessary.
 var gCallbackBinFile = "callback_app" + mozinfo.bin_suffix;
 var gCallbackArgs = ["./", "callback.log", "Test Arg 2", "Test Arg 3"];
 var gPostUpdateBinFile = "postup_app" + mozinfo.bin_suffix;
-var gSvcOriginalLogContents;
-// Some update staging failures can remove the update. This allows tests to
-// specify that the status file and the active update should not be checked
-// after an update is staged.
-var gStagingRemovedUpdate = false;
 
 var gTimeoutRuns = 0;
 var gFileInUseTimeoutRuns = 0;
 
 // Environment related globals
 var gShouldResetEnv = undefined;
 var gAddedEnvXRENoWindowsCrashDialog = false;
 var gEnvXPCOMDebugBreak;
@@ -1928,137 +1923,99 @@ function setupActiveUpdate() {
   writeVersionFile(DEFAULT_UPDATE_VERSION);
   writeStatusFile(pendingState);
   reloadUpdateManagerData();
   Assert.ok(!!gUpdateManager.activeUpdate,
             "the active update should be defined");
 }
 
 /**
- * The update-staged observer for the call to nsIUpdateProcessor:processUpdate.
- */
-const gUpdateStagedObserver = {
-  observe(aSubject, aTopic, aData) {
-    debugDump("observe called with topic: " + aTopic + ", data: " + aData);
-    if (aTopic == "update-staged") {
-      Services.obs.removeObserver(gUpdateStagedObserver, "update-staged");
-      // The environment is reset after the update-staged observer topic because
-      // processUpdate in nsIUpdateProcessor uses a new thread and clearing the
-      // environment immediately after calling processUpdate can clear the
-      // environment before the updater is launched.
-      resetEnvironment();
-      // Use do_execute_soon to prevent any failures from propagating to the
-      // update service.
-      executeSoon(checkUpdateStagedState.bind(null, aData));
-    }
-  },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
-};
-
-/**
  * Stages an update using nsIUpdateProcessor:processUpdate for updater tests.
  *
+ * @param   aStateAfterStage
+ *          The expected update state after the update has been staged.
  * @param   aCheckSvcLog
  *          Whether the service log should be checked for service tests.
+ * @param   aUpdateRemoved (optional)
+ *          Whether the update is removed after staging. This can happen when
+ *          a staging failure occurs.
  */
-function stageUpdate(aCheckSvcLog) {
+async function stageUpdate(aStateAfterStage, aCheckSvcLog,
+                           aUpdateRemoved = false) {
   debugDump("start - attempting to stage update");
 
+  let svcLogOriginalContents;
   if (IS_SERVICE_TEST && aCheckSvcLog) {
-    gSvcOriginalLogContents = readServiceLogFile();
+    svcLogOriginalContents = readServiceLogFile();
   }
 
-  Services.obs.addObserver(gUpdateStagedObserver, "update-staged");
-
   setAppBundleModTime();
   setEnvironment();
   try {
     // Stage the update.
     Cc["@mozilla.org/updates/update-processor;1"].
       createInstance(Ci.nsIUpdateProcessor).processUpdate();
   } catch (e) {
     Assert.ok(false,
-              "error thrown while calling processUpdate, exception: " + e);
+              "error thrown while calling processUpdate, Exception: " + e);
   }
-
-  // The environment is not reset here because processUpdate in
-  // nsIUpdateProcessor uses a new thread and clearing the environment
-  // immediately after calling processUpdate can clear the environment before
-  // the updater is launched. Instead it is reset after the update-staged
-  // observer topic.
-
-  debugDump("finish - attempting to stage update");
-}
-
-/**
- * Checks that the update state is correct as well as the expected files are
- * present after staging and update for updater tests and then calls
- * stageUpdateFinished.
- *
- * @param   aUpdateState
- *          The update state received by the observer notification.
- */
-function checkUpdateStagedState(aUpdateState) {
+  await waitForEvent("update-staged", aStateAfterStage);
+  resetEnvironment();
+
   if (AppConstants.platform == "win") {
     if (IS_SERVICE_TEST) {
       waitForServiceStop(false);
     } else {
       let updater = getApplyDirFile(FILE_UPDATER_BIN);
-      if (isFileInUse(updater)) {
-        do_timeout(FILE_IN_USE_TIMEOUT_MS,
-                   checkUpdateStagedState.bind(null, aUpdateState));
-        return;
-      }
+      await TestUtils.waitForCondition(() => (!isFileInUse(updater)),
+        "Waiting for the file tp not be in use, Path: " + updater.path);
     }
   }
 
-  Assert.equal(aUpdateState, STATE_AFTER_STAGE,
-               "the notified state" + MSG_SHOULD_EQUAL);
-
-  if (!gStagingRemovedUpdate) {
-    Assert.equal(readStatusState(), STATE_AFTER_STAGE,
+  if (!aUpdateRemoved) {
+    Assert.equal(readStatusState(), aStateAfterStage,
                  "the status file state" + MSG_SHOULD_EQUAL);
 
-    Assert.equal(gUpdateManager.activeUpdate.state, STATE_AFTER_STAGE,
+    Assert.equal(gUpdateManager.activeUpdate.state, aStateAfterStage,
                  "the update state" + MSG_SHOULD_EQUAL);
   }
 
   let log = getUpdateDirFile(FILE_LAST_UPDATE_LOG);
   Assert.ok(log.exists(),
             MSG_SHOULD_EXIST + getMsgPath(log.path));
 
   log = getUpdateDirFile(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
 
   log = getUpdateDirFile(FILE_BACKUP_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
 
   let stageDir = getStageDirFile();
-  if (STATE_AFTER_STAGE == STATE_APPLIED ||
-      STATE_AFTER_STAGE == STATE_APPLIED_SVC) {
+  if (aStateAfterStage == STATE_APPLIED ||
+      aStateAfterStage == STATE_APPLIED_SVC) {
     Assert.ok(stageDir.exists(),
               MSG_SHOULD_EXIST + getMsgPath(stageDir.path));
   } else {
     Assert.ok(!stageDir.exists(),
               MSG_SHOULD_NOT_EXIST + getMsgPath(stageDir.path));
   }
 
-  if (IS_SERVICE_TEST && gSvcOriginalLogContents !== undefined) {
+  if (IS_SERVICE_TEST && aCheckSvcLog) {
     let contents = readServiceLogFile();
-    Assert.notEqual(contents, gSvcOriginalLogContents,
+    Assert.notEqual(contents, svcLogOriginalContents,
                     "the contents of the maintenanceservice.log should not " +
                     "be the same as the original contents");
     Assert.notEqual(contents.indexOf(LOG_SVC_SUCCESSFUL_LAUNCH), -1,
                     "the contents of the maintenanceservice.log should " +
                     "contain the successful launch string");
   }
 
-  executeSoon(stageUpdateFinished);
+  debugDump("finish - attempting to stage update");
 }
 
 /**
  * Helper function to check whether the maintenance service updater tests should
  * run. See bug 711660 for more details.
  *
  * @return true if the test should run and false if it shouldn't.
  * @throws  If called from a platform other than Windows.
@@ -3385,24 +3342,24 @@ function isFileInUse(aFile) {
       fileBak.remove(false);
     }
     aFile.copyTo(aFile.parent, fileBak.leafName);
     aFile.remove(false);
     fileBak.moveTo(aFile.parent, aFile.leafName);
     debugDump("file is not in use, path: " + aFile.path);
     return false;
   } catch (e) {
-    debugDump("file in use, path: " + aFile.path + ", exception: " + e);
+    debugDump("file in use, path: " + aFile.path + ", Exception: " + e);
     try {
       if (fileBak.exists()) {
         fileBak.remove(false);
       }
     } catch (ex) {
       logTestInfo("unable to remove backup file, path: " +
-                  fileBak.path + ", exception: " + ex);
+                  fileBak.path + ", Exception: " + ex);
     }
   }
   return true;
 }
 
 /**
  * Waits until files that are in use that break tests are no longer in use and
  * then calls doTestFinish to end the test.
@@ -3784,28 +3741,28 @@ function adjustGeneralPaths() {
       debugDump("finish - cancel app timer");
     }
 
     if (gProcess && gProcess.isRunning) {
       debugDump("start - kill process");
       try {
         gProcess.kill();
       } catch (e) {
-        debugDump("kill process failed. Exception: " + e);
+        debugDump("kill process failed, Exception: " + e);
       }
       gProcess = null;
       debugDump("finish - kill process");
     }
 
     if (gPIDPersistProcess && gPIDPersistProcess.isRunning) {
       debugDump("start - kill pid persist process");
       try {
         gPIDPersistProcess.kill();
       } catch (e) {
-        debugDump("kill pid persist process failed. Exception: " + e);
+        debugDump("kill pid persist process failed, Exception: " + e);
       }
       gPIDPersistProcess = null;
       debugDump("finish - kill pid persist process");
     }
 
     if (gHandle) {
       try {
         debugDump("start - closing handle");
@@ -3815,17 +3772,17 @@ function adjustGeneralPaths() {
                                            ctypes.voidptr_t /* handle*/);
         if (!CloseHandle(gHandle)) {
           debugDump("call to CloseHandle failed");
         }
         kernel32.close();
         gHandle = null;
         debugDump("finish - closing handle");
       } catch (e) {
-        debugDump("call to CloseHandle failed. Exception: " + e);
+        debugDump("call to CloseHandle failed, Exception: " + e);
       }
     }
 
     ds.unregisterProvider(dirProvider);
     cleanupTestCommon();
 
     debugDump("finish - unregistering directory provider");
   });
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js
@@ -1,22 +1,21 @@
 /* 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/.
  */
 
 /* Callback file not in install directory or a sub-directory of the install
    directory failure */
 
-const STATE_AFTER_RUNUPDATE = STATE_FAILED_INVALID_CALLBACK_DIR_ERROR;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_RUNUPDATE = STATE_FAILED_INVALID_CALLBACK_DIR_ERROR;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getTestDirFile(FILE_HELPER_BIN).path;
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, null, path);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js
@@ -1,21 +1,20 @@
 /* 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/.
  */
 
 /* Too long callback file path failure test */
 
-const STATE_AFTER_RUNUPDATE = STATE_FAILED_INVALID_CALLBACK_PATH_ERROR;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_RUNUPDATE = STATE_FAILED_INVALID_CALLBACK_PATH_ERROR;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "123456789";
   if (AppConstants.platform == "win") {
     path = "\\" + path;
     path = path.repeat(30); // 300 characters
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js
@@ -1,27 +1,26 @@
 /* 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/.
  */
 
 /* Too long install directory path failure test */
 
-/* The service cannot safely write update.status for this failure. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "123456789";
   if (AppConstants.platform == "win") {
     path = "\\" + path;
     path = path.repeat(30); // 300 characters
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js
@@ -1,27 +1,26 @@
 /* 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/.
  */
 
 /* Install directory path traversal failure test */
 
-/* The service cannot safely write update.status for this failure. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "123456789";
   if (AppConstants.platform == "win") {
     path = "C:\\" + path + "\\..\\" + path;
   } else {
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js
@@ -1,28 +1,27 @@
 /* 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/.
  */
 
 /* Different install and working directories for a regular update failure */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_APPLYTO_DIR_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_APPLYTO_DIR_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getApplyDirFile("..", false).path;
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js
@@ -1,22 +1,21 @@
 /* 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/.
  */
 
 /* Patch directory path traversal failure test */
 
-const STATE_AFTER_RUNUPDATE =
-  IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_RUNUPDATE =
+    IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getUpdateDirFile(DIR_PATCH);
   if (AppConstants.platform == "win") {
     path = path + "\\..\\";
   } else {
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js
@@ -1,29 +1,28 @@
 /* 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/.
  */
 
 /* Different install and working directories for a regular update failure */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE =
-  STATE_FAILED_INVALID_APPLYTO_DIR_STAGED_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE =
+    STATE_FAILED_INVALID_APPLYTO_DIR_STAGED_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getApplyDirFile("..", false).path;
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true, null, null, path, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js
@@ -1,28 +1,27 @@
 /* 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/.
  */
 
 /* Working directory path local UNC failure test */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "\\\\.\\" + getApplyDirFile(null, false).path;
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js
@@ -1,28 +1,27 @@
 /* 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/.
  */
 
 /* Relative working directory path failure test */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, "test", null);
   standardInit();
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
@@ -2,34 +2,27 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
  * Test applying an update by staging an update and launching an application to
  * apply it.
  */
 
-const STATE_AFTER_STAGE = STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   createUpdateInProgressLockFile(getGREBinDir());
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(false);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, false);
   removeUpdateInProgressLockFile(getGREBinDir());
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(PERFORMING_STAGED_UPDATE);
   checkUpdateLogContains(ERR_UPDATE_IN_PROGRESS);
   await waitForUpdateXMLFiles(true, false);
   checkUpdateManager(STATE_AFTER_STAGE, true, STATE_AFTER_STAGE, 0, 0);
   waitForFilesInUse();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js
@@ -2,32 +2,25 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
  * Test applying an update by staging an update and launching an application to
  * apply it.
  */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   lockDirectory(getGREBinDir().path);
   // Switch the application to the staged application that was updated.
   await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
@@ -4,22 +4,21 @@
 
 /**
  * Test a replace request for a staged update with a version file that specifies
  * an older version failure. The same check is used in nsUpdateDriver.cpp for
  * all update types which is why there aren't tests for the maintenance service
  * as well as for other update types.
  */
 
-const STATE_AFTER_STAGE = STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, null, "", false);
   let patchProps = {state: STATE_AFTER_STAGE};
   let patches = getLocalPatchString(patchProps);
   let updateProps = {appVersion: "0.9"};
   let updates = getLocalUpdateString(updateProps, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
@@ -2,32 +2,25 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
  * Test applying an update by staging an update and launching an application to
  * apply it.
  */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
@@ -1,32 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Application in use complete MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
@@ -1,36 +1,28 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Application in use complete MAR file staged patch apply success test */
 
-const START_STATE = STATE_PENDING;
-const STATE_AFTER_STAGE = STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestFiles[gTestFiles.length - 1].originalContents = null;
   gTestFiles[gTestFiles.length - 1].compareContents = "FromComplete\n";
   gTestFiles[gTestFiles.length - 1].comparePerms = 0o644;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, true);
   setupSymLinks();
   await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await waitForHelperExit();
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
@@ -1,31 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Replace app binary complete MAR file staged patch apply success test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   gCallbackBinFile = "exe0.exe";
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   standardInit();
   checkPostUpdateRunningFile(true);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
@@ -1,31 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Patch app binary partial MAR file staged patch apply success test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   gCallbackBinFile = "exe0.exe";
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   standardInit();
   checkPostUpdateRunningFile(true);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
@@ -1,33 +1,26 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use complete MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperFileInUse(gTestFiles[13].relPathDir + gTestFiles[13].fileName,
                            false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
@@ -1,33 +1,26 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use partial MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
   await runHelperFileInUse(gTestFiles[11].relPathDir + gTestFiles[11].fileName,
                            false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
@@ -1,32 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File locked complete MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperLockFile(gTestFiles[3]);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   // Files aren't checked after staging since this test locks a file which
   // prevents reading the file.
   checkUpdateLogContains(ERR_ENSURE_COPY);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_FAILED_WRITE_ERROR, false, 1, false);
   await waitForHelperExit();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
@@ -1,32 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File locked partial MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_PENDING;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
   await runHelperLockFile(gTestFiles[2]);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   // Files aren't checked after staging since this test locks a file which
   // prevents reading the file.
   checkUpdateLogContains(ERR_ENSURE_COPY);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_FAILED_READ_ERROR, false, 1, false);
   await waitForHelperExit();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marMissingUpdateSettingsStage.js
@@ -1,38 +1,30 @@
 /* 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/.
  */
 
 /* Test update-settings.ini missing channel MAR security check */
 
-const STATE_AFTER_STAGE = STATE_FAILED;
-gStagingRemovedUpdate = true;
-
 async function run_test() {
   if (!MOZ_VERIFY_MAR_SIGNATURE) {
     return;
   }
 
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_FAILED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestFiles[gTestFiles.length - 2].originalContents = null;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(STATE_FAILED_UPDATE_SETTINGS_FILE_CHANNEL);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      UPDATE_SETTINGS_FILE_CHANNEL, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
@@ -1,34 +1,27 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir complete MAR file staged patch apply failure
    test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperFileInUse(gTestDirs[4].relPathDir + gTestDirs[4].subDirs[0] +
                            gTestDirs[4].subDirFiles[0], true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
@@ -1,34 +1,27 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir partial MAR file staged patch apply failure
    test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
   await runHelperFileInUse(gTestDirs[2].relPathDir + gTestDirs[2].files[0],
                            true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
@@ -1,34 +1,26 @@
 /* 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/.
  */
 
 /* General Partial MAR File Staged Patch Apply Failure Test */
 
-const STATE_AFTER_STAGE = STATE_FAILED;
-gStagingRemovedUpdate = true;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_FAILED;
   gTestFiles = gTestFilesPartialSuccess;
   gTestFiles[11].originalFile = "partial.png";
   gTestDirs = gTestDirsPartialSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_LOADSOURCEFILE_FAILED);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      LOADSOURCE_ERROR_WRONG_SIZE, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessComplete.js
@@ -1,35 +1,28 @@
 /* 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/.
  */
 
 /* General Complete MAR File Staged Patch Apply Test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestFiles[gTestFiles.length - 1].originalContents = null;
   gTestFiles[gTestFiles.length - 1].compareContents = "FromComplete\n";
   gTestFiles[gTestFiles.length - 1].comparePerms = 0o644;
   gTestDirs = gTestDirsCompleteSuccess;
   setupSymLinks();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   checkSymLinks();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
@@ -1,35 +1,28 @@
 /* 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/.
  */
 
 /* General Partial MAR File Staged Patch Apply Test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesPartialSuccess;
   gTestFiles[gTestFiles.length - 1].originalContents = null;
   gTestFiles[gTestFiles.length - 1].compareContents = "FromPartial\n";
   gTestFiles[gTestFiles.length - 1].comparePerms = 0o644;
   gTestDirs = gTestDirsPartialSuccess;
   preventDistributionFiles();
   await setupUpdaterTest(FILE_PARTIAL_MAR, true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true, false, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannelStage.js
@@ -1,39 +1,31 @@
 /* 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/.
  */
 
 /* Test product/channel MAR security check */
 
-const STATE_AFTER_STAGE = STATE_FAILED;
-gStagingRemovedUpdate = true;
-
 async function run_test() {
   if (!MOZ_VERIFY_MAR_SIGNATURE) {
     return;
   }
 
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_FAILED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestFiles[gTestFiles.length - 2].originalContents =
     UPDATE_SETTINGS_CONTENTS.replace("xpcshell-test", "wrong-channel");
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(STATE_FAILED_MAR_CHANNEL_MISMATCH_ERROR);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      MAR_CHANNEL_MISMATCH_ERROR, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTooLongFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTooLongFailureSvc.js
@@ -1,27 +1,26 @@
 /* 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/.
  */
 
 /* Too long install directory path failure test */
 
-/* The service cannot safely write update.status for this failure. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "123456789";
   if (AppConstants.platform == "win") {
     path = "\\" + path;
     path = path.repeat(30); // 300 characters
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTraversalFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTraversalFailureSvc.js
@@ -1,27 +1,26 @@
 /* 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/.
  */
 
 /* Install directory path traversal failure test */
 
-/* The service cannot safely write update.status for this failure. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_INSTALL_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "123456789";
   if (AppConstants.platform == "win") {
     path = "C:\\" + path + "\\..\\" + path;
   } else {
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js
@@ -1,28 +1,27 @@
 /* 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/.
  */
 
 /* Different install and working directories for a regular update failure */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_APPLYTO_DIR_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_APPLYTO_DIR_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getApplyDirFile("..", false).path;
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathSuffixFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathSuffixFailureSvc.js
@@ -1,22 +1,21 @@
 /* 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/.
  */
 
 /* Patch directory path must end with \updates\0 failure test */
 
-const STATE_AFTER_RUNUPDATE =
-  IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_RUNUPDATE =
+    IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getUpdateDirFile(DIR_PATCH).parent.path;
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, path, null, null, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathTraversalFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathTraversalFailureSvc.js
@@ -1,22 +1,21 @@
 /* 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/.
  */
 
 /* Patch directory path traversal failure test */
 
-const STATE_AFTER_RUNUPDATE =
-  IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_RUNUPDATE =
+    IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getUpdateDirFile(DIR_PATCH);
   if (AppConstants.platform == "win") {
     path = path + "\\..\\";
   } else {
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgStageDirNotInInstallDirFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgStageDirNotInInstallDirFailureSvc_win.js
@@ -1,29 +1,28 @@
 /* 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/.
  */
 
 /* Different install and working directories for a regular update failure */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE =
-  STATE_FAILED_INVALID_APPLYTO_DIR_STAGED_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE =
+    STATE_FAILED_INVALID_APPLYTO_DIR_STAGED_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = getApplyDirFile("..", false).path;
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true, null, null, path, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathLocalUNCFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathLocalUNCFailureSvc_win.js
@@ -1,28 +1,27 @@
 /* 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/.
  */
 
 /* Working directory path local UNC failure test */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   let path = "\\\\.\\" + getApplyDirFile(null, false).path;
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathRelativeFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathRelativeFailureSvc.js
@@ -1,28 +1,27 @@
 /* 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/.
  */
 
 /* Relative working directory path failure test */
 
-/* The service cannot safely write update.status for this failure because the
- * check is done before validating the installed updater. */
-const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
-    ? STATE_PENDING_SVC
-    : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
-                                              : STATE_AFTER_RUNUPDATE_BASE;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  // The service cannot safely write update.status for this failure because the
+  // check is done before validating the installed updater.
+  const STATE_AFTER_RUNUPDATE_BASE = STATE_FAILED_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE_SERVICE = AppConstants.EARLY_BETA_OR_EARLIER
+      ? STATE_PENDING_SVC
+      : STATE_FAILED_SERVICE_INVALID_WORKING_DIR_PATH_ERROR;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_AFTER_RUNUPDATE_SERVICE
+                                                : STATE_AFTER_RUNUPDATE_BASE;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, "test", null);
   standardInit();
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
@@ -2,34 +2,27 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
  * Test applying an update by staging an update and launching an application to
  * apply it.
  */
 
-const STATE_AFTER_STAGE = STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   createUpdateInProgressLockFile(getGREBinDir());
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(false);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, false);
   removeUpdateInProgressLockFile(getGREBinDir());
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(PERFORMING_STAGED_UPDATE);
   checkUpdateLogContains(ERR_UPDATE_IN_PROGRESS);
   await waitForUpdateXMLFiles(true, false);
   checkUpdateManager(STATE_AFTER_STAGE, true, STATE_AFTER_STAGE, 0, 0);
   waitForFilesInUse();
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
@@ -2,32 +2,25 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
  * Test applying an update by staging an update and launching an application to
  * apply it.
  */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   lockDirectory(getGREBinDir().path);
   // Switch the application to the staged application that was updated.
   await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
@@ -2,32 +2,25 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /**
  * Test applying an update by staging an update and launching an application to
  * apply it.
  */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
@@ -1,32 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Application in use complete MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperFileInUse(DIR_RESOURCES + gCallbackBinFile, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
@@ -1,31 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Replace app binary complete MAR file staged patch apply success test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   gCallbackBinFile = "exe0.exe";
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   standardInit();
   checkPostUpdateRunningFile(true);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
@@ -1,31 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* Patch app binary partial MAR file staged patch apply success test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   gCallbackBinFile = "exe0.exe";
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   standardInit();
   checkPostUpdateRunningFile(true);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
@@ -1,33 +1,26 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use complete MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperFileInUse(gTestFiles[13].relPathDir + gTestFiles[13].fileName,
                            false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
@@ -1,33 +1,26 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use partial MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
   await runHelperFileInUse(gTestFiles[11].relPathDir + gTestFiles[11].fileName,
                            false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
@@ -1,32 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File locked complete MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperLockFile(gTestFiles[3]);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   // Files aren't checked after staging since this test locks a file which
   // prevents reading the file.
   checkUpdateLogContains(ERR_ENSURE_COPY);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_FAILED_WRITE_ERROR, false, 1, false);
   await waitForHelperExit();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
@@ -1,32 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File locked partial MAR file staged patch apply failure test */
 
-const STATE_AFTER_STAGE = STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_PENDING;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
   await runHelperLockFile(gTestFiles[2]);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   // Files aren't checked after staging since this test locks a file which
   // prevents reading the file.
   checkUpdateLogContains(ERR_ENSURE_COPY);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_FAILED_READ_ERROR, false, 1, false);
   await waitForHelperExit();
   standardInit();
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
@@ -1,34 +1,27 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir complete MAR file staged patch apply failure
    test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   await runHelperFileInUse(gTestDirs[4].relPathDir + gTestDirs[4].subDirs[0] +
                            gTestDirs[4].subDirFiles[0], true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
@@ -1,34 +1,27 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* File in use inside removed dir partial MAR file staged patch apply failure
    test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
+  const STATE_AFTER_RUNUPDATE = IS_SERVICE_TEST ? STATE_PENDING_SVC : STATE_PENDING;
   gTestFiles = gTestFilesPartialSuccess;
   gTestDirs = gTestDirsPartialSuccess;
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
   await runHelperFileInUse(gTestDirs[2].relPathDir + gTestDirs[2].files[0],
                            true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true);
   await waitForHelperExit();
   standardInit();
   checkPostUpdateRunningFile(false);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
@@ -1,34 +1,26 @@
 /* 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/.
  */
 
 /* General Partial MAR File Staged Patch Apply Failure Test */
 
-const STATE_AFTER_STAGE = STATE_FAILED;
-gStagingRemovedUpdate = true;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = STATE_FAILED;
   gTestFiles = gTestFilesPartialSuccess;
   gTestFiles[11].originalFile = "partial.png";
   gTestDirs = gTestDirsPartialSuccess;
   setTestFilesAndDirsForFailure();
   await setupUpdaterTest(FILE_PARTIAL_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_LOADSOURCEFILE_FAILED);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      LOADSOURCE_ERROR_WRONG_SIZE, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessCompleteSvc.js
@@ -1,35 +1,28 @@
 /* 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/.
  */
 
 /* General Complete MAR File Staged Patch Apply Test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesCompleteSuccess;
   gTestFiles[gTestFiles.length - 1].originalContents = null;
   gTestFiles[gTestFiles.length - 1].compareContents = "FromComplete\n";
   gTestFiles[gTestFiles.length - 1].comparePerms = 0o644;
   gTestDirs = gTestDirsCompleteSuccess;
   setupSymLinks();
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   checkSymLinks();
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
@@ -1,35 +1,28 @@
 /* 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/.
  */
 
 /* General Partial MAR File Staged Patch Apply Test */
 
-const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
-
 async function run_test() {
   if (!setupTestCommon()) {
     return;
   }
+  const STATE_AFTER_STAGE = IS_SERVICE_TEST ? STATE_APPLIED_SVC : STATE_APPLIED;
   gTestFiles = gTestFilesPartialSuccess;
   gTestFiles[gTestFiles.length - 1].originalContents = null;
   gTestFiles[gTestFiles.length - 1].compareContents = "FromPartial\n";
   gTestFiles[gTestFiles.length - 1].comparePerms = 0o644;
   gTestDirs = gTestDirsPartialSuccess;
   preventDistributionFiles();
   await setupUpdaterTest(FILE_PARTIAL_MAR, true);
-  stageUpdate(true);
-}
-
-/**
- * Called after the call to stageUpdate finishes.
- */
-async function stageUpdateFinished() {
+  await stageUpdate(STATE_AFTER_STAGE, true);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS, true, false, true);
   // Switch the application to the staged application that was updated.
   runUpdate(STATE_SUCCEEDED, true, 0, true);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();