Bug 1529043 - Part 7 (test only) - Make the runUpdateUsingApp function async and change call sites so they use await. r=mhowell
authorRobert Strong <robert.bugzilla@gmail.com>
Fri, 22 Feb 2019 21:26:08 +0000
changeset 460681 0633e80e4acc19875b6573ecede25a2d1a8f70d0
parent 460680 7cff5bc91962d41b78afce754654ff878abda3cd
child 460682 17a347c991657ad0b01087caa9702a22d4daf777
push id35596
push userrmaries@mozilla.com
push dateSat, 23 Feb 2019 04:13:22 +0000
treeherdermozilla-central@fdd04819e350 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell
bugs1529043
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1529043 - Part 7 (test only) - Make the runUpdateUsingApp function async and change call sites so they use await. r=mhowell Depends on D20798 Differential Revision: https://phabricator.services.mozilla.com/D20799
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.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_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -3843,111 +3843,65 @@ const gAppTimerCallback = {
     }
     Assert.ok(false, "launch application timer expired");
   },
   QueryInterface: ChromeUtils.generateQI([Ci.nsITimerCallback]),
 };
 
 /**
  * Launches an application to apply an update.
+ *
+ * @param   aExpectedStatus
+ *          The expected value of update.status when the update finishes.
  */
