2. tests - Bug 466778 - [Win] Unable to update when files to be patched are in use on Windows. r=dtownsend, a=blocking2.0-BetaN

--HG--
rename : toolkit/mozapps/update/test/unit/data/aus-0110_general.mar => toolkit/mozapps/update/test/unit/data/complete.mar
rename : toolkit/mozapps/update/test/unit/data/aus-0110_general_ref_image.png => toolkit/mozapps/update/test/unit/data/complete.png
rename : toolkit/mozapps/update/test/unit/data/aus-0111_general.mar => toolkit/mozapps/update/test/unit/data/partial.mar
rename : toolkit/mozapps/update/test/unit/data/aus-0111_general_ref_image.png => toolkit/mozapps/update/test/unit/data/partial.png
This commit is contained in:
Robert Strong 2010-11-18 17:20:58 -08:00
parent 448f5a3f44
commit d7b6ac5f86
19 changed files with 1297 additions and 796 deletions

View File

@ -14,6 +14,8 @@
_snwprintf(dest, _count, fmt, ##__VA_ARGS__); \
dest[_count] = L'\0';
# define NS_tfopen _wfopen
# define NS_tstrcmp wcscmp
# define NS_ttoi _wtoi
# define LOG_S "%S"
#else
# include <unistd.h>
@ -22,10 +24,14 @@
# define NS_T(str) str
# define NS_tsnprintf snprintf
# define NS_tfopen fopen
# define NS_tstrcmp strcmp
# define NS_ttoi atoi
# define LOG_S "%s"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifndef MAXPATHLEN
# ifdef PATH_MAX
@ -43,18 +49,64 @@
int NS_main(int argc, NS_tchar **argv)
{
if (argc < 2) {
fprintf(stderr, \
"\n" \
"Application Update Service Test Helper\n" \
"\n" \
"Usage: -s SECONDS [LOCKTYPE FILETOLOCK]\n" \
" or: LOGFILE [ARG2 ARG3...]\n" \
"\n" \
" SECONDS \tThe number of seconds to sleep.\n" \
" FILETOLOCK \tThe relative path to an existing file to open exlusively.\n" \
" \tOnly available on Windows platforms and silently ignored on" \
" \tother platforms.\n" \
" LOGFILE \tThe file path relative to the working directory to log the\n" \
" \targuments passed to.\n" \
" ARG2 ARG3...\tArguments to write to the log file.\n" \
"\n" \
"All paths should be relative since paths in a build environment can have a\n" \
"path length that is larger than the maximum path length on Windows.\n" \
"\n");
return 1;
}
// File in use test helper section
if (NS_tstrcmp(argv[1], NS_T("-s")) == 0) {
#ifdef XP_WIN
int milliseconds = NS_ttoi(argv[2]) * 1000;
HANDLE hFile = INVALID_HANDLE_VALUE;
if (argc == 4) {
hFile = CreateFileW(argv[3],
#ifdef WINCE
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
#else
DELETE | GENERIC_WRITE, 0,
#endif
NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return 1;
}
}
Sleep(milliseconds);
if (argc == 5) {
CloseHandle(hFile);
}
#else
int seconds = NS_ttoi(argv[2]);
sleep(seconds);
#endif
return 0;
}
// Command line argument test helper section
NS_tchar logFilePath[MAXPATHLEN];
#ifdef XP_WIN
NS_tchar exePath[MAXPATHLEN];
::GetModuleFileNameW(0, exePath, MAXPATHLEN);
NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
NS_T("%s.log"), exePath);
#else
NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
NS_T("%s.log"), argv[0]);
#endif
NS_T("%s"), argv[1]);
FILE* logFP = NS_tfopen(logFilePath, NS_T("w"));

View File

