bug 1361102 - change tests to account for updating the application update xml files asynchronously. r=dothayer
authorRobert Strong <robert.bugzilla@gmail.com>
Fri, 08 Sep 2017 10:38:55 -0700
changeset 661590 b04b2abfc1701601879947e934c1b2271c154e38
parent 661589 814b441b2bad6ac477225918bf1c7f6034c3ed82
child 661591 c1d35cfb410bfeacc3a30e838c792ae27aa551d0
push id78830
push userasasaki@mozilla.com
push dateFri, 08 Sep 2017 19:44:43 +0000
reviewersdothayer
bugs1361102
milestone57.0a1
bug 1361102 - change tests to account for updating the application update xml files asynchronously. r=dothayer
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/mozapps/update/tests/unit_aus_update/canCheckForAndCanApplyUpdates.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForDifferentChannel.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForOlderAppVersion.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForSameVersionAndBuildID.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingIncorrectStatus.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupPendingVersionFileIncorrectStatus.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupSuccessLogMove.js
toolkit/mozapps/update/tests/unit_aus_update/cleanupSuccessLogsFIFO.js
toolkit/mozapps/update/tests/unit_aus_update/downloadCompleteAfterPartialFailure.js
toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedNoRecovery.js
toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedOffline.js
toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js
toolkit/mozapps/update/tests/unit_aus_update/downloadInvalidSizeMar.js
toolkit/mozapps/update/tests/unit_aus_update/downloadMissingMar.js
toolkit/mozapps/update/tests/unit_aus_update/downloadResumeForSameAppVersion.js
toolkit/mozapps/update/tests/unit_aus_update/remoteUpdateXML.js
toolkit/mozapps/update/tests/unit_aus_update/uiAutoPref.js
toolkit/mozapps/update/tests/unit_aus_update/uiSilentPref.js
toolkit/mozapps/update/tests/unit_aus_update/uiUnsupportedAlreadyNotified.js
toolkit/mozapps/update/tests/unit_aus_update/xpcshell.ini
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/marAppApplyUpdateSuccess.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/marAppInUseSuccessComplete.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/marCallbackAppSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.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/marFileInUseSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_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/marPIDPersistsSuccessComplete_win.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/marRMRFDirFileInUseSuccessComplete_win.js
toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_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/marSuccessComplete.js
toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js
toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js
toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.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/marAppApplyUpdateSuccessSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.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/marCallbackAppSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.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/marFileInUseSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_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/marRMRFDirFileInUseSuccessCompleteSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_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
toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -48,17 +48,16 @@ function getLogSuffix() {
   }
   if (IS_MACOSX) {
     return "_mac";
   }
   return "_linux";
 }
 
 Cu.import("resource://gre/modules/Services.jsm", this);
-Cu.import("resource://gre/modules/ctypes.jsm", this);
 
 const DIR_MACOS = IS_MACOSX ? "Contents/MacOS/" : "";
 const DIR_RESOURCES = IS_MACOSX ? "Contents/Resources/" : "";
 const TEST_FILE_SUFFIX = IS_MACOSX ? "_mac" : "";
 const FILE_COMPLETE_MAR = "complete" + TEST_FILE_SUFFIX + ".mar";
 const FILE_PARTIAL_MAR = "partial" + TEST_FILE_SUFFIX + ".mar";
 const FILE_COMPLETE_PRECOMPLETE = "complete_precomplete" + TEST_FILE_SUFFIX;
 const FILE_PARTIAL_PRECOMPLETE = "partial_precomplete" + TEST_FILE_SUFFIX;
@@ -135,17 +134,17 @@ const gHTTPHandlerPath = "updates.xml";
 
 // This default value will be overridden when using the http server.
 var gURLData = URL_HOST + "/";
 
 var gTestID;
 
 var gTestserver;
 
-var gRegisteredServiceCleanup;
+var gIncrementalDownloadErrorType;
 
 var gCheckFunc;
 var gResponseBody;
 var gResponseStatusCode = 200;
 var gRequestURL;
 var gUpdateCount;
 var gUpdates;
 var gStatusCode;
@@ -189,16 +188,21 @@ var gASanOptions;
 // information for an individual test set DEBUG_AUS_TEST to true in the test's
 // run_test function.
 var DEBUG_AUS_TEST = true;
 
 const DATA_URI_SPEC = Services.io.newFileURI(do_get_file("../data", false)).spec;
 /* import-globals-from ../data/shared.js */
 Services.scriptloader.loadSubScript(DATA_URI_SPEC + "shared.js", this);
 
+XPCOMUtils.defineLazyModuleGetter(this, "ctypes",
+                                  "resource://gre/modules/ctypes.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "MockRegistrar",
+                                  "resource://testing-common/MockRegistrar.jsm");
+
 var gTestFiles = [];
 var gTestDirs = [];
 
 // Common files for both successful and failed updates.
 var gTestFilesCommon = [
   {
     description: "Should never change",
     fileName: FILE_UPDATE_SETTINGS_INI,
@@ -744,55 +748,31 @@ var gTestDirsPartialSuccess = [
     description: "Removed by update.manifest (rmdir)",
     relPathDir: DIR_RESOURCES + "1/",
     dirRemoved: true
   }];
 
 // Concatenate the common files to the beginning of the array.
 gTestDirsPartialSuccess = gTestDirsCommon.concat(gTestDirsPartialSuccess);
 
-// This makes it possible to run most tests on xulrunner where the update
-// channel default preference is not set.
-if (MOZ_APP_NAME == "xulrunner") {
-  try {
-    gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_CHANNEL);
-  } catch (e) {
-    setUpdateChannel("test_channel");
-  }
-}
-
 /**
  * Helper function for setting up the test environment.
  */
 function setupTestCommon() {
   debugDump("start - general test setup");
 
   Assert.strictEqual(gTestID, undefined,
                      "gTestID should be 'undefined' (setupTestCommon should " +
                      "only be called once)");
 
   let caller = Components.stack.caller;
   gTestID = caller.filename.toString().split("/").pop().split(".")[0];
 
   createAppInfo("xpcshell@tests.mozilla.org", APP_INFO_NAME, "1.0", "2.0");
 
-  // Tests that don't work with XULRunner.
-  const XUL_RUNNER_INCOMPATIBLE = ["marAppApplyUpdateAppBinInUseStageSuccess_win",
-                                   "marAppApplyUpdateStageSuccess",
-                                   "marAppApplyUpdateSuccess",
-                                   "marAppApplyUpdateAppBinInUseStageSuccessSvc_win",
-                                   "marAppApplyUpdateStageSuccessSvc",
-                                   "marAppApplyUpdateSuccessSvc"];
-  // Replace with Array.prototype.includes when it has stabilized.
-  if (MOZ_APP_NAME == "xulrunner" &&
-      XUL_RUNNER_INCOMPATIBLE.indexOf(gTestID) != -1) {
-    logTestInfo("Unable to run this test on xulrunner");
-    return false;
-  }
-
   if (IS_SERVICE_TEST && !shouldRunServiceTest()) {
     return false;
   }
 
   do_test_pending();
 
   setDefaultPrefs();
 
@@ -872,30 +852,26 @@ function setupTestCommon() {
 
 /**
  * Nulls out the most commonly used global vars used by tests to prevent leaks
  * as needed and attempts to restore the system to its original state.
  */
 function cleanupTestCommon() {
   debugDump("start - general test cleanup");
 
-  // Force the update manager to reload the update data to prevent it from
-  // writing the old data to the files that have just been removed.
-  reloadUpdateManagerData();
-
   if (gChannel) {
     gPrefRoot.removeObserver(PREF_APP_UPDATE_CHANNEL, observer);
   }
 
-  // Call app update's observe method passing xpcom-shutdown to test that the
+  // Call app update's observe method passing quit-application to test that the
   // shutdown of app update runs without throwing or leaking. The observer
   // method is used directly instead of calling notifyObservers so components
   // outside of the scope of this test don't assert and thereby cause app update
   // tests to fail.
-  gAUS.observe(null, "xpcom-shutdown", "");
+  gAUS.observe(null, "quit-application", "");
 
   gTestserver = null;
 
   if (IS_UNIX) {
     // This will delete the launch script if it exists.
     getLaunchScript();
   }
 
@@ -984,23 +960,74 @@ function cleanupTestCommon() {
 }
 
 /**
  * Helper function that calls do_test_finished that tracks whether a parallel
  * run of a test passed when it runs synchronously so the log output can be
  * inspected.
  */
 function doTestFinish() {
+  // Create empty update xml files and force the update manager to reload the
+  // update data. This will prevent the update manager from writing the test
+  // update data to the files when the test ends.
+  writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), true);
+  writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
+  reloadUpdateManagerData();
+  gUpdateManager.saveUpdates();
+
   if (DEBUG_AUS_TEST) {
     // This prevents do_print errors from being printed by the xpcshell test
     // harness due to nsUpdateService.js logging to the console when the
     // app.update.log preference is true.
     Services.prefs.setBoolPref(PREF_APP_UPDATE_LOG, false);
     gAUS.observe(null, "nsPref:changed", PREF_APP_UPDATE_LOG);
   }
+  do_execute_soon(testFinishWaitForUpdateXMLFiles);
+}
+
+/**
+ * Waits until the active-update.xml and updates.xml files don't exist and then
+ * calls do_test_finished to end the test. This is necessary due to these files
+ * being written asynchronously by nsIUpdateManager.
+ */
+function testFinishWaitForUpdateXMLFiles() {
+  let tmpActiveUpdateXML = getUpdatesRootDir();
+  tmpActiveUpdateXML.append(FILE_ACTIVE_UPDATE_XML + ".tmp");
+  if (tmpActiveUpdateXML.exists()) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, testFinishWaitForUpdateXMLFiles);
+    return;
+  }
+
+  let tmpUpdatesXML = getUpdatesRootDir();
+  tmpUpdatesXML.append(FILE_UPDATES_XML + ".tmp");
+  if (tmpUpdatesXML.exists()) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, testFinishWaitForUpdateXMLFiles);
+    return;
+  }
+
+  let activeUpdateXML = getUpdatesXMLFile(true);
+  if (activeUpdateXML.exists()) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, testFinishWaitForUpdateXMLFiles);
+    return;
+  }
+
+  let updatesXML = getUpdatesXMLFile(false);
+  if (updatesXML.exists()) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, testFinishWaitForUpdateXMLFiles);
+    return;
+  }
+
   do_execute_soon(do_test_finished);
 }
 
 /**
  * Sets the most commonly used preferences used by tests
  */
 function setDefaultPrefs() {
   Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true);
