Use update-staged notification and only copy files that are necessary - Fix for Bug 909489 - Intermittent test_0202_app_launch_apply_update_dirlocked.js | Test timed out | test failed (with xpcshell return code: 1). r=bbondy

This commit is contained in:
Robert Strong 2013-09-06 08:58:57 -07:00
Родитель dc7ba6c33f
Коммит bead553204
7 изменённых файлов: 108 добавлений и 131 удалений

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

@ -115,7 +115,7 @@ const TEST_HELPER_TIMEOUT = 100;
const TEST_CHECK_TIMEOUT = 100;
// How many of TEST_CHECK_TIMEOUT to wait before we abort the test.
const MAX_TIMEOUT_RUNS = 300;
const MAX_TIMEOUT_RUNS = 1000;
// Use a copy of the main application executable for the test to avoid main
// executable in use errors.
@ -480,8 +480,8 @@ if (IS_WIN) {
}
/**
* Copies a directory and its children. First it tries nsIFile::CopyTo on the
* source directory and if that fails it will fall back to recursing.
* Copies the minimum files required by the application to be able to process
* an application update when the application is launched for a test.
*
* @param aSrcDir
* nsIFile for the source directory to be copied from.
@ -490,17 +490,7 @@ if (IS_WIN) {
* @param aDestLeafName
* the destination directory name.
*/
function copyDirRecursive(aSrcDir, aDestDir, aDestLeafName) {
try {
aSrcDir.copyTo(aDestDir, aDestLeafName);
return;
}
catch (e) {
logTestInfo("copyTo error - src path: " + aSrcDir.path + ", dest path: " +
aDestDir.path + ", dir name: " + aDestLeafName +
", exception: " + e);
}
function copyMinimumAppFiles(aSrcDir, aDestDir, aDestLeafName) {
let destDir = aDestDir.clone();
destDir.append(aDestLeafName);
if (!destDir.exists()) {
@ -513,47 +503,43 @@ function copyDirRecursive(aSrcDir, aDestDir, aDestLeafName) {
do_throw(e);
}
}
var dirEntries = aSrcDir.directoryEntries;
while (dirEntries.hasMoreElements()) {
let entry = dirEntries.getNext().QueryInterface(AUS_Ci.nsIFile);
if (entry.isDirectory()) {
copyDirRecursive(entry, destDir, entry.leafName);
// Required files for the application or the test that aren't listed in the
// dependentlibs.list file.
let fileLeafNames = [APP_BIN_NAME + APP_BIN_SUFFIX, UPDATER_BIN_FILE,
FILE_UPDATE_SETTINGS_INI, "application.ini",
"dependentlibs.list"];
// Read the dependent libs file leafnames from the dependentlibs.list file
// into the array.
let deplibsFile = aSrcDir.clone();
deplibsFile.append("dependentlibs.list");
let istream = AUS_Cc["@mozilla.org/network/file-input-stream;1"].
createInstance(AUS_Ci.nsIFileInputStream);
istream.init(deplibsFile, 0x01, 0444, 0);
istream.QueryInterface(AUS_Ci.nsILineInputStream);
let hasMore;
let line = {};
do {
hasMore = istream.readLine(line);
fileLeafNames.push(line.value);
} while(hasMore);
istream.close();
fileLeafNames.forEach(function CMAF_FLN_FE(aLeafName) {
let srcFile = aSrcDir.clone();
srcFile.append(aLeafName);
try {
srcFile.copyTo(destDir, aLeafName);
}
else {
let destFile = destDir.clone();
destFile.append(entry.leafName);
if (destFile.exists()) {
try {
destFile.remove(false);
}
catch (e) {
logTestInfo("unable to remove file, path: " + destFile.path +
", exception: " + e);
let bakFile = destDir.clone();
bakFile.append(entry.leafName + ".bak");
logTestInfo("attempting moveTo of file, src path: " + destFile.path +
", dest path: " + bakFile.path + ", exception: " + e);
try {
destFile.moveTo(destDir, bakFile.leafName);
}
catch (e) {
logTestInfo("unable to move file, src path: " + destFile.path +
", dest path: " + bakFile.path + ", exception: " + e);
do_throw(e);
}
}
}
try {
entry.copyTo(destDir, entry.leafName);
}
catch (e) {
logTestInfo("unable to copy file, src path: " + entry.path +
", dest path: " + destFile.path + ", exception: " + e);
do_throw(e);
}
catch (e) {
logTestInfo("unable to copy file, src path: " + srcFile.path +
", dest path: " + destFile.path + ", exception: " + e);
do_throw(e);
}
}
});
}
/**
@ -722,7 +708,7 @@ function shouldRunServiceTest(aFirstTest) {
// service should be anything but stopped, so be strict here and throw
// an error.
if (aFirstTest && process.exitValue != 0) {
do_throw("First test, check for service stopped state returned error " +
do_throw("First test, check for service stopped state returned error " +
process.exitValue);
}
@ -779,7 +765,7 @@ function attemptServiceInstall() {
if (isVistaOrHigher) {
return;
}
let binDir = getGREDir();
let installerFile = binDir.clone();
installerFile.append(MAINTENANCE_SERVICE_INSTALLER_BIN_FILE);
@ -830,13 +816,13 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus,
waitForApplicationStop("maintenanceservice.exe");
}
function waitForServiceStop(aFailTest) {
waitServiceApps();
waitServiceApps();
logTestInfo("Waiting for service to stop if necessary...");
// Use the helper bin to ensure the service is stopped. If not
// stopped then wait for the service to be stopped (at most 120 seconds)
let helperBin = do_get_file(HELPER_BIN_FILE);
let helperBinArgs = ["wait-for-service-stop",
"MozillaMaintenance",
let helperBinArgs = ["wait-for-service-stop",
"MozillaMaintenance",
"120"];
let helperBinProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
@ -851,22 +837,22 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus,
do_throw("maintenance service did not stop, last state: " +
helperBinProcess.exitValue + ". Forcing test failure.");
} else {
logTestInfo("maintenance service did not stop, last state: " +
logTestInfo("maintenance service did not stop, last state: " +
helperBinProcess.exitValue + ". May cause failures.");
}
} else {
logTestInfo("Service stopped.");
}
waitServiceApps();
waitServiceApps();
}
function waitForApplicationStop(application) {
logTestInfo("Waiting for " + application + " to stop if " +
logTestInfo("Waiting for " + application + " to stop if " +
"necessary...");
// Use the helper bin to ensure the application is stopped.
// Use the helper bin to ensure the application is stopped.
// If not, then wait for it to be stopped (at most 120 seconds)
let helperBin = do_get_file(HELPER_BIN_FILE);
let helperBinArgs = ["wait-for-application-exit",
application,
let helperBinArgs = ["wait-for-application-exit",
application,
"120"];
let helperBinProcess = AUS_Cc["@mozilla.org/process/util;1"].
createInstance(AUS_Ci.nsIProcess);
@ -957,8 +943,8 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus,
setEnvironment();
// There is a security check done by the service to make sure the updater
// we are executing is the same as the one in the apply-to dir.
// There is a security check done by the service to make sure the updater
// we are executing is the same as the one in the apply-to dir.
// To make sure they match from tests we copy updater.exe to the apply-to dir.
copyBinToApplyToDir(UPDATER_BIN_FILE);
@ -998,13 +984,13 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus,
// status will probably always be equal to STATE_APPLYING but there is a
// race condition where it would be possible on slower machines where status
// could be equal to STATE_PENDING_SVC.
if (status == STATE_APPLYING ||
if (status == STATE_APPLYING ||
status == STATE_PENDING_SVC) {
logTestInfo("Still waiting to see the " + aExpectedStatus +
" status, got " + status + " for now...");
return;
}
// Make sure all of the logs are written out.
waitForServiceStop(false);
@ -1022,7 +1008,7 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus,
if (aCheckSvcLog) {
checkServiceLogs(svcOriginalLog);
}
}
aCallback();
}
@ -1541,7 +1527,7 @@ function checkCallbackServiceLog() {
let logFile = AUS_Cc["@mozilla.org/file/local;1"].createInstance(AUS_Ci.nsILocalFile);
logFile.initWithPath(gServiceLaunchedCallbackLog);
let logContents = readFile(logFile);
// 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
@ -1697,7 +1683,7 @@ function checkFilesInDirRecursive(aDir, aCallback) {
}
/**
* Sets up the bare bones XMLHttpRequest implementation below.
* Sets up the bare bones XMLHttpRequest implementation below.
*
* @param callback
* The callback function that will call the nsIDomEventListener's
@ -1946,7 +1932,7 @@ function createAppInfo(id, name, version, platformVersion) {
throw AUS_Cr.NS_ERROR_NO_INTERFACE;
}
};
var XULAppInfoFactory = {
createInstance: function (outer, iid) {
if (outer == null)
@ -2191,7 +2177,7 @@ function adjustPathsOnWindows() {
tmpDir.createUnique(tmpDir.DIRECTORY_TYPE, 0755);
let procDir = getCurrentProcessDir();
logTestInfo("start - copy the process directory");
copyDirRecursive(procDir, tmpDir, "bin");
copyMinimumAppFiles(procDir, tmpDir, "bin");
logTestInfo("finish - copy the process directory");
let newDir = tmpDir.clone();
newDir.append("bin");
@ -2333,6 +2319,19 @@ let gTimerCallback = {
QueryInterface: XPCOMUtils.generateQI([AUS_Ci.nsITimerCallback])
};
/**
* The update-staged observer for the call to nsIUpdateProcessor:processUpdate.
*/
let gUpdateStagedObserver = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == "update-staged") {
Services.obs.removeObserver(gUpdateStagedObserver, "update-staged");
checkUpdateApplied();
}
},
QueryInterface: XPCOMUtils.generateQI([AUS_Ci.nsIObserver])
};
// Environment related globals
let gShouldResetEnv = undefined;
let gAddedEnvXRENoWindowsCrashDialog = false;

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