@ -315,7 +315,7 @@ function readFileBytes(aFile) {
data.push(String.fromCharCode.apply(null, bytes));
count -= bytes.length;
if (bytes.length == 0)
do_throw("Nothing read from input stream!");
throw "Nothing read from input stream!";
}
data.join('');
fis.close();
@ -432,7 +432,8 @@ function cleanUpdatesDir(aDir) {
* Deletes a directory and its children. First it tries nsIFile::Remove(true).
* If that fails it will fall back to recursing, setting the appropriate
* permissions, and deleting the current entry.
* @param dir
*
* @param aDir
* A nsIFile for the directory to be deleted
*/
function removeDirRecursive(aDir) {

View File

Before

Width:  |  Height:  |  Size: 854 B

After

Width:  |  Height:  |  Size: 854 B

View File

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 759 B

View File

@ -35,9 +35,66 @@
*
* ***** END LICENSE BLOCK ***** */
const INSTALL_LOCALE = "@AB_CD@";
const APP_BIN_NAME = "@MOZ_APP_NAME@";
const BIN_SUFFIX = "@BIN_SUFFIX@";
#ifdef XP_UNIX
const APP_BIN_SUFFIX = "-bin";
#else
const APP_BIN_SUFFIX = "@BIN_SUFFIX@";
#endif
#ifdef XP_WIN
const IS_WIN = true;
#else
const IS_WIN = false;
#endif
#ifdef WINCE
const IS_WINCE = true;
#else
const IS_WINCE = false;
#endif
#ifdef XP_OS2
const IS_OS2 = true;
#else
const IS_OS2 = false;
#endif
#ifdef XP_MACOSX
const IS_MACOSX = true;
#else
const IS_MACOSX = false;
#endif
#ifdef XP_UNIX
const IS_UNIX = true;
#else
const IS_UNIX = false;
#endif
#ifdef ANDROID
const IS_ANDROID = true;
#else
const IS_ANDROID = false;
#endif
const URL_HOST = "http://localhost:4444/";
const URL_PATH = "data";
const AFTER_APPLY_DIR = "afterApplyDir";
const APPLY_TO_DIR_SUFFIX = "_applyToDir";
const HELPER_BIN_FILE = "TestAUSHelper" + BIN_SUFFIX;
const MAR_COMPLETE_FILE = "data/complete.mar";
const MAR_PARTIAL_FILE = "data/partial.mar";
const UPDATER_BIN_FILE = "updater" + BIN_SUFFIX;
const UPDATES_DIR_SUFFIX = "_mar";
const CALLBACK_BIN_FILE = "callback_app" + BIN_SUFFIX;
const CALLBACK_ARGS = [AFTER_APPLY_DIR + "/output.log", "Test Arg 2", "Test Arg 3"];
var gTestserver;
var gXHR;
@ -124,29 +181,30 @@ function pathHandler(metadata, response) {
}
/**
* Launches the updater binary to apply a mar file using the current working
* directory for the location to apply the mar.
* Helper function for updater tests for launching the updater binary to apply
* a mar file.
*
* @param aUpdater
* The updater binary binary to copy to aUpdatesDir.
* @param aUpdatesDir
* The directory to copy the update mar, binary, etc.
* @param aApplyToDir
* The directory where the update will be applied.
* @param aCallbackApp (optional)
* The application to launch after the update.
* @param aAppArgs (optional)
* The arguments to pass to the callback application.
* @param aTestID
* A string used to identify the name of directories for a test.
* @return The exit value returned from the updater binary.
*/
function runUpdate(aUpdater, aUpdatesDir, aApplyToDir, aCallbackApp, aAppArgs) {
// Copy the updater binary to the update directory so the updater.ini is not
// in the same directory as it is. This prevents the PostUpdate executable
// which is defined in the updater.ini from launching and the updater ui from
// displaying.
aUpdater.copyTo(aUpdatesDir, aUpdater.leafName);
var updateBin = aUpdatesDir.clone();
updateBin.append(aUpdater.leafName);
function runUpdate(aTestID) {
// Copy the updater binary to the updates directory.
let binDir = getGREDir();
let updater = binDir.clone();
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
}
let updatesDir = do_get_file(aTestID + UPDATES_DIR_SUFFIX, true);
updater.copyTo(updatesDir, updater.leafName);
let updateBin = updatesDir.clone();
updateBin.append(updater.leafName);
if (updateBin.leafName == "updater.app") {
updateBin.append("Contents");
updateBin.append("MacOS");
@ -155,36 +213,359 @@ function runUpdate(aUpdater, aUpdatesDir, aApplyToDir, aCallbackApp, aAppArgs) {
do_throw("Unable to find the updater executable!");
}
var updatesDirPath = aUpdatesDir.path;
let updatesDirPath = updatesDir.path;
if (/ /.test(updatesDirPath))
updatesDirPath = '"' + updatesDirPath + '"';
var applyToPath = aApplyToDir.path;
if (/ /.test(applyToPath))
applyToPath = '"' + applyToPath + '"';
let applyToDir = do_get_file(aTestID + APPLY_TO_DIR_SUFFIX, true);
let applyToDirPath = applyToDir.path;
if (/ /.test(applyToDirPath))
applyToDirPath = '"' + applyToDirPath + '"';
var args;
if (aCallbackApp) {
var cwdPath = aCallbackApp.parent.parent.path;
if (/ /.test(cwdPath))
cwdPath = '"' + cwdPath + '"';
let callbackApp = applyToDir.clone();
callbackApp.append(AFTER_APPLY_DIR);
callbackApp.append(CALLBACK_BIN_FILE);
callbackApp.permissions = PERMS_DIRECTORY;
var testAppPath = aCallbackApp.path;
if (/ /.test(testAppPath))
testAppPath = '"' + testAppPath + '"';
args = [updatesDirPath, applyToPath, 0, cwdPath, testAppPath].
concat(aAppArgs);
}
else {
args = [updatesDirPath, applyToPath];
}
var process = AUS_Cc["@mozilla.org/process/util;1"].
let cwdPath = callbackApp.parent.parent.path;
if (/ /.test(cwdPath))
cwdPath = '"' + cwdPath + '"';
let callbackAppPath = callbackApp.path;
if (/ /.test(callbackAppPath))
callbackAppPath = '"' + callbackAppPath + '"';
let args = [updatesDirPath, applyToDirPath, 0, cwdPath, callbackAppPath].
concat(CALLBACK_ARGS);
let process = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
process.init(updateBin);
process.run(true, args, args.length);
return process.exitValue;
}
/**
* Helper function for updater tests for setting up the files and directories
* used by the updater tests.
*
* @param aTestID
* A string used to identify the name of directories for a test.
* @param aMarFile
* The mar file to copy the update mar to.
* @param aTestFiles
* An array of JavaScript objects representing the test files to create
* for the test.
*/
function setupUpdaterTest(aTestID, aMarFile, aTestFiles) {
// Remove the directory where the updater, mar file, etc. will be copied to
let updatesDir = do_get_file(aTestID + UPDATES_DIR_SUFFIX, true);
try {
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
if (!updatesDir.exists()) {
updatesDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
}
// Remove the directory where the update will be applied if it exists.
let applyToDir = do_get_file(aTestID + APPLY_TO_DIR_SUFFIX, true);
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
logTestInfo("testing successful removal of the directory used to apply the " +
"mar file");
do_check_false(applyToDir.exists());
// Add the test files that will be updated for a successful update or left in
// the initial state for a failed update.
for (let i = 0; i < aTestFiles.length; i++) {
let f = aTestFiles[i];
if (f.originalFile || f.originalContents) {
let testDir = do_get_file(f.destinationDir, true);
if (!testDir.exists())
testDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
let testFile;
if (f.originalFile) {
testFile = do_get_file(f.originalFile);
testFile.copyTo(testDir, f.fileName);
testFile = do_get_file(f.destinationDir + f.fileName);
}
else {
testFile = do_get_file(f.destinationDir + f.fileName, true);
writeFile(testFile, f.originalContents);
}
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.originalPerms) {
testFile.permissions = f.originalPerms;
// Store the actual permissions on the file for reference later after
// setting the permissions.
if (!f.comparePerms)
f.comparePerms = testFile.permissions;
}
}
}
let afterApplyBinDir = applyToDir.clone();
afterApplyBinDir.append(AFTER_APPLY_DIR);
let helperBin = do_get_file(HELPER_BIN_FILE);
helperBin.copyTo(afterApplyBinDir, CALLBACK_BIN_FILE);
let updaterIniContents = "[Strings]\n" +
"Title=Update XPCShell Test\n" +
"Info=Application Update Test - " + aTestID + "\n";
let updaterIni = updatesDir.clone();
updaterIni.append(FILE_UPDATER_INI);
writeFile(updaterIni, updaterIniContents);
updaterIni.copyTo(afterApplyBinDir, FILE_UPDATER_INI);
// Copy the mar that will be applied
let mar = do_get_file(aMarFile);
mar.copyTo(updatesDir, FILE_UPDATE_ARCHIVE);
}
/**
* Helper function for updater tests for cleaning up the state after an updater
* test has finished.
*
* @param aTestID
* A string used to identify the name of directories for a test.
*/
function cleanupUpdaterTest(aTestID) {
let updatesDir = do_get_file(aTestID + UPDATES_DIR_SUFFIX, true);
try {
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
// Try to remove the updates and the apply to directories.
let applyToDir = do_get_file(aTestID + APPLY_TO_DIR_SUFFIX, true);
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
cleanUp();
}
/**
* Helper function for updater tests for verifying the state of files and
* directories after a successful update.
*
* @param aTestID
* A string used to identify the name of directories for a test.
* @param aTestFiles
* An array of JavaScript objects representing the test files to create
* for the test.
*/
function checkFilesAfterUpdateSuccess(aTestID, aTestFiles) {
logTestInfo("testing contents of files after a successful update");
for (let i = 0; i < aTestFiles.length; i++) {
let f = aTestFiles[i];
let testFile = do_get_file(f.destinationDir + f.fileName, true);
logTestInfo("testing file: " + testFile.path);
if (f.compareFile || f.compareContents) {
do_check_true(testFile.exists());
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.comparePerms) {
// Check if the permssions as set in the complete mar file are correct.
let logPerms = "testing file permissions - ";
if (f.originalPerms) {
logPerms += "original permissions: " + f.originalPerms.toString(8) + ", ";
}
logPerms += "compare permissions : " + f.comparePerms.toString(8) + ", ";
logPerms += "updated permissions : " + testFile.permissions.toString(8);
logTestInfo(logPerms);
do_check_eq(testFile.permissions & 0xfff, f.comparePerms & 0xfff);
}
if (f.compareFile) {
do_check_eq(readFileBytes(testFile),
readFileBytes(do_get_file(f.compareFile)));
if (f.originalFile) {
// Verify that readFileBytes returned the entire contents by checking
// the contents against the original file.
do_check_neq(readFileBytes(testFile),
readFileBytes(do_get_file(f.originalFile)));
}
}
else {
do_check_eq(readFileBytes(testFile), f.compareContents);
}
}
else {
do_check_false(testFile.exists());
}
}
checkFilesAfterUpdateCommon(aTestID);
}
/**
* Helper function for updater tests for verifying the state of files and
* directories after a failed update.
*
* @param aTestID
* A string used to identify the name of directories for a test.
* @param aTestFiles
* An array of JavaScript objects representing the test files to create
* for the test.
*/
function checkFilesAfterUpdateFailure(aTestID, aTestFiles) {
logTestInfo("testing contents of files after a failed update");
for (let i = 0; i < aTestFiles.length; i++) {
let f = aTestFiles[i];
let testFile = do_get_file(f.destinationDir + f.fileName, true);
logTestInfo("testing file: " + testFile.path);
if (f.compareFile || f.compareContents) {
do_check_true(testFile.exists());
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.comparePerms) {
// Check the original permssions are retained on the file.
let logPerms = "testing file permissions - ";
if (f.originalPerms) {
logPerms += "original permissions: " + f.originalPerms.toString(8) + ", ";
}
logPerms += "compare permissions : " + f.comparePerms.toString(8) + ", ";
logPerms += "updated permissions : " + testFile.permissions.toString(8);
logTestInfo(logPerms);
do_check_eq(testFile.permissions & 0xfff, f.comparePerms & 0xfff);
}
if (f.compareFile) {
do_check_eq(readFileBytes(testFile),
readFileBytes(do_get_file(f.compareFile)));
}
else {
do_check_eq(readFileBytes(testFile), f.compareContents);
}
}
else {
do_check_false(testFile.exists());
}
}
checkFilesAfterUpdateCommon(aTestID);
}
/**
* Helper function for updater tests for verifying patch files and moz-backup
* files aren't left behind after a successful or failed update.
*
* @param aTestID
* A string used to identify the name of directories for a test.
*/
function checkFilesAfterUpdateCommon(aTestID) {
logTestInfo("testing patch files should not be left behind");
let updatesDir = do_get_file(aTestID + UPDATES_DIR_SUFFIX, true);
let entries = updatesDir.QueryInterface(AUS_Ci.nsIFile).directoryEntries;
while (entries.hasMoreElements()) {
let entry = entries.getNext().QueryInterface(AUS_Ci.nsIFile);
do_check_neq(getFileExtension(entry), "patch");
}
logTestInfo("testing backup files should not be left behind");
let applyToDir = do_get_file(aTestID + APPLY_TO_DIR_SUFFIX, true);
checkFilesInDirRecursive(applyToDir, checkForBackupFiles);
}
/**
* Helper function for updater tests for verifying the contents of the updater
* callback application log which should contain the string executed and the
* arguments passed to the callback application.
*/
function checkCallbackAppLog(aTestID) {
let appLaunchLog = do_get_file(aTestID + APPLY_TO_DIR_SUFFIX + "/" +
CALLBACK_ARGS[0], true);
if (!appLaunchLog.exists()) {
do_timeout(0, function() {
checkCallbackAppLog(aTestID);
});
return;
}
let expectedLogContents = "executed\n" + CALLBACK_ARGS.join("\n") + "\n";
let logContents = readFile(appLaunchLog).replace(/\r\n/g, "\n");
// It is possible for the log file contents check to occur before the log file
// contents are completely written so wait until the contents are the expected
// value. If the contents are never the expected value then the test will
// fail by timing out.
if (logContents != expectedLogContents) {
do_timeout(0, function() {
checkCallbackAppLog(aTestID);
});
return;
}
logTestInfo("testing that the callback application successfully launched " +
"and the expected command line arguments passed to it");
do_check_eq(logContents, expectedLogContents);
do_test_finished();
}
/**
* Helper function for updater tests for verifying there are no update backup
* files left behind after an update.
*
* @param aFile
* An nsIFile to check if it has moz-backup for its extension.
*/
function checkForBackupFiles(aFile) {
do_check_neq(getFileExtension(aFile), "moz-backup");
}
/**
* Helper function for updater tests for recursively enumerating a directory and
* calls a callback function with the file as a parameter for each file found.
*
* @param aDir
* A nsIFile for the directory to be deleted
* @param aCallback
* A callback function that will be called with the file as a
* parameter for each file found.
*/
function checkFilesInDirRecursive(aDir, aCallback) {
if (!aDir.exists())
do_throw("Directory must exist!");
let dirEntries = aDir.directoryEntries;
while (dirEntries.hasMoreElements()) {
let entry = dirEntries.getNext().QueryInterface(AUS_Ci.nsIFile);
if (entry.isDirectory()) {
checkFilesInDirRecursive(entry, aCallback);
}
else {
aCallback(entry);
}
}
}
/**
* Sets up the bare bones XMLHttpRequest implementation below.
*
@ -400,53 +781,3 @@ var gDirProvider = {
}
};
Services.dirsvc.QueryInterface(AUS_Ci.nsIDirectoryService).registerProvider(gDirProvider);
const INSTALL_LOCALE = "@AB_CD@";
// These are placed at the end so they don't mess up line numbering
const APP_BIN_NAME = "@MOZ_APP_NAME@";
#ifdef XP_UNIX
const APP_BIN_SUFFIX = "-bin";
#else
const APP_BIN_SUFFIX = "@BIN_SUFFIX@";
#endif
const BIN_SUFFIX = "@BIN_SUFFIX@";
#ifdef XP_WIN
const IS_WIN = true;
#else
const IS_WIN = false;
#endif
#ifdef WINCE
const IS_WINCE = true;
#else
const IS_WINCE = false;
#endif
#ifdef XP_OS2
const IS_OS2 = true;
#else
const IS_OS2 = false;
#endif
#ifdef XP_MACOSX
const IS_MACOSX = true;
#else
const IS_MACOSX = false;
#endif
#ifdef XP_UNIX
const IS_UNIX = true;
#else
const IS_UNIX = false;
#endif
#ifdef ANDROID
const IS_ANDROID = true;
#else
const IS_ANDROID = false;
#endif

View File

@ -11,15 +11,15 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Application Update Service.
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Robert Strong <robert.bugzilla@gmail.com>.
*
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert Strong <robert.bugzilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -38,40 +38,26 @@
/* General Complete MAR File Patch Apply Test */
const APPLY_TO_DIR = "applyToDir_0110";
const UPDATES_DIR = "0110_mar";
const AFTER_APPLY_DIR = "afterApplyDir";
const UPDATER_BIN_FILE = "updater" + BIN_SUFFIX;
const AFTER_APPLY_BIN_FILE = "TestAUSHelper" + BIN_SUFFIX;
const RELAUNCH_BIN_FILE = "relaunch_app" + BIN_SUFFIX;
const RELAUNCH_ARGS = ["Test Arg 1", "Test Arg 2", "Test Arg 3"];
const TEST_ID = "0110";
// 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;
var gTestFiles = [
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_exe1.exe",
destinationDir : APPLY_TO_DIR + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/aus-0111_general_ref_image.png",
compareFile : "data/aus-0110_general_ref_image.png",
originalPerms : 0777,
comparePerms : 0755
}, {
fileName : "1_1_image1.png",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : null,
compareFile : "data/aus-0110_general_ref_image.png",
compareFile : "data/complete.png",
originalPerms : 0776,
comparePerms : 0644
}, {
fileName : "1_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeReplacedWithToBeModified\n",
compareContents : "ToBeModified\n",
originalFile : null,
@ -80,16 +66,25 @@ var gTestFiles = [
comparePerms : 0644
}, {
fileName : "1_1_text2",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeReplacedWithToBeDeleted\n",
compareContents : "ToBeDeleted\n",
originalFile : null,
compareFile : null,
originalPerms : 0677,
comparePerms : 0644
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/complete.png",
originalPerms : 0777,
comparePerms : 0755
}, {
fileName : "2_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/2/2_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ToBeReplacedWithToBeDeleted\n",
compareContents : "ToBeDeleted\n",
originalFile : null,
@ -107,119 +102,32 @@ function run_test() {
do_test_pending();
do_register_cleanup(end_test);
var testDir, testFile;
setupUpdaterTest(TEST_ID, MAR_COMPLETE_FILE, TEST_FILES);
// The directory the updates will be applied to is the directory name stored
// in the APPLY_TO_DIR constant located in the current working directory and
// not dist/bin.
var applyToDir = do_get_file(APPLY_TO_DIR, true);
// The testUpdate function is used for consistency with the tests that require
// a timeout before continuing the test.
testUpdate();
}
// Remove the directory where the update will be applied if it exists.
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
logTestInfo("testing successful removal of the directory used to apply the " +
"mar file");
do_check_false(applyToDir.exists());
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
// Use a directory outside of dist/bin to lessen the garbage in dist/bin
var updatesDir = do_get_file(UPDATES_DIR, true);
try {
// Mac OS X intermittently fails when removing the dir where the updater
// binary was launched.
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
if (!updatesDir.exists()) {
updatesDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
}
// Create the files to test the complete mar's ability to replace files.
for (var i = 0; i < gTestFiles.length; i++) {
var f = gTestFiles[i];
if (f.originalFile || f.originalContents) {
testDir = do_get_file(f.destinationDir, true);
if (!testDir.exists())
testDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
if (f.originalFile) {
testFile = do_get_file(f.originalFile);
testFile.copyTo(testDir, f.fileName);
testFile = do_get_file(f.destinationDir + f.fileName);
}
else {
testFile = do_get_file(f.destinationDir + f.fileName, true);
writeFile(testFile, f.originalContents);
}
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.originalPerms) {
testFile.permissions = f.originalPerms;
// Store the actual permissions on the file for reference later after
// setting the permissions.
if (!f.comparePerms)
f.comparePerms = testFile.permissions;
}
}
}
var afterApplyBinDir = applyToDir.clone();
afterApplyBinDir.append(AFTER_APPLY_DIR);
var afterApplyBin = do_get_file(AFTER_APPLY_BIN_FILE);
afterApplyBin.copyTo(afterApplyBinDir, RELAUNCH_BIN_FILE);
var relaunchApp = afterApplyBinDir.clone();
relaunchApp.append(RELAUNCH_BIN_FILE);
relaunchApp.permissions = PERMS_DIRECTORY;
let updaterIniContents = "[Strings]\n" +
"Title=Update Test\n" +
"Info=Application Update XPCShell Test - " +
"test_0110_general.js\n";
var updaterIni = updatesDir.clone();
updaterIni.append(FILE_UPDATER_INI);
writeFile(updaterIni, updaterIniContents);
updaterIni.copyTo(afterApplyBinDir, FILE_UPDATER_INI);
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// 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 a successful
// update (bug 600098).
if (IS_MACOSX) {
var now = Date.now();
var yesterday = now - (1000 * 60 * 60 * 24);
let now = Date.now();
let yesterday = now - (1000 * 60 * 60 * 24);
applyToDir.lastModifiedTime = yesterday;
}
var binDir = getGREDir();
// The updater binary file
var updater = binDir.clone();
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
}
var mar = do_get_file("data/aus-0110_general.mar");
mar.copyTo(updatesDir, FILE_UPDATE_ARCHIVE);
// apply the complete mar and check the innards of the files
var exitValue = runUpdate(updater, updatesDir, applyToDir, relaunchApp,
RELAUNCH_ARGS);
// apply the complete mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a complete mar");
do_check_eq(exitValue, 0);
@ -232,110 +140,17 @@ function run_test() {
if (IS_MACOSX) {
logTestInfo("testing last modified time on the apply to directory has " +
"changed after a successful update (bug 600098)");
now = Date.now();
var timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
let now = Date.now();
let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
do_check_true(timeDiff < MAX_TIME_DIFFERENCE);
}
logTestInfo("testing contents of files added by a complete mar");
for (i = 0; i < gTestFiles.length; i++) {
f = gTestFiles[i];
testFile = do_get_file(f.destinationDir + f.fileName, true);
logTestInfo("testing file: " + testFile.path);
if (f.compareFile || f.compareContents) {
do_check_true(testFile.exists());
checkFilesAfterUpdateSuccess(TEST_ID, TEST_FILES);
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.comparePerms) {
// Check if the permssions as set in the complete mar file are correct.
let logPerms = "testing file permissions - ";
if (f.originalPerms) {
logPerms += "original permissions: " + f.originalPerms.toString(8) + ", ";
}
logPerms += "compare permissions : " + f.comparePerms.toString(8) + ", ";
logPerms += "updated permissions : " + testFile.permissions.toString(8);
logTestInfo(logPerms);
do_check_eq(testFile.permissions & 0xfff, f.comparePerms & 0xfff);
}
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_false(toBeDeletedDir.exists());
if (f.compareFile) {
do_check_eq(readFileBytes(testFile),
readFileBytes(do_get_file(f.compareFile)));
if (f.originalFile) {
// Verify that readFileBytes returned the entire contents by checking
// the contents against the original file.
do_check_neq(readFileBytes(testFile),
readFileBytes(do_get_file(f.originalFile)));
}
}
else {
do_check_eq(readFileBytes(testFile), f.compareContents);
}
}
else {
do_check_false(testFile.exists());
}
}
logTestInfo("testing patch files should not be left behind");
var entries = updatesDir.QueryInterface(AUS_Ci.nsIFile).directoryEntries;
while (entries.hasMoreElements()) {
var entry = entries.getNext().QueryInterface(AUS_Ci.nsIFile);
do_check_neq(getFileExtension(entry), "patch");
}
check_app_launch_log();
}
function end_test() {
// Try to remove the updates and the apply to directories.
var applyToDir = do_get_file(APPLY_TO_DIR, true);
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
var updatesDir = do_get_file(UPDATES_DIR, true);
try {
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
cleanUp();
}
function check_app_launch_log() {
var appLaunchLog = do_get_file(APPLY_TO_DIR);
appLaunchLog.append(AFTER_APPLY_DIR);
appLaunchLog.append(RELAUNCH_BIN_FILE + ".log");
if (!appLaunchLog.exists()) {
do_timeout(0, check_app_launch_log);
return;
}
var expectedLogContents = "executed\n" + RELAUNCH_ARGS.join("\n") + "\n";
var logContents = readFile(appLaunchLog).replace(/\r\n/g, "\n");
// It is possible for the log file contents check to occur before the log file
// contents are completely written so wait until the contents are the expected
// value. If the contents are never the expected value then the test will
// fail by timing out.
if (logContents != expectedLogContents) {
do_timeout(0, check_app_launch_log);
return;
}
logTestInfo("testing that the callback application successfully launched " +
"and the expected command line arguments passed to it");
do_check_eq(logContents, expectedLogContents);
do_test_finished();
checkCallbackAppLog(TEST_ID);
}

View File

@ -11,15 +11,15 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Application Update Service.
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Robert Strong <robert.bugzilla@gmail.com>.
*
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert Strong <robert.bugzilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -38,40 +38,26 @@
/* General Partial MAR File Patch Apply Test */
const APPLY_TO_DIR = "applyToDir_0111";
const UPDATES_DIR = "0111_mar";
const AFTER_APPLY_DIR = "afterApplyDir";
const UPDATER_BIN_FILE = "updater" + BIN_SUFFIX;
const AFTER_APPLY_BIN_FILE = "TestAUSHelper" + BIN_SUFFIX;
const RELAUNCH_BIN_FILE = "relaunch_app" + BIN_SUFFIX;
const RELAUNCH_ARGS = ["Test Arg 1", "Test Arg 2", "Test Arg 3"];
const TEST_ID = "0111";
// 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;
var gTestFiles = [
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_exe1.exe",
destinationDir : APPLY_TO_DIR + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/aus-0110_general_ref_image.png",
compareFile : "data/aus-0111_general_ref_image.png",
originalPerms : 0755,
comparePerms : null
}, {
fileName : "1_1_image1.png",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : "data/aus-0110_general_ref_image.png",
compareFile : "data/aus-0111_general_ref_image.png",
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0644,
comparePerms : null
}, {
fileName : "1_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeModified\n",
compareContents : "Modified\n",
originalFile : null,
@ -80,7 +66,25 @@ var gTestFiles = [
comparePerms : null
}, {
fileName : "1_1_text2",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png",
originalPerms : 0755,
comparePerms : null
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
@ -89,25 +93,16 @@ var gTestFiles = [
comparePerms : null
}, {
fileName : "1_1_text3",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : "Added\n",
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : 0644
}, {
fileName : "2_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/2/2_1/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
compareFile : null,
originalPerms : null,
comparePerms : null
}, {
fileName : "3_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/3/3_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/3/3_1/",
originalContents : null,
compareContents : "Added\n",
originalFile : null,
@ -125,120 +120,32 @@ function run_test() {
do_test_pending();
do_register_cleanup(end_test);
var testDir, testFile;
setupUpdaterTest(TEST_ID, MAR_PARTIAL_FILE, TEST_FILES);
// The directory the updates will be applied to is the directory name stored
// in the APPLY_TO_DIR constant located in the current working directory and
// not dist/bin.
var applyToDir = do_get_file(APPLY_TO_DIR, true);
// The testUpdate function is used for consistency with the tests that require
// a timeout before continuing the test.
testUpdate();
}
// Remove the directory where the update will be applied if it exists.
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
logTestInfo("testing successful removal of the directory used to apply the " +
"mar file");
do_check_false(applyToDir.exists());
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
// Use a directory outside of dist/bin to lessen the garbage in dist/bin
var updatesDir = do_get_file(UPDATES_DIR, true);
try {
// Mac OS X intermittently fails when removing the dir where the updater
// binary was launched.
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
if (!updatesDir.exists()) {
updatesDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
}
// Create the files to test the partial mar's ability to modify and delete
// files.
for (var i = 0; i < gTestFiles.length; i++) {
var f = gTestFiles[i];
if (f.originalFile || f.originalContents) {
testDir = do_get_file(f.destinationDir, true);
if (!testDir.exists())
testDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
if (f.originalFile) {
testFile = do_get_file(f.originalFile);
testFile.copyTo(testDir, f.fileName);
testFile = do_get_file(f.destinationDir + f.fileName);
}
else {
testFile = do_get_file(f.destinationDir + f.fileName, true);
writeFile(testFile, f.originalContents);
}
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.originalPerms) {
testFile.permissions = f.originalPerms;
// Store the actual permissions on the file for reference later after
// setting the permissions.
if (!f.comparePerms)
f.comparePerms = testFile.permissions;
}
}
}
var afterApplyBinDir = applyToDir.clone();
afterApplyBinDir.append(AFTER_APPLY_DIR);
var afterApplyBin = do_get_file(AFTER_APPLY_BIN_FILE);
afterApplyBin.copyTo(afterApplyBinDir, RELAUNCH_BIN_FILE);
var relaunchApp = afterApplyBinDir.clone();
relaunchApp.append(RELAUNCH_BIN_FILE);
relaunchApp.permissions = PERMS_DIRECTORY;
let updaterIniContents = "[Strings]\n" +
"Title=Update Test\n" +
"Info=Application Update XPCShell Test - " +
"test_0111_general.js\n";
var updaterIni = updatesDir.clone();
updaterIni.append(FILE_UPDATER_INI);
writeFile(updaterIni, updaterIniContents);
updaterIni.copyTo(afterApplyBinDir, FILE_UPDATER_INI);
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// 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 a successful
// update (bug 600098).
if (IS_MACOSX) {
var now = Date.now();
var yesterday = now - (1000 * 60 * 60 * 24);
let now = Date.now();
let yesterday = now - (1000 * 60 * 60 * 24);
applyToDir.lastModifiedTime = yesterday;
}
var binDir = getGREDir();
// The updater binary file
var updater = binDir.clone();
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
}
var mar = do_get_file("data/aus-0111_general.mar");
mar.copyTo(updatesDir, FILE_UPDATE_ARCHIVE);
// apply the partial mar and check the innards of the files
var exitValue = runUpdate(updater, updatesDir, applyToDir, relaunchApp,
RELAUNCH_ARGS);
// apply the partial mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
@ -251,115 +158,23 @@ function run_test() {
if (IS_MACOSX) {
logTestInfo("testing last modified time on the apply to directory has " +
"changed after a successful update (bug 600098)");
now = Date.now();
var timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
let now = Date.now();
let timeDiff = Math.abs(applyToDir.lastModifiedTime - now);
do_check_true(timeDiff < MAX_TIME_DIFFERENCE);
}
logTestInfo("testing the removal of files and the contents of added / " +
"modified files by a partial mar");
for (i = 0; i < gTestFiles.length; i++) {
f = gTestFiles[i];
testFile = do_get_file(f.destinationDir + f.fileName, true);
logTestInfo("testing file: " + testFile.path);
if (f.compareFile || f.compareContents) {
do_check_true(testFile.exists());
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.comparePerms) {
// Check the original permssions are retained on the file.
let logPerms = "testing file permissions - ";
if (f.originalPerms) {
logPerms += "original permissions: " + f.originalPerms.toString(8) + ", ";
}
logPerms += "compare permissions : " + f.comparePerms.toString(8) + ", ";
logPerms += "updated permissions : " + testFile.permissions.toString(8);
logTestInfo(logPerms);
do_check_eq(testFile.permissions & 0xfff, f.comparePerms & 0xfff);
}
if (f.compareFile) {
do_check_eq(readFileBytes(testFile),
readFileBytes(do_get_file(f.compareFile)));
if (f.originalFile) {
// Verify that readFileBytes returned the entire contents by checking
// the contents against the original file.
do_check_neq(readFileBytes(testFile),
readFileBytes(do_get_file(f.originalFile)));
}
}
else {
do_check_eq(readFileBytes(testFile), f.compareContents);
}
}
else {
do_check_false(testFile.exists());
}
}
checkFilesAfterUpdateSuccess(TEST_ID, TEST_FILES);
logTestInfo("testing directory still exists after removal of the last file " +
"in the directory (bug 386760)");
do_check_true(do_get_file(APPLY_TO_DIR + "/mar_test/2/2_1/", true).exists());
let testDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
true);
do_check_true(testDir.exists());
logTestInfo("testing patch files should not be left behind");
var entries = updatesDir.QueryInterface(AUS_Ci.nsIFile).directoryEntries;
while (entries.hasMoreElements()) {
var entry = entries.getNext().QueryInterface(AUS_Ci.nsIFile);
do_check_neq(getFileExtension(entry), "patch");
}
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_false(toBeDeletedDir.exists());
check_app_launch_log();
}
function end_test() {
// Try to remove the updates and the apply to directories.
var applyToDir = do_get_file(APPLY_TO_DIR, true);
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
var updatesDir = do_get_file(UPDATES_DIR, true);
try {
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
cleanUp();
}
function check_app_launch_log() {
var appLaunchLog = do_get_file(APPLY_TO_DIR);
appLaunchLog.append(AFTER_APPLY_DIR);
appLaunchLog.append(RELAUNCH_BIN_FILE + ".log");
if (!appLaunchLog.exists()) {
do_timeout(0, check_app_launch_log);
return;
}
var expectedLogContents = "executed\n" + RELAUNCH_ARGS.join("\n") + "\n";
var logContents = readFile(appLaunchLog).replace(/\r\n/g, "\n");
// It is possible for the log file contents check to occur before the log file
// contents are completely written so wait until the contents are the expected
// value. If the contents are never the expected value then the test will
// fail by timing out.
if (logContents != expectedLogContents) {
do_timeout(0, check_app_launch_log);
return;
}
logTestInfo("testing that the callback application successfully launched " +
"and the expected command line arguments passed to it");
do_check_eq(logContents, expectedLogContents);
do_test_finished();
checkCallbackAppLog(TEST_ID);
}

View File

@ -11,15 +11,15 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Application Update Service.
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Robert Strong <robert.bugzilla@gmail.com>.
*
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert Strong <robert.bugzilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -38,36 +38,22 @@
/* General Partial MAR File Patch Apply Failure Test */
const APPLY_TO_DIR = "applyToDir_0112";
const UPDATES_DIR = "0112_mar";
const AFTER_APPLY_DIR = "afterApplyDir";
const UPDATER_BIN_FILE = "updater" + BIN_SUFFIX;
const AFTER_APPLY_BIN_FILE = "TestAUSHelper" + BIN_SUFFIX;
const RELAUNCH_BIN_FILE = "relaunch_app" + BIN_SUFFIX;
const RELAUNCH_ARGS = ["Test Arg 1", "Test Arg 2", "Test Arg 3"];
const TEST_ID = "0112";
var gTestFiles = [
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_exe1.exe",
destinationDir : APPLY_TO_DIR + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/aus-0111_general_ref_image.png",
compareFile : "data/aus-0111_general_ref_image.png",
originalPerms : 0755,
comparePerms : null
}, {
fileName : "1_1_image1.png",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : "data/aus-0110_general_ref_image.png",
compareFile : "data/aus-0110_general_ref_image.png",
originalFile : "data/complete.png",
compareFile : "data/complete.png",
originalPerms : 0644,
comparePerms : null
}, {
fileName : "1_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeDeleted\n",
compareContents : "ShouldNotBeDeleted\n",
originalFile : null,
@ -76,16 +62,25 @@ var gTestFiles = [
comparePerms : null
}, {
fileName : "1_1_text2",
destinationDir : APPLY_TO_DIR + "/mar_test/1/1_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeDeleted\n",
compareContents : "ShouldNotBeDeleted\n",
originalFile : null,
compareFile : null,
originalPerms : 0644,
comparePerms : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/partial.png",
originalPerms : 0755,
comparePerms : null
}, {
fileName : "2_1_text1",
destinationDir : APPLY_TO_DIR + "/mar_test/2/2_1/",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ShouldNotBeDeleted\n",
compareContents : "ShouldNotBeDeleted\n",
originalFile : null,
@ -103,125 +98,38 @@ function run_test() {
do_test_pending();
do_register_cleanup(end_test);
var testDir, testFile;
setupUpdaterTest(TEST_ID, MAR_PARTIAL_FILE, TEST_FILES);
// The directory the updates will be applied to is the directory name stored
// in the APPLY_TO_DIR constant located in the current working directory and
// not dist/bin.
var applyToDir = do_get_file(APPLY_TO_DIR, true);
// The testUpdate function is used for consistency with the tests that require
// a timeout before continuing the test.
testUpdate();
}
// Remove the directory where the update will be applied if it exists.
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
logTestInfo("testing successful removal of the directory used to apply the " +
"mar file");
do_check_false(applyToDir.exists());
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
// Use a directory outside of dist/bin to lessen the garbage in dist/bin
var updatesDir = do_get_file(UPDATES_DIR, true);
try {
// Mac OS X intermittently fails when removing the dir where the updater
// binary was launched.
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
if (!updatesDir.exists()) {
updatesDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
}
// Create the files to test the partial mar's ability to rollback to the
// original files.
for (var i = 0; i < gTestFiles.length; i++) {
var f = gTestFiles[i];
if (f.originalFile || f.originalContents) {
testDir = do_get_file(f.destinationDir, true);
if (!testDir.exists())
testDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
if (f.originalFile) {
testFile = do_get_file(f.originalFile);
testFile.copyTo(testDir, f.fileName);
testFile = do_get_file(f.destinationDir + f.fileName);
}
else {
testFile = do_get_file(f.destinationDir + f.fileName, true);
writeFile(testFile, f.originalContents);
}
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.originalPerms) {
testFile.permissions = f.originalPerms;
// Store the actual permissions on the file for reference later after
// setting the permissions.
if (!f.comparePerms)
f.comparePerms = testFile.permissions;
}
}
}
var afterApplyBinDir = applyToDir.clone();
afterApplyBinDir.append(AFTER_APPLY_DIR);
var afterApplyBin = do_get_file(AFTER_APPLY_BIN_FILE);
afterApplyBin.copyTo(afterApplyBinDir, RELAUNCH_BIN_FILE);
var relaunchApp = afterApplyBinDir.clone();
relaunchApp.append(RELAUNCH_BIN_FILE);
relaunchApp.permissions = PERMS_DIRECTORY;
let updaterIniContents = "[Strings]\n" +
"Title=Update Test\n" +
"Info=Application Update XPCShell Test - " +
"test_0112_general.js\n";
var updaterIni = updatesDir.clone();
updaterIni.append(FILE_UPDATER_INI);
writeFile(updaterIni, updaterIniContents);
updaterIni.copyTo(afterApplyBinDir, FILE_UPDATER_INI);
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// For Mac OS X set the last modified time for a directory to a date in the
// past to test that the last modified time on the directories in not updated
// when an update fails (bug 600098).
let lastModTime;
if (IS_MACOSX) {
// All we care about is that the last modified time has not changed when an
// update has failed.
var now = Date.now();
var lastModTime = now - (1000 * 60 * 60 * 24);
let now = Date.now();
lastModTime = now - (1000 * 60 * 60 * 24);
applyToDir.lastModifiedTime = lastModTime;
// Set lastModTime to the value the OS returns in case it is different than
// the value stored by the OS.
lastModTime = applyToDir.lastModifiedTime;
}
var binDir = getGREDir();
// The updater binary file
var updater = binDir.clone();
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
}
var mar = do_get_file("data/aus-0111_general.mar");
mar.copyTo(updatesDir, FILE_UPDATE_ARCHIVE);
// apply the partial mar and check the innards of the files
var exitValue = runUpdate(updater, updatesDir, applyToDir, relaunchApp,
RELAUNCH_ARGS);
// apply the partial mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
@ -239,100 +147,12 @@ function run_test() {
do_check_eq(applyToDir.lastModifiedTime, lastModTime);
}
logTestInfo("testing files should not be modified or deleted when an " +
"update fails");
for (i = 0; i < gTestFiles.length; i++) {
f = gTestFiles[i];
testFile = do_get_file(f.destinationDir + f.fileName, true);
logTestInfo("testing file: " + testFile.path);
if (f.compareFile || f.compareContents) {
do_check_true(testFile.exists());
checkFilesAfterUpdateFailure(TEST_ID, TEST_FILES);
// Skip these tests on Windows (includes WinCE) and OS/2 since their
// implementaions of chmod doesn't really set permissions.
if (!IS_WIN && !IS_OS2 && f.comparePerms) {
// Check the original permssions are retained on the file.
let logPerms = "testing file permissions - ";
if (f.originalPerms) {
logPerms += "original permissions: " + f.originalPerms.toString(8) + ", ";
}
logPerms += "compare permissions : " + f.comparePerms.toString(8) + ", ";
logPerms += "updated permissions : " + testFile.permissions.toString(8);
logTestInfo(logPerms);
do_check_eq(testFile.permissions & 0xfff, f.comparePerms & 0xfff);
}
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_false(toBeDeletedDir.exists());
if (f.compareFile) {
do_check_eq(readFileBytes(testFile),
readFileBytes(do_get_file(f.compareFile)));
}
else {
do_check_eq(readFileBytes(testFile), f.compareContents);
}
}
else {
do_check_false(testFile.exists());
}
}
logTestInfo("testing patch files should not be left behind");
var entries = updatesDir.QueryInterface(AUS_Ci.nsIFile).directoryEntries;
while (entries.hasMoreElements()) {
var entry = entries.getNext().QueryInterface(AUS_Ci.nsIFile);
do_check_neq(getFileExtension(entry), "patch");
}
check_app_launch_log();
}
function end_test() {
// Try to remove the updates and the apply to directories.
var applyToDir = do_get_file(APPLY_TO_DIR, true);
try {
removeDirRecursive(applyToDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + applyToDir.path + "\n" +
"Exception: " + e + "\n");
}
var updatesDir = do_get_file(UPDATES_DIR, true);
try {
removeDirRecursive(updatesDir);
}
catch (e) {
dump("Unable to remove directory\n" +
"path: " + updatesDir.path + "\n" +
"Exception: " + e + "\n");
}
cleanUp();
}
function check_app_launch_log() {
var appLaunchLog = do_get_file(APPLY_TO_DIR);
appLaunchLog.append(AFTER_APPLY_DIR);
appLaunchLog.append(RELAUNCH_BIN_FILE + ".log");
if (!appLaunchLog.exists()) {
do_timeout(0, check_app_launch_log);
return;
}
var expectedLogContents = "executed\n" + RELAUNCH_ARGS.join("\n") + "\n";
var logContents = readFile(appLaunchLog).replace(/\r\n/g, "\n");
// It is possible for the log file contents check to occur before the log file
// contents are completely written so wait until the contents are the expected
// value. If the contents are never the expected value then the test will
// fail by timing out.
if (logContents != expectedLogContents) {
do_timeout(0, check_app_launch_log);
return;
}
logTestInfo("testing that the callback application successfully launched " +
"and the expected command line arguments passed to it");
do_check_eq(logContents, expectedLogContents);
do_test_finished();
checkCallbackAppLog(TEST_ID);
}

View File

@ -0,0 +1,133 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* Application in use complete MAR file patch apply success test */
const TEST_ID = "0160";
// 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 in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_1_image1.png",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : null,
compareFile : "data/complete.png",
originalPerms : 0776,
comparePerms : 0644
}, {
fileName : "1_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeReplacedWithToBeModified\n",
compareContents : "ToBeModified\n",
originalFile : null,
compareFile : null,
originalPerms : 0775,
comparePerms : 0644
}, {
fileName : "1_1_text2",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeReplacedWithToBeDeleted\n",
compareContents : "ToBeDeleted\n",
originalFile : null,
compareFile : null,
originalPerms : 0677,
comparePerms : 0644
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/complete.png",
originalPerms : 0777,
comparePerms : 0755
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ToBeReplacedWithToBeDeleted\n",
compareContents : "ToBeDeleted\n",
originalFile : null,
compareFile : null,
originalPerms : 0767,
comparePerms : 0644
}];
let gCallbackAppProcess;
function run_test() {
if (!IS_UNIX || IS_ANDROID) {
logTestInfo("this test is only applicable to XP_UNIX platforms except " +
"for Android... returning early");
return;
}
do_test_pending();
do_register_cleanup(end_test);
setupUpdaterTest(TEST_ID, MAR_COMPLETE_FILE, TEST_FILES);
// Launch the callback helper application so it is in use during the update
let callbackApp = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
callbackApp.append(AFTER_APPLY_DIR);
callbackApp.append(CALLBACK_BIN_FILE);
callbackApp.permissions = PERMS_DIRECTORY;
let args = ["-s", "20"];
gCallbackAppProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
gCallbackAppProcess.init(callbackApp);
gCallbackAppProcess.run(false, args, args.length);
// Give the lock file process time to lock the file before updating otherwise
// this test can fail intermittently on Windows debug builds.
do_timeout(100, testUpdate);
}
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// 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 a successful
// update (bug 600098).
if (IS_MACOSX) {
let now = Date.now();
let yesterday = now - (1000 * 60 * 60 * 24);
applyToDir.lastModifiedTime = yesterday;
}
// apply the complete mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a complete mar");
do_check_eq(exitValue, 0);
gCallbackAppProcess.kill();
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(TEST_ID, TEST_FILES);
checkCallbackAppLog(TEST_ID);
}

View File

@ -0,0 +1,105 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* Application in use complete MAR file patch apply failure test */
const TEST_ID = "0160";
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_1_image1.png",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/partial.png"
}, {
fileName : "1_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_1_text2",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/partial.png"
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null
}];
let gCallbackAppProcess;
function run_test() {
if (!IS_WIN || IS_WINCE) {
logTestInfo("this test is only applicable to Windows... returning early");
return;
}
do_test_pending();
do_register_cleanup(end_test);
setupUpdaterTest(TEST_ID, MAR_COMPLETE_FILE, TEST_FILES);
// Launch the callback helper application so it is in use during the update
let callbackApp = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
callbackApp.append(AFTER_APPLY_DIR);
callbackApp.append(CALLBACK_BIN_FILE);
let args = ["-s", "20"];
gCallbackAppProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
gCallbackAppProcess.init(callbackApp);
gCallbackAppProcess.run(false, args, args.length);
// Give the lock file process time to lock the file before updating otherwise
// this test can fail intermittently on Windows debug builds.
do_timeout(100, testUpdate);
}
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// apply the complete mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a complete mar");
do_check_eq(exitValue, 1);
gCallbackAppProcess.kill();
logTestInfo("testing update.status should be " + STATE_FAILED);
// The update status format for a failure is failed: # where # is the error
// code for the failure.
do_check_eq(readStatusFile(updatesDir).split(": ")[0], STATE_FAILED);
checkFilesAfterUpdateFailure(TEST_ID, TEST_FILES);
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_false(toBeDeletedDir.exists());
checkCallbackAppLog(TEST_ID);
}

