Backed out changeset 2a6ee5724361 (bug 1522214) for XPCshell failure in toolkit/components/extensions/test/xpcshell/test_load_all_api_modules.js

This commit is contained in:
Dorel Luca 2019-06-27 10:44:29 +03:00
Родитель a2e31cbc26
Коммит 920ce17938
18 изменённых файлов: 60 добавлений и 502 удалений

Просмотреть файл

@ -122,7 +122,7 @@ const WEBEXT_STORAGE_USER_CONTEXT_ID = -1 >>> 0;
const CHILD_SHUTDOWN_TIMEOUT_MS = 8000;
// Permissions that are only available to privileged extensions.
const PRIVILEGED_PERMS = new Set(["mozillaAddons", "geckoViewAddons", "telemetry", "urlbar", "normandyAddonStudy"]);
const PRIVILEGED_PERMS = new Set(["mozillaAddons", "geckoViewAddons", "telemetry", "urlbar"]);
/**
* Classify an individual permission from a webextension manifest

Просмотреть файл

@ -106,14 +106,6 @@
["management"]
]
},
"normandyAddonStudy": {
"url": "chrome://extensions/content/parent/ext-normandyAddonStudy.js",
"schema": "chrome://extensions/content/schemas/normandyAddonStudy.json",
"scopes": ["addon_parent", "content_parent", "devtools_parent"],
"paths": [
["normandyAddonStudy"]
]
},
"notifications": {
"url": "chrome://extensions/content/parent/ext-notifications.js",
"schema": "chrome://extensions/content/schemas/notifications.json",

Просмотреть файл

@ -29,7 +29,6 @@ toolkit.jar:
#endif
content/extensions/parent/ext-idle.js (parent/ext-idle.js)
content/extensions/parent/ext-management.js (parent/ext-management.js)
content/extensions/parent/ext-normandyAddonStudy.js (parent/ext-normandyAddonStudy.js)
content/extensions/parent/ext-notifications.js (parent/ext-notifications.js)
content/extensions/parent/ext-permissions.js (parent/ext-permissions.js)
content/extensions/parent/ext-privacy.js (parent/ext-privacy.js)

Просмотреть файл

@ -1,75 +0,0 @@
"use strict";
const {AddonStudies} = ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm");
const {ClientID} = ChromeUtils.import("resource://gre/modules/ClientID.jsm");
ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
this.normandyAddonStudy = class extends ExtensionAPI {
getAPI(context) {
let {extension} = context;
return {
normandyAddonStudy: {
/**
* Returns a study object for the current study.
*
* @returns {Study}
*/
async getStudy() {
const studies = await AddonStudies.getAll();
return studies.find(study => study.addonId === extension.id);
},
/**
* Marks the study as ended and then uninstalls the addon.
*
* @param {string} reason Why the study is ending
*/
async endStudy(reason) {
const study = await this.getStudy();
// Mark the study as ended
await AddonStudies.markAsEnded(study, reason);
// Uninstall the addon
const addon = await AddonManager.getAddonByID(study.addonId);
if (addon) {
await addon.uninstall();
}
},
/**
* Returns an object with metadata about the client which may
* be required for constructing survey URLs.
*
* @returns {Object}
*/
async getClientMetadata() {
return {
updateChannel: Services.appinfo.defaultUpdateChannel,
fxVersion: Services.appinfo.version,
clientID: await ClientID.getClientID(),
};
},
onUnenroll: new EventManager({
context,
name: "normandyAddonStudy.onUnenroll",
register: (fire) => {
const listener = async (reason) => {
await fire.async(reason);
};
AddonStudies.addUnenrollListener(extension.id, listener);
return () => {
AddonStudies.removeUnenrollListener(extension.id, listener);
};
},
}).api(),
},
};
}
};

Просмотреть файл

@ -31,7 +31,6 @@ toolkit.jar:
content/extensions/schemas/management.json
content/extensions/schemas/manifest.json
content/extensions/schemas/native_manifest.json
content/extensions/schemas/normandyAddonStudy.json
content/extensions/schemas/notifications.json
content/extensions/schemas/permissions.json
content/extensions/schemas/proxy.json

