Bug 1463635: Part 1 - Use slightly less dodgy, WebExtension-compatible bootstrap monitor for temporary add-on tests. r=aswan

MozReview-Commit-ID: CHq1nV8rEv4

--HG--
extra : rebase_source : b3b377861777e66b2a0cc36cab904c6335daf0b2
This commit is contained in:
Kris Maglione 2018-05-22 19:51:48 -07:00
parent 0a2e6e139e
commit cf0ebb485a
4 changed files with 469 additions and 249 deletions

View File

@ -749,6 +749,19 @@ var AddonTestUtils = {
let XPIScope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", null);
XPIScope.AsyncShutdown = MockAsyncShutdown;
XPIScope.XPIInternal.BootstrapScope.prototype
._beforeCallBootstrapMethod = (method, params, reason) => {
try {
this.emit("bootstrap-method", {method, params, reason});
} catch (e) {
try {
this.testScope.do_throw(e);
} catch (e) {
// Le sigh.
}
}
};
this.addonIntegrationService = Cc["@mozilla.org/addons/integration;1"]
.getService(Ci.nsIObserver);

View File

@ -1585,6 +1585,8 @@ class BootstrapScope {
} else {
logger.debug(`Calling bootstrap method ${aMethod} on ${addon.id} version ${addon.version}`);
this._beforeCallBootstrapMethod(aMethod, params, aReason);
try {
result = method.call(scope, params, aReason);
} catch (e) {
@ -1608,6 +1610,9 @@ class BootstrapScope {
}
}
// No-op method to be overridden by tests.
_beforeCallBootstrapMethod() {}
/**
* Loads a bootstrapped add-on's bootstrap.js into a sandbox and the reason
* values as constants in the scope.

View File

@ -103,6 +103,19 @@ ExtensionTestUtils.init(this);
AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();
XPCOMUtils.defineLazyGetter(this, "BOOTSTRAP_REASONS",
() => AddonManagerPrivate.BOOTSTRAP_REASONS);
function getReasonName(reason) {
for (let key of Object.keys(BOOTSTRAP_REASONS)) {
if (BOOTSTRAP_REASONS[key] == reason) {
return key;
}
}
throw new Error("This shouldn't happen.");
}
Object.defineProperty(this, "gAppInfo", {
get() {
return AddonTestUtils.appInfo;
@ -351,6 +364,128 @@ this.BootstrapMonitor = {
AddonTestUtils.on("addon-manager-shutdown", () => BootstrapMonitor.shutdownCheck());
var SlightlyLessDodgyBootstrapMonitor = {
started: new Map(),
stopped: new Map(),
installed: new Map(),
uninstalled: new Map(),
init() {
this.onEvent = this.onEvent.bind(this);
AddonTestUtils.on("addon-manager-shutdown", this.onEvent);
AddonTestUtils.on("bootstrap-method", this.onEvent);
},
shutdownCheck() {
equal(this.started.size, 0,
"Should have no add-ons that were started but not shutdown");
},
onEvent(msg, data) {
switch (msg) {
case "addon-manager-shutdown":
this.shutdownCheck();
break;
case "bootstrap-method":
this.onBootstrapMethod(data.method, data.params, data.reason);
break;
}
},
onBootstrapMethod(method, params, reason) {
let {id} = params;
info(`Bootstrap method ${method} for ${params.id} version ${params.version}`);
if (method !== "install") {
this.checkInstalled(id);
}
switch (method) {
case "install":
this.checkNotInstalled(id);
this.installed.set(id, {reason, params});
this.uninstalled.delete(id);
break;
case "startup":
this.checkNotStarted(id);
this.started.set(id, {reason, params});
this.stopped.delete(id);
break;
case "shutdown":
this.checkMatches("shutdown", "startup", params, this.started.get(id));
this.checkStarted(id);
this.stopped.set(id, {reason, params});
this.started.delete(id);
break;
case "uninstall":
this.checkMatches("uninstall", "install", params, this.installed.get(id));
this.uninstalled.set(id, {reason, params});
this.installed.delete(id);
break;
case "update":
// Close enough, for now.
this.onBootstrapMethod("uninstall",
Object.assign({}, params, {version: params.oldVersion}),
reason);
this.onBootstrapMethod("install", params, reason);
break;
}
},
clear(id) {
this.installed.delete(id);
this.started.delete(id);
this.stopped.delete(id);
this.uninstalled.delete(id);
},
checkMatches(method, lastMethod, params, {params: lastParams} = {}) {
ok(lastParams,
`Expecting matching ${lastMethod} call for add-on ${params.id} ${method} call`);
equal(params.version, lastParams.version,
"params.version should match last call");
equal(params.installPath.path, lastParams.installPath.path,
`params.installPath should match last call`);
ok(params.resourceURI.equals(lastParams.resourceURI),
`params.resourceURI should match: "${params.resourceURI.spec}" == "${lastParams.resourceURI.spec}"`);
},
checkStarted(id, version = undefined) {
let started = this.started.get(id);
ok(started, `Should have seen startup method call for ${id}`);
if (version !== undefined)
equal(started.params.version, version,
"Expected version number");
},
checkNotStarted(id) {
ok(!this.started.has(id),
`Should not have seen startup method call for ${id}`);
},
checkInstalled(id, version = undefined) {
const installed = this.installed.get(id);
ok(installed, `Should have seen install call for ${id}`);
if (version !== undefined)
equal(installed.params.version, version,
"Expected version number");
return installed;
},
checkNotInstalled(id) {
ok(!this.installed.has(id),
`Should not have seen install method call for ${id}`);
},
};
function isNightlyChannel() {
var channel = Services.prefs.getCharPref("app.update.channel", "default");

View File

@ -19,36 +19,35 @@ const sampleRDFManifest = {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
BootstrapMonitor.init();
// Partial list of bootstrap reasons from XPIProvider.jsm
const BOOTSTRAP_REASONS = {
APP_STARTUP: 1,
ADDON_INSTALL: 5,
ADDON_UNINSTALL: 6,
ADDON_UPGRADE: 7,
ADDON_DOWNGRADE: 8,
};
function waitForBootstrapEvent(expectedEvent, addonId) {
return new Promise(resolve => {
const observer = {
observe: (subject, topic, data) => {
const info = JSON.parse(data);
const targetAddonId = info.data.id;
if (targetAddonId === addonId && info.event === expectedEvent) {
resolve(info);
Services.obs.removeObserver(observer, "bootstrapmonitor-event");
} else {
info(
`Ignoring bootstrap event: ${info.event} for ${targetAddonId}`);
}
},
};
Services.obs.addObserver(observer, "bootstrapmonitor-event");
function listener(msg, {method, params, reason}) {
if (params.id === addonId && method === expectedEvent) {
resolve({params, method, reason});
AddonTestUtils.off("bootstrap-method", listener);
} else {
info(`Ignoring bootstrap event: ${method} for ${params.id}`);
}
}
AddonTestUtils.on("bootstrap-method", listener);
});
}
async function checkEvent(promise, {reason, params}) {
let event = await promise;
info(`Checking bootstrap event ${event.method} for ${event.params.id}`);
equal(event.reason, reason,
`Expected bootstrap reason ${getReasonName(reason)} got ${getReasonName(event.reason)}`);
for (let [param, value] of Object.entries(params)) {
equal(event.params[param], value, `Expected value for params.${param}`);
}
}
let Monitor = SlightlyLessDodgyBootstrapMonitor;
Monitor.init();
// Install a temporary add-on with no existing add-on present.
// Restart and make sure it has gone away.
add_task(async function() {
@ -87,23 +86,25 @@ add_task(async function() {
Assert.ok(installingCalled);
Assert.ok(installedCalled);
const install = BootstrapMonitor.checkAddonInstalled(ID, "1.0");
const install = Monitor.checkInstalled(ID, "1.0");
equal(install.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
BootstrapMonitor.checkAddonStarted(ID, "1.0");
let info = BootstrapMonitor.started.get(ID);
Monitor.checkStarted(ID, "1.0");
let info = Monitor.started.get(ID);
Assert.equal(info.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
let addon = await promiseAddonByID(ID);
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
Assert.equal(addon.name, "Test Bootstrap 1");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "1.0",
name: "Test Bootstrap 1",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
let onShutdown = waitForBootstrapEvent("shutdown", ID);
let onUninstall = waitForBootstrapEvent("uninstall", ID);
@ -116,8 +117,8 @@ add_task(async function() {
let uninstall = await onUninstall;
equal(uninstall.reason, BOOTSTRAP_REASONS.ADDON_UNINSTALL);
BootstrapMonitor.checkAddonNotInstalled(ID);
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkNotInstalled(ID);
Monitor.checkNotStarted(ID);
addon = await promiseAddonByID(ID);
Assert.equal(addon, null);
@ -128,21 +129,20 @@ add_task(async function() {
// Install a temporary add-on over the top of an existing add-on.
// Restart and make sure the existing add-on comes back.
add_task(async function() {
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_2")], true);
let {addon} = await promiseInstallFile(do_get_addon("test_bootstrap1_2"), true);
BootstrapMonitor.checkAddonInstalled(ID, "2.0");
BootstrapMonitor.checkAddonStarted(ID, "2.0");
Monitor.checkInstalled(ID, "2.0");
Monitor.checkStarted(ID, "2.0");
let addon = await promiseAddonByID(ID);
Assert.notEqual(addon, null);
Assert.equal(addon.version, "2.0");
Assert.equal(addon.name, "Test Bootstrap 1");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "2.0",
name: "Test Bootstrap 1",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
let tempdir = gTmpD.clone();
@ -202,37 +202,50 @@ add_task(async function() {
BOOTSTRAP_REASONS.ADDON_DOWNGRADE :
BOOTSTRAP_REASONS.ADDON_UPGRADE;
let shutdown = await onShutdown;
equal(shutdown.data.version, "2.0");
equal(shutdown.reason, reason);
await checkEvent(onShutdown, {
reason,
params: {
version: "2.0",
},
});
let uninstall = await onUninstall;
equal(uninstall.data.version, "2.0");
equal(uninstall.reason, reason);
await checkEvent(onUninstall, {
reason,
params: {
version: "2.0",
},
});
let install = await onInstall;
equal(install.data.version, newversion);
equal(install.reason, reason);
equal(install.data.oldVersion, "2.0");
await checkEvent(onInstall, {
reason,
params: {
version: newversion,
oldVersion: "2.0",
},
});
let startup = await onStartup;
equal(startup.data.version, newversion);
equal(startup.reason, reason);
equal(startup.data.oldVersion, "2.0");
await checkEvent(onStartup, {
reason,
params: {
version: newversion,
oldVersion: "2.0",
},
});
addon = await promiseAddonByID(ID);
let signedState = packed ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_UNKNOWN;
// temporary add-on is installed and started
Assert.notEqual(addon, null);
Assert.equal(addon.version, newversion);
Assert.equal(addon.name, "Test Bootstrap 1 (temporary)");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? signedState : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: newversion,
name: "Test Bootstrap 1 (temporary)",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? signedState : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
// Now restart, the temporary addon will go away which should
// be the opposite action (ie, if the temporary addon was an
@ -248,40 +261,53 @@ add_task(async function() {
await promiseRestartManager();
shutdown = await onShutdown;
equal(shutdown.data.version, newversion);
equal(shutdown.reason, reason);
await checkEvent(onShutdown, {
reason,
params: {
version: newversion,
},
});
uninstall = await onUninstall;
equal(uninstall.data.version, newversion);
equal(uninstall.reason, reason);
await checkEvent(onUninstall, {
reason,
params: {
version: newversion,
},
});
install = await onInstall;
equal(install.data.version, "2.0");
equal(install.reason, reason);
equal(install.data.oldVersion, newversion);
await checkEvent(onInstall, {
reason,
params: {
version: "2.0",
oldVersion: newversion,
},
});
startup = await onStartup;
equal(startup.data.version, "2.0");
// We don't actually propagate the upgrade/downgrade reason across
// the browser restart when a temporary addon is removed. See
// bug 1359558 for detailed reasoning.
equal(startup.reason, BOOTSTRAP_REASONS.APP_STARTUP);
await checkEvent(onStartup, {
// We don't actually propagate the upgrade/downgrade reason across
// the browser restart when a temporary addon is removed. See
// bug 1359558 for detailed reasoning.
reason: BOOTSTRAP_REASONS.APP_STARTUP,
params: {
version: "2.0",
},
});
BootstrapMonitor.checkAddonInstalled(ID, "2.0");
BootstrapMonitor.checkAddonStarted(ID, "2.0");
Monitor.checkInstalled(ID, "2.0");
Monitor.checkStarted(ID, "2.0");
addon = await promiseAddonByID(ID);
// existing add-on is back
Assert.notEqual(addon, null);
Assert.equal(addon.version, "2.0");
Assert.equal(addon.name, "Test Bootstrap 1");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "2.0",
name: "Test Bootstrap 1",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
Services.obs.notifyObservers(target, "flush-cache-entry");
target.remove(true);
@ -291,8 +317,8 @@ add_task(async function() {
// remove original add-on
await addon.uninstall();
BootstrapMonitor.checkAddonNotInstalled(ID);
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkNotInstalled(ID);
Monitor.checkNotStarted(ID);
await promiseRestartManager();
});
@ -317,18 +343,18 @@ add_task(async function test_samefile() {
}
});
await AddonManager.installTemporaryAddon(webext);
let addon = await promiseAddonByID(ID);
let addon = await AddonManager.installTemporaryAddon(webext);
// temporary add-on is installed and started
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
Assert.equal(addon.name, "Test WebExtension 1 (temporary)");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "1.0",
name: "Test WebExtension 1 (temporary)",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
Services.obs.notifyObservers(webext, "flush-cache-entry");
webext.remove(false);
@ -344,19 +370,19 @@ add_task(async function test_samefile() {
}
});
await AddonManager.installTemporaryAddon(webext);
addon = await promiseAddonByID(ID);
addon = await AddonManager.installTemporaryAddon(webext);
// temporary add-on is installed and started
Assert.notEqual(addon, null);
Assert.equal(addon.version, "2.0");
Assert.equal(addon.name, "Test WebExtension 1 (temporary)");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.ok(addon.isWebExtension);
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "2.0",
name: "Test WebExtension 1 (temporary)",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
isWebExtension: true,
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
await addon.uninstall();
});
@ -371,8 +397,8 @@ add_task(async function() {
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_1")], true);
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonStarted(ID, "1.0");
Monitor.checkInstalled(ID, "1.0");
Monitor.checkStarted(ID, "1.0");
let tempdir = gTmpD.clone();
await promiseWriteInstallRDFToDir({
@ -420,50 +446,49 @@ add_task(async function() {
}
});
await AddonManager.installTemporaryAddon(unpacked_addon);
let addon = await AddonManager.installTemporaryAddon(unpacked_addon);
Assert.ok(extInstallCalled);
Assert.ok(installingCalled);
Assert.ok(installedCalled);
let addon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonNotInstalled(ID);
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkNotInstalled(ID);
Monitor.checkNotStarted(ID);
// temporary add-on is installed and started
Assert.notEqual(addon, null);
Assert.equal(addon.version, "2.0");
Assert.equal(addon.name, "Test Bootstrap 1 (temporary)");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_UNKNOWN : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "2.0",
name: "Test Bootstrap 1 (temporary)",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_UNKNOWN : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
await addon.uninstall();
await new Promise(executeSoon);
Monitor.checkInstalled(ID);
Monitor.checkStarted(ID);
addon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonInstalled(ID);
BootstrapMonitor.checkAddonStarted(ID);
// existing add-on is back
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
Assert.equal(addon.name, "Test Bootstrap 1");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "1.0",
name: "Test Bootstrap 1",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
unpacked_addon.remove(true);
await addon.uninstall();
BootstrapMonitor.checkAddonNotInstalled(ID);
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkNotInstalled(ID);
Monitor.checkNotStarted(ID);
await promiseRestartManager();
});
@ -499,23 +524,35 @@ add_task(async function() {
const onStartup = waitForBootstrapEvent("startup", ID);
await AddonManager.installTemporaryAddon(unpackedAddon);
const shutdown = await onShutdown;
equal(shutdown.data.version, "1.0");
equal(shutdown.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
await checkEvent(onShutdown, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "1.0",
},
});
const uninstall = await onUninstall;
equal(uninstall.data.version, "1.0");
equal(uninstall.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
await checkEvent(onUninstall, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "1.0",
},
});
const install = await onInstall;
equal(install.data.version, "2.0");
equal(install.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
equal(install.data.oldVersion, "1.0");
await checkEvent(onInstall, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "2.0",
oldVersion: "1.0",
},
});
const startup = await onStartup;
equal(startup.data.version, "2.0");
equal(startup.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
equal(startup.data.oldVersion, "1.0");
await checkEvent(onStartup, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "2.0",
oldVersion: "1.0",
},
});
const addon = await promiseAddonByID(ID);
await addon.uninstall();
@ -555,21 +592,33 @@ add_task(async function() {
const onStartup = waitForBootstrapEvent("startup", ID);
await AddonManager.installTemporaryAddon(unpackedAddon);
const shutdown = await onShutdown;
equal(shutdown.data.version, "1.0");
equal(shutdown.reason, BOOTSTRAP_REASONS.ADDON_DOWNGRADE);
await checkEvent(onShutdown, {
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
params: {
version: "1.0",
},
});
const uninstall = await onUninstall;
equal(uninstall.data.version, "1.0");
equal(uninstall.reason, BOOTSTRAP_REASONS.ADDON_DOWNGRADE);
await checkEvent(onUninstall, {
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
params: {
version: "1.0",
},
});
const install = await onInstall;
equal(install.data.version, "0.8");
equal(install.reason, BOOTSTRAP_REASONS.ADDON_DOWNGRADE);
await checkEvent(onInstall, {
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
params: {
version: "0.8",
},
});
const startup = await onStartup;
equal(startup.data.version, "0.8");
equal(startup.reason, BOOTSTRAP_REASONS.ADDON_DOWNGRADE);
await checkEvent(onStartup, {
reason: BOOTSTRAP_REASONS.ADDON_DOWNGRADE,
params: {
version: "0.8",
},
});
const addon = await promiseAddonByID(ID);
await addon.uninstall();
@ -599,15 +648,21 @@ add_task(async function() {
const onInitialStartup = waitForBootstrapEvent("startup", ID);
await AddonManager.installTemporaryAddon(unpackedAddon);
const initialInstall = await onInitialInstall;
equal(initialInstall.data.version, "1.0");
equal(initialInstall.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
await checkEvent(onInitialInstall, {
reason: BOOTSTRAP_REASONS.ADDON_INSTALL,
params: {
version: "1.0",
},
});
const initialStartup = await onInitialStartup;
equal(initialStartup.data.version, "1.0");
equal(initialStartup.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
await checkEvent(onInitialStartup, {
reason: BOOTSTRAP_REASONS.ADDON_INSTALL,
params: {
version: "1.0",
},
});
let info = BootstrapMonitor.started.get(ID);
let info = Monitor.started.get(ID);
Assert.equal(info.reason, BOOTSTRAP_REASONS.ADDON_INSTALL);
// Install it again.
@ -617,21 +672,33 @@ add_task(async function() {
const onStartup = waitForBootstrapEvent("startup", ID);
await AddonManager.installTemporaryAddon(unpackedAddon);
const shutdown = await onShutdown;
equal(shutdown.data.version, "1.0");
equal(shutdown.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
await checkEvent(onShutdown, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "1.0",
},
});
const uninstall = await onUninstall;
equal(uninstall.data.version, "1.0");
equal(uninstall.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
await checkEvent(onUninstall, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "1.0",
},
});
const reInstall = await onInstall;
equal(reInstall.data.version, "1.0");
equal(reInstall.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
await checkEvent(onInstall, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "1.0",
},
});
const startup = await onStartup;
equal(startup.data.version, "1.0");
equal(startup.reason, BOOTSTRAP_REASONS.ADDON_UPGRADE);
await checkEvent(onStartup, {
reason: BOOTSTRAP_REASONS.ADDON_UPGRADE,
params: {
version: "1.0",
},
});
const addon = await promiseAddonByID(ID);
await addon.uninstall();
@ -648,17 +715,15 @@ add_task(async function() {
return;
}
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_1")], true);
let {addon} = await promiseInstallFile(do_get_addon("test_bootstrap1_1"), true);
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonStarted(ID, "1.0");
let addon = await promiseAddonByID(ID);
Monitor.checkInstalled(ID, "1.0");
Monitor.checkStarted(ID, "1.0");
await addon.disable();
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkInstalled(ID, "1.0");
Monitor.checkNotStarted(ID);
let tempdir = gTmpD.clone();
await promiseWriteInstallRDFToDir({
@ -688,24 +753,23 @@ add_task(async function() {
},
});
await AddonManager.installTemporaryAddon(unpacked_addon);
let tempAddon = await AddonManager.installTemporaryAddon(unpacked_addon);
Assert.ok(extInstallCalled);
let tempAddon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonInstalled(ID, "2.0");
BootstrapMonitor.checkAddonStarted(ID);
Monitor.checkInstalled(ID, "2.0");
Monitor.checkStarted(ID);
// temporary add-on is installed and started
Assert.notEqual(tempAddon, null);
Assert.equal(tempAddon.version, "2.0");
Assert.equal(tempAddon.name, "Test Bootstrap 1 (temporary)");
Assert.ok(tempAddon.isCompatible);
Assert.ok(!tempAddon.appDisabled);
Assert.ok(tempAddon.isActive);
Assert.equal(tempAddon.type, "extension");
Assert.equal(tempAddon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_UNKNOWN : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, tempAddon, {
version: "2.0",
name: "Test Bootstrap 1 (temporary)",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_UNKNOWN : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
await tempAddon.uninstall();
unpacked_addon.remove(true);
@ -714,23 +778,24 @@ add_task(async function() {
await new Promise(executeSoon);
addon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonStarted(ID);
Monitor.checkInstalled(ID, "1.0");
Monitor.checkStarted(ID);
// existing add-on is back
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
Assert.equal(addon.name, "Test Bootstrap 1");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "1.0",
name: "Test Bootstrap 1",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
await addon.uninstall();
BootstrapMonitor.checkAddonNotInstalled(ID);
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkNotInstalled(ID);
Monitor.checkNotStarted(ID);
await promiseRestartManager();
});
@ -742,28 +807,29 @@ add_task(async function() {
let addon = await promiseAddonByID(ID);
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonStarted(ID, "1.0");
Monitor.checkInstalled(ID, "1.0");
Monitor.checkStarted(ID, "1.0");
Assert.notEqual(addon, null);
Assert.equal(addon.version, "1.0");
Assert.equal(addon.name, "Test Bootstrap 1");
Assert.ok(addon.isCompatible);
Assert.ok(!addon.appDisabled);
Assert.ok(addon.isActive);
Assert.equal(addon.type, "extension");
Assert.ok(!addon.isWebExtension);
Assert.equal(addon.signedState, mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED);
checkAddon(ID, addon, {
version: "1.0",
name: "Test Bootstrap 1",
isCompatible: true,
appDisabled: false,
isActive: true,
type: "extension",
isWebExtension: false,
signedState: mozinfo.addon_signing ? AddonManager.SIGNEDSTATE_PRIVILEGED : AddonManager.SIGNEDSTATE_NOT_REQUIRED,
});
await AddonManager.installTemporaryAddon(do_get_addon("test_bootstrap1_1"));
BootstrapMonitor.checkAddonInstalled(ID, "1.0");
BootstrapMonitor.checkAddonStarted(ID, "1.0");
Monitor.checkInstalled(ID, "1.0");
Monitor.checkStarted(ID, "1.0");
await promiseRestartManager();
BootstrapMonitor.checkAddonNotInstalled(ID);
BootstrapMonitor.checkAddonNotStarted(ID);
Monitor.checkNotInstalled(ID);
Monitor.checkNotStarted(ID);
});
// Check that a temporary add-on is marked as such.
@ -771,19 +837,20 @@ add_task(async function() {
await AddonManager.installTemporaryAddon(do_get_addon("test_bootstrap1_1"));
const addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.temporarilyInstalled, true);
checkAddon(ID, addon, {
temporarilyInstalled: true,
});
await promiseRestartManager();
});
// Check that a permanent add-on is not marked as temporarily installed.
add_task(async function() {
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_1")], true);
const addon = await promiseAddonByID(ID);
let {addon} = await promiseInstallFile(do_get_addon("test_bootstrap1_1"), true);
notEqual(addon, null);
equal(addon.temporarilyInstalled, false);
checkAddon(ID, addon, {
temporarilyInstalled: false,
});
await promiseRestartManager();
});