Bug 606410 - add tests for calling the callback app and the arguments passed to it. r=dtownsend, a=tests

This commit is contained in:
Robert Strong 2010-11-06 23:41:49 -07:00
Родитель 09a9280d1b
Коммит 51aef17342
7 изменённых файлов: 340 добавлений и 89 удалений

Просмотреть файл

@ -63,6 +63,7 @@ DIRS = \
CPPSRCS = \
TestAUSReadStrings.cpp \
TestAUSHelper.cpp \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
@ -116,3 +117,6 @@ endif # ANDROID
libs:: unit/head_update.js.in
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) $^ > $(TESTROOT)/unit/head_update.js
libs::
$(INSTALL) TestAUSHelper$(BIN_SUFFIX) $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit

Просмотреть файл

@ -0,0 +1,72 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifdef XP_WIN
# include <windows.h>
# include <direct.h>
# include <io.h>
typedef WCHAR NS_tchar;
# define NS_main wmain
# define NS_T(str) L ## str
# define NS_tsnprintf(dest, count, fmt, ...) \
int _count = count - 1; \
_snwprintf(dest, _count, fmt, ##__VA_ARGS__); \
dest[_count] = L'\0';
# define NS_tfopen _wfopen
# define LOG_S "%S"
#else
# include <unistd.h>
# define NS_main main
typedef char NS_tchar;
# define NS_T(str) str
# define NS_tsnprintf snprintf
# define NS_tfopen fopen
# define LOG_S "%s"
#endif
#include <stdio.h>
#ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# elif defined(MAX_PATH)
# define MAXPATHLEN MAX_PATH
# elif defined(_MAX_PATH)
# define MAXPATHLEN _MAX_PATH
# elif defined(CCHMAXPATH)
# define MAXPATHLEN CCHMAXPATH
# else
# define MAXPATHLEN 1024
# endif
#endif
int NS_main(int argc, NS_tchar **argv)
{
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
FILE* logFP = NS_tfopen(logFilePath, NS_T("w"));
fprintf(logFP, "executed\n");
int i;
for (i = 1; i < argc; ++i) {
fprintf(logFP, LOG_S "\n", argv[i]);
}
fclose(logFP);
logFP = NULL;
return 0;
}

Просмотреть файл

@ -126,15 +126,20 @@ 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.
*
* @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.
* @returns The exit value returned from the updater binary.
* @param aCallbackApp (optional)
* The application to launch after the update.
* @param aAppArgs (optional)
* The arguments to pass to the callback application.
* @return The exit value returned from the updater binary.
*/
function runUpdate(aUpdater, aUpdatesDir, aApplyToDir) {
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
@ -158,10 +163,24 @@ function runUpdate(aUpdater, aUpdatesDir, aApplyToDir) {
if (/ /.test(applyToPath))
applyToPath = '"' + applyToPath + '"';
var args;
if (aCallbackApp) {
var cwdPath = aCallbackApp.parent.parent.path;
if (/ /.test(cwdPath))
cwdPath = '"' + cwdPath + '"';
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"].
createInstance(AUS_Ci.nsIProcess);
process.init(updateBin);
var args = [updatesDirPath, applyToPath];
process.run(true, args, args.length);
return process.exitValue;
}
@ -286,6 +305,7 @@ const updateCheckListener = {
/**
* Helper for starting the http server used by the tests
*
* @param aRelativeDirName
* The directory name to register relative to
* toolkit/mozapps/update/test/unit/
@ -314,6 +334,7 @@ function stop_httpserver(callback) {
/**
* Creates an nsIXULAppInfo
*
* @param id
* The ID of the test application
* @param name
@ -392,6 +413,8 @@ const APP_BIN_SUFFIX = "-bin";
const APP_BIN_SUFFIX = "@BIN_SUFFIX@";
#endif
const BIN_SUFFIX = "@BIN_SUFFIX@";
#ifdef XP_WIN
const IS_WIN = true;
#else

Просмотреть файл

@ -40,6 +40,15 @@
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"];
// 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 = [
{
@ -89,11 +98,6 @@ var gTestFiles = [
comparePerms : 0644
}];
// 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;
function run_test() {
if (IS_ANDROID) {
logTestInfo("this test is not applicable to Android... returning early");
@ -123,6 +127,22 @@ function run_test() {
"mar file");
do_check_false(applyToDir.exists());
// 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];
@ -153,6 +173,25 @@ function run_test() {
}
}
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);
// 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).
@ -169,34 +208,18 @@ function run_test() {
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append("updater.exe");
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
updater = binDir.clone();
updater.append("updater");
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
do_throw("Unable to find updater binary!");
}
}
// 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");
}
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);
var exitValue = runUpdate(updater, updatesDir, applyToDir, relaunchApp,
RELAUNCH_ARGS);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a complete mar");
do_check_eq(exitValue, 0);
@ -262,7 +285,7 @@ function run_test() {
do_check_neq(getFileExtension(entry), "patch");
}
do_test_finished();
check_app_launch_log();
}
function end_test() {
@ -289,3 +312,30 @@ function end_test() {
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();
}

Просмотреть файл

@ -37,8 +37,18 @@
*/
/* 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"];
// 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 = [
{
@ -106,11 +116,6 @@ var gTestFiles = [
comparePerms : 0644
}];
// 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;
function run_test() {
if (IS_ANDROID) {
logTestInfo("this test is not applicable to Android... returning early");
@ -140,6 +145,22 @@ function run_test() {
"mar file");
do_check_false(applyToDir.exists());
// 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++) {
@ -171,6 +192,25 @@ function run_test() {
}
}
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);
// 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).
@ -187,35 +227,18 @@ function run_test() {
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append("updater.exe");
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
updater = binDir.clone();
updater.append("updater");
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
do_throw("Unable to find updater binary!");
}
}
// 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");
}
updatesDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
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);
var exitValue = runUpdate(updater, updatesDir, applyToDir, relaunchApp,
RELAUNCH_ARGS);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
@ -286,7 +309,7 @@ function run_test() {
do_check_neq(getFileExtension(entry), "patch");
}
do_test_finished();
check_app_launch_log();
}
function end_test() {
@ -313,3 +336,30 @@ function end_test() {
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();
}

Просмотреть файл

@ -40,6 +40,11 @@
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"];
var gTestFiles = [
{
@ -118,6 +123,22 @@ function run_test() {
"mar file");
do_check_false(applyToDir.exists());
// 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++) {
@ -149,6 +170,25 @@ function run_test() {
}
}
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);
// 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).
@ -170,35 +210,18 @@ function run_test() {
updater.append("updater.app");
if (!updater.exists()) {
updater = binDir.clone();
updater.append("updater.exe");
updater.append(UPDATER_BIN_FILE);
if (!updater.exists()) {
updater = binDir.clone();
updater.append("updater");
if (!updater.exists()) {
do_throw("Unable to find updater binary!");
}
do_throw("Unable to find updater binary!");
}
}
// 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");
}
updatesDir.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
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);
var exitValue = runUpdate(updater, updatesDir, applyToDir, relaunchApp,
RELAUNCH_ARGS);
logTestInfo("testing updater binary process exitValue for success when " +
"applying a partial mar");
do_check_eq(exitValue, 0);
@ -259,7 +282,7 @@ function run_test() {
do_check_neq(getFileExtension(entry), "patch");
}
do_test_finished();
check_app_launch_log();
}
function end_test() {
@ -286,3 +309,30 @@ function end_test() {
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();
}

Просмотреть файл

@ -178,16 +178,18 @@ function run_test() {
mar.copyTo(updatesPatchDir, FILE_UPDATE_ARCHIVE);
// Backup the updater.ini
let updaterINI = processDir.clone();
updaterINI.append(FILE_UPDATER_INI);
updaterINI.moveTo(processDir, FILE_UPDATER_INI_BAK);
let updaterIni = processDir.clone();
updaterIni.append(FILE_UPDATER_INI);
updaterIni.moveTo(processDir, FILE_UPDATER_INI_BAK);
// Create a new updater.ini to avoid applications that provide a post update
// executable.
updaterINI = processDir.clone();
updaterINI.append(FILE_UPDATER_INI);
writeFile(updaterINI, "[Strings]\n" +
"Title=Update Test\n" +
"Info=XPCShell Application Update Test\n");
let updaterIniContents = "[Strings]\n" +
"Title=Update Test\n" +
"Info=Application Update XPCShell Test - " +
"test_0200_general.js\n";
updaterIni = processDir.clone();
updaterIni.append(FILE_UPDATER_INI);
writeFile(updaterIni, updaterIniContents);
let launchBin = getLaunchBin();
let args = getProcessArgs();
@ -228,9 +230,9 @@ function end_test() {
let processDir = getCurrentProcessDir();
// Restore the backed up updater.ini
let updaterINI = processDir.clone();
updaterINI.append(FILE_UPDATER_INI_BAK);
updaterINI.moveTo(processDir, FILE_UPDATER_INI);
let updaterIni = processDir.clone();
updaterIni.append(FILE_UPDATER_INI_BAK);
updaterIni.moveTo(processDir, FILE_UPDATER_INI);
if (IS_WIN) {
// Remove the copy of the application executable used for the test on