Test code - Bug 1358336 - app update tries to install staged updates for older versions. r=mhowell, a=tests
authorRobert Strong <robert.bugzilla@gmail.com>
Wed, 03 May 2017 16:33:02 -0700
changeset 396139 4969ec22e2b513ece3d0d0cc68d20f31c4a8303f
parent 396138 3b6617c56ac3c4a8bc786867c0f4c9dea39cc40d
child 396140 52fdb2acc0001a1135ed90301da8bb46e610eee2
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell, tests
bugs1358336
milestone54.0
Test code - Bug 1358336 - app update tries to install staged updates for older versions. r=mhowell, a=tests
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -3186,26 +3186,16 @@ function checkFilesAfterUpdateCommon(aGe
   checkFilesInDirRecursive(applyToDir, checkForBackupFiles);
 
   if (stageDir.exists()) {
     debugDump("testing backup files should not be left behind in the " +
               "staging directory");
     applyToDir = getApplyDirFile(null, true);
     checkFilesInDirRecursive(stageDir, checkForBackupFiles);
   }
-
-  debugDump("testing patch files should not be left behind");
-  let updatesDir = getUpdatesPatchDir();
-  let entries = updatesDir.QueryInterface(Ci.nsIFile).directoryEntries;
-  while (entries.hasMoreElements()) {
-    let entry = entries.getNext().QueryInterface(Ci.nsIFile);
-    Assert.notEqual(getFileExtension(entry), "patch",
-                    "the file's extension should not equal patch" +
-                    getMsgPath(entry.path));
-  }
 }
 
 /**
  * Helper function for updater binary tests for verifying the contents of the
  * updater callback application log which should contain the arguments passed to
  * the callback application.
  */
 function checkCallbackLog() {
@@ -3851,30 +3841,37 @@ function runUpdateUsingApp(aExpectedStat
     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_execute_soon(afterAppExits);
+        do_timeout(FILE_IN_USE_TIMEOUT_MS, afterAppExits);
       }
       return;
     }
 
-    // Don't proceed until the update log has been created.
-    let log = getUpdateLog(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);
+    // 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 = getUpdateLog(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;
       }
-      do_execute_soon(afterAppExits);
-      return;
     }
 
     do_execute_soon(runUpdateFinished);
   }
 
   debugDump("start - launching application to apply update");
 
   let launchBin = getLaunchBin();
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateStageOldVersionFailure.js
@@ -0,0 +1,88 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/**
+ * Test a replace request for a staged update with a version file that specifies
+ * an older version failure. The same check is used in nsUpdateDriver.cpp for
+ * all update types which is why there aren't tests for the maintenance service
+ * as well as for other update types.
+ */
+
+const STATE_AFTER_STAGE = STATE_APPLIED;
+
+function run_test() {
+  if (!setupTestCommon()) {
+    return;
+  }
+
+  gTestFiles = gTestFilesCompleteSuccess;
+  gTestDirs = gTestDirsCompleteSuccess;
+  setupUpdaterTest(FILE_COMPLETE_MAR);
+}
+
+/**
+ * Called after the call to setupUpdaterTest finishes.
+ */
+function setupUpdaterTestFinished() {
+  stageUpdate(false);
+}
+
+/**
+ * Called after the call to stageUpdate finishes.
+ */
+function stageUpdateFinished() {
+  checkPostUpdateRunningFile(false);
+  checkFilesAfterUpdateSuccess(getStageDirFile, true);
+  checkUpdateLogContents(LOG_COMPLETE_SUCCESS, true);
+  // Change the active update to an older version to simulate installing a new
+  // version of the application while there is an update that has been staged.
+  let channel = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_CHANNEL);
+  let patches = getLocalPatchString(null, null, null, null, null, "true",
+                                    STATE_AFTER_STAGE);
+  let updates = getLocalUpdateString(patches, null, null, null, "1.0", null,
+                                     null, null, null, null, "true", channel);
+  writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
+  // Change the version file to an older version to simulate installing a new
+  // version of the application while there is an update that has been staged.
+   writeVersionFile("1.0");
+  reloadUpdateManagerData();
+  // Try to switch the application to the staged application that was updated.
+  runUpdateUsingApp(STATE_AFTER_STAGE);
+}
+
+/**
+ * Called after the call to runUpdateUsingApp finishes.
+ */
+function runUpdateFinished() {
+  standardInit();
+  Assert.equal(readStatusState(), STATE_NONE,
+               "the status file state" + MSG_SHOULD_EQUAL);
+  Assert.ok(!gUpdateManager.activeUpdate,
+            "the active update should not be defined");
+  Assert.equal(gUpdateManager.updateCount, 1,
+               "the update manager updateCount attribute" + MSG_SHOULD_EQUAL);
+  Assert.equal(gUpdateManager.getUpdateAt(0).state, STATE_AFTER_STAGE,
+               "the update state" + MSG_SHOULD_EQUAL);
+  checkPostUpdateRunningFile(false);
+  setTestFilesAndDirsForFailure();
+  checkFilesAfterUpdateFailure(getApplyDirFile, IS_MACOSX ? false : true, false);
+
+  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));
+
+  log = getUpdateLog(FILE_LAST_UPDATE_LOG);
+  Assert.ok(log.exists(),
+            MSG_SHOULD_EXIST + getMsgPath(log.path));
+
+  log = getUpdateLog(FILE_BACKUP_UPDATE_LOG);
+  Assert.ok(!log.exists(),
+            MSG_SHOULD_NOT_EXIST + getMsgPath(log.path));
+
+  waitForFilesInUse();
+}
--- a/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini
+++ b/toolkit/mozapps/update/tests/unit_base_updater/xpcshell.ini
@@ -91,8 +91,9 @@ reason = Windows only test
 [marAppApplyDirLockedStageFailure_win.js]
 skip-if = os != 'win'
 reason = Windows only test
 [marAppApplyUpdateAppBinInUseStageSuccess_win.js]
 skip-if = os != 'win'
 reason = Windows only test
 [marAppApplyUpdateSuccess.js]
 [marAppApplyUpdateStageSuccess.js]
+[marAppApplyUpdateStageOldVersionFailure.js]