View File

@ -0,0 +1,104 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* File locked complete MAR file patch apply failure test */
const TEST_ID = "0170";
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_1_image1.png",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/partial.png"
}, {
fileName : "1_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_1_text2",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/partial.png"
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ShouldNotBeReplaced\n",
compareContents : "ShouldNotBeReplaced\n",
originalFile : null,
compareFile : null
}];
let gLockFileProcess;
function run_test() {
if (!IS_WIN || IS_WINCE) {
logTestInfo("this test is only applicable to Windows... returning early");
return;
}
do_test_pending();
do_register_cleanup(end_test);
setupUpdaterTest(TEST_ID, MAR_COMPLETE_FILE, TEST_FILES);
// Exclusively lock an existing file so it is in use during the update
let helperBin = do_get_file(HELPER_BIN_FILE);
let lockFileRelPath = TEST_FILES[3].destinationDir + TEST_FILES[3].fileName;
let args = ["-s", "20", lockFileRelPath];
gLockFileProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
gLockFileProcess.init(helperBin);
gLockFileProcess.run(false, args, args.length);
// Give the lock file process time to lock the file before updating otherwise
// this test can fail intermittently on Windows debug builds.
do_timeout(100, testUpdate);
}
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// apply the complete mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a complete mar");
do_check_eq(exitValue, 0);
gLockFileProcess.kill();
logTestInfo("testing update.status should be " + STATE_FAILED);
// The update status format for a failure is failed: # where # is the error
// code for the failure.
do_check_eq(readStatusFile(updatesDir).split(": ")[0], STATE_FAILED);
checkFilesAfterUpdateFailure(TEST_ID, TEST_FILES);
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_false(toBeDeletedDir.exists());
checkCallbackAppLog(TEST_ID);
}

