summaryrefslogtreecommitdiffstats
path: root/dom/quota/test/modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/quota/test/modules
parentInitial commit. (diff)
downloadfirefox-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')
-rw-r--r--dom/quota/test/modules/content/.eslintrc.js24
-rw-r--r--dom/quota/test/modules/content/Assert.js10
-rw-r--r--dom/quota/test/modules/content/ModuleLoader.js61
-rw-r--r--dom/quota/test/modules/content/StorageUtils.js67
-rw-r--r--dom/quota/test/modules/content/Utils.js14
-rw-r--r--dom/quota/test/modules/content/UtilsParent.js21
-rw-r--r--dom/quota/test/modules/content/WorkerDriver.js68
-rw-r--r--dom/quota/test/modules/content/worker/.eslintrc.js21
-rw-r--r--dom/quota/test/modules/content/worker/Assert.js22
-rw-r--r--dom/quota/test/modules/content/worker/ModuleLoader.js52
-rw-r--r--dom/quota/test/modules/content/worker/Utils.js27
-rw-r--r--dom/quota/test/modules/content/worker/UtilsChild.mjs22
-rw-r--r--dom/quota/test/modules/content/worker/head.js55
-rw-r--r--dom/quota/test/modules/system/ModuleLoader.sys.mjs63
-rw-r--r--dom/quota/test/modules/system/StorageUtils.sys.mjs101
-rw-r--r--dom/quota/test/modules/system/Utils.sys.mjs38
-rw-r--r--dom/quota/test/modules/system/UtilsParent.sys.mjs32
-rw-r--r--dom/quota/test/modules/system/WorkerDriver.sys.mjs68
-rw-r--r--dom/quota/test/modules/system/worker/.eslintrc.js21
-rw-r--r--dom/quota/test/modules/system/worker/Assert.js22
-rw-r--r--dom/quota/test/modules/system/worker/ModuleLoader.js52
-rw-r--r--dom/quota/test/modules/system/worker/Utils.js55
-rw-r--r--dom/quota/test/modules/system/worker/UtilsChild.js56
-rw-r--r--dom/quota/test/modules/system/worker/head.js56
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);
+});