Просмотреть файл

@ -1,130 +0,0 @@
[
{
"namespace": "manifest",
"types": [{
"$extend": "Permission",
"choices": [{
"type": "string",
"enum": [
"normandyAddonStudy"
]
}]
}]
},
{
"namespace": "normandyAddonStudy",
"description": "Normandy Study API",
"allowedContexts": ["content", "devtools"],
"defaultContexts": ["content", "devtools"],
"permissions": [
"normandyAddonStudy"
],
"types": [
{
"id": "Study",
"type": "object",
"properties": {
"recipeId": {
"type": "integer",
"description": "The ID of the recipe for the study."
},
"slug": {
"type": "string",
"description": "A slug to identify the study."
},
"userFacingName": {
"type": "string",
"description": "The name presented on about:studies."
},
"userFacingDescription": {
"type": "string",
"description": "The description presented on about:studies."
},
"branch": {
"type": "string",
"description": "The study branch in which the user is enrolled."
},
"active": {
"type": "boolean",
"description": "The state of the study."
},
"addonId": {
"type": "string",
"description": "The ID of the extension installed by the study."
},
"addonUrl": {
"type": "string",
"description": "The URL of the XPI that was downloaded and installed by the study."
},
"addonVersion": {
"type": "string",
"description": "The version of the extension installed by the study."
},
"studyStartDate": {
"$ref": "extensionTypes.Date",
"description": "The start date for the study."
},
"studyEndDate": {
"$ref": "extensionTypes.Date",
"description": "The end date for the study."
},
"extensionApiId": {
"type": "integer",
"description": "The record ID for the extension in Normandy server's database."
},
"extensionHash": {
"type": "string",
"description": "A hash of the extension XPI file."
},
"extensionHashAlgorithm": {
"type": "string",
"description": "The algorithm used to hash the extension XPI file."
}
}
}
],
"functions": [
{
"name": "getStudy",
"type": "function",
"description": "Returns a study object for the current study.",
"async": true,
"parameters": []
},
{
"name": "endStudy",
"type": "function",
"description": "Marks the study as ended and then uninstalls the addon.",
"async": true,
"parameters": [
{
"type": "string",
"name": "reason",
"description": "The reason why the study is ending."
}
]
},
{
"name": "getClientMetadata",
"type": "function",
"description": "Returns an object with metadata about the client which may be required for constructing survey URLs.",
"async": true,
"parameters": []
}
],
"events": [
{
"name": "onUnenroll",
"type": "function",
"description": "Fired when a user unenrolls from a study but before the addon is uninstalled.",
"parameters": [
{
"type": "string",
"name": "reason",
"description": "The reason why the study is ending."
}
]
}
]
}
]

Просмотреть файл