View File

@ -0,0 +1,104 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* File locked partial MAR file patch apply failure test */
const TEST_ID = "0171";
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_1_image1.png",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial.png",
compareFile : "data/partial.png"
}, {
fileName : "1_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeModified\n",
compareContents : "ShouldNotBeModified\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_1_text2",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ShouldNotBeDeleted\n",
compareContents : "ShouldNotBeDeleted\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/complete.png"
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ShouldNotBeDeleted\n",
compareContents : "ShouldNotBeDeleted\n",
originalFile : null,
compareFile : null
}];
let gLockFileProcess;
function run_test() {
if (!IS_WIN || IS_WINCE) {
logTestInfo("this test is only applicable to Windows... returning early");
return;
}
do_test_pending();
do_register_cleanup(end_test);
setupUpdaterTest(TEST_ID, MAR_PARTIAL_FILE, TEST_FILES);
// Exclusively lock an existing file so it is in use during the update
let helperBin = do_get_file(HELPER_BIN_FILE);
let lockFileRelPath = TEST_FILES[3].destinationDir + TEST_FILES[3].fileName;
let args = ["-s", "20", lockFileRelPath];
gLockFileProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
gLockFileProcess.init(helperBin);
gLockFileProcess.run(false, args, args.length);
// Give the lock file process time to lock the file before updating otherwise
// this test can fail intermittently on Windows debug builds.
do_timeout(100, testUpdate);
}
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// apply the partial mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
gLockFileProcess.kill();
logTestInfo("testing update.status should be " + STATE_FAILED);
// The update status format for a failure is failed: # where # is the error
// code for the failure.
do_check_eq(readStatusFile(updatesDir).split(": ")[0], STATE_FAILED);
checkFilesAfterUpdateFailure(TEST_ID, TEST_FILES);
logTestInfo("testing tobedeleted directory doesn't exist");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_false(toBeDeletedDir.exists());
checkCallbackAppLog(TEST_ID);
}

