Bug 1214058: Part 2 - Run add-on update tests against comparable JSON and RDF manifests. r=Mossop

I tried to keep the changes to existing tests as minimal as
possible. There were a few exceptions, though:

* test_update_ignorecompat.js was completely broken. I couldn't
  figure out why it was suddenly failing after I changed it to use
  `add_test`, and it turned out that it had been failing all along,
  but in a way that the harness didn't pick up.

* I changed most of the `do_throw` in update callbacks to `ok(false`
  because it took me about an hour to figure out where the test was
  failing when I hit one of them.

* I made some changes to sync `test_update.js` and `test_update_ignorecompat.js`
  where one appeared to have been changed without updating the
  other.

* I made `promiseFindAddonUpdates` a bit more generic, because I was
  planning to convert most of `test_update.js` to use it, rather
  than nested callbacks. I changed my mind a quarter of the way
  through, but decided to keep the changes, since they'll probably
  be useful elsewhere.
This commit is contained in:
Kris Maglione 2015-10-19 09:18:42 -07:00
parent 7ffbc9e953
commit 3767292a88
11 changed files with 2410 additions and 2126 deletions

View File

@ -0,0 +1,215 @@
{
"addons": {
"addon1@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_min_version": "1"
}
}
},
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "2",
"strict_min_version": "2"
}
}
},
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update.xpi",
"update_info_url": "http://example.com/updateInfo.xhtml",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_min_version": "1"
}
}
}
]
},
"addon2@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "1"
}
}
}
]
},
"addon2@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "1"
}
}
}
]
},
"addon3@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "3",
"advisory_max_version": "3"
}
}
}
]
},
"addon4@tests.mozilla.org": {
"updates": [
{
"version": "5.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "0"
}
}
}
]
},
"addon7@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "1"
}
}
}
]
},
"addon8@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update8.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "1"
}
}
}
]
},
"addon9@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_2.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "1"
}
}
},
{
"_comment_": "Incompatible when strict compatibility is enabled",
"version": "3.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_3.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.9",
"advisory_max_version": "0.9"
}
}
},
{
"_comment_": "Incompatible due to compatibility override",
"version": "4.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_4.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.9",
"advisory_max_version": "0.9"
}
}
},
{
"_comment_": "Addon for future version of app",
"version": "4.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_5.xpi",
"applications": {
"gecko": {
"strict_min_version": "5",
"advisory_max_version": "6"
}
}
}
]
},
"addon10@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"update_link": "http://localhost:%PORT%/addons/test_update10.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"advisory_max_version": "0.4"
}
}
}
]
},
"addon11@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update11.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"strict_max_version": "0.2"
}
}
}
]
},
"addon12@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update12.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "1"
}
}
}
]
}
}
}

View File

