Bug 1526865 - The browser chrome tests should continue instead of fail when the continue file isn't removed. r=mhowell

Reworked the continue file code so the test doesn't fail if the continue file isn't removed. Instead tests will then check if the UI has advanced to the next check and the continue file is removed at the end of the test.
Increases timeouts since some of the tests need longer for verify / TV runs.
Removes skip-if for tests that now pass verify / TV on Linux
Adds an .eslintrc to the test data directory
Modified the sjs files so they pass eslint

Differential Revision: https://phabricator.services.mozilla.com/D19335

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Robert Strong 2019-02-11 19:13:44 +00:00
parent 5f83bb1aed
commit aac226118b
6 changed files with 116 additions and 72 deletions

View File

@ -2,13 +2,22 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
/**
* Server side http server script for application update tests.
*/
// ChromeUtils isn't available in sjs files so disable the eslint rule for it.
/* eslint-disable mozilla/use-chromeutils-import */
// Definitions from test and other files used by the tests
/* global getState */
Cu.import("resource://gre/modules/Services.jsm");
function getTestDataFile(aFilename) {
let file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).get("CurWorkD", Ci.nsIFile);
let file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
let pathParts = REL_PATH_DATA.split("/");
for (let i = 0; i < pathParts.length; ++i) {
file.append(pathParts[i]);
@ -20,26 +29,28 @@ function getTestDataFile(aFilename) {
}
function loadHelperScript(aScriptFile) {
let io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
let scriptSpec = io.newFileURI(aScriptFile).spec;
let scriptloader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
scriptloader.loadSubScript(scriptSpec, this);
let scriptSpec = Services.io.newFileURI(aScriptFile).spec;
Services.scriptloader.loadSubScript(scriptSpec, this);
}
var scriptFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
var scriptFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
scriptFile.initWithPath(getState("__LOCATION__"));
scriptFile = scriptFile.parent;
/* import-globals-from testConstants.js */
scriptFile.append("testConstants.js");
loadHelperScript(scriptFile);
/* import-globals-from ../data/sharedUpdateXML.js */
scriptFile = getTestDataFile("sharedUpdateXML.js");
loadHelperScript(scriptFile);
const SERVICE_URL = URL_HOST + "/" + REL_PATH_DATA + FILE_SIMPLE_MAR;
const BAD_SERVICE_URL = URL_HOST + "/" + REL_PATH_DATA + "not_here.mar";
const SLOW_RESPONSE_INTERVAL = 10;
// A value of 10 caused the tests to intermittently fail on Mac OS X so be
// careful when changing this value.
const SLOW_RESPONSE_INTERVAL = 100;
const MAX_SLOW_RESPONSE_RETRIES = 50;
var gSlowDownloadTimer;
var gSlowCheckTimer;
@ -60,20 +71,25 @@ function handleRequest(aRequest, aResponse) {
// mar will be downloaded asynchronously which will allow the ui to load
// before the download completes.
if (params.slowDownloadMar) {
let retries = 0;
aResponse.processAsync();
aResponse.setHeader("Content-Type", "binary/octet-stream");
aResponse.setHeader("Content-Length", SIZE_SIMPLE_MAR);
var continueFile = getTestDataFile(CONTINUE_DOWNLOAD);
var contents = readFileBytes(getTestDataFile(FILE_SIMPLE_MAR));
gSlowDownloadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
gSlowDownloadTimer.initWithCallback(function(aTimer) {
if (continueFile.exists()) {
let continueFile = getTestDataFile(CONTINUE_DOWNLOAD);
retries++;
if (continueFile.exists() || retries == MAX_SLOW_RESPONSE_RETRIES) {
try {
// If the continue file is in use try again the next time the timer
// fires.
continueFile.remove(false);
// fires unless the retries has reached the value defined by
// MAX_SLOW_RESPONSE_RETRIES in which case let the test remove the
// continue file.
if (retries < MAX_SLOW_RESPONSE_RETRIES) {
continueFile.remove(false);
}
gSlowDownloadTimer.cancel();
aResponse.write(contents);
aResponse.write(readFileBytes(getTestDataFile(FILE_SIMPLE_MAR)));
aResponse.finish();
} catch (e) {
}
@ -114,23 +130,23 @@ function handleRequest(aRequest, aResponse) {
let patches = "";
let url = "";
if (params.useSlowDownloadMar) {
url = URL_HTTP_UPDATE_SJS + "?slowDownloadMar=1"
url = URL_HTTP_UPDATE_SJS + "?slowDownloadMar=1";
} else {
url = params.badURL ? BAD_SERVICE_URL : SERVICE_URL
url = params.badURL ? BAD_SERVICE_URL : SERVICE_URL;
}
if (!params.partialPatchOnly) {
size = SIZE_SIMPLE_MAR + (params.invalidCompleteSize ? "1" : "");
let patchProps = {type: "complete",
url: url,
size: size};
url,
size};
patches += getRemotePatchString(patchProps);
}
if (!params.completePatchOnly) {
size = SIZE_SIMPLE_MAR + (params.invalidPartialSize ? "1" : "");
let patchProps = {type: "partial",
url: url,
size: size};
url,
size};
patches += getRemotePatchString(patchProps);
}
@ -166,15 +182,21 @@ function handleRequest(aRequest, aResponse) {
function respond(aResponse, aParams, aResponseString) {
if (aParams.slowUpdateCheck) {
let retries = 0;
aResponse.processAsync();
var continueFile = getTestDataFile(CONTINUE_CHECK);
gSlowCheckTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
gSlowCheckTimer.initWithCallback(function(aTimer) {
if (continueFile.exists()) {
retries++;
let continueFile = getTestDataFile(CONTINUE_CHECK);
if (continueFile.exists() || retries == MAX_SLOW_RESPONSE_RETRIES) {
try {
// If the continue file is in use try again the next time the timer
// fires.
continueFile.remove(false);
// fires unless the retries has reached the value defined by
// MAX_SLOW_RESPONSE_RETRIES in which case let the test remove the
// continue file.
if (retries < MAX_SLOW_RESPONSE_RETRIES) {
continueFile.remove(false);
}
gSlowCheckTimer.cancel();
aResponse.write(aResponseString);
aResponse.finish();

View File

@ -24,12 +24,8 @@ reason = Windows only feature.
[browser_aboutDialog_fc_check_unsupported.js]
[browser_aboutDialog_fc_downloadAuto.js]
[browser_aboutDialog_fc_downloadAuto_staging.js]
skip-if = (os == "linux" && verify)
reason = Bug 1520672
[browser_aboutDialog_fc_downloadOptIn.js]
[browser_aboutDialog_fc_downloadOptIn_staging.js]
skip-if = (os == "linux" && verify)
reason = Bug 1520672
[browser_aboutDialog_fc_patch_completeBadSize.js]
[browser_aboutDialog_fc_patch_partialBadSize.js]
[browser_aboutDialog_fc_patch_partialBadSize_complete.js]
@ -51,12 +47,8 @@ reason = Windows only feature.
[browser_aboutPrefs_fc_check_unsupported.js]
[browser_aboutPrefs_fc_downloadAuto.js]
[browser_aboutPrefs_fc_downloadAuto_staging.js]
skip-if = (os == "linux" && verify)
reason = Bug 1520672
[browser_aboutPrefs_fc_downloadOptIn.js]
[browser_aboutPrefs_fc_downloadOptIn_staging.js]
skip-if = (os == "linux" && verify)
reason = Bug 1520672
[browser_aboutPrefs_fc_patch_completeBadSize.js]
[browser_aboutPrefs_fc_patch_partialBadSize.js]
[browser_aboutPrefs_fc_patch_partialBadSize_complete.js]

View File

@ -37,6 +37,9 @@ let gOriginalUpdateAutoValue = null;
// the test's onload function.
gDebugTest = true;
// This is to accommodate the TV task which runs the tests with --verify.
requestLongerTimeout(10);
/**
* Common tasks to perform for all tests before each one has started.
*/
@ -88,27 +91,27 @@ registerCleanupFunction(async () => {
* CONTINUE_DOWNLOAD
* CONTINUE_STAGING
* @return Promise
* Resolves when the file is deleted.
* Rejects if timeout is exceeded or condition ever throws.
* Resolves when the file is deleted or if the file is not deleted when
* the check for the file's existence times out. If the file isn't
* deleted before the check for the file's existence times out it will
* be deleted when the test ends so it doesn't affect tests that run
* after the test that created the continue file.
* @throws If the file already exists.
*/
async function continueFileHandler(leafName) {
// The default number of retries of 50 in TestUtils.waitForCondition is
// sufficient for test http server requests. The total time to wait with the
// default interval of 100 is approximately 5 seconds.
let retries = undefined;
// The total time to wait with 200 retries and the default interval of 100 is
// approximately 20 seconds.
let interval = 100;
let retries = 200;
let continueFile;
if (leafName == CONTINUE_STAGING) {
debugDump("creating " + leafName + " file for slow update staging");
// Use 100 retries for staging requests to lessen the likelihood of tests
// intermittently failing on debug builds due to launching the updater. The
// total time to wait with the default interval of 100 is approximately 10
// seconds. The test updater uses the same values.
retries = 100;
continueFile = getUpdateDirFile(DIR_PATCH);
// The total time to wait with 600 retries and an interval of 200 is
// approximately 120 seconds.
interval = 200;
retries = 600;
continueFile = getGREBinDir();
continueFile.append(leafName);
} else {
debugDump("creating " + leafName + " file for slow http server requests");
continueFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
let continuePath = REL_PATH_DATA + leafName;
let continuePathParts = continuePath.split("/");
@ -120,6 +123,7 @@ async function continueFileHandler(leafName) {
throw new Error("The continue file should not exist, path: " +
continueFile.path);
}
debugDump("Creating continue file, path: " + continueFile.path);
continueFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
// If for whatever reason the continue file hasn't been removed when a test
// has finished remove it during cleanup so it doesn't affect tests that run
@ -131,10 +135,14 @@ async function continueFileHandler(leafName) {
continueFile.remove(false);
}
});
return BrowserTestUtils.waitForCondition(() =>
(!continueFile.exists()),
return BrowserTestUtils.waitForCondition(() => (
!continueFile.exists()),
"Waiting for file to be deleted, path: " + continueFile.path,
undefined, retries);
interval, retries
).catch(e => {
logTestInfo("Continue file was not removed after checking " +
retries + " times, path: " + continueFile.path);
});
}
/**
@ -640,7 +648,8 @@ function runAboutDialogUpdateTest(updateParams, backgroundUpdate, steps) {
await BrowserTestUtils.waitForCondition(() =>
(updateDeck.selectedPanel && updateDeck.selectedPanel.id == panelId),
"Waiting for expected panel ID - got: \"" +
updateDeck.selectedPanel.id + "\", expected \"" + panelId + "\"");
updateDeck.selectedPanel.id + "\", expected \"" + panelId + "\"",
undefined, 200);
let selectedPanel = updateDeck.selectedPanel;
is(selectedPanel.id, panelId, "The panel ID should equal " + panelId);
@ -755,7 +764,8 @@ function runAboutPrefsUpdateTest(updateParams, backgroundUpdate, steps) {
await ContentTaskUtils.waitForCondition(() =>
(updateDeck.selectedPanel && updateDeck.selectedPanel.id == panelId),
"Waiting for expected panel ID - got: \"" +
updateDeck.selectedPanel.id + "\", expected \"" + panelId + "\"");
updateDeck.selectedPanel.id + "\", expected \"" + panelId + "\"",
undefined, 200);
is(updateDeck.selectedPanel.id, panelId,
"The panel ID should equal " + panelId);
});

View File

@ -2,13 +2,22 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
/**
* Server side http server script for application update tests.
*/
// ChromeUtils isn't available in sjs files so disable the eslint rule for it.
/* eslint-disable mozilla/use-chromeutils-import */
// Definitions from files used by this file
/* global getState */
Cu.import("resource://gre/modules/Services.jsm");
function getTestDataFile(aFilename) {
let file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).get("CurWorkD", Ci.nsIFile);
let file = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
let pathParts = REL_PATH_DATA.split("/");
for (let i = 0; i < pathParts.length; ++i) {
file.append(pathParts[i]);
@ -20,19 +29,18 @@ function getTestDataFile(aFilename) {
}
function loadHelperScript(aScriptFile) {
let io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
let scriptSpec = io.newFileURI(aScriptFile).spec;
let scriptloader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
scriptloader.loadSubScript(scriptSpec, this);
let scriptSpec = Services.io.newFileURI(aScriptFile).spec;
Services.scriptloader.loadSubScript(scriptSpec, this);
}
var scriptFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
var scriptFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
scriptFile.initWithPath(getState("__LOCATION__"));
scriptFile = scriptFile.parent;
/* import-globals-from testConstants.js */
scriptFile.append("testConstants.js");
loadHelperScript(scriptFile);
/* import-globals-from ../data/sharedUpdateXML.js */
scriptFile = getTestDataFile("sharedUpdateXML.js");
loadHelperScript(scriptFile);
@ -113,16 +121,16 @@ function handleRequest(aRequest, aResponse) {
if (!params.partialPatchOnly) {
size = SIZE_SIMPLE_MAR + (params.invalidCompleteSize ? "1" : "");
let patchProps = {type: "complete",
url: url,
size: size};
url,
size};
patches += getRemotePatchString(patchProps);
}
if (!params.completePatchOnly) {
size = SIZE_SIMPLE_MAR + (params.invalidPartialSize ? "1" : "");
let patchProps = {type: "partial",
url: url,
size: size};
url,
size};
patches += getRemotePatchString(patchProps);
}

View File

@ -0,0 +1,11 @@
// The files in this directory are shared by mochitest-browser-chrome,
// mochitest-chrome, and xpcshell tests. At this time it is simpler to just use
// plugin:mozilla/xpcshell-test for eslint.
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/xpcshell-test"
]
};

View File

@ -2473,23 +2473,24 @@ static void UpdateThreadFunc(void *param) {
NS_tchar continueFilePath[MAXPATHLEN] = {NS_T('\0')};
NS_tsnprintf(continueFilePath,
sizeof(continueFilePath) / sizeof(continueFilePath[0]),
NS_T("%s/continueStaging"), gPatchDirPath);
NS_T("%s/continueStaging"), gInstallDirPath);
// Use 100 retries for staging requests to lessen the likelihood of
// tests intermittently failing on debug builds due to launching the
// updater. The total time to wait with the default interval of 100 ms
// is approximately 10 seconds. The tests use the same values.
const int max_retries = 100;
int retries = 1;
// is approximately 5 seconds. The total time for tests is longer to
// account for the extra time it takes for the updater to launch.
const int max_retries = 50;
int retries = 0;
while (retries++ < max_retries) {
# ifdef XP_WIN
Sleep(100);
# else
usleep(100000);
# endif
// Continue after the continue file exists and it is successfully
// removed.
if (!NS_taccess(continueFilePath, F_OK) &&
!NS_tremove(continueFilePath)) {
// Continue after the continue file exists.
if (!NS_taccess(continueFilePath, F_OK)) {
// Remove the continue file.
NS_tremove(continueFilePath);
break;
}
}