@ -1,176 +0,0 @@
"use strict";
ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
const {AddonStudies} = ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm");
const {NormandyTestUtils} = ChromeUtils.import("resource://testing-common/NormandyTestUtils.jsm");
const {TestUtils} = ChromeUtils.import("resource://testing-common/TestUtils.jsm");
const {addonStudyFactory} = NormandyTestUtils.factories;
AddonTestUtils.init(this);
// All tests run privileged unless otherwise specified not to.
function createExtension(backgroundScript, permissions, isPrivileged = true) {
let extensionData = {
background: backgroundScript,
manifest: {
applications: {
gecko: {
id: "test@shield.mozilla.com",
},
},
permissions,
},
isPrivileged,
};
return ExtensionTestUtils.loadExtension(extensionData);
}
async function run(test) {
let extension = createExtension(
test.backgroundScript,
test.permissions || ["normandyAddonStudy"],
test.isPrivileged
);
await extension.startup();
if (test.doneSignal) {
await extension.awaitFinish(test.doneSignal);
} else if (test.validationScript) {
await test.validationScript(extension);
}
await extension.unload();
}
add_task(async function setup() {
await ExtensionTestUtils.startAddonManager();
});
add_task(async function test_normandyAddonStudy_without_normandyAddonStudy_permission_privileged() {
await run({
backgroundScript: () => {
browser.test.assertTrue(!browser.normandyAddonStudy, "'normandyAddonStudy' permission is required");
browser.test.notifyPass("normandyAddonStudy_permission");
},
permissions: [],
doneSignal: "normandyAddonStudy_permission",
});
});
add_task(async function test_normandyAddonStudy_without_privilege() {
await run({
backgroundScript: () => {
browser.test.assertTrue(!browser.normandyAddonStudy, "Extension must be privileged");
browser.test.notifyPass("normandyAddonStudy_permission");
},
isPrivileged: false,
doneSignal: "normandyAddonStudy_permission",
});
});
add_task(async function test_getStudy_works() {
const study = addonStudyFactory({
addonId: "test@shield.mozilla.com",
});
const testWrapper = AddonStudies.withStudies([study]);
const test = testWrapper(async () => {
await run({
backgroundScript: async () => {
const result = await browser.normandyAddonStudy.getStudy();
browser.test.sendMessage("study", result);
},
validationScript: async extension => {
let studyResult = await extension.awaitMessage("study");
deepEqual(studyResult, study, "normandyAddonStudy.getStudy returns the correct study");
},
});
});
await test();
});
add_task(async function test_endStudy_works() {
const study = addonStudyFactory({
addonId: "test@shield.mozilla.com",
});
const testWrapper = AddonStudies.withStudies([study]);
const test = testWrapper(async () => {
await run({
backgroundScript: async () => {
await browser.normandyAddonStudy.endStudy("test");
},
validationScript: async () => {
// Check that `AddonStudies.markAsEnded` was called
await TestUtils.topicObserved("shield-study-ended", (subject, message) => {
return message === `${study.recipeId}`;
});
const addon = await AddonManager.getAddonByID(study.addonId);
equal(addon, undefined, "Addon should be uninstalled.");
},
});
});
await test();
});
add_task(async function test_getClientMetadata_works() {
const study = addonStudyFactory({
addonId: "test@shield.mozilla.com",
slug: "test-slug",
branch: "test-branch",
});
const testWrapper = AddonStudies.withStudies([study]);
const test = testWrapper(async () => {
await run({
backgroundScript: async () => {
const metadata = await browser.normandyAddonStudy.getClientMetadata();
browser.test.sendMessage("clientMetadata", metadata);
},
validationScript: async extension => {
let clientMetadata = await extension.awaitMessage("clientMetadata");
ok(
clientMetadata.updateChannel === Services.appinfo.defaultUpdateChannel,
"clientMetadata contains correct updateChannel",
);
ok(
clientMetadata.fxVersion === Services.appinfo.version,
"clientMetadata contains correct fxVersion",
);
ok("clientID" in clientMetadata, "clientMetadata contains a clientID");
},
});
});
await test();
});
add_task(async function test_onUnenroll_works() {
const study = addonStudyFactory({
addonId: "test@shield.mozilla.com",
});
const testWrapper = AddonStudies.withStudies([study]);
const test = testWrapper(async () => {
await run({
backgroundScript: async () => {
browser.normandyAddonStudy.onUnenroll.addListener(reason => {
browser.test.sendMessage("unenrollReason", reason);
});
},
validationScript: async extension => {
await AddonStudies.markAsEnded(study, "test");
const unenrollReason = await extension.awaitMessage("unenrollReason");
equal(unenrollReason, "test", "Unenroll listener should be called.");
},
});
});
await test();
});

Просмотреть файл