@ -1920,18 +1920,48 @@ function promiseAddonByID(aId) {
*/
function promiseFindAddonUpdates(addon, reason = AddonManager.UPDATE_WHEN_PERIODIC_UPDATE) {
return new Promise((resolve, reject) => {
let result = {};
addon.findUpdates({
install: null,
onUpdateAvailable: function(addon, install) {
this.install = install;
onNoCompatibilityUpdateAvailable: function(addon2) {
if ("compatibilityUpdate" in result) {
do_throw("Saw multiple compatibility update events");
}
equal(addon, addon2);
addon.compatibilityUpdate = false;
},
onUpdateFinished: function(addon, error) {
if (error == AddonManager.UPDATE_STATUS_NO_ERROR)
resolve(this.install);
else
reject(error);
onCompatibilityUpdateAvailable: function(addon2) {
if ("compatibilityUpdate" in result) {
do_throw("Saw multiple compatibility update events");
}
equal(addon, addon2);
addon.compatibilityUpdate = true;
},
onNoUpdateAvailable: function(addon2) {
if ("updateAvailable" in result) {
do_throw("Saw multiple update available events");
}
equal(addon, addon2);
result.updateAvailable = false;
},
onUpdateAvailable: function(addon2, install) {
if ("updateAvailable" in result) {
do_throw("Saw multiple update available events");
}
equal(addon, addon2);
result.updateAvailable = install;
},
onUpdateFinished: function(addon2, error) {
equal(addon, addon2);
if (error == AddonManager.UPDATE_STATUS_NO_ERROR) {
resolve(result);
} else {
result.error = error;
reject(result);
}
}
}, reason);
});

View File

@ -505,9 +505,8 @@ add_task(function* setup() {
yield promiseInstallAllFiles(ADDON_FILES);
yield promiseRestartManager();
gServer = new HttpServer();
gServer = createHttpServer(PORT);
gServer.registerDirectory("/data/", do_get_file("data"));
gServer.start(PORT);
});
// Tests AddonRepository.cacheEnabled
@ -704,7 +703,3 @@ add_task(function* run_test_17() {
let aAddons = yield promiseAddonsByIDs(ADDON_IDS);
check_results(aAddons, WITH_EXTENSION_CACHE);
});
add_task(function* end_test() {
yield new Promise((resolve, reject) => gServer.stop(resolve));
});

View File

@ -41,8 +41,7 @@ Cu.import("resource://testing-common/MockRegistrar.jsm");
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false)
Cu.import("resource://testing-common/httpd.js");
var testserver = new HttpServer();
testserver.start(-1);
var testserver = createHttpServer();
gPort = testserver.identity.primaryPort;
// register static files with server and interpolate port numbers in them
@ -1305,9 +1304,3 @@ add_task(function* run_local_install_test() {
check_addon(h, "1.0", false, false, Ci.nsIBlocklistService.STATE_BLOCKED);
check_addon(r, "1.0", false, false, Ci.nsIBlocklistService.STATE_BLOCKED);
});
add_task(function* shutdown_httpserver() {
yield new Promise((resolve, reject) => {
testserver.stop(resolve);
});
});

View File

@ -296,10 +296,9 @@ add_task(function* init() {
}, profileDir);
// Create and configure the HTTP server.
testserver = new HttpServer();
testserver = createHttpServer(4444);
testserver.registerDirectory("/data/", do_get_file("data"));
testserver.registerDirectory("/addons/", do_get_file("addons"));
testserver.start(4444);
startupManager();
@ -464,13 +463,3 @@ add_task(function* run_test_6() {
"override1x2-1x3@tests.mozilla.org"]);
check_state_v1_2(addons);
});
add_task(function* cleanup() {
return new Promise((resolve, reject) => {
testserver.stop(resolve);
});
});
function run_test() {
run_next_test();
}

View File

@ -16,65 +16,47 @@ function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
// Create and configure the HTTP server.
testserver = new HttpServer();
testserver = createHttpServer();
testserver.registerDirectory("/data/", do_get_file("data"));
testserver.registerDirectory("/addons/", do_get_file("addons"));
testserver.start(-1);
gPort = testserver.identity.primaryPort;
writeInstallRDFForExtension({
id: "addon1@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/test_missing.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}],
name: "Test Addon 1",
}, profileDir);
startupManager();
do_test_pending();
run_test_1();
}
function end_test() {
testserver.stop(do_test_finished);
run_next_test();
}
// Verify that an update check returns the correct errors.
function run_test_1() {
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
do_check_neq(a1, null);
do_check_eq(a1.version, "1.0");
add_task(function* () {
for (let manifestType of ["rdf", "json"]) {
writeInstallRDFForExtension({
id: "addon1@tests.mozilla.org",
version: "1.0",
updateURL: `http://localhost:${gPort}/data/test_missing.${manifestType}`,
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}],
name: "Test Addon 1",
bootstrap: "true",
}, profileDir);
let sawCompat = false;
let sawUpdate = false;
a1.findUpdates({
onNoCompatibilityUpdateAvailable: function(addon) {
sawCompat = true;
},
yield promiseRestartManager();
onCompatibilityUpdateAvailable: function(addon) {
do_throw("Should not have seen a compatibility update");
},
let addon = yield promiseAddonByID("addon1@tests.mozilla.org");
onNoUpdateAvailable: function(addon) {
sawUpdate = true;
},
ok(addon);
ok(addon.updateURL.endsWith(manifestType));
equal(addon.version, "1.0");
onUpdateAvailable: function(addon, install) {
do_throw("Should not have seen an update");
},
// We're expecting an error, so resolve when the promise is rejected.
let update = yield promiseFindAddonUpdates(addon, AddonManager.UPDATE_WHEN_USER_REQUESTED)
.catch(Promise.resolve);
onUpdateFinished: function(addon, error) {
do_check_true(sawCompat);
do_check_true(sawUpdate);
do_check_eq(error, AddonManager.UPDATE_STATUS_DOWNLOAD_ERROR);
end_test();
}
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
});
}
ok(!update.compatibilityUpdate, "not expecting a compatibility update");
ok(!update.updateAvailable, "not expecting a compatibility update");
equal(update.error, AddonManager.UPDATE_STATUS_DOWNLOAD_ERROR);
addon.uninstall();
}
});

View File

