diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/quota/test/modules | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/quota/test/modules')
24 files changed, 1028 insertions, 0 deletions
diff --git a/dom/quota/test/modules/content/.eslintrc.js b/dom/quota/test/modules/content/.eslintrc.js new file mode 100644 index 0000000000..f4482935e5 --- /dev/null +++ b/dom/quota/test/modules/content/.eslintrc.js @@ -0,0 +1,24 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +"use strict"; + +module.exports = { + overrides: [ + { + files: [ + "Assert.js", + "ModuleLoader.js", + "StorageUtils.js", + "Utils.js", + "UtilsParent.js", + "WorkerDriver.js", + ], + parserOptions: { + sourceType: "module", + }, + }, + ], +}; diff --git a/dom/quota/test/modules/content/Assert.js b/dom/quota/test/modules/content/Assert.js new file mode 100644 index 0000000000..e2c8df19c8 --- /dev/null +++ b/dom/quota/test/modules/content/Assert.js @@ -0,0 +1,10 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Just a wrapper around SimpleTest related functions for now. +export const Assert = { + ok, + equal: is, +}; diff --git a/dom/quota/test/modules/content/ModuleLoader.js b/dom/quota/test/modules/content/ModuleLoader.js new file mode 100644 index 0000000000..7e2b7cd89d --- /dev/null +++ b/dom/quota/test/modules/content/ModuleLoader.js @@ -0,0 +1,61 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +export function ModuleLoader(base, depth, proto) { + const modules = {}; + + const principal = SpecialPowers.wrap(document).nodePrincipal; + + const sharedGlobalSandbox = SpecialPowers.Cu.Sandbox(principal, { + invisibleToDebugger: true, + sandboxName: "FS Module Loader", + sandboxPrototype: proto, + wantComponents: false, + wantGlobalProperties: [], + wantXrays: false, + }); + + 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 properties = { + require_module: require, + exported_symbols: module.exported_symbols, + }; + + // Create a new object in this sandbox, that will be used as the scope + // object for this particular module. + const sandbox = sharedGlobalSandbox.Object(); + Object.assign(sandbox, properties); + + SpecialPowers.Services.scriptloader.loadSubScript(url.href, sandbox); + + return module.exported_symbols; + }; + + const returnObj = { + require: { + enumerable: true, + value: require, + }, + }; + + return Object.create(null, returnObj); +} diff --git a/dom/quota/test/modules/content/StorageUtils.js b/dom/quota/test/modules/content/StorageUtils.js new file mode 100644 index 0000000000..bb264966af --- /dev/null +++ b/dom/quota/test/modules/content/StorageUtils.js @@ -0,0 +1,67 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +class RequestError extends Error { + constructor(resultCode, resultName) { + super(`Request failed (code: ${resultCode}, name: ${resultName})`); + this.name = "RequestError"; + this.resultCode = resultCode; + this.resultName = resultName; + } +} + +export async function setStoragePrefs(optionalPrefsToSet) { + const prefsToSet = [ + // Not needed right now, but might be needed in future. + // ["dom.quotaManager.testing", true], + ]; + + if (SpecialPowers.Services.appinfo.OS === "WINNT") { + prefsToSet.push(["dom.quotaManager.useDOSDevicePathSyntax", true]); + } + + if (optionalPrefsToSet) { + prefsToSet.push(...optionalPrefsToSet); + } + + await SpecialPowers.pushPrefEnv({ set: prefsToSet }); +} + +export async function getUsageForOrigin(principal, fromMemory) { + const request = SpecialPowers.Services.qms.getUsageForPrincipal( + principal, + function () {}, + fromMemory + ); + + await new Promise(function (resolve) { + request.callback = SpecialPowers.wrapCallback(function () { + resolve(); + }); + }); + + if (request.resultCode != SpecialPowers.Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; +} + +export async function clearStoragesForOrigin(principal) { + const request = + SpecialPowers.Services.qms.clearStoragesForPrincipal(principal); + + await new Promise(function (resolve) { + request.callback = SpecialPowers.wrapCallback(function () { + resolve(); + }); + }); + + if (request.resultCode != SpecialPowers.Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; +} diff --git a/dom/quota/test/modules/content/Utils.js b/dom/quota/test/modules/content/Utils.js new file mode 100644 index 0000000000..3f011e32f4 --- /dev/null +++ b/dom/quota/test/modules/content/Utils.js @@ -0,0 +1,14 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import { getUsageForOrigin } from "/tests/dom/quota/test/modules/StorageUtils.js"; + +export const Utils = { + async getCachedOriginUsage() { + const principal = SpecialPowers.wrap(document).nodePrincipal; + const result = await getUsageForOrigin(principal, true); + return result.usage; + }, +}; diff --git a/dom/quota/test/modules/content/UtilsParent.js b/dom/quota/test/modules/content/UtilsParent.js new file mode 100644 index 0000000000..56859500be --- /dev/null +++ b/dom/quota/test/modules/content/UtilsParent.js @@ -0,0 +1,21 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import { Utils } from "/tests/dom/quota/test/modules/Utils.js"; + +export const UtilsParent = { + async OnMessageReceived(worker, msg) { + switch (msg.op) { + case "getCachedOriginUsage": { + const result = await Utils.getCachedOriginUsage(); + worker.postMessage(result); + break; + } + + default: + throw new Error(`Unknown op ${msg.op}`); + } + }, +}; diff --git a/dom/quota/test/modules/content/WorkerDriver.js b/dom/quota/test/modules/content/WorkerDriver.js new file mode 100644 index 0000000000..52ca382c25 --- /dev/null +++ b/dom/quota/test/modules/content/WorkerDriver.js @@ -0,0 +1,68 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +export async function runTestInWorker(script, base, listener) { + return new Promise(function (resolve) { + const globalHeadUrl = new URL( + "/tests/dom/quota/test/modules/worker/head.js", + base + ); + + let modules = {}; + + const worker = new Worker(globalHeadUrl.href); + + worker.onmessage = async function (event) { + const data = event.data; + const moduleName = data.moduleName; + const objectName = data.objectName; + + if (moduleName && objectName) { + if (!modules[moduleName]) { + // eslint-disable-next-line no-unsanitized/method + modules[moduleName] = await import( + "/tests/dom/quota/test/modules/" + moduleName + ".js" + ); + } + await modules[moduleName][objectName].OnMessageReceived(worker, data); + return; + } + + 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]); + }); +} diff --git a/dom/quota/test/modules/content/worker/.eslintrc.js b/dom/quota/test/modules/content/worker/.eslintrc.js new file mode 100644 index 0000000000..a62b649451 --- /dev/null +++ b/dom/quota/test/modules/content/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: ["Assert.js", "ModuleLoader.js", "Utils.js"], + parserOptions: { + sourceType: "script", + }, + }, + ], +}; diff --git a/dom/quota/test/modules/content/worker/Assert.js b/dom/quota/test/modules/content/worker/Assert.js new file mode 100644 index 0000000000..7c7e2683ea --- /dev/null +++ b/dom/quota/test/modules/content/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/content/worker/ModuleLoader.js b/dom/quota/test/modules/content/worker/ModuleLoader.js new file mode 100644 index 0000000000..5354c26e34 --- /dev/null +++ b/dom/quota/test/modules/content/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) { + 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/content/worker/Utils.js b/dom/quota/test/modules/content/worker/Utils.js new file mode 100644 index 0000000000..0f8888fc00 --- /dev/null +++ b/dom/quota/test/modules/content/worker/Utils.js @@ -0,0 +1,27 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +let UtilsChild; + +async function ensureUtilsChild() { + if (UtilsChild) { + return; + } + + const { UtilsChild: importedUtilsChild } = await import( + "/tests/dom/quota/test/modules/worker/UtilsChild.mjs" + ); + + UtilsChild = importedUtilsChild; +} + +const Utils = { + async getCachedOriginUsage() { + await ensureUtilsChild(); + + const result = await UtilsChild.getCachedOriginUsage(); + return result; + }, +}; diff --git a/dom/quota/test/modules/content/worker/UtilsChild.mjs b/dom/quota/test/modules/content/worker/UtilsChild.mjs new file mode 100644 index 0000000000..db5757bff0 --- /dev/null +++ b/dom/quota/test/modules/content/worker/UtilsChild.mjs @@ -0,0 +1,22 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +export const UtilsChild = { + async getCachedOriginUsage() { + postMessage({ + moduleName: "UtilsParent", + objectName: "UtilsParent", + op: "getCachedOriginUsage", + }); + + return new Promise(function (resolve) { + addEventListener("message", async function onMessage(event) { + removeEventListener("message", onMessage); + const data = event.data; + resolve(data); + }); + }); + }, +}; diff --git a/dom/quota/test/modules/content/worker/head.js b/dom/quota/test/modules/content/worker/head.js new file mode 100644 index 0000000000..ab7a916d22 --- /dev/null +++ b/dom/quota/test/modules/content/worker/head.js @@ -0,0 +1,55 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +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/modules/system/ModuleLoader.sys.mjs b/dom/quota/test/modules/system/ModuleLoader.sys.mjs new file mode 100644 index 0000000000..d4f8f51c11 --- /dev/null +++ b/dom/quota/test/modules/system/ModuleLoader.sys.mjs @@ -0,0 +1,63 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +export function ModuleLoader(base, depth, proto) { + const modules = {}; + + const principal = Cc["@mozilla.org/systemprincipal;1"].createInstance( + Ci.nsIPrincipal + ); + + const sharedGlobalsandbox = Cu.Sandbox(principal, { + invisibleToDebugger: true, + sandboxName: "FS Module Loader", + sandboxPrototype: proto, + wantComponents: false, + wantGlobalProperties: [], + wantXrays: false, + }); + + 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 properties = { + require_module: require, + exported_symbols: module.exported_symbols, + }; + + // Create a new object in this sandbox, that will be used as the scope + // object for this particular module. + const sandbox = sharedGlobalsandbox.Object(); + Object.assign(sandbox, properties); + + Services.scriptloader.loadSubScript(url.href, sandbox); + + return module.exported_symbols; + }; + + const returnObj = { + require: { + enumerable: true, + value: require, + }, + }; + + return Object.create(null, returnObj); +} diff --git a/dom/quota/test/modules/system/StorageUtils.sys.mjs b/dom/quota/test/modules/system/StorageUtils.sys.mjs new file mode 100644 index 0000000000..0e87906035 --- /dev/null +++ b/dom/quota/test/modules/system/StorageUtils.sys.mjs @@ -0,0 +1,101 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +class RequestError extends Error { + constructor(resultCode, resultName) { + super(`Request failed (code: ${resultCode}, name: ${resultName})`); + this.name = "RequestError"; + this.resultCode = resultCode; + this.resultName = resultName; + } +} + +export function setStoragePrefs(optionalPrefsToSet) { + const prefsToSet = [["dom.quotaManager.testing", true]]; + + if (Services.appinfo.OS === "WINNT") { + prefsToSet.push(["dom.quotaManager.useDOSDevicePathSyntax", true]); + } + + if (optionalPrefsToSet) { + prefsToSet.push(...optionalPrefsToSet); + } + + for (const pref of prefsToSet) { + Services.prefs.setBoolPref(pref[0], pref[1]); + } +} + +export function clearStoragePrefs(optionalPrefsToClear) { + const prefsToClear = [ + "dom.quotaManager.testing", + "dom.simpleDB.enabled", + "dom.storageManager.enabled", + ]; + + if (Services.appinfo.OS === "WINNT") { + prefsToClear.push("dom.quotaManager.useDOSDevicePathSyntax"); + } + + if (optionalPrefsToClear) { + prefsToClear.push(...optionalPrefsToClear); + } + + for (const pref of prefsToClear) { + Services.prefs.clearUserPref(pref); + } +} + +export async function getUsageForOrigin(principal, fromMemory) { + const request = Services.qms.getUsageForPrincipal( + principal, + function () {}, + fromMemory + ); + + await new Promise(function (resolve) { + request.callback = function () { + resolve(); + }; + }); + + if (request.resultCode != Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; +} + +export async function clearStoragesForOrigin(principal) { + const request = Services.qms.clearStoragesForPrincipal(principal); + + await new Promise(function (resolve) { + request.callback = function () { + resolve(); + }; + }); + + if (request.resultCode != Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; +} + +export async function resetStorage() { + const request = Services.qms.reset(); + + await new Promise(function (resolve) { + request.callback = function () { + resolve(); + }; + }); + + if (request.resultCode != Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; +} diff --git a/dom/quota/test/modules/system/Utils.sys.mjs b/dom/quota/test/modules/system/Utils.sys.mjs new file mode 100644 index 0000000000..8c5430aa06 --- /dev/null +++ b/dom/quota/test/modules/system/Utils.sys.mjs @@ -0,0 +1,38 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import { + getUsageForOrigin, + resetStorage, +} from "resource://testing-common/dom/quota/test/modules/StorageUtils.sys.mjs"; + +export const Utils = { + async getCachedOriginUsage() { + const principal = Cc["@mozilla.org/systemprincipal;1"].createInstance( + Ci.nsIPrincipal + ); + const result = await getUsageForOrigin(principal, true); + return result.usage; + }, + + async shrinkStorageSize(size) { + Services.prefs.setIntPref( + "dom.quotaManager.temporaryStorage.fixedLimit", + size + ); + + const result = await resetStorage(); + return result; + }, + + async restoreStorageSize() { + Services.prefs.clearUserPref( + "dom.quotaManager.temporaryStorage.fixedLimit" + ); + + const result = await resetStorage(); + return result; + }, +}; diff --git a/dom/quota/test/modules/system/UtilsParent.sys.mjs b/dom/quota/test/modules/system/UtilsParent.sys.mjs new file mode 100644 index 0000000000..41ca7e2940 --- /dev/null +++ b/dom/quota/test/modules/system/UtilsParent.sys.mjs @@ -0,0 +1,32 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import { Utils } from "resource://testing-common/dom/quota/test/modules/Utils.sys.mjs"; + +export const UtilsParent = { + async OnMessageReceived(worker, msg) { + switch (msg.op) { + case "getCachedOriginUsage": { + const result = await Utils.getCachedOriginUsage(); + worker.postMessage(result); + break; + } + case "shrinkStorageSize": { + const result = await Utils.shrinkStorageSize(msg.size); + worker.postMessage(result); + break; + } + + case "restoreStorageSize": { + const result = await Utils.restoreStorageSize(); + worker.postMessage(result); + break; + } + + default: + throw new Error(`Unknown op ${msg.op}`); + } + }, +}; diff --git a/dom/quota/test/modules/system/WorkerDriver.sys.mjs b/dom/quota/test/modules/system/WorkerDriver.sys.mjs new file mode 100644 index 0000000000..60e6790760 --- /dev/null +++ b/dom/quota/test/modules/system/WorkerDriver.sys.mjs @@ -0,0 +1,68 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +export 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" + ); + + let modules = {}; + + const worker = new Worker(globalHeadUrl.href); + + worker.onmessage = async function (event) { + const data = event.data; + const moduleName = data.moduleName; + const objectName = data.objectName; + + if (moduleName && objectName) { + if (!modules[moduleName]) { + modules[moduleName] = ChromeUtils.importESModule( + "resource://testing-common/dom/quota/test/modules/" + + moduleName + + ".sys.mjs" + ); + } + await modules[moduleName][objectName].OnMessageReceived(worker, data); + return; + } + + 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]); + }); +} 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 0000000000..505e079c57 --- /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 0000000000..7c7e2683ea --- /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 0000000000..b79f3ff5b9 --- /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/Utils.js b/dom/quota/test/modules/system/worker/Utils.js new file mode 100644 index 0000000000..ca9b54a92a --- /dev/null +++ b/dom/quota/test/modules/system/worker/Utils.js @@ -0,0 +1,55 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +let UtilsChild; + +async function ensureUtilsChild() { + if (UtilsChild) { + return; + } + + try { + const { UtilsChild: importedUtilsChild } = await import( + "/dom/quota/test/modules/worker/UtilsChild.js" + ); + + UtilsChild = importedUtilsChild; + + throw Error("Please switch to dynamic module import"); + } catch (e) { + if (e.message == "Please switch to dynamic module import") { + throw e; + } + + importScripts("/dom/quota/test/modules/worker/UtilsChild.js"); + + const { UtilsChild: importedUtilsChild } = globalThis.importUtilsChild(); + + UtilsChild = importedUtilsChild; + } +} + +const Utils = { + async getCachedOriginUsage() { + await ensureUtilsChild(); + + const result = await UtilsChild.getCachedOriginUsage(); + return result; + }, + + async shrinkStorageSize(size) { + await ensureUtilsChild(); + + const result = await UtilsChild.shrinkStorageSize(size); + return result; + }, + + async restoreStorageSize() { + await ensureUtilsChild(); + + const result = await UtilsChild.restoreStorageSize(); + return result; + }, +}; diff --git a/dom/quota/test/modules/system/worker/UtilsChild.js b/dom/quota/test/modules/system/worker/UtilsChild.js new file mode 100644 index 0000000000..4addd6b948 --- /dev/null +++ b/dom/quota/test/modules/system/worker/UtilsChild.js @@ -0,0 +1,56 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +function _sendMessage(messageBody) { + const messageHeader = { + moduleName: "UtilsParent", + objectName: "UtilsParent", + }; + + const message = { ...messageHeader, ...messageBody }; + + postMessage(message); +} + +function _recvMessage() { + return new Promise(function (resolve) { + addEventListener("message", async function onMessage(event) { + removeEventListener("message", onMessage); + const data = event.data; + resolve(data); + }); + }); +} + +const _UtilsChild = { + async getCachedOriginUsage() { + _sendMessage({ + op: "getCachedOriginUsage", + }); + + return _recvMessage(); + }, + + async shrinkStorageSize(size) { + _sendMessage({ + op: "shrinkStorageSize", + size, + }); + + return _recvMessage(); + }, + + async restoreStorageSize() { + _sendMessage({ + op: "restoreStorageSize", + }); + + return _recvMessage(); + }, +}; + +function importUtilsChild() { + return { UtilsChild: _UtilsChild }; +} 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 0000000000..c415e0c56b --- /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); +}); |