@@ -1121,16 +1148,66 @@ function checkUpdateManager(aStatusFileS
     }
     if (i != msgTags.length - 1) {
       reloadUpdateManagerData();
     }
   }
 }
 
 /**
+ * Waits until the active-update.xml and updates.xml files exists or not based
+ * on the parameters specified when calling this function or the default values
+ * if the parameters are not specified. After these conditions are met the
+ * waitForUpdateXMLFilesFinished function is called. This is necessary due to
+ * these files being written asynchronously by nsIUpdateManager.
+ *
+ * @param   aActiveUpdateExists (optional)
+ *          Whether the active-update.xml file should exist (default is false).
+ * @param   aUpdatesExists (optional)
+ *          Whether the updates.xml file should exist (default is true).
+ */
+function waitForUpdateXMLFiles(aActiveUpdateExists = false, aUpdatesExists = true) {
+  let tmpActiveUpdateXML = getUpdatesRootDir();
+  tmpActiveUpdateXML.append(FILE_ACTIVE_UPDATE_XML + ".tmp");
+  if (tmpActiveUpdateXML.exists()) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, () => waitForUpdateXMLFiles(aActiveUpdateExists, aUpdatesExists));
+    return;
+  }
+
+  let tmpUpdatesXML = getUpdatesRootDir();
+  tmpUpdatesXML.append(FILE_UPDATES_XML + ".tmp");
+  if (tmpUpdatesXML.exists()) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, () => waitForUpdateXMLFiles(aActiveUpdateExists, aUpdatesExists));
+    return;
+  }
+
+  let activeUpdateXML = getUpdatesXMLFile(true);
+  if (activeUpdateXML.exists() != aActiveUpdateExists) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, () => waitForUpdateXMLFiles(aActiveUpdateExists, aUpdatesExists));
+    return;
+  }
+
+  let updatesXML = getUpdatesXMLFile(false);
+  if (updatesXML.exists() != aUpdatesExists) {
+    // Since the file is removed asynchronously wait until it has been removed.
+    // Uses do_timeout instead of do_execute_soon to lessen log spew.
+    do_timeout(10, () => waitForUpdateXMLFiles(aActiveUpdateExists, aUpdatesExists));
+    return;
+  }
+
+  do_execute_soon(waitForUpdateXMLFilesFinished);
+}
+
+/**
  * On Mac OS X and Windows this checks if the post update '.running' file exists
  * to determine if the post update binary was launched.
  *
  * @param   aShouldExist
  *          Whether the post update '.running' file should exist.
  */
 function checkPostUpdateRunningFile(aShouldExist) {
   if (!IS_WIN && !IS_MACOSX) {
@@ -3598,17 +3675,17 @@ const downloadListener = {
   },
 
   onStatus: function DL_onStatus(aRequest, aContext, aStatus, aStatusText) {
   },
 
   onStopRequest: function DL_onStopRequest(aRequest, aContext, aStatus) {
     gStatusResult = aStatus;
     // Use a timeout to allow the request to complete
-    do_execute_soon(gCheckFunc);
+    do_execute_soon(downloadListenerStop);
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
                                          Ci.nsIProgressEventSink])
 };
 
 /**
  * Helper for starting the http server used by the tests
@@ -3989,16 +4066,142 @@ function runUpdateUsingApp(aExpectedStat
 
   setEnvironment();
   debugDump("launching application");
   gProcess.runAsync(args, args.length, processObserver);
 
   debugDump("finish - launching application to apply update");
 }
 
+/* This Mock incremental downloader is used to verify that connection interrupts
+ * work correctly in updater code. The implementation of the mock incremental
+ * downloader is very simple, it simply copies the file to the destination
+ * location.
+ */
+function initMockIncrementalDownload() {
+  const INC_CONTRACT_ID = "@mozilla.org/network/incremental-download;1";
+  let incrementalDownloadCID =
+    MockRegistrar.register(INC_CONTRACT_ID, IncrementalDownload);
+  do_register_cleanup(() => {
+    MockRegistrar.unregister(incrementalDownloadCID);
+  });
+}
+
+function IncrementalDownload() {
+  this.wrappedJSObject = this;
+}
+
+IncrementalDownload.prototype = {
+  /* nsIIncrementalDownload */
+  init(uri, file, chunkSize, intervalInSeconds) {
+    this._destination = file;
+    this._URI = uri;
+    this._finalURI = uri;
+  },
+
+  start(observer, ctxt) {
+    let tm = Cc["@mozilla.org/thread-manager;1"].
+             getService(Ci.nsIThreadManager);
+    // Do the actual operation async to give a chance for observers to add
+    // themselves.
+    tm.dispatchToMainThread(() => {
+      this._observer = observer.QueryInterface(Ci.nsIRequestObserver);
+      this._ctxt = ctxt;
+      this._observer.onStartRequest(this, this._ctxt);
+      let mar = getTestDirFile(FILE_SIMPLE_MAR);
+      mar.copyTo(this._destination.parent, this._destination.leafName);
+      let status = Cr.NS_OK;
+      switch (gIncrementalDownloadErrorType++) {
+        case 0:
+          status = Cr.NS_ERROR_NET_RESET;
+          break;
+        case 1:
+          status = Cr.NS_ERROR_CONNECTION_REFUSED;
+          break;
+        case 2:
+          status = Cr.NS_ERROR_NET_RESET;
+          break;
+        case 3:
+          status = Cr.NS_OK;
+          break;
+        case 4:
+          status = Cr.NS_ERROR_OFFLINE;
+          // After we report offline, we want to eventually show offline
+          // status being changed to online.
+          let tm2 = Cc["@mozilla.org/thread-manager;1"].
+                    getService(Ci.nsIThreadManager);
+          tm2.dispatchToMainThread(function() {
+            Services.obs.notifyObservers(gAUS,
+                                         "network:offline-status-changed",
+                                         "online");
+          });
+          break;
+      }
+      this._observer.onStopRequest(this, this._ctxt, status);
+    });
+  },
+
+  get URI() {
+    return this._URI;
+  },
+
+  get currentSize() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  get destination() {
+    return this._destination;
+  },
+
+  get finalURI() {
+    return this._finalURI;
+  },
+
+  get totalSize() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  /* nsIRequest */
+  cancel(aStatus) {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  suspend() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  isPending() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  _loadFlags: 0,
+  get loadFlags() {
+    return this._loadFlags;
+  },
+  set loadFlags(val) {
+    this._loadFlags = val;
+  },
+
+  _loadGroup: null,
+  get loadGroup() {
+    return this._loadGroup;
+  },
+  set loadGroup(val) {
+    this._loadGroup = val;
+  },
+
+  _name: "",
+  get name() {
+    return this._name;
+  },
+
+  _status: 0,
+  get status() {
+    return this._status;
+  },
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIIncrementalDownload])
+};
+
 /**
  * Sets the environment that will be used by the application process when it is
  * launched.
  */
 function setEnvironment() {
   if (IS_WIN) {
     // The tests use nsIProcess to launch the updater and it is simpler to just
     // set an environment variable and have the test updater set the current
--- a/toolkit/mozapps/update/tests/unit_aus_update/canCheckForAndCanApplyUpdates.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/canCheckForAndCanApplyUpdates.js
@@ -10,18 +10,16 @@ function run_test() {
   debugDump("testing write access to the application directory");
   let testFile = getCurrentProcessDir();
   testFile.append("update_write_access_test");
   testFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
   Assert.ok(testFile.exists(), MSG_SHOULD_EXIST);
   testFile.remove(false);
   Assert.ok(!testFile.exists(), MSG_SHOULD_NOT_EXIST);
 
-  standardInit();
-
   if (IS_WIN) {
     // Create a mutex to prevent being able to check for or apply updates.
     debugDump("attempting to create mutex");
     let handle = createMutex(getPerInstallationMutexName());
     Assert.ok(!!handle, "the update mutex should have been created");
 
     // Check if available updates cannot be checked for when there is a mutex
     // for this installation.
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForDifferentChannel.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForDifferentChannel.js
@@ -1,52 +1,50 @@
 /* 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 Update Manager Tests */
-
 function run_test() {
   setupTestCommon();
 
-  debugDump("testing removal of an active update for a channel that is not" +
+  debugDump("testing removal of an active update for a channel that is not " +
             "valid due to switching channels (Bug 486275).");
 
   let patchProps = {state: STATE_DOWNLOADING};
   let patches = getLocalPatchString(patchProps);
   let updateProps = {appVersion: "1.0"};
   let updates = getLocalUpdateString(updateProps, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeStatusFile(STATE_DOWNLOADING);
 
-  patchProps = {state: STATE_FAILED};
-  patches = getLocalPatchString(patchProps);
-  updateProps = {name: "Existing"};
-  updates = getLocalUpdateString(updateProps, patches);
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), false);
-
   setUpdateChannel("original_channel");
 
   standardInit();
 
   Assert.ok(!gUpdateManager.activeUpdate,
             "there should not be an active update");
-  let activeUpdateXML = getUpdatesXMLFile(true);
-  Assert.ok(!activeUpdateXML.exists(),
-            MSG_SHOULD_NOT_EXIST + getMsgPath(activeUpdateXML.path));
-  Assert.equal(gUpdateManager.updateCount, 2,
+  Assert.equal(gUpdateManager.updateCount, 1,
                "the update manager update count" + MSG_SHOULD_EQUAL);
   let update = gUpdateManager.getUpdateAt(0);
   Assert.equal(update.state, STATE_FAILED,
                "the first update state" + MSG_SHOULD_EQUAL);
   Assert.equal(update.errorCode, ERR_CHANNEL_CHANGE,
                "the first update errorCode" + MSG_SHOULD_EQUAL);
   Assert.equal(update.statusText, getString("statusFailed"),
                "the first update statusText " + MSG_SHOULD_EQUAL);
-  update = gUpdateManager.getUpdateAt(1);
-  Assert.equal(update.state, STATE_FAILED,
-               "the second update state" + MSG_SHOULD_EQUAL);
-  Assert.equal(update.name, "Existing",
-               "the second update name" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  let dir = getUpdatesDir();
+  dir.append(DIR_PATCH);
+  Assert.ok(dir.exists(), MSG_SHOULD_EXIST);
+
+  let statusFile = dir.clone();
+  statusFile.append(FILE_UPDATE_STATUS);
+  Assert.ok(!statusFile.exists(), MSG_SHOULD_NOT_EXIST);
 
   doTestFinish();
 }
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForOlderAppVersion.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForOlderAppVersion.js
@@ -1,49 +1,48 @@
 /* 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/.
  */
 
-
 function run_test() {
   setupTestCommon();
 
   debugDump("testing cleanup of an update download in progress for an " +
             "older version of the application on startup (Bug 485624)");
 
   let patchProps = {state: STATE_DOWNLOADING};
   let patches = getLocalPatchString(patchProps);
   let updateProps = {appVersion: "0.9"};
   let updates = getLocalUpdateString(updateProps, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeStatusFile(STATE_DOWNLOADING);
 
-  patchProps = {state: STATE_FAILED};
-  patches = getLocalPatchString(patchProps);
-  updateProps = {name: "Existing"};
-  updates = getLocalUpdateString(updateProps, patches);
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), false);
-
   standardInit();
 
   Assert.ok(!gUpdateManager.activeUpdate,
             "there should not be an active update");
-  let activeUpdateXML = getUpdatesXMLFile(true);
-  Assert.ok(!activeUpdateXML.exists(),
-            MSG_SHOULD_NOT_EXIST + getMsgPath(activeUpdateXML.path));
-  Assert.equal(gUpdateManager.updateCount, 2,
+  Assert.equal(gUpdateManager.updateCount, 1,
                "the update manager update count" + MSG_SHOULD_EQUAL);
   let update = gUpdateManager.getUpdateAt(0);
   Assert.equal(update.state, STATE_FAILED,
                "the first update state" + MSG_SHOULD_EQUAL);
   Assert.equal(update.errorCode, ERR_OLDER_VERSION_OR_SAME_BUILD,
                "the first update errorCode" + MSG_SHOULD_EQUAL);
   Assert.equal(update.statusText, getString("statusFailed"),
                "the first update statusText " + MSG_SHOULD_EQUAL);
-  update = gUpdateManager.getUpdateAt(1);
-  Assert.equal(update.state, STATE_FAILED,
-               "the second update state" + MSG_SHOULD_EQUAL);
-  Assert.equal(update.name, "Existing",
-               "the second update name" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  let dir = getUpdatesDir();
+  dir.append(DIR_PATCH);
+  Assert.ok(dir.exists(), MSG_SHOULD_EXIST);
+
+  let statusFile = dir.clone();
+  statusFile.append(FILE_UPDATE_STATUS);
+  Assert.ok(!statusFile.exists(), MSG_SHOULD_NOT_EXIST);
 
   doTestFinish();
 }
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForSameVersionAndBuildID.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingForSameVersionAndBuildID.js
@@ -13,38 +13,38 @@ function run_test() {
   let patchProps = {state: STATE_DOWNLOADING};
   let patches = getLocalPatchString(patchProps);
   let updateProps = {appVersion: "1.0",
                      buildID: "2007010101"};
   let updates = getLocalUpdateString(updateProps, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeStatusFile(STATE_DOWNLOADING);
 
-  patchProps = {state: STATE_FAILED};
-  patches = getLocalPatchString(patchProps);
-  updateProps = {name: "Existing"};
-  updates = getLocalUpdateString(updateProps, patches);
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), false);
-
   standardInit();
 
   Assert.ok(!gUpdateManager.activeUpdate,
             "there should not be an active update");
-  let activeUpdateXML = getUpdatesXMLFile(true);
-  Assert.ok(!activeUpdateXML.exists(),
-            MSG_SHOULD_NOT_EXIST + getMsgPath(activeUpdateXML.path));
-  Assert.equal(gUpdateManager.updateCount, 2,
+  Assert.equal(gUpdateManager.updateCount, 1,
                "the update manager update count" + MSG_SHOULD_EQUAL);
   let update = gUpdateManager.getUpdateAt(0);
   Assert.equal(update.state, STATE_FAILED,
                "the first update state" + MSG_SHOULD_EQUAL);
   Assert.equal(update.errorCode, ERR_OLDER_VERSION_OR_SAME_BUILD,
                "the first update errorCode" + MSG_SHOULD_EQUAL);
   Assert.equal(update.statusText, getString("statusFailed"),
                "the first update statusText " + MSG_SHOULD_EQUAL);
-  update = gUpdateManager.getUpdateAt(1);
-  Assert.equal(update.state, STATE_FAILED,
-               "the second update state" + MSG_SHOULD_EQUAL);
-  Assert.equal(update.name, "Existing",
-               "the second update name" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  let dir = getUpdatesDir();
+  dir.append(DIR_PATCH);
+  Assert.ok(dir.exists(), MSG_SHOULD_EXIST);
+
+  let statusFile = dir.clone();
+  statusFile.append(FILE_UPDATE_STATUS);
+  Assert.ok(!statusFile.exists(), MSG_SHOULD_NOT_EXIST);
 
   doTestFinish();
 }
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingIncorrectStatus.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupDownloadingIncorrectStatus.js
@@ -10,44 +10,36 @@ function run_test() {
             "STATE_DOWNLOADING (Bug 539717).");
 
   let patchProps = {state: STATE_DOWNLOADING};
   let patches = getLocalPatchString(patchProps);
   let updates = getLocalUpdateString({}, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeStatusFile(STATE_NONE);
 
-  patchProps = {state: STATE_FAILED};
-  patches = getLocalPatchString(patchProps);
-  let updateProps = {name: "Existing"};
-  updates = getLocalUpdateString(updateProps, patches);
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), false);
-
   standardInit();
 
   Assert.ok(!gUpdateManager.activeUpdate,
             "there should not be an active update");
-  let activeUpdateXML = getUpdatesXMLFile(true);
-  Assert.ok(!activeUpdateXML.exists(),
-            MSG_SHOULD_NOT_EXIST + getMsgPath(activeUpdateXML.path));
-  Assert.equal(gUpdateManager.updateCount, 2,
+  Assert.equal(gUpdateManager.updateCount, 1,
                "the update manager update count" + MSG_SHOULD_EQUAL);
   let update = gUpdateManager.getUpdateAt(0);
   Assert.equal(update.state, STATE_FAILED,
                "the first update state" + MSG_SHOULD_EQUAL);
   Assert.equal(update.errorCode, ERR_UPDATE_STATE_NONE,
                "the first update errorCode" + MSG_SHOULD_EQUAL);
   Assert.equal(update.statusText, getString("statusFailed"),
                "the first update statusText " + MSG_SHOULD_EQUAL);
-  update = gUpdateManager.getUpdateAt(1);
-  Assert.equal(update.state, STATE_FAILED,
-               "the second update state" + MSG_SHOULD_EQUAL);
-  Assert.equal(update.name, "Existing",
-               "the second update name" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
 
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let dir = getUpdatesDir();
   dir.append(DIR_PATCH);
   Assert.ok(dir.exists(), MSG_SHOULD_EXIST);
 
   let statusFile = dir.clone();
   statusFile.append(FILE_UPDATE_STATUS);
   Assert.ok(!statusFile.exists(), MSG_SHOULD_NOT_EXIST);
 
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupPendingVersionFileIncorrectStatus.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupPendingVersionFileIncorrectStatus.js
@@ -10,46 +10,36 @@ function run_test() {
             "update xml has an update with STATE_PENDING (Bug 601701).");
 
   let patchProps = {state: STATE_PENDING};
   let patches = getLocalPatchString(patchProps);
   let updates = getLocalUpdateString({}, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeVersionFile("99.9");
 
-  patchProps = {state: STATE_FAILED};
-  patches = getLocalPatchString(patchProps);
-  let updateProps = {name: "Existing"};
-  updates = getLocalUpdateString(updateProps, patches);
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), false);
-
-  standardInit();
-
   // Check that there is no activeUpdate first so the updates directory is
   // cleaned up by the UpdateManager before the remaining tests.
   Assert.ok(!gUpdateManager.activeUpdate,
             "there should not be an active update");
-  let activeUpdateXML = getUpdatesXMLFile(true);
-  Assert.ok(!activeUpdateXML.exists(),
-            MSG_SHOULD_NOT_EXIST + getMsgPath(activeUpdateXML.path));
-  Assert.equal(gUpdateManager.updateCount, 2,
+  Assert.equal(gUpdateManager.updateCount, 1,
                "the update manager update count" + MSG_SHOULD_EQUAL);
   let update = gUpdateManager.getUpdateAt(0);
   Assert.equal(update.state, STATE_FAILED,
                "the first update state" + MSG_SHOULD_EQUAL);
   Assert.equal(update.errorCode, ERR_UPDATE_STATE_NONE,
                "the first update errorCode" + MSG_SHOULD_EQUAL);
   Assert.equal(update.statusText, getString("statusFailed"),
                "the first update statusText " + MSG_SHOULD_EQUAL);
-  update = gUpdateManager.getUpdateAt(1);
-  Assert.equal(update.state, STATE_FAILED,
-               "the second update state" + MSG_SHOULD_EQUAL);
-  Assert.equal(update.name, "Existing",
-               "the second update name" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
 
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let dir = getUpdatesDir();
   dir.append(DIR_PATCH);
   Assert.ok(dir.exists(), MSG_SHOULD_EXIST);
 
   let versionFile = dir.clone();
   versionFile.append(FILE_UPDATE_VERSION);
   Assert.ok(!versionFile.exists(), MSG_SHOULD_NOT_EXIST);
 
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupSuccessLogMove.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupSuccessLogMove.js
@@ -16,21 +16,33 @@ function run_test() {
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeStatusFile(STATE_SUCCEEDED);
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   writeFile(log, "Last Update Log");
 
   standardInit();
 
+  Assert.ok(!gUpdateManager.activeUpdate,
+            "there should not be an active update");
+  Assert.equal(gUpdateManager.updateCount, 1,
+               "the update manager update count" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let cancelations = Services.prefs.getIntPref(PREF_APP_UPDATE_CANCELATIONS, 0);
   Assert.equal(cancelations, 0,
                "the " + PREF_APP_UPDATE_CANCELATIONS + " preference " +
                MSG_SHOULD_EQUAL);
 
+  let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST);
 
   log = getUpdateLog(FILE_LAST_UPDATE_LOG);
   Assert.ok(log.exists(), MSG_SHOULD_EXIST);
   Assert.equal(readFile(log), "Last Update Log",
                "the last update log contents" + MSG_SHOULD_EQUAL);
 
   log = getUpdateLog(FILE_BACKUP_UPDATE_LOG);
--- a/toolkit/mozapps/update/tests/unit_aus_update/cleanupSuccessLogsFIFO.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/cleanupSuccessLogsFIFO.js
@@ -20,16 +20,28 @@ function run_test() {
   log = getUpdateLog(FILE_BACKUP_UPDATE_LOG);
   writeFile(log, "To Be Deleted Backup Update Log");
 
   log = getUpdateLog(FILE_UPDATE_LOG);
   writeFile(log, "Last Update Log");
 
   standardInit();
 
+  Assert.ok(!gUpdateManager.activeUpdate,
+            "there should not be an active update");
+  Assert.equal(gUpdateManager.updateCount, 1,
+               "the update manager update count" + MSG_SHOULD_EQUAL);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(), MSG_SHOULD_NOT_EXIST);
 
   log = getUpdateLog(FILE_LAST_UPDATE_LOG);
   Assert.ok(log.exists(), MSG_SHOULD_EXIST);
   Assert.equal(readFile(log), "Last Update Log",
                "the last update log contents" + MSG_SHOULD_EQUAL);
 
   log = getUpdateLog(FILE_BACKUP_UPDATE_LOG);
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadCompleteAfterPartialFailure.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadCompleteAfterPartialFailure.js
@@ -1,14 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-Components.utils.import("resource://testing-common/MockRegistrar.jsm");
-
 const WindowWatcher = {
   getNewPrompter: function WW_getNewPrompter(aParent) {
     Assert.ok(!aParent,
               "the aParent parameter should not be defined");
     return {
       alert: function WW_GNP_alert(aTitle, aText) {
         let title = getString("updaterIOErrorTitle");
         Assert.equal(aTitle, title,
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedNoRecovery.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedNoRecovery.js
@@ -1,223 +1,56 @@
 /* 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 MAR File Download Tests */
-
-Components.utils.import("resource://testing-common/MockRegistrar.jsm");
-const INC_CONTRACT_ID = "@mozilla.org/network/incremental-download;1";
-
-// gIncrementalDownloadErrorType is used to loop through each of the connection
-// error types in the Mock incremental downloader.
-var gIncrementalDownloadErrorType = 0;
-
-var gNextRunFunc;
-var gExpectedStatusResult;
-
 function run_test() {
   setupTestCommon();
 
-  debugDump("testing mar downloads and mar download interrupted recovery");
+  debugDump("testing mar download with interrupted recovery count exceeded");
 
   Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
   start_httpserver();
   setUpdateURL(gURLData + gHTTPHandlerPath);
-  standardInit();
-  do_execute_soon(run_test_pt1);
-}
-
-// The HttpServer must be stopped before calling do_test_finished
-function finish_test() {
-  stop_httpserver(doTestFinish);
-}
-
-// Helper function for testing mar downloads that have the correct size
-// specified in the update xml.
-function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
-  gUpdates = null;
-  gUpdateCount = null;
-  gStatusResult = null;
-  gCheckFunc = check_test_helper_pt1_1;
-  gNextRunFunc = aNextRunFunc;
-  gExpectedStatusResult = aExpectedStatusResult;
-  debugDump(aMsg, Components.stack.caller);
+  initMockIncrementalDownload();
+  gIncrementalDownloadErrorType = 0;
+  Services.prefs.setIntPref(PREF_APP_UPDATE_SOCKET_MAXERRORS, 2);
+  Services.prefs.setIntPref(PREF_APP_UPDATE_RETRYTIMEOUT, 0);
+  let patches = getRemotePatchString({});
+  let updates = getRemoteUpdateString({}, patches);
+  gResponseBody = getRemoteUpdatesXMLString(updates);
+  gCheckFunc = updateCheckCompleted;
   gUpdateChecker.checkForUpdates(updateCheckListener, true);
 }
 
-function check_test_helper_pt1_1() {
+/**
+ * Since gCheckFunc value is the updateCheckCompleted function at this stage
+ * this is called after the update check completes in updateCheckListener.
+ */
+function updateCheckCompleted() {
   Assert.equal(gUpdateCount, 1,
                "the update count" + MSG_SHOULD_EQUAL);
-  gCheckFunc = check_test_helper_pt1_2;
   let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   let state = gAUS.downloadUpdate(bestUpdate, false);
   if (state == STATE_NONE || state == STATE_FAILED) {
     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
   }
   gAUS.addDownloadListener(downloadListener);
 }
 
-function check_test_helper_pt1_2() {
-  Assert.equal(gStatusResult, gExpectedStatusResult,
+/**
+ * Called after the download listener onStopRequest is called.
+ */
+function downloadListenerStop() {
+  Assert.equal(gStatusResult, Cr.NS_ERROR_NET_RESET,
                "the download status result" + MSG_SHOULD_EQUAL);
   gAUS.removeDownloadListener(downloadListener);
-  gNextRunFunc();
-}
-
-function setResponseBody() {
-  let patches = getRemotePatchString({});
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-}
-
-function initMockIncrementalDownload() {
-  let incrementalDownloadCID =
-    MockRegistrar.register(INC_CONTRACT_ID, IncrementalDownload);
-  do_register_cleanup(() => {
-    MockRegistrar.unregister(incrementalDownloadCID);
-  });
-}
-
-/* This Mock incremental downloader is used to verify that connection
- * interrupts work correctly in updater code.  The implementation of
- * the mock incremental downloader is very simple, it simply copies
- * the file to the destination location.
- */
-
-function IncrementalDownload() {
-  this.wrappedJSObject = this;
+  do_execute_soon(waitForUpdateXMLFiles);
 }
 
-IncrementalDownload.prototype = {
-  /* nsIIncrementalDownload */
-  init(uri, file, chunkSize, intervalInSeconds) {
-    this._destination = file;
-    this._URI = uri;
-    this._finalURI = uri;
-  },
-
-  start(observer, ctxt) {
-    let tm = Cc["@mozilla.org/thread-manager;1"].
-             getService(Ci.nsIThreadManager);
-    // Do the actual operation async to give a chance for observers
-    // to add themselves.
-    tm.dispatchToMainThread(() => {
-      this._observer = observer.QueryInterface(Ci.nsIRequestObserver);
-      this._ctxt = ctxt;
-      this._observer.onStartRequest(this, this._ctxt);
-      let mar = getTestDirFile(FILE_SIMPLE_MAR);
-      mar.copyTo(this._destination.parent, this._destination.leafName);
-      let status = Cr.NS_OK;
-      switch (gIncrementalDownloadErrorType++) {
-        case 0:
-          status = Cr.NS_ERROR_NET_RESET;
-          break;
-        case 1:
-          status = Cr.NS_ERROR_CONNECTION_REFUSED;
-          break;
-        case 2:
-          status = Cr.NS_ERROR_NET_RESET;
-          break;
-        case 3:
-          status = Cr.NS_OK;
-          break;
-        case 4:
-          status = Cr.NS_ERROR_OFFLINE;
-          // After we report offline, we want to eventually show offline
-          // status being changed to online.
-          let tm2 = Cc["@mozilla.org/thread-manager;1"].
-                    getService(Ci.nsIThreadManager);
-          tm2.dispatchToMainThread(function() {
-            Services.obs.notifyObservers(gAUS,
-                                         "network:offline-status-changed",
-                                         "online");
-          });
-          break;
-      }
-      this._observer.onStopRequest(this, this._ctxt, status);
-    });
-  },
-
-  get URI() {
-    return this._URI;
-  },
-
-  get currentSize() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  get destination() {
-    return this._destination;
-  },
-
-  get finalURI() {
-    return this._finalURI;
-  },
-
-  get totalSize() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /* nsIRequest */
-  cancel(aStatus) {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  suspend() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  isPending() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  _loadFlags: 0,
-  get loadFlags() {
-    return this._loadFlags;
-  },
-  set loadFlags(val) {
-    this._loadFlags = val;
-  },
-
-  _loadGroup: null,
-  get loadGroup() {
-    return this._loadGroup;
-  },
-  set loadGroup(val) {
-    this._loadGroup = val;
-  },
-
-  _name: "",
-  get name() {
-    return this._name;
-  },
-
-  _status: 0,
-  get status() {
-    return this._status;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIIncrementalDownload])
-};
-
-// Test disconnecting during an update
-function run_test_pt1() {
-  initMockIncrementalDownload();
-  setResponseBody();
-  run_test_helper_pt1("mar download with connection interruption",
-                      Cr.NS_OK, run_test_pt2);
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  // The HttpServer must be stopped before calling do_test_finished
+  stop_httpserver(doTestFinish);
 }
-
-// Test disconnecting during an update
-function run_test_pt2() {
-  gIncrementalDownloadErrorType = 0;
-  Services.prefs.setIntPref(PREF_APP_UPDATE_SOCKET_MAXERRORS, 2);
-  Services.prefs.setIntPref(PREF_APP_UPDATE_RETRYTIMEOUT, 0);
-  setResponseBody();
-  run_test_helper_pt1("mar download with connection interruption without recovery",
-                      Cr.NS_ERROR_NET_RESET, run_test_pt3);
-}
-
-// Test entering offline mode while downloading
-function run_test_pt3() {
-  gIncrementalDownloadErrorType = 4;
-  setResponseBody();
-  run_test_helper_pt1("mar download with offline mode",
-                      Cr.NS_OK, finish_test);
-}
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedOffline.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedOffline.js
@@ -1,223 +1,55 @@
 /* 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 MAR File Download Tests */
-
-Components.utils.import("resource://testing-common/MockRegistrar.jsm");
-const INC_CONTRACT_ID = "@mozilla.org/network/incremental-download;1";
-
-// gIncrementalDownloadErrorType is used to loop through each of the connection
-// error types in the Mock incremental downloader.
-var gIncrementalDownloadErrorType = 0;
-
-var gNextRunFunc;
-var gExpectedStatusResult;
-
 function run_test() {
   setupTestCommon();
 
-  debugDump("testing mar downloads and mar download interrupted recovery");
+  debugDump("testing mar download when offline");
 
   Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
   start_httpserver();
   setUpdateURL(gURLData + gHTTPHandlerPath);
-  standardInit();
-  do_execute_soon(run_test_pt1);
-}
-
-// The HttpServer must be stopped before calling do_test_finished
-function finish_test() {
-  stop_httpserver(doTestFinish);
-}
-
-// Helper function for testing mar downloads that have the correct size
-// specified in the update xml.
-function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
-  gUpdates = null;
-  gUpdateCount = null;
-  gStatusResult = null;
-  gCheckFunc = check_test_helper_pt1_1;
-  gNextRunFunc = aNextRunFunc;
-  gExpectedStatusResult = aExpectedStatusResult;
-  debugDump(aMsg, Components.stack.caller);
+  initMockIncrementalDownload();
+  gIncrementalDownloadErrorType = 4;
+  let patches = getRemotePatchString({});
+  let updates = getRemoteUpdateString({}, patches);
+  gResponseBody = getRemoteUpdatesXMLString(updates);
+  gCheckFunc = updateCheckCompleted;
   gUpdateChecker.checkForUpdates(updateCheckListener, true);
 }
 
-function check_test_helper_pt1_1() {
+/**
+ * Since gCheckFunc value is the updateCheckCompleted function at this stage
+ * this is called after the update check completes in updateCheckListener.
+ */
+function updateCheckCompleted() {
   Assert.equal(gUpdateCount, 1,
                "the update count" + MSG_SHOULD_EQUAL);
-  gCheckFunc = check_test_helper_pt1_2;
   let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   let state = gAUS.downloadUpdate(bestUpdate, false);
   if (state == STATE_NONE || state == STATE_FAILED) {
     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
   }
   gAUS.addDownloadListener(downloadListener);
 }
 
-function check_test_helper_pt1_2() {
-  Assert.equal(gStatusResult, gExpectedStatusResult,
+/**
+ * Called after the download listener onStopRequest is called.
+ */
+function downloadListenerStop() {
+  Assert.equal(gStatusResult, Cr.NS_OK,
                "the download status result" + MSG_SHOULD_EQUAL);
   gAUS.removeDownloadListener(downloadListener);
-  gNextRunFunc();
-}
-
-function setResponseBody() {
-  let patches = getRemotePatchString({});
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-}
-
-function initMockIncrementalDownload() {
-  let incrementalDownloadCID =
-    MockRegistrar.register(INC_CONTRACT_ID, IncrementalDownload);
-  do_register_cleanup(() => {
-    MockRegistrar.unregister(incrementalDownloadCID);
-  });
-}
-
-/* This Mock incremental downloader is used to verify that connection
- * interrupts work correctly in updater code.  The implementation of
- * the mock incremental downloader is very simple, it simply copies
- * the file to the destination location.
- */
-
-function IncrementalDownload() {
-  this.wrappedJSObject = this;
+  gUpdateManager.cleanupActiveUpdate();
+  do_execute_soon(waitForUpdateXMLFiles);
 }
 
-IncrementalDownload.prototype = {
-  /* nsIIncrementalDownload */
-  init(uri, file, chunkSize, intervalInSeconds) {
-    this._destination = file;
-    this._URI = uri;
-    this._finalURI = uri;
-  },
-
-  start(observer, ctxt) {
-    let tm = Cc["@mozilla.org/thread-manager;1"].
-             getService(Ci.nsIThreadManager);
-    // Do the actual operation async to give a chance for observers
-    // to add themselves.
-    tm.dispatchToMainThread(() => {
-      this._observer = observer.QueryInterface(Ci.nsIRequestObserver);
-      this._ctxt = ctxt;
-      this._observer.onStartRequest(this, this._ctxt);
-      let mar = getTestDirFile(FILE_SIMPLE_MAR);
-      mar.copyTo(this._destination.parent, this._destination.leafName);
-      let status = Cr.NS_OK;
-      switch (gIncrementalDownloadErrorType++) {
-        case 0:
-          status = Cr.NS_ERROR_NET_RESET;
-          break;
-        case 1:
-          status = Cr.NS_ERROR_CONNECTION_REFUSED;
-          break;
-        case 2:
-          status = Cr.NS_ERROR_NET_RESET;
-          break;
-        case 3:
-          status = Cr.NS_OK;
-          break;
-        case 4:
-          status = Cr.NS_ERROR_OFFLINE;
-          // After we report offline, we want to eventually show offline
-          // status being changed to online.
-          let tm2 = Cc["@mozilla.org/thread-manager;1"].
-                    getService(Ci.nsIThreadManager);
-          tm2.dispatchToMainThread(function() {
-            Services.obs.notifyObservers(gAUS,
-                                         "network:offline-status-changed",
-                                         "online");
-          });
-          break;
-      }
-      this._observer.onStopRequest(this, this._ctxt, status);
-    });
-  },
-
-  get URI() {
-    return this._URI;
-  },
-
-  get currentSize() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  get destination() {
-    return this._destination;
-  },
-
-  get finalURI() {
-    return this._finalURI;
-  },
-
-  get totalSize() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /* nsIRequest */
-  cancel(aStatus) {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  suspend() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  isPending() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  _loadFlags: 0,
-  get loadFlags() {
-    return this._loadFlags;
-  },
-  set loadFlags(val) {
-    this._loadFlags = val;
-  },
-
-  _loadGroup: null,
-  get loadGroup() {
-    return this._loadGroup;
-  },
-  set loadGroup(val) {
-    this._loadGroup = val;
-  },
-
-  _name: "",
-  get name() {
-    return this._name;
-  },
-
-  _status: 0,
-  get status() {
-    return this._status;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIIncrementalDownload])
-};
-
-// Test disconnecting during an update
-function run_test_pt1() {
-  initMockIncrementalDownload();
-  setResponseBody();
-  run_test_helper_pt1("mar download with connection interruption",
-                      Cr.NS_OK, run_test_pt2);
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  // The HttpServer must be stopped before calling do_test_finished
+  stop_httpserver(doTestFinish);
 }
-
-// Test disconnecting during an update
-function run_test_pt2() {
-  gIncrementalDownloadErrorType = 0;
-  Services.prefs.setIntPref(PREF_APP_UPDATE_SOCKET_MAXERRORS, 2);
-  Services.prefs.setIntPref(PREF_APP_UPDATE_RETRYTIMEOUT, 0);
-  setResponseBody();
-  run_test_helper_pt1("mar download with connection interruption without recovery",
-                      Cr.NS_ERROR_NET_RESET, run_test_pt3);
-}
-
-// Test entering offline mode while downloading
-function run_test_pt3() {
-  gIncrementalDownloadErrorType = 4;
-  setResponseBody();
-  run_test_helper_pt1("mar download with offline mode",
-                      Cr.NS_OK, finish_test);
-}
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js
@@ -1,223 +1,59 @@
 /* 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 MAR File Download Tests */
-
-Components.utils.import("resource://testing-common/MockRegistrar.jsm");
-const INC_CONTRACT_ID = "@mozilla.org/network/incremental-download;1";
-
-// gIncrementalDownloadErrorType is used to loop through each of the connection
-// error types in the Mock incremental downloader.
-var gIncrementalDownloadErrorType = 0;
-
-var gNextRunFunc;
-var gExpectedStatusResult;
-
 function run_test() {
   setupTestCommon();
 
-  debugDump("testing mar downloads and mar download interrupted recovery");
+  debugDump("testing mar mar download interrupted recovery");
 
   Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
   start_httpserver();
   setUpdateURL(gURLData + gHTTPHandlerPath);
-  standardInit();
-  do_execute_soon(run_test_pt1);
-}
 
-// The HttpServer must be stopped before calling do_test_finished
-function finish_test() {
-  stop_httpserver(doTestFinish);
-}
-
-// Helper function for testing mar downloads that have the correct size
-// specified in the update xml.
-function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
+  initMockIncrementalDownload();
+  gIncrementalDownloadErrorType = 0;
+  let patches = getRemotePatchString({});
+  let updates = getRemoteUpdateString({}, patches);
+  gResponseBody = getRemoteUpdatesXMLString(updates);
   gUpdates = null;
   gUpdateCount = null;
   gStatusResult = null;
-  gCheckFunc = check_test_helper_pt1_1;
-  gNextRunFunc = aNextRunFunc;
-  gExpectedStatusResult = aExpectedStatusResult;
-  debugDump(aMsg, Components.stack.caller);
+  gCheckFunc = updateCheckCompleted;
   gUpdateChecker.checkForUpdates(updateCheckListener, true);
 }
 
-function check_test_helper_pt1_1() {
+/**
+ * Since gCheckFunc value is the updateCheckCompleted function at this stage
+ * this is called after the update check completes in updateCheckListener.
+ */
+function updateCheckCompleted() {
   Assert.equal(gUpdateCount, 1,
                "the update count" + MSG_SHOULD_EQUAL);
-  gCheckFunc = check_test_helper_pt1_2;
   let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   let state = gAUS.downloadUpdate(bestUpdate, false);
   if (state == STATE_NONE || state == STATE_FAILED) {
     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
   }
   gAUS.addDownloadListener(downloadListener);
 }
 
-function check_test_helper_pt1_2() {
-  Assert.equal(gStatusResult, gExpectedStatusResult,
+/**
+ * Called after the download listener onStopRequest is called.
+ */
+function downloadListenerStop() {
+  Assert.equal(gStatusResult, Cr.NS_OK,
                "the download status result" + MSG_SHOULD_EQUAL);
   gAUS.removeDownloadListener(downloadListener);
-  gNextRunFunc();
-}
-
-function setResponseBody() {
-  let patches = getRemotePatchString({});
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-}
-
-function initMockIncrementalDownload() {
-  let incrementalDownloadCID =
-    MockRegistrar.register(INC_CONTRACT_ID, IncrementalDownload);
-  do_register_cleanup(() => {
-    MockRegistrar.unregister(incrementalDownloadCID);
-  });
-}
-
-/* This Mock incremental downloader is used to verify that connection
- * interrupts work correctly in updater code.  The implementation of
- * the mock incremental downloader is very simple, it simply copies
- * the file to the destination location.
- */
-
-function IncrementalDownload() {
-  this.wrappedJSObject = this;
+  gUpdateManager.cleanupActiveUpdate();
+  do_execute_soon(waitForUpdateXMLFiles);
 }
 
-IncrementalDownload.prototype = {
-  /* nsIIncrementalDownload */
-  init(uri, file, chunkSize, intervalInSeconds) {
-    this._destination = file;
-    this._URI = uri;
-    this._finalURI = uri;
-  },
-
-  start(observer, ctxt) {
-    let tm = Cc["@mozilla.org/thread-manager;1"].
-             getService(Ci.nsIThreadManager);
-    // Do the actual operation async to give a chance for observers
-    // to add themselves.
-    tm.dispatchToMainThread(() => {
-      this._observer = observer.QueryInterface(Ci.nsIRequestObserver);
-      this._ctxt = ctxt;
-      this._observer.onStartRequest(this, this._ctxt);
-      let mar = getTestDirFile(FILE_SIMPLE_MAR);
-      mar.copyTo(this._destination.parent, this._destination.leafName);
-      let status = Cr.NS_OK;
-      switch (gIncrementalDownloadErrorType++) {
-        case 0:
-          status = Cr.NS_ERROR_NET_RESET;
-          break;
-        case 1:
-          status = Cr.NS_ERROR_CONNECTION_REFUSED;
-          break;
-        case 2:
-          status = Cr.NS_ERROR_NET_RESET;
-          break;
-        case 3:
-          status = Cr.NS_OK;
-          break;
-        case 4:
-          status = Cr.NS_ERROR_OFFLINE;
-          // After we report offline, we want to eventually show offline
-          // status being changed to online.
-          let tm2 = Cc["@mozilla.org/thread-manager;1"].
-                    getService(Ci.nsIThreadManager);
-          tm2.dispatchToMainThread(function() {
-            Services.obs.notifyObservers(gAUS,
-                                         "network:offline-status-changed",
-                                         "online");
-          });
-          break;
-      }
-      this._observer.onStopRequest(this, this._ctxt, status);
-    });
-  },
-
-  get URI() {
-    return this._URI;
-  },
-
-  get currentSize() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  get destination() {
-    return this._destination;
-  },
-
-  get finalURI() {
-    return this._finalURI;
-  },
-
-  get totalSize() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /* nsIRequest */
-  cancel(aStatus) {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  suspend() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  isPending() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  _loadFlags: 0,
-  get loadFlags() {
-    return this._loadFlags;
-  },
-  set loadFlags(val) {
-    this._loadFlags = val;
-  },
-
-  _loadGroup: null,
-  get loadGroup() {
-    return this._loadGroup;
-  },
-  set loadGroup(val) {
-    this._loadGroup = val;
-  },
-
-  _name: "",
-  get name() {
-    return this._name;
-  },
-
-  _status: 0,
-  get status() {
-    return this._status;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIIncrementalDownload])
-};
-
-// Test disconnecting during an update
-function run_test_pt1() {
-  initMockIncrementalDownload();
-  setResponseBody();
-  run_test_helper_pt1("mar download with connection interruption",
-                      Cr.NS_OK, run_test_pt2);
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  // The HttpServer must be stopped before calling do_test_finished
+  stop_httpserver(doTestFinish);
 }
-
-// Test disconnecting during an update
-function run_test_pt2() {
-  gIncrementalDownloadErrorType = 0;
-  Services.prefs.setIntPref(PREF_APP_UPDATE_SOCKET_MAXERRORS, 2);
-  Services.prefs.setIntPref(PREF_APP_UPDATE_RETRYTIMEOUT, 0);
-  setResponseBody();
-  run_test_helper_pt1("mar download with connection interruption without recovery",
-                      Cr.NS_ERROR_NET_RESET, run_test_pt3);
-}
-
-// Test entering offline mode while downloading
-function run_test_pt3() {
-  gIncrementalDownloadErrorType = 4;
-  setResponseBody();
-  run_test_helper_pt1("mar download with offline mode",
-                      Cr.NS_OK, finish_test);
-}
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadInvalidSizeMar.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadInvalidSizeMar.js
@@ -1,16 +1,13 @@
 /* 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/.
  */
 
-var gNextRunFunc;
-var gExpectedStatusResult;
-
 function run_test() {
   // The network code that downloads the mar file accesses the profile to cache
   // the download, but the profile is only available after calling
   // do_get_profile in xpcshell tests. This prevents an error from being logged.
   do_get_profile();
 
   setupTestCommon();
 
@@ -18,64 +15,47 @@ function run_test() {
 
   Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
   start_httpserver();
   setUpdateURL(gURLData + gHTTPHandlerPath);
   standardInit();
   do_execute_soon(run_test_pt1);
 }
 
-// The HttpServer must be stopped before calling do_test_finished
-function finish_test() {
-  stop_httpserver(doTestFinish);
-}
-
-// Helper function for testing mar downloads that have the correct size
-// specified in the update xml.
-function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
-  gUpdates = null;
-  gUpdateCount = null;
-  gStatusResult = null;
+// mar download with an invalid file size
+function run_test_pt1() {
+  let patchProps = {size: "1024000"};
+  let patches = getRemotePatchString(patchProps);
+  let updates = getRemoteUpdateString({}, patches);
+  gResponseBody = getRemoteUpdatesXMLString(updates);
   gCheckFunc = check_test_helper_pt1_1;
-  gNextRunFunc = aNextRunFunc;
-  gExpectedStatusResult = aExpectedStatusResult;
-  debugDump(aMsg, Components.stack.caller);
+  debugDump("mar download with an invalid file size");
   gUpdateChecker.checkForUpdates(updateCheckListener, true);
 }
 
 function check_test_helper_pt1_1() {
   Assert.equal(gUpdateCount, 1,
                "the update count" + MSG_SHOULD_EQUAL);
-  gCheckFunc = check_test_helper_pt1_2;
   let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   let state = gAUS.downloadUpdate(bestUpdate, false);
   if (state == STATE_NONE || state == STATE_FAILED) {
     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
   }
   gAUS.addDownloadListener(downloadListener);
 }
 
-function check_test_helper_pt1_2() {
-  Assert.equal(gStatusResult, gExpectedStatusResult,
+/**
+ * Called after the download listener onStopRequest is called.
+ */
+function downloadListenerStop() {
+  Assert.equal(gStatusResult, Cr.NS_ERROR_UNEXPECTED,
                "the download status result" + MSG_SHOULD_EQUAL);
   gAUS.removeDownloadListener(downloadListener);
-  gNextRunFunc();
+  do_execute_soon(waitForUpdateXMLFiles);
 }
 
-// mar download with the mar not found
-function run_test_pt1() {
-  let patchProps = {url: gURLData + "missing.mar"};
-  let patches = getRemotePatchString(patchProps);
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-  run_test_helper_pt1("mar download with the mar not found",
-                      Cr.NS_ERROR_UNEXPECTED, run_test_pt2);
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  // The HttpServer must be stopped before calling do_test_finished
+  stop_httpserver(doTestFinish);
 }
-
-// mar download with an invalid file size
-function run_test_pt2() {
-  let patchProps = {size: "1024000"};
-  let patches = getRemotePatchString(patchProps);
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-  run_test_helper_pt1("mar download with an invalid file size",
-                      Cr.NS_ERROR_UNEXPECTED, finish_test);
-}
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadMissingMar.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadMissingMar.js
@@ -1,81 +1,64 @@
 /* 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/.
  */
 
-var gNextRunFunc;
-var gExpectedStatusResult;
-
 function run_test() {
   // The network code that downloads the mar file accesses the profile to cache
   // the download, but the profile is only available after calling
   // do_get_profile in xpcshell tests. This prevents an error from being logged.
   do_get_profile();
 
   setupTestCommon();
 
-  debugDump("testing invalid mar downloads");
+  debugDump("testing invalid size mar download");
 
   Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
   start_httpserver();
   setUpdateURL(gURLData + gHTTPHandlerPath);
   standardInit();
   do_execute_soon(run_test_pt1);
 }
 
-// The HttpServer must be stopped before calling do_test_finished
-function finish_test() {
-  stop_httpserver(doTestFinish);
-}
-
-// Helper function for testing mar downloads that have the correct size
-// specified in the update xml.
-function run_test_helper_pt1(aMsg, aExpectedStatusResult, aNextRunFunc) {
+// mar download with the mar not found
+function run_test_pt1() {
+  let patchProps = {url: gURLData + "missing.mar"};
+  let patches = getRemotePatchString(patchProps);
+  let updates = getRemoteUpdateString({}, patches);
+  gResponseBody = getRemoteUpdatesXMLString(updates);
   gUpdates = null;
   gUpdateCount = null;
   gStatusResult = null;
   gCheckFunc = check_test_helper_pt1_1;
-  gNextRunFunc = aNextRunFunc;
-  gExpectedStatusResult = aExpectedStatusResult;
-  debugDump(aMsg, Components.stack.caller);
+  debugDump("mar download with the mar not found");
   gUpdateChecker.checkForUpdates(updateCheckListener, true);
 }
 
 function check_test_helper_pt1_1() {
   Assert.equal(gUpdateCount, 1,
                "the update count" + MSG_SHOULD_EQUAL);
-  gCheckFunc = check_test_helper_pt1_2;
   let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   let state = gAUS.downloadUpdate(bestUpdate, false);
   if (state == STATE_NONE || state == STATE_FAILED) {
     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
   }
   gAUS.addDownloadListener(downloadListener);
 }
 
-function check_test_helper_pt1_2() {
-  Assert.equal(gStatusResult, gExpectedStatusResult,
+/**
+ * Called after the download listener onStopRequest is called.
+ */
+function downloadListenerStop() {
+  Assert.equal(gStatusResult, Cr.NS_ERROR_UNEXPECTED,
                "the download status result" + MSG_SHOULD_EQUAL);
   gAUS.removeDownloadListener(downloadListener);
-  gNextRunFunc();
+  do_execute_soon(waitForUpdateXMLFiles);
 }
 
-// mar download with the mar not found
-function run_test_pt1() {
-  let patchProps = {url: gURLData + "missing.mar"};
-  let patches = getRemotePatchString(patchProps);
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-  run_test_helper_pt1("mar download with the mar not found",
-                      Cr.NS_ERROR_UNEXPECTED, run_test_pt2);
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  // The HttpServer must be stopped before calling do_test_finished
+  stop_httpserver(doTestFinish);
 }
-
-// mar download with an invalid file size
-function run_test_pt2() {
-  let patchProps = {size: "1024000"};
-  let patches = getRemotePatchString(patchProps);
-  let updates = getRemoteUpdateString({}, patches);
-  gResponseBody = getRemoteUpdatesXMLString(updates);
-  run_test_helper_pt1("mar download with an invalid file size",
-                      Cr.NS_ERROR_UNEXPECTED, finish_test);
-}
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadResumeForSameAppVersion.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadResumeForSameAppVersion.js
@@ -19,18 +19,21 @@ function run_test() {
   standardInit();
 
   Assert.equal(gUpdateManager.updateCount, 0,
                "the update manager updateCount attribute" + MSG_SHOULD_EQUAL);
   Assert.equal(gUpdateManager.activeUpdate.state, STATE_DOWNLOADING,
                "the update manager activeUpdate state attribute" +
                MSG_SHOULD_EQUAL);
 
-  // Pause the download and reload the Update Manager with an empty update so
-  // the Application Update Service doesn't write the update xml files during
-  // xpcom-shutdown which will leave behind the test directory.
+  // Pausing the download along with reloading the update manager in
+  // doTestFinish will prevent writing the update xml files during shutdown.
   gAUS.pauseDownload();
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), true);
-  writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
-  reloadUpdateManagerData();
+  gUpdateManager.cleanupActiveUpdate();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
 
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   do_execute_soon(doTestFinish);
 }
--- a/toolkit/mozapps/update/tests/unit_aus_update/remoteUpdateXML.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/remoteUpdateXML.js
@@ -282,11 +282,10 @@ function run_test_pt11() {
 function check_test_pt11() {
   let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   Assert.ok(!!bestUpdate,
             "there should be one update available");
   Assert.equal(bestUpdate.appVersion, "1.0",
                "the update appVersion attribute" + MSG_SHOULD_EQUAL);
   Assert.equal(bestUpdate.displayVersion, "1.0",
                "the update displayVersion attribute" + MSG_SHOULD_EQUAL);
-
   doTestFinish();
 }
--- a/toolkit/mozapps/update/tests/unit_aus_update/uiAutoPref.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/uiAutoPref.js
@@ -1,17 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-Components.utils.import("resource://testing-common/MockRegistrar.jsm");
-
 const WindowWatcher = {
   openWindow(aParent, aUrl, aName, aFeatures, aArgs) {
-    gCheckFunc();
+    check_showUpdateAvailable();
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowWatcher])
 };
 
 const WindowMediator = {
   getMostRecentWindow(aWindowType) {
     do_execute_soon(check_status);
@@ -42,17 +40,16 @@ function run_test() {
   let windowMediatorCID =
     MockRegistrar.register("@mozilla.org/appshell/window-mediator;1",
                            WindowMediator);
   do_register_cleanup(() => {
     MockRegistrar.unregister(windowWatcherCID);
     MockRegistrar.unregister(windowMediatorCID);
   });
 
-  gCheckFunc = check_showUpdateAvailable;
   let patches = getRemotePatchString({});
   let updates = getRemoteUpdateString({}, patches);
   gResponseBody = getRemoteUpdatesXMLString(updates);
   gAUS.notify(null);
 }
 
 function check_status() {
   let status = readStatusFile();
--- a/toolkit/mozapps/update/tests/unit_aus_update/uiSilentPref.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/uiSilentPref.js
@@ -1,26 +1,19 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-Components.utils.import("resource://testing-common/MockRegistrar.jsm");
-
-/**
- * Test that nsIUpdatePrompt doesn't display UI for showUpdateAvailable and
- * showUpdateError when the app.update.silent preference is true.
- */
-
 const WindowWatcher = {
   openWindow(aParent, aUrl, aName, aFeatures, aArgs) {
-    gCheckFunc();
+    do_throw("should not have called openWindow!");
   },
 
   getNewPrompter(aParent) {
-    gCheckFunc();
+    do_throw("should not have seen getNewPrompter!");
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowWatcher])
 };
 
 function run_test() {
   setupTestCommon();
 
@@ -33,43 +26,41 @@ function run_test() {
     MockRegistrar.register("@mozilla.org/embedcomp/window-watcher;1",
                            WindowWatcher);
   do_register_cleanup(() => {
     MockRegistrar.unregister(windowWatcherCID);
   });
 
   standardInit();
 
-  debugDump("testing showUpdateAvailable should not call openWindow");
+  logTestInfo("testing showUpdateAvailable should not call openWindow");
   let patchProps = {state: STATE_FAILED};
   let patches = getLocalPatchString(patchProps);
   let updates = getLocalUpdateString({}, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   writeStatusFile(STATE_FAILED);
   reloadUpdateManagerData();
 
-  gCheckFunc = check_showUpdateAvailable;
   let update = gUpdateManager.activeUpdate;
   gUP.showUpdateAvailable(update);
   // Report a successful check after the call to showUpdateAvailable since it
   // didn't throw and otherwise it would report no tests run.
   Assert.ok(true,
             "calling showUpdateAvailable should not attempt to open a window");
 
-  debugDump("testing showUpdateError should not call getNewPrompter");
-  gCheckFunc = check_showUpdateError;
+  logTestInfo("testing showUpdateError should not call getNewPrompter");
   update.errorCode = WRITE_ERROR;
   gUP.showUpdateError(update);
   // Report a successful check after the call to showUpdateError since it
   // didn't throw and otherwise it would report no tests run.
   Assert.ok(true,
             "calling showUpdateError should not attempt to open a window");
 
-  doTestFinish();
+  gUpdateManager.cleanupActiveUpdate();
+  do_execute_soon(waitForUpdateXMLFiles);
 }
 
-function check_showUpdateAvailable() {
-  do_throw("showUpdateAvailable should not have called openWindow!");
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  doTestFinish();
 }
-
-function check_showUpdateError() {
-  do_throw("showUpdateError should not have seen getNewPrompter!");
-}
--- a/toolkit/mozapps/update/tests/unit_aus_update/uiUnsupportedAlreadyNotified.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/uiUnsupportedAlreadyNotified.js
@@ -1,14 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-Cu.import("resource://testing-common/MockRegistrar.jsm");
-
 const WindowWatcher = {
   openWindow(aParent, aUrl, aName, aFeatures, aArgs) {
     check_showUpdateAvailable();
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowWatcher])
 };
 
--- a/toolkit/mozapps/update/tests/unit_aus_update/xpcshell.ini
+++ b/toolkit/mozapps/update/tests/unit_aus_update/xpcshell.ini
@@ -6,22 +6,25 @@
 tags = appupdate
 head = head_update.js
 
 [ausReadStrings.js]
 [canCheckForAndCanApplyUpdates.js]
 [urlConstruction.js]
 [updateManagerXML.js]
 [remoteUpdateXML.js]
-[downloadInvalidMar.js]
+[downloadInvalidSizeMar.js]
+[downloadMissingMar.js]
 [cleanupDownloadingForOlderAppVersion.js]
 [cleanupDownloadingForDifferentChannel.js]
 [cleanupDownloadingForSameVersionAndBuildID.js]
 [cleanupDownloadingIncorrectStatus.js]
 [cleanupPendingVersionFileIncorrectStatus.js]
 [cleanupSuccessLogMove.js]
 [cleanupSuccessLogsFIFO.js]
+[downloadInterruptedOffline.js]
+[downloadInterruptedNoRecovery.js]
 [downloadInterruptedRecovery.js]
 [downloadResumeForSameAppVersion.js]
 [downloadCompleteAfterPartialFailure.js]
 [uiSilentPref.js]
 [uiUnsupportedAlreadyNotified.js]
 [uiAutoPref.js]
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFileNotInInstallDirFailure.js
@@ -26,14 +26,21 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, null, path);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      INVALID_CALLBACK_DIR_ERROR, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgCallbackFilePathTooLongFailure.js
@@ -34,14 +34,21 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, null, path);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      INVALID_CALLBACK_PATH_ERROR, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTooLongFailure.js
@@ -36,15 +36,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, path, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_INSTALL_DIR_PATH_ERROR
                                   : INVALID_INSTALL_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallDirPathTraversalFailure.js
@@ -33,15 +33,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, path, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_INSTALL_DIR_PATH_ERROR
                                   : INVALID_INSTALL_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgInstallWorkingDirPathNotSameFailure_win.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_APPLYTO_DIR_ERROR
                                   : INVALID_APPLYTO_DIR_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgPatchDirPathTraversalFailure.js
@@ -32,13 +32,20 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, path, null, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgStageDirNotInInstallDirFailure_win.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true, null, null, path, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR
                                   : INVALID_APPLYTO_DIR_STAGED_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathLocalUNCFailure_win.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_WORKING_DIR_PATH_ERROR
                                   : INVALID_WORKING_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/invalidArgWorkingDirPathRelativeFailure.js
@@ -26,15 +26,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, "test", null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_WORKING_DIR_PATH_ERROR
                                   : INVALID_WORKING_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyDirLockedStageFailure_win.js
@@ -27,16 +27,23 @@ function run_test() {
 function setupUpdaterTestFinished() {
   stageUpdate(false);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
 function stageUpdateFinished() {
-  checkUpdateManager(STATE_AFTER_STAGE, true, STATE_AFTER_STAGE, 0, 0);
   removeUpdateInProgressLockFile(getAppBaseDir());
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(PERFORMING_STAGED_UPDATE);
   checkUpdateLogContains(ERR_UPDATE_IN_PROGRESS);
+  do_execute_soon(() => waitForUpdateXMLFiles(true, false));
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  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
@@ -46,20 +46,27 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
@@ -52,22 +52,30 @@ function runUpdateFinished() {
   let patches = getLocalPatchString(patchProps);
   let updateProps = {appVersion: "0.9"};
   let updates = getLocalUpdateString(updateProps, patches);
   getUpdatesXMLFile(true).remove(false);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   reloadUpdateManagerData();
 
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     ERR_OLDER_VERSION_OR_SAME_BUILD, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile, !IS_MACOSX, false);
 
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
+                     ERR_OLDER_VERSION_OR_SAME_BUILD, 1);
+
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
 
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
@@ -45,20 +45,27 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js
@@ -28,20 +28,27 @@ function setupUpdaterTestFinished() {
 }
 
 /**
  * Called after the call to runUpdateUsingApp finishes.
  */
 function runUpdateFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageFailureComplete_win.js
@@ -48,16 +48,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseStageSuccessComplete_unix.js
@@ -61,20 +61,27 @@ function waitForHelperExitFinished() {
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   checkSymLinks();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup symlinks for the test.
  */
 function setupSymLinks() {
   if (IS_UNIX) {
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppInUseSuccessComplete.js
@@ -42,14 +42,21 @@ function waitForHelperExitFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessComplete_win.js
@@ -41,14 +41,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppStageSuccessPartial_win.js
@@ -41,14 +41,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessComplete_win.js
@@ -28,14 +28,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marCallbackAppSuccessPartial_win.js
@@ -28,14 +28,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFailurePartial.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
 }
 
 /**
  * Called after the call to runUpdate finishes.
  */
 function runUpdateFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     LOADSOURCE_ERROR_WRONG_SIZE, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContents(LOG_PARTIAL_FAILURE);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
+                     LOADSOURCE_ERROR_WRONG_SIZE, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailureComplete_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseStageFailurePartial_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessComplete_win.js
@@ -42,15 +42,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileInUseSuccessPartial_win.js
@@ -42,15 +42,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailureComplete_win.js
@@ -35,16 +35,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_BACKUP_CREATE_7);
   checkUpdateLogContains(STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(() => waitForUpdateXMLFiles(true, false));
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedFailurePartial_win.js
@@ -35,15 +35,22 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_UNABLE_OPEN_DEST);
   checkUpdateLogContains(STATE_FAILED_READ_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailureComplete_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_BACKUP_CREATE_7);
   checkUpdateLogContains(STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(() => waitForUpdateXMLFiles(true, false));
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marFileLockedStageFailurePartial_win.js
@@ -49,15 +49,22 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_UNABLE_OPEN_DEST);
   checkUpdateLogContains(STATE_FAILED_READ_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marPIDPersistsSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marPIDPersistsSuccessComplete_win.js
@@ -45,14 +45,21 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContains(ERR_PARENT_PID_PERSISTS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailureComplete_win.js
@@ -50,16 +50,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseStageFailurePartial_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessComplete_win.js
@@ -42,15 +42,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marRMRFDirFileInUseSuccessPartial_win.js
@@ -41,15 +41,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageFailurePartial.js
@@ -25,15 +25,22 @@ function run_test() {
 function setupUpdaterTestFinished() {
   stageUpdate(true);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
 function stageUpdateFinished() {
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     LOADSOURCE_ERROR_WRONG_SIZE, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_LOADSOURCEFILE_FAILED);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  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
@@ -48,21 +48,28 @@ function runUpdateFinished() {
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   checkSymLinks();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marStageSuccessPartial.js
@@ -47,21 +47,28 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true, true);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessComplete.js
@@ -31,21 +31,28 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, false, false, true);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marSuccessPartial.js
@@ -31,21 +31,28 @@ function setupUpdaterTestFinished() {
 }
 
 /**
  * Called after the call to runUpdate finishes.
  */
 function runUpdateFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marVersionDowngrade.js
@@ -29,15 +29,22 @@ function setupUpdaterTestFinished() {
             false);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     VERSION_DOWNGRADE_ERROR, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(STATE_FAILED_VERSION_DOWNGRADE_ERROR);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
+                     VERSION_DOWNGRADE_ERROR, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marWrongChannel.js
@@ -29,15 +29,22 @@ function setupUpdaterTestFinished() {
             false);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     MAR_CHANNEL_MISMATCH_ERROR, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(STATE_FAILED_MAR_CHANNEL_MISMATCH_ERROR);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  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
@@ -36,15 +36,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, path, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_INSTALL_DIR_PATH_ERROR
                                   : INVALID_INSTALL_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTraversalFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallDirPathTraversalFailureSvc.js
@@ -33,15 +33,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, path, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_INSTALL_DIR_PATH_ERROR
                                   : INVALID_INSTALL_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_APPLYTO_DIR_ERROR
                                   : INVALID_APPLYTO_DIR_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathSuffixFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathSuffixFailureSvc.js
@@ -26,13 +26,20 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, path, null, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathTraversalFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgPatchDirPathTraversalFailureSvc.js
@@ -32,13 +32,20 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, path, null, null, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgStageDirNotInInstallDirFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgStageDirNotInInstallDirFailureSvc_win.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, true, 1, true, null, null, path, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR
                                   : INVALID_APPLYTO_DIR_STAGED_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathLocalUNCFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathLocalUNCFailureSvc_win.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, path, null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_WORKING_DIR_PATH_ERROR
                                   : INVALID_WORKING_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathRelativeFailureSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/invalidArgWorkingDirPathRelativeFailureSvc.js
@@ -26,15 +26,22 @@ function setupUpdaterTestFinished() {
   runUpdate(STATE_AFTER_RUNUPDATE, false, 1, true, null, null, "test", null);
 }
 
 /**
  * Called after the call to runUpdateUsingUpdater finishes.
  */
 function runUpdateFinished() {
   standardInit();
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateFailure(getApplyDirFile);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
   let errorCode = IS_SERVICE_TEST ? SERVICE_INVALID_WORKING_DIR_PATH_ERROR
                                   : INVALID_WORKING_DIR_PATH_ERROR;
   checkUpdateManager(STATE_NONE, false, STATE_FAILED, errorCode, 1);
-  checkPostUpdateRunningFile(false);
-  checkFilesAfterUpdateFailure(getApplyDirFile);
   waitForFilesInUse();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyDirLockedStageFailureSvc_win.js
@@ -27,16 +27,23 @@ function run_test() {
 function setupUpdaterTestFinished() {
   stageUpdate(false);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
 function stageUpdateFinished() {
-  checkUpdateManager(STATE_AFTER_STAGE, true, STATE_AFTER_STAGE, 0, 0);
   removeUpdateInProgressLockFile(getAppBaseDir());
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(PERFORMING_STAGED_UPDATE);
   checkUpdateLogContains(ERR_UPDATE_IN_PROGRESS);
+  do_execute_soon(() => waitForUpdateXMLFiles(true, false));
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  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
@@ -46,20 +46,27 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
@@ -45,20 +45,27 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js
@@ -28,20 +28,27 @@ function setupUpdaterTestFinished() {
 }
 
 /**
  * Called after the call to runUpdateUsingApp finishes.
  */
 function runUpdateFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
   let updatesDir = getUpdatesPatchDir();
   Assert.ok(updatesDir.exists(),
             MSG_SHOULD_EXIST + getMsgPath(updatesDir.path));
 
   let log = getUpdateLog(FILE_UPDATE_LOG);
   Assert.ok(!log.exists(),
             MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseStageFailureCompleteSvc_win.js
@@ -48,16 +48,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppInUseSuccessCompleteSvc.js
@@ -42,14 +42,21 @@ function waitForHelperExitFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessCompleteSvc_win.js
@@ -41,14 +41,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppStageSuccessPartialSvc_win.js
@@ -41,14 +41,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessCompleteSvc_win.js
@@ -28,14 +28,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marCallbackAppSuccessPartialSvc_win.js
@@ -28,14 +28,21 @@ function runUpdateFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFailurePartialSvc.js
@@ -27,15 +27,22 @@ function setupUpdaterTestFinished() {
 }
 
 /**
  * Called after the call to runUpdate finishes.
  */
 function runUpdateFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     LOADSOURCE_ERROR_WRONG_SIZE, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContents(LOG_PARTIAL_FAILURE);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
+                     LOADSOURCE_ERROR_WRONG_SIZE, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailureCompleteSvc_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseStageFailurePartialSvc_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessCompleteSvc_win.js
@@ -42,15 +42,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileInUseSuccessPartialSvc_win.js
@@ -42,15 +42,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailureCompleteSvc_win.js
@@ -35,16 +35,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_BACKUP_CREATE_7);
   checkUpdateLogContains(STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(() => waitForUpdateXMLFiles(true, false));
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedFailurePartialSvc_win.js
@@ -35,15 +35,22 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_UNABLE_OPEN_DEST);
   checkUpdateLogContains(STATE_FAILED_READ_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailureCompleteSvc_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_BACKUP_CREATE_7);
   checkUpdateLogContains(STATE_FAILED_WRITE_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(() => waitForUpdateXMLFiles(true, false));
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_PENDING, true, STATE_PENDING, WRITE_ERROR, 0);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marFileLockedStageFailurePartialSvc_win.js
@@ -49,15 +49,22 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_UNABLE_OPEN_DEST);
   checkUpdateLogContains(STATE_FAILED_READ_ERROR + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_FAILED, READ_ERROR, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailureCompleteSvc_win.js
@@ -50,16 +50,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseStageFailurePartialSvc_win.js
@@ -49,16 +49,23 @@ function runUpdateFinished() {
   waitForHelperExit();
 }
 
 /**
  * Called after the call to waitForHelperExit finishes.
  */
 function waitForHelperExitFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_RENAME_FILE);
   checkUpdateLogContains(ERR_MOVE_DESTDIR_7 + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_AFTER_RUNUPDATE, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessCompleteSvc_win.js
@@ -42,15 +42,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marRMRFDirFileInUseSuccessPartialSvc_win.js
@@ -41,15 +41,22 @@ function waitForHelperExitFinished() {
   checkPostUpdateAppLog();
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContains(ERR_BACKUP_DISCARD);
   checkUpdateLogContains(STATE_SUCCEEDED + "\n" + CALL_QUIT);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageFailurePartialSvc.js
@@ -25,15 +25,22 @@ function run_test() {
 function setupUpdaterTestFinished() {
   stageUpdate(true);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
 function stageUpdateFinished() {
-  checkUpdateManager(STATE_NONE, false, STATE_FAILED,
-                     LOADSOURCE_ERROR_WRONG_SIZE, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateFailure(getApplyDirFile);
   checkUpdateLogContains(ERR_LOADSOURCEFILE_FAILED);
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  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
@@ -48,21 +48,28 @@ function runUpdateFinished() {
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   checkSymLinks();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marStageSuccessPartialSvc.js
@@ -47,21 +47,28 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true, true);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessCompleteSvc.js
@@ -31,21 +31,28 @@ function runUpdateFinished() {
 }
 
 /**
  * Called after the call to checkPostUpdateAppLog finishes.
  */
 function checkPostUpdateAppLogFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, false, false, true);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {
--- a/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marSuccessPartialSvc.js
@@ -31,21 +31,28 @@ function setupUpdaterTestFinished() {
 }
 
 /**
  * Called after the call to runUpdate finishes.
  */
 function runUpdateFinished() {
   checkAppBundleModTime();
   standardInit();
-  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
   checkDistributionDir();
+  do_execute_soon(waitForUpdateXMLFiles);
+}
+
+/**
+ * Called after the call to waitForUpdateXMLFiles finishes.
+ */
+function waitForUpdateXMLFilesFinished() {
+  checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
   checkCallbackLog();
 }
 
 /**
  * Setup the state of the distribution directory for the test.
  */
 function setupDistributionDir() {
   if (IS_MACOSX) {