From f963bf99b19e675a5ef379d301cd619c1e667de5 Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Wed, 7 Sep 2022 01:14:53 +0000 Subject: [PATCH] Bug 1789270 - Add support for workers in xpcshell tests; r=dom-storage-reviewers,jari Differential Revision: https://phabricator.services.mozilla.com/D156475 --- dom/fs/test/common/moz.build | 5 ++ dom/fs/test/mochitest/head.js | 17 +++++- dom/fs/test/xpcshell/head.js | 22 ++++++++ dom/fs/test/xpcshell/moz.build | 4 ++ dom/fs/test/xpcshell/test_basics_worker.js | 8 +++ dom/fs/test/xpcshell/worker/.eslintrc.js | 12 ++++ dom/fs/test/xpcshell/worker/dummy.js | 0 dom/fs/test/xpcshell/worker/head.js | 20 +++++++ dom/fs/test/xpcshell/worker/moz.build | 10 ++++ .../xpcshell/worker/test_basics_worker.js | 11 ++++ dom/fs/test/xpcshell/xpcshell.ini | 1 + .../test/modules/content/WorkerDriver.js | 16 +++--- .../test/modules/system/WorkerDriver.jsm | 54 ++++++++++++++++++ .../test/modules/system/worker/.eslintrc.js | 21 +++++++ .../test/modules/system/worker/Assert.js | 22 ++++++++ .../modules/system/worker/ModuleLoader.js | 52 +++++++++++++++++ dom/quota/test/modules/system/worker/head.js | 56 +++++++++++++++++++ dom/quota/test/moz.build | 7 +++ 18 files changed, 329 insertions(+), 9 deletions(-) create mode 100644 dom/fs/test/xpcshell/test_basics_worker.js create mode 100644 dom/fs/test/xpcshell/worker/.eslintrc.js create mode 100644 dom/fs/test/xpcshell/worker/dummy.js create mode 100644 dom/fs/test/xpcshell/worker/head.js create mode 100644 dom/fs/test/xpcshell/worker/moz.build create mode 100644 dom/fs/test/xpcshell/worker/test_basics_worker.js create mode 100644 dom/quota/test/modules/system/WorkerDriver.jsm create mode 100644 dom/quota/test/modules/system/worker/.eslintrc.js create mode 100644 dom/quota/test/modules/system/worker/Assert.js create mode 100644 dom/quota/test/modules/system/worker/ModuleLoader.js create mode 100644 dom/quota/test/modules/system/worker/head.js diff --git a/dom/fs/test/common/moz.build b/dom/fs/test/common/moz.build index d202a59b0995..e4c6acda7ce0 100644 --- a/dom/fs/test/common/moz.build +++ b/dom/fs/test/common/moz.build @@ -11,3 +11,8 @@ MOCHITEST_MANIFESTS += [ XPCSHELL_TESTS_MANIFESTS += [ "xpcshell.ini", ] + +TESTING_JS_MODULES.dom.fs.test.common += [ + "nsresult.js", + "test_basics.js", +] diff --git a/dom/fs/test/mochitest/head.js b/dom/fs/test/mochitest/head.js index bc3ba8e00936..ae58b62f2143 100644 --- a/dom/fs/test/mochitest/head.js +++ b/dom/fs/test/mochitest/head.js @@ -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() { diff --git a/dom/fs/test/xpcshell/head.js b/dom/fs/test/xpcshell/head.js index 810a5c3c950d..7417eb0ef08b 100644 --- a/dom/fs/test/xpcshell/head.js +++ b/dom/fs/test/xpcshell/head.js @@ -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, diff --git a/dom/fs/test/xpcshell/moz.build b/dom/fs/test/xpcshell/moz.build index 3d8553203499..108d89b0a9e4 100644 --- a/dom/fs/test/xpcshell/moz.build +++ b/dom/fs/test/xpcshell/moz.build @@ -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", ] diff --git a/dom/fs/test/xpcshell/test_basics_worker.js b/dom/fs/test/xpcshell/test_basics_worker.js new file mode 100644 index 000000000000..4569a6a88ce0 --- /dev/null +++ b/dom/fs/test/xpcshell/test_basics_worker.js @@ -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"); +}); diff --git a/dom/fs/test/xpcshell/worker/.eslintrc.js b/dom/fs/test/xpcshell/worker/.eslintrc.js new file mode 100644 index 000000000000..93bf938654ab --- /dev/null +++ b/dom/fs/test/xpcshell/worker/.eslintrc.js @@ -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, + }, +}; diff --git a/dom/fs/test/xpcshell/worker/dummy.js b/dom/fs/test/xpcshell/worker/dummy.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/dom/fs/test/xpcshell/worker/head.js b/dom/fs/test/xpcshell/worker/head.js new file mode 100644 index 000000000000..5c79ae3ff330 --- /dev/null +++ b/dom/fs/test/xpcshell/worker/head.js @@ -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); +} diff --git a/dom/fs/test/xpcshell/worker/moz.build b/dom/fs/test/xpcshell/worker/moz.build new file mode 100644 index 000000000000..afaef39d7924 --- /dev/null +++ b/dom/fs/test/xpcshell/worker/moz.build @@ -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", +] diff --git a/dom/fs/test/xpcshell/worker/test_basics_worker.js b/dom/fs/test/xpcshell/worker/test_basics_worker.js new file mode 100644 index 000000000000..e4a4958071a1 --- /dev/null +++ b/dom/fs/test/xpcshell/worker/test_basics_worker.js @@ -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); + }); +}); diff --git a/dom/fs/test/xpcshell/xpcshell.ini b/dom/fs/test/xpcshell/xpcshell.ini index 44cdf644dc9e..d18a1e8ee385 100644 --- a/dom/fs/test/xpcshell/xpcshell.ini +++ b/dom/fs/test/xpcshell/xpcshell.ini @@ -6,4 +6,5 @@ head = head.js [test_basics.js] +[test_basics_worker.js] [test_fileSystemDirectoryHandle.js] diff --git a/dom/quota/test/modules/content/WorkerDriver.js b/dom/quota/test/modules/content/WorkerDriver.js index 42d1bb66bbc4..365d00f3638c 100644 --- a/dom/quota/test/modules/content/WorkerDriver.js +++ b/dom/quota/test/modules/content/WorkerDriver.js @@ -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); diff --git a/dom/quota/test/modules/system/WorkerDriver.jsm b/dom/quota/test/modules/system/WorkerDriver.jsm new file mode 100644 index 000000000000..a48ce3845251 --- /dev/null +++ b/dom/quota/test/modules/system/WorkerDriver.jsm @@ -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"]; diff --git a/dom/quota/test/modules/system/worker/.eslintrc.js b/dom/quota/test/modules/system/worker/.eslintrc.js new file mode 100644 index 000000000000..505e079c5769 --- /dev/null +++ b/dom/quota/test/modules/system/worker/.eslintrc.js @@ -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, + }, + }, + ], +}; diff --git a/dom/quota/test/modules/system/worker/Assert.js b/dom/quota/test/modules/system/worker/Assert.js new file mode 100644 index 000000000000..7c7e2683eaac --- /dev/null +++ b/dom/quota/test/modules/system/worker/Assert.js @@ -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, + }); + }, +}; diff --git a/dom/quota/test/modules/system/worker/ModuleLoader.js b/dom/quota/test/modules/system/worker/ModuleLoader.js new file mode 100644 index 000000000000..6de1fbc2992f --- /dev/null +++ b/dom/quota/test/modules/system/worker/ModuleLoader.js @@ -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); +} diff --git a/dom/quota/test/modules/system/worker/head.js b/dom/quota/test/modules/system/worker/head.js new file mode 100644 index 000000000000..1308508918bf --- /dev/null +++ b/dom/quota/test/modules/system/worker/head.js @@ -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); +}); diff --git a/dom/quota/test/moz.build b/dom/quota/test/moz.build index f3a1b4d93316..5410f609fc6f 100644 --- a/dom/quota/test/moz.build +++ b/dom/quota/test/moz.build @@ -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", ]