@ -69,10 +69,9 @@ add_task(function* checkFirstMetadata() {
Services.prefs.setBoolPref(PREF_EM_SHOW_MISMATCH_UI, true);
// Create and configure the HTTP server.
testserver = new HttpServer();
testserver = createHttpServer();
testserver.registerDirectory("/data/", do_get_file("data"));
testserver.registerDirectory("/addons/", do_get_file("addons"));
testserver.start(-1);
gPort = testserver.identity.primaryPort;
const BASE_URL = "http://localhost:" + gPort;
const GETADDONS_RESULTS = BASE_URL + "/data/test_AddonRepository_cache.xml";
@ -159,15 +158,3 @@ add_task(function* upgrade_young_pref_lastupdate() {
yield promiseRestartManager("2");
do_check_false(WindowWatcher.expected);
});
add_task(function* cleanup() {
return new Promise((resolve, reject) => {
testserver.stop(resolve);
});
});
function run_test() {
run_next_test();
}

View File

@ -16,8 +16,7 @@ const WORKING = "signed_bootstrap_1.xpi";
const ID = "test@tests.mozilla.org";
Components.utils.import("resource://testing-common/httpd.js");
var gServer = new HttpServer();
gServer.start(4444);
var gServer = createHttpServer(4444);
// Creates an add-on with a broken signature by changing an existing file
function createBrokenAddonModify(file) {
@ -137,7 +136,8 @@ function* test_update_broken(file, expectedError) {
serveUpdateRDF(file.leafName);
let addon = yield promiseAddonByID(ID);
let install = yield promiseFindAddonUpdates(addon);
let update = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
@ -158,7 +158,8 @@ function* test_update_working(file, expectedSignedState) {
serveUpdateRDF(file.leafName);
let addon = yield promiseAddonByID(ID);
let install = yield promiseFindAddonUpdates(addon);
let update = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_INSTALLED);

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,13 @@ const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
// The test extension uses an insecure update url.
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
Components.utils.import("resource://testing-common/httpd.js");
var testserver = new HttpServer();
testserver.start(-1);
var testserver = createHttpServer();
gPort = testserver.identity.primaryPort;
mapFile("/data/test_update.rdf", testserver);
mapFile("/data/test_update.json", testserver);
mapFile("/data/test_update.xml", testserver);
testserver.registerDirectory("/addons/", do_get_file("addons"));
@ -22,77 +23,86 @@ const profileDir = gProfD.clone();
profileDir.append("extensions");
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
run_test_1();
}
let testParams = [
{ updateFile: "test_update.rdf",
appId: "xpcshell@tests.mozilla.org" },
{ updateFile: "test_update.json",
appId: "toolkit@mozilla.org" },
];
// Test that the update check correctly observes the
// extensions.strictCompatibility pref and compatibility overrides.
function run_test_1() {
writeInstallRDFForExtension({
id: "addon9@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 9",
}, profileDir);
restartManager();
for (let test of testParams) {
let { updateFile, appId } = test;
AddonManager.addInstallListener({
onNewInstall: function(aInstall) {
if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
do_check_eq(aInstall.version, "4.0");
},
onDownloadFailed: function(aInstall) {
do_execute_soon(run_test_2);
}
});
// Test that the update check correctly observes the
// extensions.strictCompatibility pref and compatibility overrides.
add_test(function () {
writeInstallRDFForExtension({
id: "addon9@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
targetApplications: [{
id: appId,
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 9",
}, profileDir);
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE,
"http://localhost:" + gPort + "/data/test_update.xml");
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
restartManager();
AddonManagerInternal.backgroundUpdateCheck();
}
// Test that the update check correctly observes when an addon opts-in to
// strict compatibility checking.
function run_test_2() {
writeInstallRDFForExtension({
id: "addon11@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 11",
}, profileDir);
restartManager();
AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
do_check_neq(a11, null);
a11.findUpdates({
onCompatibilityUpdateAvailable: function() {
do_throw("Should have not have seen compatibility information");
AddonManager.addInstallListener({
onNewInstall: function(aInstall) {
if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
do_check_eq(aInstall.version, "4.0");
},
onNoUpdateAvailable: function() {
do_throw("Should have seen an available update");
},
onUpdateFinished: function() {
end_test();
onDownloadFailed: function(aInstall) {
run_next_test();
}
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
});
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE,
"http://localhost:" + gPort + "/data/" + updateFile);
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
AddonManagerInternal.backgroundUpdateCheck();
});
// Test that the update check correctly observes when an addon opts-in to
// strict compatibility checking.
add_test(function () {
writeInstallRDFForExtension({
id: "addon11@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
targetApplications: [{
id: appId,
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 11",
}, profileDir);
restartManager();
AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
do_check_neq(a11, null);
a11.findUpdates({
onCompatibilityUpdateAvailable: function() {
do_throw("Should not have seen compatibility information");
},
onUpdateAvailable: function() {
do_throw("Should not have seen an available update");
},
onUpdateFinished: function() {
run_next_test();
}
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
});
});
}