-function runUpdateUsingApp(aExpectedStatus) {
-  /**
-   * The observer for the call to nsIProcess:runAsync. When completed
-   * runUpdateFinished will be called.
-   */
-  const processObserver = {
-    observe: function PO_observe(aSubject, aTopic, aData) {
-      debugDump("topic: " + aTopic + ", process exitValue: " +
-                gProcess.exitValue);
-      resetEnvironment();
-      if (gAppTimer) {
-        gAppTimer.cancel();
-        gAppTimer = null;
-      }
-      Assert.equal(gProcess.exitValue, 0,
-                   "the application process exit value should be 0");
-      Assert.equal(aTopic, "process-finished",
-                   "the application process observer topic should be " +
-                   "process-finished");
-
-      if (IS_SERVICE_TEST) {
-        waitForServiceStop(false);
-      }
-
-      executeSoon(afterAppExits);
-    },
-    QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
-  };
-
-  function afterAppExits() {
-    gTimeoutRuns++;
-
-    if (AppConstants.platform == "win") {
-      waitForApplicationStop(FILE_UPDATER_BIN);
-    }
-
-    let status;
-    try {
-      status = readStatusFile();
-    } catch (e) {
-      logTestInfo("error reading status file, exception: " + e);
-    }
-    // Don't proceed until the update's status is the expected value.
-    if (status != aExpectedStatus) {
-      if (gTimeoutRuns > MAX_TIMEOUT_RUNS) {
-        logUpdateLog(FILE_UPDATE_LOG);
-        do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update " +
-                 "status to equal: " +
-                 aExpectedStatus +
-                 ", current status: " + status);
-      } else {
-        do_timeout(FILE_IN_USE_TIMEOUT_MS, afterAppExits);
-      }
-      return;
-    }
-
-    // Don't check for an update log when the code in nsUpdateDriver.cpp skips
-    // updating.
-    if (aExpectedStatus != STATE_PENDING &&
-        aExpectedStatus != STATE_PENDING_SVC &&
-        aExpectedStatus != STATE_APPLIED &&
-        aExpectedStatus != STATE_APPLIED_SVC) {
-      // Don't proceed until the update log has been created.
-      let log = getUpdateDirFile(FILE_UPDATE_LOG);
-      if (!log.exists()) {
-        if (gTimeoutRuns > MAX_TIMEOUT_RUNS) {
-          do_throw("Exceeded MAX_TIMEOUT_RUNS while waiting for the update " +
-                   "log to be created. Path: " + log.path);
-        }
-        do_timeout(FILE_IN_USE_TIMEOUT_MS, afterAppExits);
-        return;
-      }
-    }
-
-    executeSoon(runUpdateFinished);
-  }
-
+async function runUpdateUsingApp(aExpectedStatus) {
   debugDump("start - launching application to apply update");
 
   let launchBin = getLaunchBin();
   let args = getProcessArgs();
   debugDump("launching " + launchBin.path + " " + args.join(" "));
 
   gProcess = Cc["@mozilla.org/process/util;1"].
              createInstance(Ci.nsIProcess);
   gProcess.init(launchBin);
 
   gAppTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   gAppTimer.initWithCallback(gAppTimerCallback, APP_TIMER_TIMEOUT,
                              Ci.nsITimer.TYPE_ONE_SHOT);
 
   setEnvironment();
+
   debugDump("launching application");
-  gProcess.runAsync(args, args.length, processObserver);
+  gProcess.run(true, args, args.length);
+  debugDump("launched application exited");
+
+  resetEnvironment();
+
+  if (AppConstants.platform == "win") {
+    waitForApplicationStop(FILE_UPDATER_BIN);
+  }
+
+  let file = getUpdateDirFile(FILE_UPDATE_STATUS);
+  await TestUtils.waitForCondition(() => (file.exists()),
+    "Waiting for file to exist, path: " + file.path);
+
+  await TestUtils.waitForCondition(() => (readStatusFile() == aExpectedStatus),
+    "Waiting for expected status file contents: " + aExpectedStatus);
+
+  // Don't check for an update log when the code in nsUpdateDriver.cpp skips
+  // updating.
+  if (aExpectedStatus != STATE_PENDING &&
+      aExpectedStatus != STATE_PENDING_SVC &&
+      aExpectedStatus != STATE_APPLIED &&
+      aExpectedStatus != STATE_APPLIED_SVC) {
+    // Don't proceed until the update log has been created.
+    file = getUpdateDirFile(FILE_UPDATE_LOG);
+    await TestUtils.waitForCondition(() => (file.exists()),
+      "Waiting for file to exist, path: " + file.path);
+  }
 
   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.
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js
@@ -17,29 +17,23 @@ async function run_test() {
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   stageUpdate(true);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
-function stageUpdateFinished() {
+async function stageUpdateFinished() {
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   lockDirectory(getGREBinDir().path);
   // Switch the application to the staged application that was updated.
-  runUpdateUsingApp(STATE_SUCCEEDED);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
@@ -24,23 +24,17 @@ async function run_test() {
   let updates = getLocalUpdateString(updateProps, patches);
   writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
   getUpdateDirFile(FILE_UPDATE_LOG).create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
   writeStatusFile(STATE_AFTER_STAGE);
   // Create the version file with an older version to simulate installing a new
   // version of the application while there is an update that has been staged.
   writeVersionFile("0.9");
   // Try to switch the application to the fake staged application.
-  runUpdateUsingApp(STATE_AFTER_STAGE);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_AFTER_STAGE);
   standardInit();
   checkPostUpdateRunningFile(false);
   setTestFilesAndDirsForFailure();
   checkFilesAfterUpdateFailure(getApplyDirFile);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_FAILED,
                      ERR_OLDER_VERSION_OR_SAME_BUILD, 1);
 
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageSuccess.js
@@ -17,28 +17,22 @@ async function run_test() {
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, true);
   stageUpdate(true);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
-function stageUpdateFinished() {
+async function stageUpdateFinished() {
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
-  runUpdateUsingApp(STATE_SUCCEEDED);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
--- a/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateSuccess.js
@@ -12,23 +12,17 @@ async function run_test() {
     return;
   }
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   // The third parameter will test that a full path to the post update binary
   // doesn't execute.
   await setupUpdaterTest(FILE_COMPLETE_MAR, undefined,
                          getApplyDirFile(null, true).path + "/");
-  runUpdateUsingApp(STATE_SUCCEEDED);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_SUCCEEDED);
   checkAppBundleModTime();
   standardInit();
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
 
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
@@ -17,29 +17,23 @@ async function run_test() {
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, false);
   stageUpdate(true);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
-function stageUpdateFinished() {
+async function stageUpdateFinished() {
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true, false);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   lockDirectory(getGREBinDir().path);
   // Switch the application to the staged application that was updated.
-  runUpdateUsingApp(STATE_SUCCEEDED);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateStageSuccessSvc.js
@@ -17,28 +17,22 @@ async function run_test() {
   gTestDirs = gTestDirsCompleteSuccess;
   await setupUpdaterTest(FILE_COMPLETE_MAR, true);
   stageUpdate(true);
 }
 
 /**
  * Called after the call to stageUpdate finishes.
  */
-function stageUpdateFinished() {
+async function stageUpdateFinished() {
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getStageDirFile, true);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
   // Switch the application to the staged application that was updated.
-  runUpdateUsingApp(STATE_SUCCEEDED);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_SUCCEEDED);
   await checkPostUpdateAppLog();
   checkAppBundleModTime();
   standardInit();
   checkPostUpdateRunningFile(true);
   checkFilesAfterUpdateSuccess(getApplyDirFile, false, true);
   checkUpdateLogContents(LOG_REPLACE_SUCCESS, false, true);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);
--- a/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js
+++ b/toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateSuccessSvc.js
@@ -12,23 +12,17 @@ async function run_test() {
     return;
   }
   gTestFiles = gTestFilesCompleteSuccess;
   gTestDirs = gTestDirsCompleteSuccess;
   // The third parameter will test that a full path to the post update binary
   // doesn't execute.
   await setupUpdaterTest(FILE_COMPLETE_MAR, undefined,
                          getApplyDirFile(null, true).path + "/");
-  runUpdateUsingApp(STATE_SUCCEEDED);
-}
-
-/**
- * Called after the call to runUpdateUsingApp finishes.
- */
-async function runUpdateFinished() {
+  await runUpdateUsingApp(STATE_SUCCEEDED);
   checkAppBundleModTime();
   standardInit();
   checkPostUpdateRunningFile(false);
   checkFilesAfterUpdateSuccess(getApplyDirFile);
   checkUpdateLogContents(LOG_COMPLETE_SUCCESS);
   await waitForUpdateXMLFiles();
   checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);