зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 989137) for a sudden influx of xpcshell failures
CLOSED TREE Backed out changeset 831a3ccce100 (bug 989137) Backed out changeset d3053c4e4c51 (bug 989137) Backed out changeset 7e410c1d61e6 (bug 989137)
This commit is contained in:
Родитель
d0164b11b6
Коммит
8d395ba254
|
@ -98,10 +98,6 @@ let gPolicyCounter = 0;
|
|||
let gExperimentsCounter = 0;
|
||||
let gExperimentEntryCounter = 0;
|
||||
|
||||
// Tracks active AddonInstall we know about so we can deny external
|
||||
// installs.
|
||||
let gActiveInstallURLs = new Set();
|
||||
|
||||
let gLogger;
|
||||
let gLogDumping = false;
|
||||
|
||||
|
@ -212,10 +208,6 @@ function uninstallAddons(addons) {
|
|||
AddonManager.addAddonListener(listener);
|
||||
|
||||
for (let addon of addons) {
|
||||
// Disabling the add-on before uninstalling is necessary to cause tests to
|
||||
// pass. This might be indicative of a bug in XPIProvider.
|
||||
// TODO follow up in bug 992396.
|
||||
addon.userDisabled = true;
|
||||
addon.uninstall();
|
||||
}
|
||||
|
||||
|
@ -367,7 +359,7 @@ Experiments.Experiments.prototype = {
|
|||
AsyncShutdown.profileBeforeChange.addBlocker("Experiments.jsm shutdown",
|
||||
this.uninit.bind(this));
|
||||
|
||||
this._startWatchingAddons();
|
||||
AddonManager.addAddonListener(this);
|
||||
|
||||
this._loadTask = Task.spawn(this._loadFromCache.bind(this));
|
||||
this._loadTask.then(
|
||||
|
@ -388,7 +380,7 @@ Experiments.Experiments.prototype = {
|
|||
*/
|
||||
uninit: function () {
|
||||
if (!this._shutdown) {
|
||||
this._stopWatchingAddons();
|
||||
AddonManager.removeAddonListener(this);
|
||||
|
||||
gPrefs.ignore(PREF_LOGGING, configureLogging);
|
||||
gPrefs.ignore(PREF_MANIFEST_URI, this.updateManifest, this);
|
||||
|
@ -408,16 +400,6 @@ Experiments.Experiments.prototype = {
|
|||
return Promise.resolve();
|
||||
},
|
||||
|
||||
_startWatchingAddons: function () {
|
||||
AddonManager.addAddonListener(this);
|
||||
AddonManager.addInstallListener(this);
|
||||
},
|
||||
|
||||
_stopWatchingAddons: function () {
|
||||
AddonManager.removeInstallListener(this);
|
||||
AddonManager.removeAddonListener(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Throws an exception if we've already shut down.
|
||||
*/
|
||||
|
@ -662,40 +644,6 @@ Experiments.Experiments.prototype = {
|
|||
this.disableExperiment();
|
||||
},
|
||||
|
||||
onInstallStarted: function (install) {
|
||||
if (install.addon.type != "experiment") {
|
||||
return;
|
||||
}
|
||||
|
||||
// We want to be in control of all experiment add-ons: reject installs
|
||||
// for add-ons that we don't know about.
|
||||
|
||||
// We have a race condition of sorts to worry about here. We have 2
|
||||
// onInstallStarted listeners. This one (the global one) and the one
|
||||
// created as part of ExperimentEntry._installAddon. Because of the order
|
||||
// they are registered in, this one likely executes first. Unfortunately,
|
||||
// this means that the add-on ID is not yet set on the ExperimentEntry.
|
||||
// So, we can't just look at this._trackedAddonIds because the new experiment
|
||||
// will have its add-on ID set to null. We work around this by storing a
|
||||
// identifying field - the source URL of the install - in a module-level
|
||||
// variable (so multiple Experiments instances doesn't cancel each other
|
||||
// out).
|
||||
|
||||
if (this._trackedAddonIds.has(install.addon.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gActiveInstallURLs.has(install.sourceURI.spec)) {
|
||||
this._log.info("onInstallStarted allowing install because install " +
|
||||
"tracked by us.");
|
||||
return;
|
||||
}
|
||||
|
||||
this._log.warn("onInstallStarted cancelling install of unknown " +
|
||||
"experiment add-on: " + install.addon.id);
|
||||
return false;
|
||||
},
|
||||
|
||||
// END OF ADD-ON LISTENERS.
|
||||
|
||||
_getExperimentByAddonId: function (addonId) {
|
||||
|
@ -903,13 +851,6 @@ Experiments.Experiments.prototype = {
|
|||
return this._run();
|
||||
},
|
||||
|
||||
/**
|
||||
* The Set of add-on IDs that we know about from manifests.
|
||||
*/
|
||||
get _trackedAddonIds() {
|
||||
return new Set([e._addonId for ([,e] of this._experiments) if (e._addonId)]);
|
||||
},
|
||||
|
||||
/*
|
||||
* Task function to check applicability of experiments, disable the active
|
||||
* experiment if needed and activate the first applicable candidate.
|
||||
|
@ -934,7 +875,7 @@ Experiments.Experiments.prototype = {
|
|||
// should have some record of it. In the end, we decide to discard all
|
||||
// knowledge for these unknown experiment add-ons.
|
||||
let installedExperiments = yield installedExperimentAddons();
|
||||
let expectedAddonIds = this._trackedAddonIds;
|
||||
let expectedAddonIds = new Set([e._addonId for ([,e] of this._experiments)]);
|
||||
let unknownAddons = [a for (a of installedExperiments) if (!expectedAddonIds.has(a.id))];
|
||||
if (unknownAddons.length) {
|
||||
this._log.warn("_evaluateExperiments() - unknown add-ons in AddonManager: " +
|
||||
|
@ -976,8 +917,6 @@ Experiments.Experiments.prototype = {
|
|||
}
|
||||
this._dirty = true;
|
||||
activeChanged = true;
|
||||
} else {
|
||||
yield activeExperiment.ensureActive();
|
||||
}
|
||||
} finally {
|
||||
this._pendingUninstall = null;
|
||||
|
@ -1463,14 +1402,11 @@ Experiments.ExperimentEntry.prototype = {
|
|||
|
||||
let install = yield addonInstallForURL(this._manifestData.xpiURL,
|
||||
this._manifestData.xpiHash);
|
||||
gActiveInstallURLs.add(install.sourceURI.spec);
|
||||
|
||||
let failureHandler = (install, handler) => {
|
||||
let message = "AddonInstall " + handler + " for " + this.id + ", state=" +
|
||||
(install.state || "?") + ", error=" + install.error;
|
||||
this._log.error("_installAddon() - " + message);
|
||||
this._failedStart = true;
|
||||
gActiveInstallURLs.delete(install.sourceURI.spec);
|
||||
|
||||
TelemetryLog.log(TELEMETRY_LOG.ACTIVATION_KEY,
|
||||
[TELEMETRY_LOG.ACTIVATION.INSTALL_FAILURE, this.id]);
|
||||
|
@ -1479,8 +1415,6 @@ Experiments.ExperimentEntry.prototype = {
|
|||
};
|
||||
|
||||
let listener = {
|
||||
_expectedID: null,
|
||||
|
||||
onDownloadEnded: install => {
|
||||
this._log.trace("_installAddon() - onDownloadEnded for " + this.id);
|
||||
|
||||
|
@ -1505,12 +1439,13 @@ Experiments.ExperimentEntry.prototype = {
|
|||
this._log.error("_installAddon() - onInstallStarted, wrong addon type");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Experiment add-ons default to userDisabled = true.
|
||||
install.addon.userDisabled = false;
|
||||
},
|
||||
|
||||
onInstallEnded: install => {
|
||||
this._log.trace("_installAddon() - install ended for " + this.id);
|
||||
gActiveInstallURLs.delete(install.sourceURI.spec);
|
||||
|
||||
this._lastChangedDate = this._policy.now();
|
||||
this._startDate = this._policy.now();
|
||||
this._enabled = true;
|
||||
|
@ -1524,26 +1459,6 @@ Experiments.ExperimentEntry.prototype = {
|
|||
this._description = addon.description || "";
|
||||
this._homepageURL = addon.homepageURL || "";
|
||||
|
||||
// Experiment add-ons default to userDisabled=true. Enable if needed.
|
||||
if (addon.userDisabled) {
|
||||
this._log.trace("Add-on is disabled. Enabling.");
|
||||
listener._expectedID = addon.id;
|
||||
AddonManager.addAddonListener(listener);
|
||||
addon.userDisabled = false;
|
||||
} else {
|
||||
this._log.trace("Add-on is enabled. start() completed.");
|
||||
deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
onEnabled: addon => {
|
||||
this._log.info("onEnabled() for " + addon.id);
|
||||
|
||||
if (addon.id != listener._expectedID) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve();
|
||||
},
|
||||
};
|
||||
|
@ -1581,7 +1496,7 @@ Experiments.ExperimentEntry.prototype = {
|
|||
this._endDate = now;
|
||||
};
|
||||
|
||||
this._getAddon().then((addon) => {
|
||||
AddonManager.getAddonByID(this._addonId, addon => {
|
||||
if (!addon) {
|
||||
let message = "could not get Addon for " + this.id;
|
||||
this._log.warn("stop() - " + message);
|
||||
|
@ -1598,61 +1513,6 @@ Experiments.ExperimentEntry.prototype = {
|
|||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Try to ensure this experiment is active.
|
||||
*
|
||||
* The returned promise will be resolved if the experiment is active
|
||||
* in the Addon Manager or rejected if it isn't.
|
||||
*
|
||||
* @return Promise<>
|
||||
*/
|
||||
ensureActive: Task.async(function* () {
|
||||
this._log.trace("ensureActive() for " + this.id);
|
||||
|
||||
let addon = yield this._getAddon();
|
||||
if (!addon) {
|
||||
this._log.warn("Experiment is not installed: " + this._addonId);
|
||||
throw new Error("Experiment is not installed: " + this._addonId);
|
||||
}
|
||||
|
||||
// User disabled likely means the experiment is disabled at startup,
|
||||
// since the permissions don't allow it to be disabled by the user.
|
||||
if (!addon.userDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let listener = {
|
||||
onEnabled: enabledAddon => {
|
||||
if (enabledAddon.id != addon.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve();
|
||||
},
|
||||
};
|
||||
|
||||
this._log.info("Activating add-on: " + addon.id);
|
||||
AddonManager.addAddonListener(listener);
|
||||
addon.userDisabled = false;
|
||||
yield deferred.promise;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Obtain the underlying Addon from the Addon Manager.
|
||||
*
|
||||
* @return Promise<Addon|null>
|
||||
*/
|
||||
_getAddon: function () {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
AddonManager.getAddonByID(this._addonId, deferred.resolve);
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_logTermination: function (terminationKind, terminationReason) {
|
||||
if (terminationKind === undefined) {
|
||||
return;
|
||||
|
|
|
@ -147,6 +147,61 @@ function loadAddonManager() {
|
|||
startupManager();
|
||||
}
|
||||
|
||||
// Install addon and return a Promise<boolean> that is
|
||||
// resolve with true on success, false otherwise.
|
||||
function installAddon(url, hash) {
|
||||
let deferred = Promise.defer();
|
||||
let success = () => deferred.resolve(true);
|
||||
let fail = () => deferred.resolve(false);
|
||||
let listener = {
|
||||
onDownloadCancelled: fail,
|
||||
onDownloadFailed: fail,
|
||||
onInstallCancelled: fail,
|
||||
onInstallFailed: fail,
|
||||
onInstallEnded: success,
|
||||
};
|
||||
|
||||
let installCallback = install => {
|
||||
install.addListener(listener);
|
||||
install.install();
|
||||
};
|
||||
|
||||
AddonManager.getInstallForURL(url, installCallback,
|
||||
"application/x-xpinstall", hash);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Uninstall addon and return a Promise<boolean> that is
|
||||
// resolve with true on success, false otherwise.
|
||||
function uninstallAddon(id) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
AddonManager.getAddonByID(id, addon => {
|
||||
if (!addon) {
|
||||
deferred.resolve(false);
|
||||
}
|
||||
|
||||
let listener = {};
|
||||
let handler = addon => {
|
||||
if (addon.id !== id) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve(true);
|
||||
};
|
||||
|
||||
listener.onUninstalled = handler;
|
||||
listener.onDisabled = handler;
|
||||
|
||||
AddonManager.addAddonListener(listener);
|
||||
addon.uninstall();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function getExperimentAddons() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
|
|
|
@ -86,12 +86,6 @@ add_task(function* test_startStop() {
|
|||
});
|
||||
let experiment = new Experiments.ExperimentEntry(gPolicy);
|
||||
experiment.initFromManifestData(manifestData);
|
||||
|
||||
// We need to associate it with the singleton so the onInstallStarted
|
||||
// Addon Manager listener will know about it.
|
||||
Experiments.instance()._experiments = new Map();
|
||||
Experiments.instance()._experiments.set(experiment.id, experiment);
|
||||
|
||||
let result;
|
||||
|
||||
defineNow(gPolicy, baseDate);
|
||||
|
@ -99,43 +93,25 @@ add_task(function* test_startStop() {
|
|||
Assert.equal(result.applicable, false, "Experiment should not be applicable.");
|
||||
Assert.equal(experiment.enabled, false, "Experiment should not be enabled.");
|
||||
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "No experiment add-ons are installed.");
|
||||
|
||||
defineNow(gPolicy, futureDate(startDate, 5 * MS_IN_ONE_DAY));
|
||||
result = yield isApplicable(experiment);
|
||||
Assert.equal(result.applicable, true, "Experiment should now be applicable.");
|
||||
Assert.equal(experiment.enabled, false, "Experiment should not be enabled.");
|
||||
|
||||
yield experiment.start();
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(experiment.enabled, true, "Experiment should now be enabled.");
|
||||
Assert.equal(addons.length, 1, "1 experiment add-on is installed.");
|
||||
Assert.equal(addons[0].id, experiment._addonId, "The add-on is the one we expect.");
|
||||
Assert.equal(addons[0].userDisabled, false, "The add-on is not userDisabled.");
|
||||
Assert.ok(addons[0].isActive, "The add-on is active.");
|
||||
|
||||
yield experiment.stop();
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(experiment.enabled, false, "Experiment should not be enabled.");
|
||||
Assert.equal(addons.length, 0, "Experiment should be uninstalled from the Addon Manager.");
|
||||
|
||||
yield experiment.start();
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(experiment.enabled, true, "Experiment should now be enabled.");
|
||||
Assert.equal(addons.length, 1, "1 experiment add-on is installed.");
|
||||
Assert.equal(addons[0].id, experiment._addonId, "The add-on is the one we expect.");
|
||||
Assert.equal(addons[0].userDisabled, false, "The add-on is not userDisabled.");
|
||||
Assert.ok(addons[0].isActive, "The add-on is active.");
|
||||
|
||||
let result = yield experiment._shouldStop();
|
||||
Assert.equal(result.shouldStop, false, "shouldStop should be false.");
|
||||
let maybeStop = yield experiment.maybeStop();
|
||||
Assert.equal(maybeStop, false, "Experiment should not have been stopped.");
|
||||
Assert.equal(experiment.enabled, true, "Experiment should be enabled.");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "Experiment still in add-ons manager.");
|
||||
Assert.ok(addons[0].isActive, "The add-on is still active.");
|
||||
|
||||
defineNow(gPolicy, futureDate(endDate, MS_IN_ONE_DAY));
|
||||
result = yield experiment._shouldStop();
|
||||
|
@ -143,6 +119,4 @@ add_task(function* test_startStop() {
|
|||
maybeStop = yield experiment.maybeStop();
|
||||
Assert.equal(maybeStop, true, "Experiment should have been stopped.");
|
||||
Assert.equal(experiment.enabled, false, "Experiment should be disabled.");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Experiment add-on is uninstalled.");
|
||||
});
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
"use strict";
|
||||
|
||||
Cu.import("resource://testing-common/httpd.js");
|
||||
Cu.import("resource://testing-common/AddonManagerTesting.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Experiments",
|
||||
"resource:///modules/experiments/Experiments.jsm");
|
||||
|
||||
|
@ -153,8 +151,6 @@ add_task(function* test_getExperiments() {
|
|||
"Experiments observer should not have been called yet.");
|
||||
let list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 0, "Experiment list should be empty.");
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Precondition: No experiment add-ons are installed.");
|
||||
|
||||
// Trigger update, clock set for experiment 1 to start.
|
||||
|
||||
|
@ -168,8 +164,6 @@ add_task(function* test_getExperiments() {
|
|||
|
||||
list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 1, "Experiment list should have 1 entry now.");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "An experiment add-on was installed.");
|
||||
|
||||
experimentListData[1].active = true;
|
||||
experimentListData[1].endDate = now.getTime() + 10 * MS_IN_ONE_DAY;
|
||||
|
@ -193,8 +187,6 @@ add_task(function* test_getExperiments() {
|
|||
|
||||
list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 1, "Experiment list should have 1 entry.");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "The experiment add-on should be uninstalled.");
|
||||
|
||||
experimentListData[1].active = false;
|
||||
experimentListData[1].endDate = now.getTime();
|
||||
|
@ -219,8 +211,6 @@ add_task(function* test_getExperiments() {
|
|||
|
||||
list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 2, "Experiment list should have 2 entries now.");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "An experiment add-on is installed.");
|
||||
|
||||
experimentListData[0].active = true;
|
||||
experimentListData[0].endDate = now.getTime() + 10 * MS_IN_ONE_DAY;
|
||||
|
@ -246,8 +236,6 @@ add_task(function* test_getExperiments() {
|
|||
|
||||
list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 2, "Experiment list should have 2 entries now.");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "No experiments add-ons are installed.");
|
||||
|
||||
experimentListData[0].active = false;
|
||||
experimentListData[0].endDate = now.getTime();
|
||||
|
@ -313,6 +301,11 @@ add_task(function* test_addonAlreadyInstalled() {
|
|||
let list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 0, "Experiment list should be empty.");
|
||||
|
||||
// Install conflicting addon.
|
||||
|
||||
let installed = yield installAddon(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1);
|
||||
Assert.ok(installed, "Addon should have been installed.");
|
||||
|
||||
// Trigger update, clock set for the experiment to start.
|
||||
|
||||
now = futureDate(startDate, 10 * MS_IN_ONE_DAY);
|
||||
|
@ -327,19 +320,6 @@ add_task(function* test_addonAlreadyInstalled() {
|
|||
Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry.");
|
||||
Assert.equal(list[0].active, true, "Experiment 1 should be active.");
|
||||
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "1 add-on is installed.");
|
||||
|
||||
// Install conflicting addon.
|
||||
|
||||
yield AddonTestUtils.installXPIFromURL(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1);
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "1 add-on is installed.");
|
||||
list = yield experiments.getExperiments();
|
||||
Assert.equal(list.length, 1, "Experiment list should still have 1 entry.");
|
||||
Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry.");
|
||||
Assert.equal(list[0].active, true, "Experiment 1 should be active.");
|
||||
|
||||
// Cleanup.
|
||||
|
||||
Services.obs.removeObserver(observer, OBSERVER_TOPIC);
|
||||
|
@ -1346,8 +1326,9 @@ add_task(function* test_unexpectedUninstall() {
|
|||
// Uninstall the addon through the addon manager instead of stopping it through
|
||||
// the experiments API.
|
||||
|
||||
yield AddonTestUtils.uninstallAddonByID(EXPERIMENT1_ID);
|
||||
let success = yield uninstallAddon(EXPERIMENT1_ID);
|
||||
yield experiments._mainTask;
|
||||
Assert.ok(success, "Addon should have been uninstalled.");
|
||||
|
||||
yield experiments.notify();
|
||||
|
||||
|
@ -1370,12 +1351,7 @@ add_task(function* testUnknownExperimentsUninstalled() {
|
|||
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Precondition: No experiment add-ons are present.");
|
||||
|
||||
// Simulate us not listening.
|
||||
experiments._stopWatchingAddons();
|
||||
yield AddonTestUtils.installXPIFromURL(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1);
|
||||
experiments._startWatchingAddons();
|
||||
|
||||
yield installAddon(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1);
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "Experiment 1 installed via AddonManager");
|
||||
|
||||
|
@ -1396,80 +1372,3 @@ add_task(function* testUnknownExperimentsUninstalled() {
|
|||
yield experiments.uninit();
|
||||
yield removeCacheFile();
|
||||
});
|
||||
|
||||
// If someone else installs an experiment add-on, we detect and stop that.
|
||||
add_task(function* testForeignExperimentInstall() {
|
||||
let experiments = new Experiments.Experiments(gPolicy);
|
||||
|
||||
gManifestObject = {
|
||||
"version": 1,
|
||||
experiments: [],
|
||||
};
|
||||
|
||||
yield experiments.init();
|
||||
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Precondition: No experiment add-ons present.");
|
||||
|
||||
let failed;
|
||||
try {
|
||||
yield AddonTestUtils.installXPIFromURL(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1);
|
||||
} catch (ex) {
|
||||
failed = true;
|
||||
}
|
||||
Assert.ok(failed, "Add-on install should not have completed successfully");
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Add-on install should have been cancelled.");
|
||||
|
||||
yield experiments.uninit();
|
||||
yield removeCacheFile();
|
||||
});
|
||||
|
||||
// Experiment add-ons will be disabled after Addon Manager restarts. Ensure
|
||||
// we enable them automatically.
|
||||
add_task(function* testEnabledAfterRestart() {
|
||||
let experiments = new Experiments.Experiments(gPolicy);
|
||||
|
||||
gManifestObject = {
|
||||
"version": 1,
|
||||
experiments: [
|
||||
{
|
||||
id: EXPERIMENT1_ID,
|
||||
xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME,
|
||||
xpiHash: EXPERIMENT1_XPI_SHA1,
|
||||
startTime: gPolicy.now().getTime() / 1000 - 60,
|
||||
endTime: gPolicy.now().getTime() / 1000 + 60,
|
||||
maxActiveSeconds: 10 * SEC_IN_ONE_DAY,
|
||||
appName: ["XPCShell"],
|
||||
channel: ["nightly"],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
let addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 0, "Precondition: No experimenta add-ons installed.");
|
||||
|
||||
yield experiments.updateManifest();
|
||||
let fromManifest = yield experiments.getExperiments();
|
||||
Assert.equal(fromManifest.length, 1, "A single experiment is known.");
|
||||
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "A single experiment add-on is installed.");
|
||||
Assert.ok(addons[0].isActive, "That experiment is active.");
|
||||
|
||||
dump("Restarting Addon Manager\n");
|
||||
experiments._stopWatchingAddons();
|
||||
restartManager();
|
||||
experiments._startWatchingAddons();
|
||||
|
||||
addons = yield getExperimentAddons();
|
||||
Assert.equal(addons.length, 1, "The experiment is still there after restart.");
|
||||
Assert.ok(addons[0].userDisabled, "But it is disabled.");
|
||||
Assert.equal(addons[0].isActive, false, "And not active.");
|
||||
|
||||
yield experiments.updateManifest();
|
||||
Assert.ok(addons[0].isActive, "It activates when the manifest is evaluated.");
|
||||
|
||||
yield experiments.uninit();
|
||||
yield removeCacheFile();
|
||||
});
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This file is a test-only JSM containing utility methods for
|
||||
// interacting with the add-ons manager.
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"AddonTestUtils",
|
||||
];
|
||||
|
||||
const {utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
this.AddonTestUtils = {
|
||||
/**
|
||||
* Uninstall an add-on that is specified by its ID.
|
||||
*
|
||||
* The returned promise resolves on successful uninstall and rejects
|
||||
* if the add-on is not unknown.
|
||||
*
|
||||
* @return Promise<restartRequired>
|
||||
*/
|
||||
uninstallAddonByID: function (id) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
AddonManager.getAddonByID(id, (addon) => {
|
||||
if (!addon) {
|
||||
deferred.reject(new Error("Add-on is not known: " + id));
|
||||
return;
|
||||
}
|
||||
|
||||
let listener = {
|
||||
onUninstalling: function (addon, needsRestart) {
|
||||
if (addon.id != id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needsRestart) {
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve(true);
|
||||
}
|
||||
},
|
||||
|
||||
onUninstalled: function (addon) {
|
||||
if (addon.id != id) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve(false);
|
||||
},
|
||||
|
||||
onOperationCancelled: function (addon) {
|
||||
if (addon.id != id) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.reject(new Error("Uninstall cancelled."));
|
||||
},
|
||||
};
|
||||
|
||||
AddonManager.addAddonListener(listener);
|
||||
addon.uninstall();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Install an XPI add-on from a URL.
|
||||
*
|
||||
* @return Promise<addon>
|
||||
*/
|
||||
installXPIFromURL: function (url, hash, name, iconURL, version) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
AddonManager.getInstallForURL(url, (install) => {
|
||||
let fail = () => { deferred.reject(new Error("Add-on install failed.")) };
|
||||
|
||||
let listener = {
|
||||
onDownloadCancelled: fail,
|
||||
onDownloadFailed: fail,
|
||||
onInstallCancelled: fail,
|
||||
onInstallFailed: fail,
|
||||
onInstallEnded: function (install, addon) {
|
||||
deferred.resolve(addon);
|
||||
},
|
||||
};
|
||||
|
||||
install.addListener(listener);
|
||||
install.install();
|
||||
}, "application/x-xpinstall", hash, name, iconURL, version);
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
};
|
|
@ -2,8 +2,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
TESTING_JS_MODULES := AddonManagerTesting.jsm
|
||||
|
||||
ADDONSRC = $(srcdir)/addons
|
||||
TESTROOT = $(CURDIR)/$(DEPTH)/_tests/xpcshell/$(relativesrcdir)
|
||||
TESTXPI = $(TESTROOT)/xpcshell/addons
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
let gManagerWindow;
|
||||
let gCategoryUtilities;
|
||||
let gInstalledAddons = [];
|
||||
let gContext = this;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
@ -14,14 +13,6 @@ function test() {
|
|||
gManagerWindow = win;
|
||||
gCategoryUtilities = new CategoryUtilities(win);
|
||||
|
||||
// The Experiments Manager will interfere with us by preventing installs
|
||||
// of experiments it doesn't know about. We remove it from the equation
|
||||
// because here we are only concerned with core Addon Manager operation,
|
||||
// not the super set Experiments Manager has imposed.
|
||||
if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
|
||||
Components.utils.import("resource:///modules/experiments/Experiments.jsm", gContext);
|
||||
gContext.Experiments.instance()._stopWatchingAddons();
|
||||
}
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
|
@ -31,13 +22,7 @@ function end_test() {
|
|||
addon.uninstall();
|
||||
}
|
||||
|
||||
close_manager(gManagerWindow, () => {
|
||||
if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
|
||||
gContext.Experiments.instance()._startWatchingAddons();
|
||||
}
|
||||
|
||||
finish();
|
||||
});
|
||||
close_manager(gManagerWindow, finish);
|
||||
}
|
||||
|
||||
// On an empty profile with no experiments, the experiment category
|
||||
|
|
Загрузка…
Ссылка в новой задаче