summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js')
-rw-r--r--testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js71
1 files changed, 71 insertions, 0 deletions
diff --git a/testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js b/testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js
new file mode 100644
index 0000000000..e84ca2c2a6
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/worker-termination-aborts-upgrade.window.js
@@ -0,0 +1,71 @@
+// META: title=Worker Termination Aborts a Pending Upgrade
+// META: script=resources/support-promises.js
+
+// This test verifies that if a Worker's shutdown races an IndexedDB
+// versionchange transaction that is creating a database that the next attempt
+// to open the database results in a versionchange from version 0 and that
+// nothing was in the database.
+//
+// Care has been taken to make this test's behavior well-defined relative to the
+// spec to avoid intermittent failures. In particular
+// `DedicatedWorkerGlobalScope.close()` is used on the worker after issuing the
+// `IDBFactory.open()` call. This precludes any further tasks running on the
+// worker by spec, although implementations may potentially have "zones of
+// danger" in the time between the worker transitioning and when any state
+// machines on the parent thread realize what's going on.
+
+async function runAsyncFunctionInWorkerThenClose(funcToStringify) {
+ const script = `// This script was created by runAsyncFunctionInWorkerThenClose
+let testFunc = ${funcToStringify.toString()};
+setTimeout(async () => {
+ await testFunc();
+ postMessage("ran");
+ self.close();
+}, 0);
+`;
+ const scriptBlob = new Blob([script]);
+ const url = URL.createObjectURL(scriptBlob);
+ const w = new Worker(url);
+ await new Promise((resolve) => {
+ w.onmessage = (evt) => {
+ if (evt.data === "ran") {
+ resolve();
+ }
+ };
+ });
+ URL.revokeObjectURL(url);
+}
+
+promise_test(async t => {
+ await runAsyncFunctionInWorkerThenClose(async function() {
+ // Note that this code will actually run on the worker, so anything
+ // lexically captured will be coming from the worker's global scope.
+ const openReq = indexedDB.open("aborted-upgrade-db", 1);
+
+ openReq.onupgradeneeded = (event) => {
+ const db = event.target.result;
+ db.createObjectStore("should-not-be-created");
+ }
+ });
+
+ // At this point we know that the open request was issued on the worker
+ // worker thread. An ordering concern at this point is that IDB only
+ // specifies that the the connection opening algorithm is run in parallel and
+ // we are not guaranteed that when we go "in parallel" here that our operation
+ // won't run first. As such, it may be necessary to add some kind of
+ // arbitrary delay in the future if implementations do not effectively
+ // maintain sequential ordering of IPC requests within a process.
+ //
+ // Note that we must NOT use `createNamedDatabase` here because it will
+ // issue a blind call to `deleteDatabase`. Because the migrate helper does
+ // not perform cleanup, we must add the cleanup deletion now, though.
+ t.add_cleanup(() => { indexedDB.deleteDatabase("aborted-upgrade-db"); });
+ let createdDB = await migrateNamedDatabase(t, "aborted-upgrade-db", 1, (db) => {
+ assert_equals(db.objectStoreNames.length, 0, "DB should have been empty");
+ // Let's make sure the database is not permanently broken / corrupted.
+ db.createObjectStore("should-be-created");
+ });
+
+ assert_equals(createdDB.objectStoreNames.length, 1, "created object store correctly");
+ assert_equals(createdDB.objectStoreNames.item(0), "should-be-created");
+});