gecko/toolkit/mozapps/update/test/unit/test_0114_general.js
Ehsan Akhgari ab9253304f Bug 307181 - Stage Firefox updates in the background after they're downloaded, and replace the application directory on restart; r=rstrong,bbondy
When Firefox downloads an update, it previously kept the update around to apply
it on the next restart.  This patch changes this so that the updater program
is launched in the background as soon as the update has finished downloading
in order to stage the updated version of the application by copying the
existing installation directory to a temporary location and applying the update
on top of it, and replace the existing installation directory with the staged
directory on the next restart.

Because the replacing step is typically very fast, this patch eliminates the
wait for the update to be applied on restart, making it unnecessary to show a
progress dialog when restarting.

--HG--
rename : toolkit/mozapps/update/test/chrome/test_0092_finishedBackground.xul => toolkit/mozapps/update/test/chrome/test_0093_stagedBackground.xul
rename : toolkit/mozapps/update/test/unit/test_0110_general.js => toolkit/mozapps/update/test/unit/test_0113_general.js
rename : toolkit/mozapps/update/test/unit/test_0111_general.js => toolkit/mozapps/update/test/unit/test_0114_general.js
rename : toolkit/mozapps/update/test/unit/test_0112_general.js => toolkit/mozapps/update/test/unit/test_0115_general.js
rename : toolkit/mozapps/update/test/unit/test_0170_fileLocked_xp_win_complete.js => toolkit/mozapps/update/test/unit/test_0172_fileLocked_xp_win_complete.js
rename : toolkit/mozapps/update/test/unit/test_0171_fileLocked_xp_win_partial.js => toolkit/mozapps/update/test/unit/test_0173_fileLocked_xp_win_partial.js
rename : toolkit/mozapps/update/test/unit/test_0110_general.js => toolkit/mozapps/update/test_svc/unit/test_0113_general_svc.js
rename : toolkit/mozapps/update/test/unit/test_0111_general.js => toolkit/mozapps/update/test_svc/unit/test_0114_general_svc.js
rename : toolkit/mozapps/update/test/unit/test_0112_general.js => toolkit/mozapps/update/test_svc/unit/test_0115_general_svc.js
rename : toolkit/mozapps/update/test/unit/test_0170_fileLocked_xp_win_complete.js => toolkit/mozapps/update/test_svc/unit/test_0172_fileLocked_xp_win_complete_svc.js
rename : toolkit/mozapps/update/test/unit/test_0171_fileLocked_xp_win_partial.js => toolkit/mozapps/update/test_svc/unit/test_0173_fileLocked_xp_win_partial_svc.js
2012-05-22 10:50:04 -04:00

