Bug 1678550 - [devtools] Load damp.js using the main DevTools Loader r=perftest-reviewers,nchevobbe,ochameau

Depends on D97626

Differential Revision: https://phabricator.services.mozilla.com/D97727
This commit is contained in:
Julian Descottes 2021-01-04 13:07:08 +00:00
Родитель b45dc96375
Коммит d8c21acf2f
5 изменённых файлов: 106 добавлений и 47 удалений

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

@ -3,7 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const loaders = ChromeUtils.import("resource://devtools/shared/base-loader.js");
const BaseLoader = ChromeUtils.import(
"resource://devtools/shared/base-loader.js"
);
const { require: devtoolsRequire, loader } = ChromeUtils.import(
"resource://devtools/shared/Loader.jsm"
);
@ -94,21 +96,21 @@ function BrowserLoader(options) {
*
* @param string baseURI
* Base path to load modules from.
* @param Object window
* The window instance to evaluate modules within
* @param Boolean useOnlyShared
* If true, ignores `baseURI` and only loads the shared
* BROWSER_BASED_DIRS via BrowserLoader.
* @param Function commonLibRequire
* Require function that should be used to load common libraries, like React.
* Allows for sharing common modules between tools, instead of loading a new
* instance into each tool. For example, pass "toolbox.browserRequire" here.
* @param Boolean useOnlyShared
* If true, ignores `baseURI` and only loads the shared
* BROWSER_BASED_DIRS via BrowserLoader.
* @param Object window
* The window instance to evaluate modules within
*/
function BrowserLoaderBuilder({
baseURI,
window,
useOnlyShared,
commonLibRequire,
useOnlyShared,
window,
}) {
assert(
!!baseURI !== !!useOnlyShared,
@ -198,13 +200,13 @@ function BrowserLoaderBuilder({
},
};
const mainModule = loaders.Module(baseURI, joinURI(baseURI, "main.js"));
this.loader = loaders.Loader(opts);
const mainModule = BaseLoader.Module(baseURI, joinURI(baseURI, "main.js"));
this.loader = BaseLoader.Loader(opts);
// When running tests, expose the BrowserLoader instance for metrics tests.
if (flags.testing) {
window.getBrowserLoaderForWindow = () => this;
}
this.require = loaders.Require(this.loader, mainModule);
this.require = BaseLoader.Require(this.loader, mainModule);
}
BrowserLoaderBuilder.prototype = {

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

@ -78,6 +78,19 @@ function DevToolsLoader({
paths.promise = "resource://gre/modules/Promise-backend.js";
}
// DAMP tests use a dynamic path. If DEBUG_DEVTOOLS_DAMP_TEST_PATH was set as
// a custom preference, add a corresponding path mapping entry.
// DAMP runner and tests are under testing/talos/talos/tests/devtools
const dampTestPath = Services.prefs.getCharPref(
"devtools.damp.test-path",
""
);
if (dampTestPath) {
// damp-test points to testing/talos/talos/tests/devtools/addon/content/
// (prefixed by the dynamically generated talos server)
paths["damp-test"] = dampTestPath;
}
this.loader = new Loader({
paths,
invisibleToDebugger,

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

@ -5,6 +5,9 @@ ChromeUtils.defineModuleGetter(
"Services",
"resource://gre/modules/Services.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
/* globals ExtensionAPI */
this.damp = class extends ExtensionAPI {
@ -13,14 +16,48 @@ this.damp = class extends ExtensionAPI {
damp: {
startTest() {
let { rootURI } = context.extension;
let window = context.appWindow;
if (!("Damp" in window)) {
let script = rootURI.resolve("content/damp.js");
Services.scriptloader.loadSubScript(script, window);
}
let damp = new window.Damp();
return damp.startTest(rootURI);
// Some notes about using a DevTools loader for DAMP.
//
// 1. The DAMP loader needs to be same loader as the one used by the
// toolbox later on. Otherwise, we will not retrieve the proper
// instance of some modules.
// The main devtools loader is the exported `loader` from Loader.jsm,
// we have to use that.
//
// 2. The DAMP test path is dynamic, so we cannot hardcode the path
// mapping in the DevTools loader. To workaround this, we set the path
// in an env variable. This will then be read by Loader.jsm when it
// creates the main DevTools loader. It is important to set this
// before accessing the Loader for the first time.
//
// 3. DAMP contains at least one protocol test that loads a DAMP test
// file in the content process (tests/server/protocol.js). In order
// for the damp-test path mapping to work, Loaders in all processes
// should be able to read the "damp test path" information. We use
// use a custom preference to make the information available to
// all processes.
dump("[damp-api] Expose damp test path as a char preference\n");
// dampTestPath points to testing/talos/talos/tests/devtools/addon/content/
// (prefixed by the dynamically generated talos server)
const dampTestPath = rootURI.resolve("content");
Services.prefs.setCharPref("devtools.damp.test-path", dampTestPath);
dump("[damp-api] Retrieve the main DevTools loader\n");
const { loader, require } = ChromeUtils.import(
"resource://devtools/shared/Loader.jsm"
);
// The loader should already support the damp-test path mapping.
// We add two additional globals.
loader.loader.globals.rootURI = rootURI;
loader.loader.globals.dampWindow = context.appWindow;
dump("[damp-api] Instanciate the DAMP runner and start the test\n");
const { Damp } = require("damp-test/damp");
const damp = new Damp();
return damp.startTest();
},
},
};

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

@ -1,19 +1,27 @@
"use strict";
/* globals dampWindow, exports, require, res:true, rootURI */
// eslint-disable-next-line mozilla/no-define-cc-etc
const { Ci, Cc, Cu } = require("chrome");
const {
gBrowser,
MozillaFileLogger,
performance,
requestIdleCallback,
} = dampWindow;
const ChromeUtils = require("ChromeUtils");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const { AddonManager } = ChromeUtils.import(
"resource://gre/modules/AddonManager.jsm"
);
const env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
XPCOMUtils.defineLazyGetter(this, "require", function() {
let { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
return require;
});
// Record allocation count in new subtests if DEBUG_DEVTOOLS_ALLOCATIONS is set to
// "normal". Print allocation sites to stdout if DEBUG_DEVTOOLS_ALLOCATIONS is set to
// "verbose".
@ -28,8 +36,6 @@ function getMostRecentBrowserWindow() {
return Services.wm.getMostRecentWindow("navigator:browser");
}
/* globals res:true */
function Damp() {}
Damp.prototype = {
@ -239,7 +245,7 @@ Damp.prototype = {
_done: false,
_runNextTest() {
window.clearTimeout(this._timeout);
clearTimeout(this._timeout);
if (this._nextTestIndex >= this._tests.length) {
this._onSequenceComplete();
@ -251,9 +257,9 @@ Damp.prototype = {
this._currentTest = test;
dump(`Loading test '${test}'\n`);
let testMethod = require(this.rootURI.resolve(`content/tests/${test}`));
let testMethod = require(`damp-test/tests/${test}`);
this._timeout = window.setTimeout(() => {
this._timeout = setTimeout(() => {
this.error("Test timed out");
}, TEST_TIMEOUT);
@ -278,11 +284,11 @@ Damp.prototype = {
},
_log(str) {
if (window.MozillaFileLogger && window.MozillaFileLogger.log) {
window.MozillaFileLogger.log(str);
if (MozillaFileLogger && MozillaFileLogger.log) {
MozillaFileLogger.log(str);
}
window.dump(str);
dump(str);
},
_logLine(str) {
@ -295,7 +301,7 @@ Damp.prototype = {
var out = "";
for (var i in this._results) {
res = this._results[i];
const res = this._results[i];
var disp = []
.concat(res.value)
.map(function(a) {
@ -418,15 +424,18 @@ Damp.prototype = {
await this.garbageCollect();
},
startTest(rootURI) {
/**
* This is the main entry point for DAMP, called from
* testing/talos/talos/tests/devtools/addon/api
*/
startTest() {
let promise = new Promise(resolve => {
this.testDone = resolve;
});
this.rootURI = rootURI;
try {
dump("Initialize the head file with a reference to this DAMP instance\n");
let head = require(rootURI.resolve("content/tests/head.js"));
let head = require("damp-test/tests/head.js");
head.initialize(this);
this._registerDampLoadActors();
@ -438,7 +447,7 @@ Damp.prototype = {
// Filter tests via `./mach --subtests filter` command line argument
let filter = Services.prefs.getCharPref("talos.subtests", "");
let DAMP_TESTS = require(rootURI.resolve("content/damp-tests.js"));
let DAMP_TESTS = require("damp-test/damp-tests.js");
let tests = DAMP_TESTS.filter(test => !test.disabled).filter(test =>
test.name.includes(filter)
);
@ -506,10 +515,10 @@ Damp.prototype = {
ChromeUtils.registerWindowActor("DampLoad", {
kind: "JSWindowActor",
parent: {
moduleURI: this.rootURI.resolve("content/actors/DampLoadParent.jsm"),
moduleURI: rootURI.resolve("content/actors/DampLoadParent.jsm"),
},
child: {
moduleURI: this.rootURI.resolve("content/actors/DampLoadChild.jsm"),
moduleURI: rootURI.resolve("content/actors/DampLoadChild.jsm"),
events: {
pageshow: { mozSystemGroup: true },
},
@ -528,12 +537,12 @@ Damp.prototype = {
_getDampLoadEventDispatcher() {
if (!this._dampLoadEventDispatcher) {
const DampLoadParentModule = ChromeUtils.import(
this.rootURI.resolve("content/actors/DampLoadParent.jsm")
);
const DampLoadParentModule = require("damp-test/actors/DampLoadParent.jsm");
this._dampLoadEventDispatcher = DampLoadParentModule.EventDispatcher;
}
return this._dampLoadEventDispatcher;
},
};
exports.Damp = Damp;

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

@ -37,8 +37,6 @@ module.exports = async function() {
let tab = await testSetup(SIMPLE_URL);
let messageManager = tab.linkedBrowser.messageManager;
let url = module.uri.replace(/protocol\.js$/, "actor.js");
// Register a test actor within the content process
messageManager.loadFrameScript(
"data:,(" +
@ -47,7 +45,7 @@ module.exports = async function() {
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
const { ActorRegistry } = require("devtools/server/actors/utils/actor-registry");
ActorRegistry.registerModule("${url}", {
ActorRegistry.registerModule("damp-test/tests/server/actor.js", {
prefix: "dampTest",
constructor: "DampTestActor",
type: { target: true }