@ -439,7 +439,6 @@ const GRANTED_WITHOUT_USER_PROMPT = [
"menus",
"menus.overrideContext",
"mozillaAddons",
"normandyAddonStudy",
"search",
"storage",
"telemetry",

Просмотреть файл

@ -76,7 +76,6 @@ skip-if = os == "android" # Not shipped on Android
skip-if = (os == "win" && !debug) #Bug 1419183 disable on Windows
[test_ext_management_uninstall_self.js]
[test_ext_messaging_startup.js]
[test_ext_normandyAddonStudy.js]
skip-if = appname == "thunderbird" || (os == "android" && debug)
[test_ext_onmessage_removelistener.js]
skip-if = true # This test no longer tests what it is meant to test.

Просмотреть файл

@ -344,24 +344,10 @@ var AddonStudies = {
listeners.add(listener);
},
/**
* Unregister a callback to be invoked when a given study ends.
*
* @param {string} id The extension id
* @param {function} listener The callback
*/
removeUnenrollListener(id, listener) {
let listeners = this._unenrollListeners.get(id);
if (listeners) {
listeners.delete(listener);
}
},
/**
* Invoke the unenroll callback (if any) for the given extension
*
* @param {string} id The extension id
* @param {string} reason Why the study is ending
*
* @returns {Promise} A Promise resolved after the unenroll listener
* (if any) has finished its unenroll tasks.

Просмотреть файл

@ -13,10 +13,6 @@ EXTRA_JS_MODULES += [
'ShieldContentProcess.jsm',
]
TESTING_JS_MODULES += [
'test/NormandyTestUtils.jsm',
]
XPCOM_MANIFESTS += [
'components.conf',
]

Просмотреть файл

@ -1,75 +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/. */
"use strict";
ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm", this);
const FIXTURE_ADDON_ID = "normandydriver-a@example.com";
var EXPORTED_SYMBOLS = ["NormandyTestUtils"];
// Factory IDs
let _addonStudyFactoryId = 0;
let _preferenceStudyFactoryId = 0;
const NormandyTestUtils = {
factories: {
addonStudyFactory(attrs) {
for (const key of ["name", "description"]) {
if (attrs && attrs[key]) {
throw new Error(`${key} is no longer a valid key for addon studies, please update to v2 study schema`);
}
}
return Object.assign({
recipeId: _addonStudyFactoryId++,
slug: "test-study",
userFacingName: "Test study",
userFacingDescription: "test description",
branch: AddonStudies.NO_BRANCHES_MARKER,
active: true,
addonId: FIXTURE_ADDON_ID,
addonUrl: "http://test/addon.xpi",
addonVersion: "1.0.0",
studyStartDate: new Date(),
studyEndDate: null,
extensionApiId: 1,
extensionHash: "ade1c14196ec4fe0aa0a6ba40ac433d7c8d1ec985581a8a94d43dc58991b5171",
extensionHashAlgorithm: "sha256",
}, attrs);
},
branchedAddonStudyFactory(attrs) {
return NormandyTestUtils.factories.addonStudyFactory(Object.assign({
branch: "a",
}, attrs));
},
preferenceStudyFactory(attrs) {
const defaultPref = {
"test.study": {},
};
const defaultPrefInfo = {
preferenceValue: false,
preferenceType: "boolean",
previousPreferenceValue: undefined,
preferenceBranchType: "default",
};
const preferences = {};
for (const [prefName, prefInfo] of Object.entries(attrs.preferences || defaultPref)) {
preferences[prefName] = { ...defaultPrefInfo, ...prefInfo };
}
return Object.assign({
name: `Test study ${_preferenceStudyFactoryId++}`,
branch: "control",
expired: false,
lastSeen: new Date().toJSON(),
experimentType: "exp",
}, attrs, {
preferences,
});
},
},
};

Просмотреть файл

@ -7,9 +7,6 @@ ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm", this);
ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm", this);
ChromeUtils.import("resource://normandy/lib/TelemetryEvents.jsm", this);
const {NormandyTestUtils} = ChromeUtils.import("resource://testing-common/NormandyTestUtils.jsm");
const {addonStudyFactory} = NormandyTestUtils.factories;
// Initialize test utils
AddonTestUtils.initMochitest(this);

Просмотреть файл

@ -7,9 +7,6 @@ ChromeUtils.import("resource://normandy/lib/ShieldPreferences.jsm", this);
const OPT_OUT_STUDIES_ENABLED_PREF = "app.shield.optoutstudies.enabled";
const {NormandyTestUtils} = ChromeUtils.import("resource://testing-common/NormandyTestUtils.jsm");
const {addonStudyFactory, preferenceStudyFactory} = NormandyTestUtils.factories;
ShieldPreferences.init();
decorate_task(

Просмотреть файл

@ -5,9 +5,6 @@ ChromeUtils.import("resource://normandy/lib/PreferenceExperiments.jsm", this);
ChromeUtils.import("resource://normandy/lib/RecipeRunner.jsm", this);
ChromeUtils.import("resource://normandy-content/AboutPages.jsm", this);
const {NormandyTestUtils} = ChromeUtils.import("resource://testing-common/NormandyTestUtils.jsm");
const {addonStudyFactory, preferenceStudyFactory} = NormandyTestUtils.factories;
function withAboutStudies(testFunc) {
return async (...args) => (
BrowserTestUtils.withNewTab("about:studies", async browser => (

Просмотреть файл

@ -6,9 +6,6 @@ ChromeUtils.import("resource://normandy/actions/AddonStudyAction.jsm", this);
ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm", this);
ChromeUtils.import("resource://normandy/lib/Uptake.jsm", this);
const {NormandyTestUtils} = ChromeUtils.import("resource://testing-common/NormandyTestUtils.jsm");
const {addonStudyFactory} = NormandyTestUtils.factories;
function addonStudyRecipeFactory(overrides = {}) {
let args = {
name: "Fake name",

Просмотреть файл

@ -6,9 +6,6 @@ ChromeUtils.import("resource://normandy/actions/BranchedAddonStudyAction.jsm", t
ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm", this);
ChromeUtils.import("resource://normandy/lib/Uptake.jsm", this);
const {NormandyTestUtils} = ChromeUtils.import("resource://testing-common/NormandyTestUtils.jsm");
const {branchedAddonStudyFactory} = NormandyTestUtils.factories;
function branchedAddonStudyRecipeFactory(overrides = {}) {
let args = {
slug: "fake-slug",

Просмотреть файл

@ -254,6 +254,65 @@ this.decorate_task = function(...args) {
return add_task(decorate(...args));
};
let _addonStudyFactoryId = 0;
this.addonStudyFactory = function(attrs = {}) {
for (const key of ["name", "description"]) {
if (attrs[key]) {
throw new Error(`${key} is no longer a valid key for addon studies, please update to v2 study schema`);
}
}
return Object.assign({
recipeId: _addonStudyFactoryId++,
slug: "test-study",
userFacingName: "Test study",
userFacingDescription: "test description",
branch: AddonStudies.NO_BRANCHES_MARKER,
active: true,
addonId: FIXTURE_ADDON_ID,
addonUrl: "http://test/addon.xpi",
addonVersion: "1.0.0",
studyStartDate: new Date(),
studyEndDate: null,
extensionApiId: 1,
extensionHash: "ade1c14196ec4fe0aa0a6ba40ac433d7c8d1ec985581a8a94d43dc58991b5171",
extensionHashAlgorithm: "sha256",
}, attrs);
};
this.branchedAddonStudyFactory = function(attrs) {
return this.addonStudyFactory(Object.assign({
branch: "a",
}, attrs));
};
let _preferenceStudyFactoryId = 0;
this.preferenceStudyFactory = function(attrs) {
const defaultPref = {
"test.study": {},
};
const defaultPrefInfo = {
preferenceValue: false,
preferenceType: "boolean",
previousPreferenceValue: undefined,
preferenceBranchType: "default",
};
const preferences = {};
for (const [prefName, prefInfo] of Object.entries(attrs.preferences || defaultPref)) {
preferences[prefName] = { ...defaultPrefInfo, ...prefInfo };
}
return Object.assign({
name: `Test study ${_preferenceStudyFactoryId++}`,
branch: "control",
expired: false,
lastSeen: new Date().toJSON(),
experimentType: "exp",
}, attrs, {
preferences,
});
};
this.withStub = function(...stubArgs) {
return function wrapper(testFunction) {
return async function wrappedTestFunction(...args) {