@ -24,7 +24,6 @@ const APP_TIMER_TIMEOUT = 120000;
let gAppTimer;
let gProcess;
let gActiveUpdate;
let gTimeoutRuns = 0;
function run_test() {
@ -91,10 +90,6 @@ function run_test() {
let mar = do_get_file("data/simple.mar");
mar.copyTo(updatesPatchDir, FILE_UPDATE_ARCHIVE);
reloadUpdateManagerData();
gActiveUpdate = gUpdateManager.activeUpdate;
do_check_true(!!gActiveUpdate);
// Backup the updater.ini file if it exists by moving it. This prevents the
// post update executable from being launched if it is specified.
let updaterIni = processDir.clone();
@ -113,12 +108,15 @@ function run_test() {
updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
reloadUpdateManagerData();
do_check_true(!!gUpdateManager.activeUpdate);
Services.obs.addObserver(gUpdateStagedObserver, "update-staged", false);
// Initiate a background update.
AUS_Cc["@mozilla.org/updates/update-processor;1"].
createInstance(AUS_Ci.nsIUpdateProcessor).
processUpdate(gActiveUpdate);
checkUpdateApplied();
processUpdate(gUpdateManager.activeUpdate);
}
function switchApp() {

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

@ -24,7 +24,6 @@ const TEST_ID = "0202";
// launching a post update executable.
const FILE_UPDATER_INI_BAK = "updater.ini.bak";
let gActiveUpdate;
let gTimeoutRuns = 0;
function run_test() {
@ -33,17 +32,6 @@ function run_test() {
return;
}
if (IS_WIN) {
var version = AUS_Cc["@mozilla.org/system-info;1"]
.getService(AUS_Ci.nsIPropertyBag2)
.getProperty("version");
var isVistaOrHigher = (parseFloat(version) >= 6.0);
if (!isVistaOrHigher) {
logTestInfo("Disabled on Windows XP due to bug 909489");
return;
}
}
do_test_pending();
do_register_cleanup(end_test);
@ -126,8 +114,9 @@ function run_test() {
writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
reloadUpdateManagerData();
gActiveUpdate = gUpdateManager.activeUpdate;
do_check_true(!!gActiveUpdate);
do_check_true(!!gUpdateManager.activeUpdate);
Services.obs.addObserver(gUpdateStagedObserver, "update-staged", false);
setEnvironment();
@ -135,12 +124,11 @@ function run_test() {
logTestInfo("update preparation completed - calling processUpdate");
AUS_Cc["@mozilla.org/updates/update-processor;1"].
createInstance(AUS_Ci.nsIUpdateProcessor).
processUpdate(gActiveUpdate);
processUpdate(gUpdateManager.activeUpdate);
resetEnvironment();
logTestInfo("processUpdate completed - calling checkUpdateApplied");
checkUpdateApplied();
logTestInfo("processUpdate completed - waiting for update-staged notification");
}
function end_test() {

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

@ -32,7 +32,6 @@ Components.utils.import("resource://gre/modules/ctypes.jsm");
let gAppTimer;
let gProcess;
let gActiveUpdate;
let gTimeoutRuns = 0;
function run_test() {
@ -99,10 +98,6 @@ function run_test() {
let mar = do_get_file("data/simple.mar");
mar.copyTo(updatesPatchDir, FILE_UPDATE_ARCHIVE);
reloadUpdateManagerData();
gActiveUpdate = gUpdateManager.activeUpdate;
do_check_true(!!gActiveUpdate);
// Backup the updater.ini file if it exists by moving it. This prevents the
// post update executable from being launched if it is specified.
let updaterIni = processDir.clone();
@ -121,12 +116,15 @@ function run_test() {
updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
reloadUpdateManagerData();
do_check_true(!!gUpdateManager.activeUpdate);
Services.obs.addObserver(gUpdateStagedObserver, "update-staged", false);
// Initiate a background update.
AUS_Cc["@mozilla.org/updates/update-processor;1"].
createInstance(AUS_Ci.nsIUpdateProcessor).
processUpdate(gActiveUpdate);
checkUpdateApplied();
processUpdate(gUpdateManager.activeUpdate);
}
function switchApp() {

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

@ -24,7 +24,6 @@ const APP_TIMER_TIMEOUT = 120000;
let gAppTimer;
let gProcess;
let gActiveUpdate;
let gTimeoutRuns = 0;
function run_test() {
@ -90,12 +89,6 @@ function run_test() {
let mar = do_get_file("data/simple.mar");
mar.copyTo(updatesPatchDir, FILE_UPDATE_ARCHIVE);
reloadUpdateManagerData();
gActiveUpdate = gUpdateManager.activeUpdate;
do_check_true(!!gActiveUpdate);
setEnvironment();
// Backup the updater.ini file if it exists by moving it. This prevents the
// post update executable from being launched if it is specified.
//XXX disabled until bug 820933 and bug 820934 are fixed
@ -117,14 +110,19 @@ if (0) {
updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
reloadUpdateManagerData();
do_check_true(!!gUpdateManager.activeUpdate);
Services.obs.addObserver(gUpdateStagedObserver, "update-staged", false);
setEnvironment();
// Initiate a background update.
AUS_Cc["@mozilla.org/updates/update-processor;1"].
createInstance(AUS_Ci.nsIUpdateProcessor).
processUpdate(gActiveUpdate);
processUpdate(gUpdateManager.activeUpdate);
resetEnvironment();
checkUpdateApplied();
}
function switchApp() {

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

@ -24,7 +24,6 @@ const TEST_ID = "0202_svc";
// launching a post update executable.
const FILE_UPDATER_INI_BAK = "updater.ini.bak";
let gActiveUpdate;
let gTimeoutRuns = 0;
function run_test() {
@ -112,19 +111,18 @@ function run_test() {
writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
reloadUpdateManagerData();
gActiveUpdate = gUpdateManager.activeUpdate;
do_check_true(!!gActiveUpdate);
do_check_true(!!gUpdateManager.activeUpdate);
Services.obs.addObserver(gUpdateStagedObserver, "update-staged", false);
setEnvironment();
// Initiate a background update.
AUS_Cc["@mozilla.org/updates/update-processor;1"].
createInstance(AUS_Ci.nsIUpdateProcessor).
processUpdate(gActiveUpdate);
processUpdate(gUpdateManager.activeUpdate);
resetEnvironment();
checkUpdateApplied();
}
function end_test() {

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

@ -32,7 +32,6 @@ Components.utils.import("resource://gre/modules/ctypes.jsm");
let gAppTimer;
let gProcess;
let gActiveUpdate;
let gTimeoutRuns = 0;
function run_test() {
@ -98,12 +97,6 @@ function run_test() {
let mar = do_get_file("data/simple.mar");
mar.copyTo(updatesPatchDir, FILE_UPDATE_ARCHIVE);
reloadUpdateManagerData();
gActiveUpdate = gUpdateManager.activeUpdate;
do_check_true(!!gActiveUpdate);
setEnvironment();
// Backup the updater.ini file if it exists by moving it. This prevents the
// post update executable from being launched if it is specified.
let updaterIni = processDir.clone();
@ -122,14 +115,19 @@ function run_test() {
updateSettingsIni.append(FILE_UPDATE_SETTINGS_INI);
writeFile(updateSettingsIni, UPDATE_SETTINGS_CONTENTS);
reloadUpdateManagerData();
do_check_true(!!gUpdateManager.activeUpdate);
Services.obs.addObserver(gUpdateStagedObserver, "update-staged", false);
setEnvironment();
// Initiate a background update.
AUS_Cc["@mozilla.org/updates/update-processor;1"].
createInstance(AUS_Ci.nsIUpdateProcessor).
processUpdate(gActiveUpdate);
processUpdate(gUpdateManager.activeUpdate);
resetEnvironment();
checkUpdateApplied();
}
function switchApp() {