View File

@ -0,0 +1,102 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* File in use complete MAR file patch apply success test */
const TEST_ID = "0180";
// The files are in the same order as they are applied from the mar
const TEST_FILES = [
{
fileName : "1_1_image1.png",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : null,
compareFile : "data/complete.png"
}, {
fileName : "1_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeReplacedWithToBeModified\n",
compareContents : "ToBeModified\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_1_text2",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeReplacedWithToBeDeleted\n",
compareContents : "ToBeDeleted\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : HELPER_BIN_FILE,
compareFile : "data/complete.png"
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ToBeReplacedWithToBeDeleted\n",
compareContents : "ToBeDeleted\n",
originalFile : null,
compareFile : null
}];
let gFileInUseProcess;
function run_test() {
if (!IS_WIN || IS_WINCE) {
logTestInfo("this test is only applicable to Windows... returning early");
return;
}
do_test_pending();
do_register_cleanup(end_test);
setupUpdaterTest(TEST_ID, MAR_COMPLETE_FILE, TEST_FILES);
// Launch an existing file so it is in use during the update
let fileInUseBin = do_get_file(TEST_FILES[3].destinationDir +
TEST_FILES[3].fileName);
let args = ["-s", "20"];
gFileInUseProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
gFileInUseProcess.init(fileInUseBin);
gFileInUseProcess.run(false, args, args.length);
// Give the file in use process time to launch before updating otherwise this
// test can fail intermittently on Windows debug builds.
do_timeout(100, testUpdate);
}
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// apply the complete mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a complete mar");
do_check_eq(exitValue, 0);
gFileInUseProcess.kill();
logTestInfo("testing update.status should be " + STATE_SUCCEEDED);
do_check_eq(readStatusFile(updatesDir), STATE_SUCCEEDED);
checkFilesAfterUpdateSuccess(TEST_ID, TEST_FILES);
logTestInfo("testing tobedeleted directory exists");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_true(toBeDeletedDir.exists());
checkCallbackAppLog(TEST_ID);
}

