Bug 1789270 - Add support for workers in xpcshell tests; r=dom-storage-reviewers,jari

Differential Revision: https://phabricator.services.mozilla.com/D156475
This commit is contained in:
Randell Jesup 2022-09-07 01:14:53 +00:00
parent 72698bc548
commit f963bf99b1
18 changed files with 329 additions and 9 deletions

View File

@ -11,3 +11,8 @@ MOCHITEST_MANIFESTS += [
XPCSHELL_TESTS_MANIFESTS += [
"xpcshell.ini",
]
TESTING_JS_MODULES.dom.fs.test.common += [
"nsresult.js",
"test_basics.js",
]

View File

@ -31,7 +31,22 @@ async function run_test_in_worker(script) {
const { runTestInWorker } = await import(
"/tests/dom/quota/test/modules/WorkerDriver.js"
);
await runTestInWorker(script);
const base = window.location.href;
const listener = {
onOk(value, message) {
ok(value, message);
},
onIs(a, b, message) {
is(a, b, message);
},
onInfo(message) {
info(message);
},
};
await runTestInWorker(script, base, listener);
}
add_setup(async function() {

View File

@ -29,6 +29,28 @@ async function require_module(id) {
return require_module.moduleLoader.require(id);
}
async function run_test_in_worker(script) {
const { runTestInWorker } = ChromeUtils.import(
"resource://testing-common/dom/quota/test/modules/WorkerDriver.jsm"
);
const base = "resource://testing-common/dom/fs/test/xpcshell/";
const listener = {
onOk(value, message) {
ok(value, message);
},
onIs(a, b, message) {
Assert.equal(a, b, message);
},
onInfo(message) {
info(message);
},
};
await runTestInWorker(script, base, listener);
}
add_setup(async function() {
const {
setStoragePrefs,

View File

@ -4,6 +4,10 @@
# 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/.
TEST_DIRS += [
"worker",
]
XPCSHELL_TESTS_MANIFESTS += [
"xpcshell.ini",
]

View File

@ -0,0 +1,8 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
add_task(async function worker() {
await run_test_in_worker("worker/test_basics_worker.js");
});

View File

@ -0,0 +1,12 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
module.exports = {
env: {
worker: true,
},
};

View File

View File

@ -0,0 +1,20 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
async function require_module(id) {
if (!require_module.moduleLoader) {
importScripts("/dom/quota/test/modules/worker/ModuleLoader.js");
const base = location.href;
const depth = "../../../../../";
importScripts("/dom/quota/test/modules/worker/Assert.js");
require_module.moduleLoader = new globalThis.ModuleLoader(base, depth);
}
return require_module.moduleLoader.require(id);
}

View File

@ -0,0 +1,10 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
TESTING_JS_MODULES.dom.fs.test.xpcshell.worker += [
"head.js",
"test_basics_worker.js",
]

View File

@ -0,0 +1,11 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
add_task(async function init() {
const testCases = await require_module("dom/fs/test/common/test_basics.js");
Object.values(testCases).forEach(async testItem => {
add_task(testItem);
});
});

View File

@ -6,4 +6,5 @@
head = head.js
[test_basics.js]
[test_basics_worker.js]
[test_fileSystemDirectoryHandle.js]

View File

@ -3,11 +3,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
export async function runTestInWorker(script) {
export async function runTestInWorker(script, base, listener) {
return new Promise(function(resolve) {
const globalHeadUrl = new URL(
"/tests/dom/quota/test/modules/worker/head.js",
window.location.href
base
);
const worker = new Worker(globalHeadUrl.href);
@ -17,15 +17,15 @@ export async function runTestInWorker(script) {
switch (data.op) {
case "ok":
ok(data.value, data.message);
listener.onOk(data.value, data.message);
break;
case "is":
is(data.a, data.b, data.message);
listener.onIs(data.a, data.b, data.message);
break;
case "info":
info(data.message);
listener.onInfo(data.message);
break;
case "finish":
@ -33,18 +33,18 @@ export async function runTestInWorker(script) {
break;
case "failure":
ok(false, "Worker had a failure: " + data.message);
listener.onOk(false, "Worker had a failure: " + data.message);
resolve();
break;
}
};
worker.onerror = function(event) {
ok(false, "Worker had an error: " + event.data);
listener.onOk(false, "Worker had an error: " + event.data);
resolve();
};
const scriptUrl = new URL(script, window.location.href);
const scriptUrl = new URL(script, base);
const localHeadUrl = new URL("head.js", scriptUrl);

View File

@ -0,0 +1,54 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
async function runTestInWorker(script, base, listener) {
return new Promise(function(resolve) {
const globalHeadUrl = new URL(
"resource://testing-common/dom/quota/test/modules/worker/head.js"
);
const worker = new Worker(globalHeadUrl.href);
worker.onmessage = function(event) {
const data = event.data;
switch (data.op) {
case "ok":
listener.onOk(data.value, data.message);
break;
case "is":
listener.onIs(data.a, data.b, data.message);
break;
case "info":
listener.onInfo(data.message);
break;
case "finish":
resolve();
break;
case "failure":
listener.onOk(false, "Worker had a failure: " + data.message);
resolve();
break;
}
};
worker.onerror = function(event) {
listener.onOk(false, "Worker had an error: " + event.data);
resolve();
};
const scriptUrl = new URL(script, base);
const localHeadUrl = new URL("head.js", scriptUrl);
worker.postMessage([localHeadUrl.href, scriptUrl.href]);
});
}
const EXPORTED_SYMBOLS = ["runTestInWorker"];

View File

@ -0,0 +1,21 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
module.exports = {
env: {
worker: true,
},
overrides: [
{
files: ["head.js"],
env: {
worker: true,
},
},
],
};

View File

@ -0,0 +1,22 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const Assert = {
ok(value, message) {
postMessage({
op: "ok",
value: !!value,
message,
});
},
equal(a, b, message) {
postMessage({
op: "is",
a,
b,
message,
});
},
};

View File

@ -0,0 +1,52 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function ModuleLoader(base, depth, proto) {
const modules = {};
const require = async function(id) {
if (modules[id]) {
return modules[id].exported_symbols;
}
const url = new URL(depth + id, base);
const module = Object.create(null, {
exported_symbols: {
configurable: false,
enumerable: true,
value: Object.create(null),
writable: true,
},
});
modules[id] = module;
const xhr = new XMLHttpRequest();
xhr.open("GET", url.href, false);
xhr.responseType = "text";
xhr.send();
let source = xhr.responseText;
let code = new Function(
"require_module",
"exported_symbols",
`eval(arguments[2] + "\\n//# sourceURL=" + arguments[3] + "\\n")`
);
code(require, module.exported_symbols, source, url.href);
return module.exported_symbols;
};
const returnObj = {
require: {
enumerable: true,
value: require,
},
};
return Object.create(null, returnObj);
}

View File

@ -0,0 +1,56 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// eslint-disable-next-line mozilla/no-define-cc-etc
const Cr = {
NS_ERROR_NOT_IMPLEMENTED: 2147500033,
};
function add_task(func) {
if (!add_task.tasks) {
add_task.tasks = [];
add_task.index = 0;
}
add_task.tasks.push(func);
}
addEventListener("message", async function onMessage(event) {
function info(message) {
postMessage({ op: "info", message });
}
function executeSoon(callback) {
const channel = new MessageChannel();
channel.port1.postMessage("");
channel.port2.onmessage = function() {
callback();
};
}
function runNextTest() {
if (add_task.index < add_task.tasks.length) {
const task = add_task.tasks[add_task.index++];
info("add_task | Entering test " + task.name);
task()
.then(function() {
executeSoon(runNextTest);
info("add_task | Leaving test " + task.name);
})
.catch(function(ex) {
postMessage({ op: "failure", message: "" + ex });
});
} else {
postMessage({ op: "finish" });
}
}
removeEventListener("message", onMessage);
const data = event.data;
importScripts(...data);
executeSoon(runNextTest);
});

View File

@ -66,4 +66,11 @@ TEST_HARNESS_FILES.xpcshell.dom.quota.test.xpcshell.common += [
TESTING_JS_MODULES.dom.quota.test.modules += [
"modules/system/ModuleLoader.jsm",
"modules/system/StorageUtils.jsm",
"modules/system/WorkerDriver.jsm",
]
TESTING_JS_MODULES.dom.quota.test.modules.worker += [
"modules/system/worker/Assert.js",
"modules/system/worker/head.js",
"modules/system/worker/ModuleLoader.js",
]