329 lines
11 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* General Partial MAR File Background Patch Apply Test */
const TEST_ID = "0114";
// All we care about is that the last modified time has changed so that Mac OS
// X Launch Services invalidates its cache so the test allows up to one minute
// difference in the last modified time.
const MAX_TIME_DIFFERENCE = 60000;
// The files are listed in the same order as they are applied from the mar's
// update.manifest. Complete updates have remove file and rmdir directory
// operations located in the precomplete file performed first.
const TEST_FILES = [
{
description : "Should never change",
fileName : "channel-prefs.js",
relPathDir : "a/b/defaults/pref/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null,
originalPerms : 0644,
comparePerms : null
}, {
description : "Added by update.manifest (add)",
fileName : "precomplete",
relPathDir : "",
originalContents : null,
compareContents : null,
originalFile : "data/complete_precomplete",
compareFile : "data/partial_precomplete",
originalPerms : 0666,
comparePerms : 0644
}, {
description : "Added by update.manifest (add)",
fileName : "searchpluginstext0",
relPathDir : "a/b/searchplugins/",
originalContents : "ToBeReplacedWithFromPartial\n",
compareContents : "FromPartial\n",
originalFile : null,
compareFile : null,
originalPerms : 0775,
comparePerms : 0644
}, {
description : "Patched by update.manifest if the file exists " +
"(patch-if)",
fileName : "searchpluginspng1.png",
relPathDir : "a/b/searchplugins/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0666,
comparePerms : 0666
}, {
description : "Patched by update.manifest if the file exists " +
"(patch-if)",
fileName : "searchpluginspng0.png",
relPathDir : "a/b/searchplugins/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0666,
comparePerms : 0666
}, {
description : "Added by update.manifest if the parent directory " +
"exists (add-if)",
fileName : "extensions1text0",
relPathDir : "a/b/extensions/extensions1/",
originalContents : null,
compareContents : "FromPartial\n",
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : 0644
}, {
description : "Patched by update.manifest if the parent directory " +
"exists (patch-if)",
fileName : "extensions1png1.png",
relPathDir : "a/b/extensions/extensions1/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0666,
comparePerms : 0666
}, {
description : "Patched by update.manifest if the parent directory " +
"exists (patch-if)",
fileName : "extensions1png0.png",
relPathDir : "a/b/extensions/extensions1/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0666,
comparePerms : 0666
}, {
description : "Added by update.manifest if the parent directory " +
"exists (add-if)",
fileName : "extensions0text0",
relPathDir : "a/b/extensions/extensions0/",
originalContents : "ToBeReplacedWithFromPartial\n",
compareContents : "FromPartial\n",
originalFile : null,
compareFile : null,
originalPerms : 0644,
comparePerms : 0644
}, {
description : "Patched by update.manifest if the parent directory " +
"exists (patch-if)",
fileName : "extensions0png1.png",
relPathDir : "a/b/extensions/extensions0/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0644,
comparePerms : 0644
}, {
description : "Patched by update.manifest if the parent directory " +
"exists (patch-if)",
fileName : "extensions0png0.png",
relPathDir : "a/b/extensions/extensions0/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0644,
comparePerms : 0644
}, {
description : "Patched by update.manifest (patch)",
fileName : "exe0.exe",
relPathDir : "a/b/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0755,
comparePerms : 0755
}, {
description : "Patched by update.manifest (patch)",
fileName : "0exe0.exe",
relPathDir : "a/b/0/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0755,
comparePerms : 0755
}, {
description : "Added by update.manifest (add)",
fileName : "00text0",
relPathDir : "a/b/0/00/",
originalContents : "ToBeReplacedWithFromPartial\n",
compareContents : "FromPartial\n",
originalFile : null,
compareFile : null,
originalPerms : 0644,
comparePerms : 0644
}, {
description : "Patched by update.manifest (patch)",
fileName : "00png0.png",
relPathDir : "a/b/0/00/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0666,
comparePerms : 0666
}, {
description : "Added by update.manifest (add)",
fileName : "20text0",
relPathDir : "a/b/2/20/",
originalContents : null,
compareContents : "FromPartial\n",
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : 0644
}, {
description : "Added by update.manifest (add)",
fileName : "20png0.png",
relPathDir : "a/b/2/20/",
originalContents : null,
compareContents : null,
originalFile : null,
compareFile : "data/partial.png",
originalPerms : null,
comparePerms : 0644
}, {
description : "Added by update.manifest (add)",
fileName : "00text2",
relPathDir : "a/b/0/00/",
originalContents : null,
compareContents : "FromPartial\n",
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : 0644
}, {
description : "Removed by update.manifest (remove)",
fileName : "10text0",
relPathDir : "a/b/1/10/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : null
}, {
description : "Removed by update.manifest (remove)",
fileName : "00text1",
relPathDir : "a/b/0/00/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : null
}];
ADDITIONAL_TEST_DIRS = [
{
description : "Removed by update.manifest (rmdir)",
relPathDir : "a/b/1/10/",
dirRemoved : true
}, {
description : "Removed by update.manifest (rmdir)",
relPathDir : "a/b/1/",
dirRemoved : true
}];
function run_test() {
do_test_pending();
do_register_cleanup(cleanupUpdaterTest);
gBackgroundUpdate = true;
setupUpdaterTest(MAR_PARTIAL_FILE);
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = getApplyDirFile();
// For Mac OS X set the last modified time for the root directory to a date in
// the past to test that the last modified time is updated on all updates since
// the precomplete file in the root of the bundle is renamed, etc. (bug 600098).
if (IS_MACOSX) {
let now = Date.now();
let yesterday = now - (1000 * 60 * 60 * 24);
applyToDir.lastModifiedTime = yesterday;
}
// apply the partial mar
let exitValue = runUpdate();
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
logTestInfo("testing update.status should be " + STATE_APPLIED);
do_check_eq(readStatusFile(updatesDir), STATE_APPLIED);
// For Mac OS X check that the last modified time for a directory has been
// updated after a successful update (bug 600098).
if (IS_MACOSX) {
logTestInfo("testing last modified time on the apply to directory has " +
"changed after a successful update (bug 600098)");
let now = Date.now();
let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
do_check_true(timeDiff < MAX_TIME_DIFFERENCE);
}
checkFilesAfterUpdateSuccess();
// Sorting on Linux is different so skip this check for now.
if (!IS_UNIX) {
checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
}
// This shouldn't exist anyways in background updates, but let's make sure
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = getApplyDirFile("tobedeleted", true);
do_check_false(toBeDeletedDir.exists());
toBeDeletedDir = getTargetDirFile("tobedeleted", true);
do_check_false(toBeDeletedDir.exists());
// Now switch the application and its updated version
gBackgroundUpdate = false;
gSwitchApp = true;
exitValue = runUpdate();
logTestInfo("testing updater binary process exitValue for success when " +
"switching to the updated application");
do_check_eq(exitValue, 0);
logTestInfo("testing update.status should be " + STATE_SUCCEEDED);
do_check_eq(readStatusFile(updatesDir), STATE_SUCCEEDED);
// For Mac OS X check that the last modified time for a directory has been
// updated after a successful update (bug 600098).
if (IS_MACOSX) {
logTestInfo("testing last modified time on the apply to directory has " +
"changed after a successful update (bug 600098)");
let now = Date.now();
let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
do_check_true(timeDiff < MAX_TIME_DIFFERENCE);
}
checkFilesAfterUpdateSuccess();
// Sorting on Linux is different so skip this check for now.
if (!IS_UNIX) {
checkUpdateLogContents(LOG_PARTIAL_SWITCH_SUCCESS);
}
// This shouldn't exist anyways in background updates, but let's make sure
logTestInfo("testing tobedeleted directory doesn't exist");
toBeDeletedDir = getApplyDirFile("tobedeleted", true);
do_check_false(toBeDeletedDir.exists());
// Make sure that the intermediate directory has been removed
let updatedDir = applyToDir.clone();
updatedDir.append(UPDATED_DIR_SUFFIX.replace("/", ""));
do_check_false(updatedDir.exists());
checkCallbackAppLog();
}