Backed out 2 changesets (bug 1000695) for introducing a near permafail on linux bc3

Backed out changeset 43306fac27e1 (bug 1000695)
Backed out changeset fcf5abdf9706 (bug 1000695)
This commit is contained in:
Wes Kocher 2014-05-05 17:54:22 -07:00
parent 0e4df22fbb
commit bb01bf4d82
11 changed files with 215 additions and 204 deletions

View File

@ -67,8 +67,6 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/AsyncShutdown.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
@ -464,7 +462,6 @@ var gUpdateEnabled = true;
var gAutoUpdateDefault = true;
var gHotfixID = null;
var gUpdateCheckInProgress = false;
/**
* This is the real manager, kept here rather than in AddonManager to keep its
* contents hidden from API users.
@ -480,6 +477,7 @@ var AddonManagerInternal = {
// Store telemetry details per addon provider
telemetryDetails: {},
// A read-only wrapper around the types dictionary
typesProxy: Proxy.create({
getOwnPropertyDescriptor: function typesProxy_getOwnPropertyDescriptor(aName) {
@ -1134,121 +1132,120 @@ var AddonManagerInternal = {
/**
* Performs a background update check by starting an update for all add-ons
* that can be updated.
* @return Promise{null} resolves when the background update check is complete
* (including all addon installs)
*/
backgroundUpdateCheck: function AMI_backgroundUpdateCheck() {
if (!gStarted)
throw Components.Exception("AddonManager is not initialized",
Cr.NS_ERROR_NOT_INITIALIZED);
if (gUpdateCheckInProgress) {
throw Components.Exception("Background update check already in progress",
Cr.NS_ERROR_UNEXPECTED);
let hotfixID = this.hotfixID;
let checkHotfix = hotfixID &&
Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED) &&
Services.prefs.getBoolPref(PREF_APP_UPDATE_AUTO);
if (!this.updateEnabled && !checkHotfix)
return;
Services.obs.notifyObservers(null, "addons-background-update-start", null);
// Start this from one to ensure the whole of this function completes before
// we can send the complete notification. Some parts can in some cases
// complete synchronously before later parts have a chance to increment
// pendingUpdates.
let pendingUpdates = 1;
function notifyComplete() {
if (--pendingUpdates == 0) {
Services.obs.notifyObservers(null,
"addons-background-update-complete",
null);
}
}
gUpdateCheckInProgress = true;
return Task.spawn(function* backgroundUpdateTask() {
let hotfixID = this.hotfixID;
let checkHotfix = hotfixID &&
Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED) &&
Services.prefs.getBoolPref(PREF_APP_UPDATE_AUTO);
if (!this.updateEnabled && !checkHotfix)
return;
Services.obs.notifyObservers(null, "addons-background-update-start", null);
if (this.updateEnabled) {
let scope = {};
Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", scope);
scope.LightweightThemeManager.updateCurrentTheme();
let aAddons = yield new Promise((resolve, reject) => this.getAllAddons(resolve));
if (this.updateEnabled) {
let scope = {};
Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", scope);
scope.LightweightThemeManager.updateCurrentTheme();
pendingUpdates++;
this.getAllAddons(function getAddonsCallback(aAddons) {
// If there is a known hotfix then exclude it from the list of add-ons to update.
var ids = [a.id for each (a in aAddons) if (a.id != hotfixID)];
// Repopulate repository cache first, to ensure compatibility overrides
// are up to date before checking for addon updates.
yield new Promise((resolve, reject) => AddonRepository.backgroundUpdateCheck(ids, resolve));
AddonRepository.backgroundUpdateCheck(
ids, function BUC_backgroundUpdateCheckCallback() {
pendingUpdates += aAddons.length;
aAddons.forEach(function BUC_forEachCallback(aAddon) {
if (aAddon.id == hotfixID) {
notifyComplete();
return;
}
// Keep track of all the async add-on updates happening in parallel
let updates = [];
for (let aAddon of aAddons) {
if (aAddon.id == hotfixID) {
continue;
}
// Check all add-ons for updates so that any compatibility updates will
// be applied
updates.push(new Promise((resolve, reject) => {
// Check all add-ons for updates so that any compatibility updates will
// be applied
aAddon.findUpdates({
onUpdateAvailable: function BUC_onUpdateAvailable(aAddon, aInstall) {
// Start installing updates when the add-on can be updated and
// background updates should be applied.
if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE &&
AddonManager.shouldAutoUpdate(aAddon)) {
// XXX we really should resolve when this install is done,
// not when update-available check completes, no?
aInstall.install();
}
},
onUpdateFinished: resolve
onUpdateFinished: notifyComplete
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
}));
}
yield Promise.all(updates);
}
if (checkHotfix) {
var hotfixVersion = "";
try {
hotfixVersion = Services.prefs.getCharPref(PREF_EM_HOTFIX_LASTVERSION);
}
catch (e) { }
let url = null;
if (Services.prefs.getPrefType(PREF_EM_HOTFIX_URL) == Ci.nsIPrefBranch.PREF_STRING)
url = Services.prefs.getCharPref(PREF_EM_HOTFIX_URL);
else
url = Services.prefs.getCharPref(PREF_EM_UPDATE_BACKGROUND_URL);
// Build the URI from a fake add-on data.
url = AddonManager.escapeAddonURI({
id: hotfixID,
version: hotfixVersion,
userDisabled: false,
appDisabled: false
}, url);
Components.utils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm");
let update = null;
try {
let foundUpdates = yield new Promise((resolve, reject) => {
AddonUpdateChecker.checkForUpdates(hotfixID, null, url, {
onUpdateCheckComplete: resolve,
onUpdateCheckError: reject
});
});
update = AddonUpdateChecker.getNewestCompatibleUpdate(foundUpdates);
} catch (e) {
// AUC.checkForUpdates already logged the error
}
// Check that we have a hotfix update, and it's newer than the one we already
// have installed (if any)
if (update) {
if (Services.vc.compare(hotfixVersion, update.version) < 0) {
logger.debug("Downloading hotfix version " + update.version);
let aInstall = yield new Promise((resolve, reject) =>
AddonManager.getInstallForURL(update.updateURL, resolve,
"application/x-xpinstall", update.updateHash, null,
null, update.version));
notifyComplete();
});
});
}
if (checkHotfix) {
var hotfixVersion = "";
try {
hotfixVersion = Services.prefs.getCharPref(PREF_EM_HOTFIX_LASTVERSION);
}
catch (e) { }
let url = null;
if (Services.prefs.getPrefType(PREF_EM_HOTFIX_URL) == Ci.nsIPrefBranch.PREF_STRING)
url = Services.prefs.getCharPref(PREF_EM_HOTFIX_URL);
else
url = Services.prefs.getCharPref(PREF_EM_UPDATE_BACKGROUND_URL);
// Build the URI from a fake add-on data.
url = AddonManager.escapeAddonURI({
id: hotfixID,
version: hotfixVersion,
userDisabled: false,
appDisabled: false
}, url);
pendingUpdates++;
Components.utils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm");
AddonUpdateChecker.checkForUpdates(hotfixID, null, url, {
onUpdateCheckComplete: function BUC_onUpdateCheckComplete(aUpdates) {
let update = AddonUpdateChecker.getNewestCompatibleUpdate(aUpdates);
if (!update) {
notifyComplete();
return;
}
// If the available version isn't newer than the last installed
// version then ignore it.
if (Services.vc.compare(hotfixVersion, update.version) >= 0) {
notifyComplete();
return;
}
logger.debug("Downloading hotfix version " + update.version);
AddonManager.getInstallForURL(update.updateURL,
function BUC_getInstallForURL(aInstall) {
aInstall.addListener({
onDownloadEnded: function BUC_onDownloadEnded(aInstall) {
try {
@ -1286,15 +1283,17 @@ var AddonManagerInternal = {
});
aInstall.install();
}
}
}
gUpdateCheckInProgress = false;
Services.obs.notifyObservers(null,
"addons-background-update-complete",
null);
}.bind(this));
notifyComplete();
}, "application/x-xpinstall", update.updateHash, null,
null, update.version);
},
onUpdateCheckError: notifyComplete
});
}
notifyComplete();
},
/**

View File

@ -3610,13 +3610,7 @@ this.XPIProvider = {
* The AddonInstall to remove
*/
removeActiveInstall: function XPI_removeActiveInstall(aInstall) {
let where = this.installs.indexOf(aInstall);
if (where == -1) {
logger.warn("removeActiveInstall: could not find active install for "
+ aInstall.sourceURI.spec);
return;
}
this.installs.splice(where, 1);
this.installs = this.installs.filter(function installFilter(i) i != aInstall);
},
/**

View File

@ -75,7 +75,7 @@ function install_test_addons(aCallback) {
// Switch to the test update URL
Services.prefs.setCharPref(PREF_UPDATEURL, TESTROOT + "browser_bug557956.rdf");
executeSoon(aCallback);
aCallback();
}
}
};

View File

@ -41,7 +41,7 @@ add_test(function () {
gInstall = new MockInstall(undefined, undefined, addon);
gInstall.addTestListener({
onNewInstall: function () {
executeSoon(run_next_test);
run_next_test();
}
});
gProvider.addInstall(gInstall);
@ -65,7 +65,7 @@ add_test(function () {
}
}
ok(false, "Item with correct name was not found");
executeSoon(run_next_test);
run_next_test();
}
});
gInstall.install();

View File

@ -21,18 +21,17 @@ var gTestInstallListener = {
onInstallEnded: function(aInstall) {
check_hidden(false);
executeSoon(run_next_test);
run_next_test();
},
onInstallCancelled: function(aInstall) {
ok(gExpectedCancel, "Should expect install cancel");
check_hidden(false);
executeSoon(run_next_test);
run_next_test();
},
onInstallFailed: function(aInstall) {
ok(false, "Did not expect onInstallFailed");
executeSoon(run_next_test);
}
};

View File

@ -40,7 +40,7 @@ function install_locale(aCallback) {
gInstall.addTestListener({
onInstallEnded: function(aInstall) {
gInstall.removeTestListener(this);
executeSoon(aCallback);
aCallback();
}
});
gInstall.install();

View File

@ -97,7 +97,7 @@ add_test(function() {
},
onInstallEnded: function() {
check_list(gItem);
executeSoon(run_next_test);
run_next_test();
}
});
@ -136,7 +136,7 @@ add_test(function() {
onInstallEnded: function() {
check_list(null);
extension.cancel();
executeSoon(run_next_test);
run_next_test();
}
});

View File

@ -15,56 +15,51 @@ const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
const HOTFIX_ID = "hotfix@tests.mozilla.org";
/*
* Register an addon install listener and return a promise that:
* resolves with the AddonInstall object if the install succeeds
* rejects with the AddonInstall if the install fails
*/
function promiseInstallListener() {
return new Promise((resolve, reject) => {
let listener = {
onInstallEnded: ai => {
AddonManager.removeInstallListener(listener);
resolve(ai);
},
onDownloadCancelled: ai => {
AddonManager.removeInstallListener(listener);
reject(ai);
}
};
AddonManager.addInstallListener(listener);
});
var gNextTest;
var SuccessfulInstallListener = {
onDownloadCancelled: function(aInstall) {
ok(false, "Should not have seen the download cancelled");
is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on");
AddonManager.removeInstallListener(this);
gNextTest();
},
onInstallEnded: function(aInstall) {
ok(true, "Should have seen the install complete");
is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on");
AddonManager.removeInstallListener(this);
aInstall.addon.uninstall();
Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION);
gNextTest();
}
}
function promiseSuccessfulInstall() {
return promiseInstallListener().then(
aInstall => {
ok(true, "Should have seen the install complete");
is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on");
aInstall.addon.uninstall();
Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION);
},
aInstall => {
ok(false, "Should not have seen the download cancelled");
is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on");
});
var FailedInstallListener = {
onDownloadCancelled: function(aInstall) {
ok(true, "Should have seen the download cancelled");
is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on");
AddonManager.removeInstallListener(this);
gNextTest();
},
onInstallEnded: function(aInstall) {
ok(false, "Should not have seen the install complete");
is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on");
AddonManager.removeInstallListener(this);
aInstall.addon.uninstall();
Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION);
gNextTest();
}
}
function promiseFailedInstall() {
return promiseInstallListener().then(
aInstall => {
ok(false, "Should not have seen the install complete");
is(aInstall.addon.id, HOTFIX_ID, "Should have installed the right add-on");
aInstall.addon.uninstall();
Services.prefs.clearUserPref(PREF_EM_HOTFIX_LASTVERSION);
},
aInstall => {
ok(true, "Should have seen the download cancelled");
is(aInstall.addon.id, HOTFIX_ID, "Should have seen the right add-on");
});
}
function test() {
waitForExplicitFinish();
add_task(function setup() {
Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true);
Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false);
Services.prefs.setBoolPref(PREF_UPDATE_REQUIREBUILTINCERTS, false);
@ -83,85 +78,109 @@ add_task(function setup() {
var prefs = Services.prefs.getChildList(PREF_EM_HOTFIX_CERTS);
prefs.forEach(Services.prefs.clearUserPref);
});
});
add_task(function* check_no_cert_checks() {
run_next_test();
}
function end_test() {
finish();
}
add_test(function check_no_cert_checks() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, false);
yield Promise.all([
promiseSuccessfulInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
AddonManager.addInstallListener(SuccessfulInstallListener);
gNextTest = run_next_test;
AddonManagerPrivate.backgroundUpdateCheck();
});
add_task(function* check_wrong_cert_fingerprint() {
add_test(function check_wrong_cert_fingerprint() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true);
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "foo");
yield Promise.all([
promiseFailedInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
AddonManager.addInstallListener(FailedInstallListener);
gNextTest = function() {
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
run_next_test();
};
AddonManagerPrivate.backgroundUpdateCheck();
});
add_task(function* check_right_cert_fingerprint() {
add_test(function check_right_cert_fingerprint() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true);
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2");
yield Promise.all([
promiseSuccessfulInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
AddonManager.addInstallListener(SuccessfulInstallListener);
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
gNextTest = function() {
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
run_next_test();
};
AddonManagerPrivate.backgroundUpdateCheck();
});
add_task(function* check_multi_cert_fingerprint_1() {
add_test(function check_multi_cert_fingerprint_1() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true);
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2");
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint", "foo");
yield Promise.all([
promiseSuccessfulInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
AddonManager.addInstallListener(SuccessfulInstallListener);
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint");
gNextTest = function() {
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint");
run_next_test();
};
AddonManagerPrivate.backgroundUpdateCheck();
});
add_task(function* check_multi_cert_fingerprint_2() {
add_test(function check_multi_cert_fingerprint_2() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true);
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "foo");
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2");
yield Promise.all([
promiseSuccessfulInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
AddonManager.addInstallListener(SuccessfulInstallListener);
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint");
gNextTest = function() {
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "2.sha1Fingerprint");
run_next_test();
};
AddonManagerPrivate.backgroundUpdateCheck();
});
add_task(function* check_no_cert_no_checks() {
add_test(function check_no_cert_no_checks() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, false);
Services.prefs.setCharPref(PREF_EM_HOTFIX_URL, TESTROOT + "unsigned_hotfix.rdf");
yield Promise.all([
promiseSuccessfulInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
AddonManager.addInstallListener(SuccessfulInstallListener);
gNextTest = run_next_test;
AddonManagerPrivate.backgroundUpdateCheck();
});
add_task(function* check_no_cert_cert_fingerprint_check() {
add_test(function check_no_cert_cert_fingerprint_check() {
Services.prefs.setBoolPref(PREF_EM_CERT_CHECKATTRIBUTES, true);
Services.prefs.setCharPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint", "3E:B9:4E:07:12:FE:3C:01:41:46:13:46:FC:84:52:1A:8C:BE:1D:A2");
yield Promise.all([
promiseFailedInstall(),
AddonManagerPrivate.backgroundUpdateCheck()
]);
AddonManager.addInstallListener(FailedInstallListener);
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
gNextTest = function() {
Services.prefs.clearUserPref(PREF_EM_HOTFIX_CERTS + "1.sha1Fingerprint");
run_next_test();
};
AddonManagerPrivate.backgroundUpdateCheck();
});

View File

@ -184,7 +184,7 @@ add_test(function() {
is_element_hidden(item._installStatus, "Install progress widget should be hidden");
if (badgeUpdated)
executeSoon(run_next_test);
run_next_test();
else
installCompleted = true;
}

View File

@ -566,7 +566,7 @@ add_test(function() {
is(installBtn.hidden, true, "Install button should be hidden after install ended");
check_filtered_results(QUERY, "relevancescore", false);
executeSoon(run_next_test);
run_next_test();
}
}

View File

@ -30,7 +30,7 @@ function install_test_addon(aCallback) {
onInstallEnded: function() {
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(addon) {
gTestAddon = addon;
executeSoon(aCallback);
aCallback();
});
}
};