View File

@ -0,0 +1,119 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* File in use partial MAR file patch apply success test */
const TEST_ID = "0181";
const MAR_IN_USE_WIN_FILE = "data/partial_in_use_win.mar";
// The files are in the same order as they are applied from the mar
var TEST_FILES = [
{
fileName : "1_1_image1.png",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : null,
originalFile : "data/complete.png",
compareFile : "data/partial.png"
}, {
fileName : "1_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeModified\n",
compareContents : "Modified\n",
originalFile : null,
compareFile : null
}, {
fileName : "1_1_text2",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
compareFile : null
}, {
fileName : "1_exe1.exe",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/",
originalContents : null,
compareContents : null,
originalFile : "data/partial_in_use_win_before.exe",
compareFile : "data/partial_in_use_win_after.exe"
}, {
fileName : "2_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/",
originalContents : "ToBeDeleted\n",
compareContents : null,
originalFile : null,
compareFile : null
}, {
fileName : "1_1_text3",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/1/1_1/",
originalContents : null,
compareContents : "Added\n",
originalFile : null,
compareFile : null
}, {
fileName : "3_1_text1",
destinationDir : TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/3/3_1/",
originalContents : null,
compareContents : "Added\n",
originalFile : null,
compareFile : null
}];
let gFileInUseProcess;
function run_test() {
if (!IS_WIN || IS_WINCE) {
logTestInfo("this test is only applicable to Windows... returning early");
return;
}
do_test_pending();
do_register_cleanup(end_test);
setupUpdaterTest(TEST_ID, MAR_IN_USE_WIN_FILE, TEST_FILES);
// Launch an existing file so it is in use during the update
let fileInUseBin = do_get_file(TEST_FILES[3].destinationDir +
TEST_FILES[3].fileName);
let args = ["-s", "20"];
gFileInUseProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
gFileInUseProcess.init(fileInUseBin);
gFileInUseProcess.run(false, args, args.length);
// Give the file in use process time to launch before updating otherwise this
// test can fail intermittently on Windows debug builds.
do_timeout(100, testUpdate);
}
function end_test() {
cleanupUpdaterTest(TEST_ID);
}
function testUpdate() {
let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
let applyToDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX);
// apply the partial mar
let exitValue = runUpdate(TEST_ID);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
gFileInUseProcess.kill();
checkFilesAfterUpdateSuccess(TEST_ID, TEST_FILES);
logTestInfo("testing directory still exists after removal of the last file " +
"in the directory (bug 386760)");
let testDir = do_get_file(TEST_ID + APPLY_TO_DIR_SUFFIX + "/mar_test/2/2_1/", true);
do_check_true(testDir.exists());
logTestInfo("testing tobedeleted directory exists");
let toBeDeletedDir = applyToDir.clone();
toBeDeletedDir.append("tobedeleted");
do_check_true(toBeDeletedDir.exists());
checkCallbackAppLog(TEST_ID);
}