indexeddb: move database open and upgrade transaction to in parallel.
The spec concept of opening a database, and the conditional upgrade of a database, should be run in-parallel, meaning on the backend indexeddb thread, and not on the script-thread.
This implements the move, but retains a blocking wait on the upgrade transaction finish. It is the first step towards a larger refactoring(see https://github.com/servo/servo/issues/40983), which will see concepts like transaction lifecyle and connection queues be implemented on the indexeddb thread, and which will make any waiting non-blocking as well.
Other smaller changes to support the above are:
- returning whether a physical db was created when instantiating the db engine.
- using a global counter to produce transaction ids.
Testing: New failures on WPT tests: to be fixed as part of several follow-ups. Fixes: The parts of https://github.com/servo/servo/issues/38942#issuecomment-3270223903 that were not addressed when the issue was closed.
@Taym95 @janvarga @jdm @arihant2math This completes the initial refactoring; I will try to run the tests tomorrow and fix any issues that come-up. Welcome to take a look already.
@Taym95 @janvarga @jdm @arihant2math This completes the initial refactoring; I will try to run the tests tomorrow and fix any issues that come-up. Welcome to take a look already.
Yes, the database opening, and in fact all IDB factory operations, need to run primarily in the backend, so this refactoring makes complete sense to me.
@Taym95 @janvarga @jdm @arihant2math This completes the initial refactoring; I will try to run the tests tomorrow and fix any issues that come-up. Welcome to take a look already.
I will take look tonight!
One thing is that since this now blocks the idb thread(instead of script), it might create other issues, even deadlocks if script does a blocking call within the upgrade event handler. But I'll look into those things when I run tests tomorrow.
Trying to keep it simple for now since a non-blocking workflow would take a lot more changes because it requires implementing the entire transaction lifecycle as a backend state machine as well as making all other operations async.
Yeah an operation like CreateObjectStore will deadlock if indexeddb is blocking, so I think I'll have to add a simple beginning of an async transaction system tomorrow. (there is one such system in place already, but it's sort of driven by script now, and like the rest it needs to be switched to parallel steps)
Will take a look later today.
So I introduced an async worfklow for the open request: it is a first step and it should be merged into something general dealing with transaction lifecyle. But this fixes the deadlock which was introduced by moving the blocking wait from script to indexeddb.
🔨 Triggering try run (#19896250328) for Linux (WPT)
Test results for linux-wpt from try job (#19896250328):Flaky unexpected result (36)
/FileAPI/url/url-with-fetch.any.html (#21517)Revoke blob URL after calling fetch, fetch should succeed
promise_test: Unhandled rejection with value: object "TypeError: Network error occurred"
/_mozilla/css/linear_gradients_reverse_a.html/_mozilla/css/offset_properties_inline.html (#40543)offsetTop
assert_equals: offsetTop of #inline-1 should be 0. expected 0 but got -1
offsetLeft
assert_equals: offsetLeft of #inline-2 should be 40. expected 40 but got 25
/_mozilla/webxr/create_session.https.htmlcreate_session
can't access property "simulateDeviceConnection", navigator.xr.test is undefined
/_mozilla/webxr/obtain_frame.https.htmlobtain_frame
promise_test: Unhandled rejection with value: object "TypeError: can't access property "simulateDeviceConnection", navigator.xr.test is undefined"
/_webgl/conformance2/wasm/readpixels-2gb-in-4gb-wasm-memory.html/content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.
assert_unreached: The IFrame should have been blocked (or cross-origin). It wasn't. Reached unreachable code
/css/CSS2/linebox/vertical-align-top-bottom-001.html (#41015)text-top+
assert_approx_equals: expected "44" +/- 0 but got 41
text-top+top
assert_approx_equals: expected "5" +/- 0 but got 3
text-top+text-top
assert_approx_equals: expected "5" +/- 0 but got 3
text-top+text-bottom
assert_approx_equals: expected "40" +/- 0 but got 37
text-bottom+
assert_approx_equals: expected "44" +/- 0 but got 45
text-bottom+top
assert_approx_equals: expected "5" +/- 0 but got 7
text-bottom+text-top
assert_approx_equals: expected "5" +/- 0 but got 7
bottom+
assert_approx_equals: expected "49" +/- 0 but got 48
bottom+text-top
assert_approx_equals: expected "45" +/- 0 but got 43
bottom+text-bottom
assert_approx_equals: expected "45" +/- 0 but got 44
/css/css-backgrounds/background-size-042.html/css/css-cascade/layer-font-face-override.html (#35935)@font-face override update with appended sheet 1@font-face override update with appended sheet 2/custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)setFormValue with an empty FormData should submit nothing/html/browsers/browsing-the-web/navigating-across-documents/008.html (#24456)Link with onclick form submit to javascript url and href navigation /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.html (#29056)Cross-origin navigation started from unload handler must be ignored/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)Same-origin navigation started from unload handler must be ignored/html/browsers/browsing-the-web/navigating-across-documents/plugin-document.historical.html/html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.html (#35948)/html/browsers/windows/browsing-context-window.html/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.html/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html (#28259)Autofocus elements in top-level browsing context's documents with empty fragments should work.
Test timed out
/html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)HTMLMediaElement.srcObject blob/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-replace-set-src.html (#32697)Navigating iframe loading='lazy' and then setting src: location.replace/html/semantics/forms/form-submission-0/jsurl-form-submit.tentative.html (#36489)Verifies that form submissions scheduled inside javascript: urls take precedence over the javascript: url's return value./html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)multipart/form-data: Basic test (formdata event)
assert_equals: expected "\r\nContent-Disposition: form-data; name=\"basic\"\r\n\r\ntest\r\n--\r\n" but got ""
/html/semantics/forms/form-submission-0/text-plain.window.html (#28687)text/plain: 0x00 in filename (formdata event)/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html (#40347)/html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)adding several types of scripts through the DOM and removing some of them confuses scheduler
assert_array_equals: expected property 1 to be "Script #1 ran" but got "Script #3 ran" (expected array ["Script #2 ran", "Script #1 ran", "Script #3 ran", "Script #4 ran"] got ["Script #2 ran", "Script #3 ran", "Script #4 ran", "Script #1 ran"])
/pointerevents/compat/pointerevent_touch-action_two-finger_interaction.html (#40418)/preload/preload-invalid-resources.html (#39091)Preloading an invalid image (invalid data) should preload and not re-fetch/preload/preload-xhr.html (#39092)Make an XHR request immediately after creating link rel=preload.
assert_equals: resources/dummy.xml?token=2027a395-13f7-43bc-8a37-dccc644269d2 expected 1 but got 0
/service-workers/service-worker/fetch-event.https.html (#36234)Service Worker falls back to network in fetch event with POST form/trusted-types/set-event-handlers-content-attributes.tentative.html/trusted-types/trusted-types-navigation.html?06-10 (#37920)Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in enforcing mode.
promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in report-only mode.
promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
/trusted-types/trusted-types-reporting-for-Document-execCommand.html/wasm/webapi/invalid-code.any.sharedworker.html/webdriver/tests/classic/execute_script/objects.pytest_object
AssertionError: no such window (404): No such window
/websockets/Close-1005-verify-code.any.worker.html?wssStable unexpected results that are known to be intermittent (37)
/IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)IDBCursor continuePrimaryKey() on object store cursor
assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
cursor.continuePrimaryKey(2, 2);
}" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
/IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)IDBCursor continuePrimaryKey() on object store cursor
assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
cursor.continuePrimaryKey(2, 2);
}" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
/IndexedDB/idbobjectstore_delete.any.worker.html (#39069)delete() key doesn't match any records/IndexedDB/idbobjectstore_getAll.any.html (#39276)Single item get
The object is in an invalid state.
getAll on empty object store
The object is in an invalid state.
Get all values
The object is in an invalid state.
Test maxCount
The object is in an invalid state.
Get bound range
The object is in an invalid state.
Get bound range with maxCount
The object is in an invalid state.
Get upper excluded
The object is in an invalid state.
Get lower excluded
The object is in an invalid state.
Non existent key
The object is in an invalid state.
zero maxCount
The object is in an invalid state.
/IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)Single item get
The object is in an invalid state.
getAll on empty object store
The object is in an invalid state.
Get all values
The object is in an invalid state.
Test maxCount
The object is in an invalid state.
Get bound range
The object is in an invalid state.
Get bound range with maxCount
The object is in an invalid state.
Get upper excluded
The object is in an invalid state.
Get lower excluded
The object is in an invalid state.
Non existent key
The object is in an invalid state.
zero maxCount
The object is in an invalid state.
/IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)indexedDB.delete called from upgradeneeded handler
assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
transaction oncomplete ordering relative to open request onsuccess/IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)indexedDB.delete called from upgradeneeded handler
assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
transaction oncomplete ordering relative to open request onsuccess/IndexedDB/key-conversion-exceptions.any.html (#39305)IndexedDB: Exceptions thrown during key conversionIDBIndex get() method with throwing/invalid keysIDBIndex getKey() method with throwing/invalid keysIDBIndex count() method with throwing/invalid keysIDBIndex openCursor() method with throwing/invalid keysIDBIndex openKeyCursor() method with throwing/invalid keysIDBIndex getAll() method with throwing/invalid keysIDBIndex getAllKeys() method with throwing/invalid keysIDBIndex getAllRecords() method with throwing/invalid keys/IndexedDB/key-conversion-exceptions.any.worker.html (#39284)IndexedDB: Exceptions thrown during key conversionIDBIndex get() method with throwing/invalid keysIDBIndex getKey() method with throwing/invalid keysIDBIndex count() method with throwing/invalid keysIDBIndex openCursor() method with throwing/invalid keysIDBIndex openKeyCursor() method with throwing/invalid keysIDBIndex getAll() method with throwing/invalid keysIDBIndex getAllKeys() method with throwing/invalid keysIDBIndex getAllRecords() method with throwing/invalid keys/IndexedDB/transaction-deactivation-timing.any.html (#38772)New transactions are not deactivated until after the microtask checkpoint
The object is in an invalid state.
New transactions from microtask are still active through the microtask checkpoint
The object is in an invalid state.
/IndexedDB/transaction-deactivation-timing.any.worker.html (#38808)New transactions are not deactivated until after the microtask checkpoint
The object is in an invalid state.
New transactions from microtask are still active through the microtask checkpoint
The object is in an invalid state.
/_mozilla/mozilla/sslfail.html (#10760)/_mozilla/mozilla/window_resize_event.html (#36741)Popup onresize event fires after resizeTo
Test timed out
/css/css-cascade/layer-cssom-order-reverse.html (#36094)Delete layer invalidates @font-face/css/css-fonts/generic-family-keywords-001.html (#37467)@font-face matching for quoted and unquoted generic(fangsong)@font-face matching for quoted and unquoted generic(kai)@font-face matching for quoted and unquoted generic(nastaliq)/css/css-fonts/generic-family-keywords-003.html (#38994)@font-face matching for quoted and unquoted generic(nastaliq) (drawing text in a canvas)/css/css-grid/grid-lanes/tentative/alignment/row-grid-lanes-align-self-003.html (#40833)/css/css-grid/grid-lanes/tentative/grid-placement/row-explicit-placement-004.html (#40834)/css/css-grid/masonry/tentative/subgrid/column/masonry-subgrid-002f.html (#40830)/fetch/api/redirect/redirect-keepalive.https.any.html (#32153)[keepalive][iframe][load] mixed content redirect; setting up
Test timed out
/fetch/fetch-later/permissions-policy/deferred-fetch-allowed-by-permissions-policy.https.window.html (#40478)Permissions policy header: "deferred-fetch=*" allows fetchLater() in the top-level document./fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)sec-fetch-storage-access - Cross-site
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
/fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)sec-fetch-storage-access - Not sent to non-trustworthy same-origin destination
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
/fetch/metadata/generated/element-img-environment-change.https.sub.html (#30111)sec-fetch-site - Cross-site, no attributessec-fetch-site - Same-Origin -> Same Origin, no attributessec-fetch-mode - no attributessec-fetch-mode - attributes: crossorigin
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
sec-fetch-mode - attributes: crossorigin=anonymoussec-fetch-mode - attributes: crossorigin=use-credentials
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
sec-fetch-dest - no attributes/fetch/metadata/generated/element-img-environment-change.sub.html (#30111)sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributessec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributessec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributessec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributessec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes/fetch/metadata/window-open.https.sub.html (#40339)Same-origin window, user-activatedSame-site window, user-activatedCross-site window, user-activatedSame-site window, user-activated: sec-fetch-site
assert_equals: expected "same-site" but got "same-origin"
Cross-site window, user-activated: sec-fetch-site
assert_equals: expected "cross-site" but got "same-origin"
/html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)/html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)Link with onclick navigation and href navigation /html/infrastructure/common-dom-interfaces/collections/domstringlist.html (#40665)/html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html (#29087)<dialog>-contained autofocus element gets focused when the dialog is shown
assert_equals: expected "DIV" but got "BODY"
/html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)Element with tabindex should support autofocus
assert_equals: expected "SPAN" but got "BODY"
Non-HTMLElement should not support autofocus
Test timed out
/html/semantics/embedded-content/media-elements/preserves-pitch.html (#40352)The default playbackRate should not affect pitch, even with preservesPitch=false
assert_approx_equals: The actual pitch should be close to the expected pitch. expected 440 +/- 66 but got 0
Speed-ups should not change the pitch when preservesPitch=true
assert_approx_equals: The actual pitch should be close to the expected pitch. expected 440 +/- 66 but got 0
Slow-downs should not change the pitch when preservesPitch=true
assert_approx_equals: The actual pitch should be close to the expected pitch. expected 440 +/- 66 but got 0
/html/semantics/forms/the-fieldset-element/disabled-003.html (#31730, #39631)/navigation-timing/test-navigation-type-reload.html (#33334)Reload domComplete > Original domCompleteReload domContentLoadedEventEnd > Original domContentLoadedEventEnd
assert_true: Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd expected true got false
Reload loadEventEnd > Original loadEventEndReload loadEventStart > Original loadEventStart/preload/preload-error.sub.html (#37177)success (fetch): main
assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?label=fetch should be loaded expected a number greater than 0 but got 0
404 (fetch): main
assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?pipe=status%28404%29&label=fetch should be loaded expected a number greater than 0 but got 0
CORS (fetch): main/resource-timing/cors-preflight.any.html (#28694)/trusted-types/trusted-types-navigation.html?26-30 (#38807)Navigate a window via form-submission with javascript:-urls in report-only mode.
Test timed out
Navigate a window via form-submission with javascript:-urls w/ default policy in report-only mode.Navigate a frame via form-submission with javascript:-urls in enforcing mode.Navigate a frame via form-submission with javascript:-urls w/ default policy in enforcing mode.Stable unexpected results (94)
/IndexedDB/back-forward-cache-open-transaction.window.htmlBFCache support test for page with open IndexedDB transaction
Test timed out
/IndexedDB/blob-composite-blob-reads.any.htmlComposite Blob Handling: Many blobs: fetch-blob-url
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Composite Blob Handling: Many blobs: direct
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/blob-composite-blob-reads.any.worker.htmlComposite Blob Handling: Many blobs: fetch-blob-url
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Composite Blob Handling: Many blobs: direct
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/blob-contenttype.any.htmlEnsure that content type round trips when reading blob data
The object is in an invalid state.
/IndexedDB/blob-contenttype.any.worker.htmlEnsure that content type round trips when reading blob data
The object is in an invalid state.
/IndexedDB/blob-valid-after-abort.any.htmlA blob can be read back after the transaction that added it was aborted.
The object is in an invalid state.
/IndexedDB/blob-valid-after-abort.any.worker.htmlA blob can be read back after the transaction that added it was aborted.
The object is in an invalid state.
/IndexedDB/blob-valid-after-deletion.any.htmlBlobs stay alive after their records are deleted.
The object is in an invalid state.
/IndexedDB/blob-valid-after-deletion.any.worker.htmlBlobs stay alive after their records are deleted.
The object is in an invalid state.
/IndexedDB/blob-valid-before-commit.any.htmlBlobs can be read back before their records are committed.
The object is in an invalid state.
/IndexedDB/blob-valid-before-commit.any.worker.htmlBlobs can be read back before their records are committed.
The object is in an invalid state.
/IndexedDB/crashtests/create-index.any.htmlAssure no crash when populating index
Test timed out
/IndexedDB/crashtests/create-index.any.worker.htmlAssure no crash when populating index
Test timed out
/IndexedDB/database-names-by-origin.htmlopen database names don't leak to cross-origin iframe
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
open database names don't leak to cross-origin window
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
closed database names don't leak to cross-origin iframe
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
closed database names don't leak to cross-origin window
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/event-dispatch-active-flag.any.htmlActive during success handlers
The object is in an invalid state.
Active during success listeners
The object is in an invalid state.
Active during error handlers
The object is in an invalid state.
Active during error listeners
The object is in an invalid state.
/IndexedDB/event-dispatch-active-flag.any.worker.htmlActive during success handlers
The object is in an invalid state.
Active during success listeners
The object is in an invalid state.
Active during error handlers
The object is in an invalid state.
Active during error listeners
The object is in an invalid state.
/IndexedDB/idb-explicit-commit.any.htmlcommit() on a version change transaction does not cause errors.
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/idb-explicit-commit.any.worker.htmlcommit() on a version change transaction does not cause errors.
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/idb-partitioned-coverage.sub.htmlDeletes are processed in order
saw is not a function
/IndexedDB/idb-partitioned-persistence.sub.htmlPersistence test for partitioned IndexedDB
assert_true: The same database should exist in both frames expected true got false
/IndexedDB/idb_webworkers.htmIndexedDB inside of a WebWorker
Test timed out
/IndexedDB/idbcursor-advance-exception-order.any.htmlIDBCursor.advance exception order: TypeError vs. TransactionInactiveError
The object is in an invalid state.
IDBCursor.advance exception order: TransactionInactiveError vs. InvalidStateError #1
Test timed out
/IndexedDB/idbcursor-advance-exception-order.any.worker.htmlIDBCursor.advance exception order: TypeError vs. TransactionInactiveError
The object is in an invalid state.
IDBCursor.advance exception order: TransactionInactiveError vs. InvalidStateError #1
Test timed out
/IndexedDB/idbcursor-continuePrimaryKey-exception-order.any.htmlTransactionInactiveError v.s. InvalidStateError(deleted index)
Test timed out
InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect source)
Test timed out
InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect direction)
Test timed out
InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration complete)
Test timed out
InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration ongoing)
Test timed out
InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration ongoing)
Test timed out
InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration complete)
Test timed out
InvalidStateError(iteration ongoing) v.s. DataError(unset key)
Test timed out
InvalidStateError(iteration complete) v.s. DataError(unset key)
Test timed out
DataError(unset key)
Test timed out
/IndexedDB/idbcursor-continuePrimaryKey-exception-order.any.worker.htmlTransactionInactiveError v.s. InvalidStateError(deleted index)
Test timed out
InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect source)
Test timed out
InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect direction)
Test timed out
InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration complete)
Test timed out
InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration ongoing)
Test timed out
InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration ongoing)
Test timed out
InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration complete)
Test timed out
InvalidStateError(iteration ongoing) v.s. DataError(unset key)
Test timed out
InvalidStateError(iteration complete) v.s. DataError(unset key)
Test timed out
DataError(unset key)
Test timed out
/IndexedDB/idbdatabase-createObjectStore-exception-order.any.htmlIDBDatabase.createObjectStore exception order: SyntaxError vs. ConstraintError
Test timed out
IDBDatabase.createObjectStore exception order: ConstraintError vs. InvalidAccessError
Test timed out
/IndexedDB/idbdatabase-createObjectStore-exception-order.any.worker.htmlIDBDatabase.createObjectStore exception order: SyntaxError vs. ConstraintError
Test timed out
IDBDatabase.createObjectStore exception order: ConstraintError vs. InvalidAccessError
Test timed out
/IndexedDB/idbdatabase_createObjectStore.any.htmlAttempt to create an object store outside of a version change transaction Object store's name appears in database's list
assert_true: objectStoreNames.contains (in success) expected true got false
/IndexedDB/idbdatabase_createObjectStore.any.worker.htmlAttempt to create an object store outside of a version change transaction Object store's name appears in database's list
assert_true: objectStoreNames.contains (in success) expected true got false
/IndexedDB/idbfactory-open-error-properties.any.htmlProperties of error event from failed open()
Test timed out
/IndexedDB/idbfactory-open-error-properties.any.worker.htmlProperties of error event from failed open()
Test timed out
/IndexedDB/idbfactory-open-request-success.any.htmlProperties of IDBOpenDBRequest during successful IDBFactory open()
assert_true: complete event should fire before success expected true got false
/IndexedDB/idbfactory-open-request-success.any.worker.htmlProperties of IDBOpenDBRequest during successful IDBFactory open()
assert_true: complete event should fire before success expected true got false
/IndexedDB/idbfactory_open.any.htmlIDBFactory.open() - database 'name' and 'version' are correctly set
assert_equals: db.version expected 13 but got 1
IDBFactory.open() - no version opens current database
assert_unreached: Unexpected upgradeneeded Reached unreachable code
IDBFactory.open() - open database with a lower version than current
assert_unreached: Unexpected success Reached unreachable code
IDBFactory.open() - open database with a higher version than current
assert_true: did upgrade expected true got false
Calling open() with version argument 1.5 should not throw.
assert_unreached: open should fail Reached unreachable code
Calling open() with version argument undefined should not throw.
Test timed out
/IndexedDB/idbfactory_open.any.worker.htmlIDBFactory.open() - database 'name' and 'version' are correctly set
assert_equals: db.version expected 13 but got 1
IDBFactory.open() - no version opens current database
assert_unreached: Unexpected upgradeneeded Reached unreachable code
IDBFactory.open() - open database with a lower version than current
assert_unreached: Unexpected success Reached unreachable code
IDBFactory.open() - open database with a higher version than current
assert_true: did upgrade expected true got false
Calling open() with version argument undefined should not throw.
Test timed out
/IndexedDB/idbindex-query-exception-order.any.htmlIDBIndex.get exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.getAll exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.count exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.openCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
/IndexedDB/idbindex-query-exception-order.any.worker.htmlIDBIndex.get exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.getAll exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.count exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.openCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBIndex.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
/IndexedDB/idbobjectstore-add-put-exception-order.any.htmlIDBObjectStore.put exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.put exception order: ReadOnlyError vs. DataError
assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
store[method]({}, 'value');
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
IDBObjectStore.add exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.add exception order: ReadOnlyError vs. DataError
assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
store[method]({}, 'value');
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore-add-put-exception-order.any.worker.htmlIDBObjectStore.put exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.put exception order: ReadOnlyError vs. DataError
assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
store[method]({}, 'value');
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
IDBObjectStore.add exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.add exception order: ReadOnlyError vs. DataError
assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
store[method]({}, 'value');
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore-clear-exception-order.any.htmlIDBObjectStore.clear exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
/IndexedDB/idbobjectstore-clear-exception-order.any.worker.htmlIDBObjectStore.clear exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
/IndexedDB/idbobjectstore-delete-exception-order.any.htmlIDBObjectStore.delete exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.delete exception order: ReadOnlyError vs. DataError
assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
store.delete({});
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore-delete-exception-order.any.worker.htmlIDBObjectStore.delete exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.delete exception order: ReadOnlyError vs. DataError
assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
store.delete({});
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore-deleteIndex-exception-order.any.htmlIDBObjectStore.deleteIndex exception order: InvalidStateError #2 vs. TransactionInactiveError
Test timed out
IDBObjectStore.deleteIndex exception order: TransactionInactiveError vs. NotFoundError
Test timed out
/IndexedDB/idbobjectstore-deleteIndex-exception-order.any.worker.htmlIDBObjectStore.deleteIndex exception order: InvalidStateError #2 vs. TransactionInactiveError
Test timed out
IDBObjectStore.deleteIndex exception order: TransactionInactiveError vs. NotFoundError
Test timed out
/IndexedDB/idbobjectstore-query-exception-order.any.htmlIDBObjectStore.get exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.getAll exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.count exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.openCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
/IndexedDB/idbobjectstore-query-exception-order.any.worker.htmlIDBObjectStore.get exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.getAll exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.count exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.openCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
IDBObjectStore.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
Test timed out
/IndexedDB/idbobjectstore-request-source.any.htmlThe source of the request from store => store.put(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.add(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.delete(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.clear() is the object store itself
The object is in an invalid state.
The source of the request from store => store.get(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.getKey(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.getAll() is the object store itself
The object is in an invalid state.
The source of the request from store => store.getAllKeys() is the object store itself
The object is in an invalid state.
The source of the request from store => store.count() is the object store itself
The object is in an invalid state.
The source of the request from store => store.openCursor() is the object store itself
The object is in an invalid state.
/IndexedDB/idbobjectstore-request-source.any.worker.htmlThe source of the request from store => store.put(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.add(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.delete(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.clear() is the object store itself
The object is in an invalid state.
The source of the request from store => store.get(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.getKey(0) is the object store itself
The object is in an invalid state.
The source of the request from store => store.getAll() is the object store itself
The object is in an invalid state.
The source of the request from store => store.getAllKeys() is the object store itself
The object is in an invalid state.
The source of the request from store => store.count() is the object store itself
The object is in an invalid state.
The source of the request from store => store.openCursor() is the object store itself
The object is in an invalid state.
/IndexedDB/idbobjectstore_createIndex.any.htmlTransactionInactiveError vs. ConstraintError. Transaction-state check should precede index name check.
Test timed out
ConstraintError vs. SyntaxError. Index name check should precede syntax check of the key path
Test timed out
SyntaxError vs. InvalidAccessError. Syntax check should precede multiEntry check of the key path.
Test timed out
/IndexedDB/idbobjectstore_createIndex.any.worker.htmlTransactionInactiveError vs. ConstraintError. Transaction-state check should precede index name check.
Test timed out
ConstraintError vs. SyntaxError. Index name check should precede syntax check of the key path
Test timed out
SyntaxError vs. InvalidAccessError. Syntax check should precede multiEntry check of the key path.
Test timed out
/IndexedDB/idbobjectstore_delete.any.htmldelete() key doesn't match any records/IndexedDB/idbobjectstore_get.any.worker.htmlAttempts to retrieve a record that doesn't exist/IndexedDB/idbobjectstore_getAll-options.any.htmlGet all values with invalid query keys
assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
queryTarget[getAllFunctionName](argument);
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore_getAll-options.any.worker.htmlGet all values with invalid query keys
assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
queryTarget[getAllFunctionName](argument);
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore_getAllKeys-options.any.htmlgetAllKeys on empty object store
The object is in an invalid state.
Get all keys
The object is in an invalid state.
Get all keys with invalid query keys
assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
queryTarget[getAllFunctionName](argument);
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore_getAllKeys-options.any.worker.htmlgetAllKeys on empty object store
The object is in an invalid state.
Get all keys
The object is in an invalid state.
Get all keys with invalid query keys
assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
queryTarget[getAllFunctionName](argument);
}" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
/IndexedDB/idbobjectstore_getAllKeys.any.htmlSingle item get
The object is in an invalid state.
Single item get (generated key)
The object is in an invalid state.
getAllKeys on empty object store
The object is in an invalid state.
Get all keys
The object is in an invalid state.
Test maxCount
The object is in an invalid state.
Get bound range
The object is in an invalid state.
Get bound range with maxCount
The object is in an invalid state.
Get upper excluded
The object is in an invalid state.
Get lower excluded
The object is in an invalid state.
Get bound range (generated) with maxCount
The object is in an invalid state.
/IndexedDB/idbobjectstore_getAllKeys.any.worker.htmlSingle item get
The object is in an invalid state.
Single item get (generated key)
The object is in an invalid state.
getAllKeys on empty object store
The object is in an invalid state.
Get all keys
The object is in an invalid state.
Test maxCount
The object is in an invalid state.
Get bound range
The object is in an invalid state.
Get bound range with maxCount
The object is in an invalid state.
Get upper excluded
The object is in an invalid state.
Get lower excluded
The object is in an invalid state.
Get bound range (generated) with maxCount
The object is in an invalid state.
/IndexedDB/idbobjectstore_getKey.any.htmlIDBObjectStore.getKey() - basic - key
The object is in an invalid state.
IDBObjectStore.getKey() - basic - range
The object is in an invalid state.
IDBObjectStore.getKey() - basic - key - no match
The object is in an invalid state.
IDBObjectStore.getKey() - key path - key
The object is in an invalid state.
IDBObjectStore.getKey() - key path - range
The object is in an invalid state.
IDBObjectStore.getKey() - key path - key - no match
The object is in an invalid state.
IDBObjectStore.getKey() - key generator - key
The object is in an invalid state.
IDBObjectStore.getKey() - key generator - range
The object is in an invalid state.
IDBObjectStore.getKey() - key generator and key path - key
The object is in an invalid state.
IDBObjectStore.getKey() - key generator and key path - range
The object is in an invalid state.
/IndexedDB/idbobjectstore_getKey.any.worker.htmlIDBObjectStore.getKey() - basic - key
The object is in an invalid state.
IDBObjectStore.getKey() - basic - range
The object is in an invalid state.
IDBObjectStore.getKey() - basic - key - no match
The object is in an invalid state.
IDBObjectStore.getKey() - key path - key
The object is in an invalid state.
IDBObjectStore.getKey() - key path - range
The object is in an invalid state.
IDBObjectStore.getKey() - key path - key - no match
The object is in an invalid state.
IDBObjectStore.getKey() - key generator - key
The object is in an invalid state.
IDBObjectStore.getKey() - key generator - range
The object is in an invalid state.
IDBObjectStore.getKey() - key generator and key path - key
The object is in an invalid state.
IDBObjectStore.getKey() - key generator and key path - range
The object is in an invalid state.
/IndexedDB/idbobjectstore_openKeyCursor.any.html/IndexedDB/idbobjectstore_openKeyCursor.any.worker.html/IndexedDB/idbtransaction-oncomplete.any.htmlIDBTransaction - complete event/IndexedDB/idbtransaction-oncomplete.any.worker.htmlIDBTransaction - complete event/IndexedDB/idbtransaction_abort.any.htmlAbort during auto-committing should throw InvalidStateError.
The object is in an invalid state.
Abort on completed transaction should throw InvalidStateError.
The object is in an invalid state.
/IndexedDB/idbtransaction_abort.any.worker.htmlAbort during auto-committing should throw InvalidStateError.
The object is in an invalid state.
Abort on completed transaction should throw InvalidStateError.
The object is in an invalid state.
/IndexedDB/idbtransaction_objectStoreNames.any.htmlIDBTransaction.objectStoreNames - during upgrade transactionIDBTransaction.objectStoreNames - value after commit
The object is in an invalid state.
/IndexedDB/idbtransaction_objectStoreNames.any.worker.htmlIDBTransaction.objectStoreNames - during upgrade transactionIDBTransaction.objectStoreNames - value after commit
The object is in an invalid state.
/IndexedDB/keypath-exceptions.any.htmlKey path evaluation: Exceptions from non-enumerable getters/IndexedDB/keypath-exceptions.any.worker.htmlKey path evaluation: Exceptions from non-enumerable getters/IndexedDB/keypath-special-identifiers.any.htmlType: String, identifier: length
The object is in an invalid state.
Type: Array, identifier: length
The object is in an invalid state.
Type: Blob, identifier: size
The object is in an invalid state.
Type: Blob, identifier: type
The object is in an invalid state.
/IndexedDB/keypath-special-identifiers.any.worker.htmlType: String, identifier: length
The object is in an invalid state.
Type: Array, identifier: length
The object is in an invalid state.
Type: Blob, identifier: size
The object is in an invalid state.
Type: Blob, identifier: type
The object is in an invalid state.
/IndexedDB/nested-cloning-basic.any.htmlsmall typed array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
blob
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/nested-cloning-basic.any.worker.htmlsmall typed array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
blob
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/nested-cloning-large.any.htmlblob with large typed array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
array of blobs and large typed arrays
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
object with blobs and large typed arrays
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/nested-cloning-large.any.worker.htmlblob with large typed array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
array of blobs and large typed arrays
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
object with blobs and large typed arrays
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/nested-cloning-small.any.htmlblob with small typed array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
blob array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
array of blobs and small typed arrays
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/nested-cloning-small.any.worker.htmlblob with small typed array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
blob array
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
array of blobs and small typed arrays
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/open-request-queue.any.htmlIndexedDB: open and delete requests are processed as a FIFO queue
Test timed out
/IndexedDB/open-request-queue.any.worker.htmlIndexedDB: open and delete requests are processed as a FIFO queue
Test timed out
/IndexedDB/structured-clone.any.html?101-lastNot serializable: function: function() {}
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: symbol: Symbol(desc)
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: Window: [object Window]
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: Event: [object Event]
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: MessageChannel: [object MessageChannel]
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/structured-clone.any.worker.html?101-lastNot serializable: function: function() {}
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: symbol: Symbol(desc)
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: DedicatedWorkerGlobalScope: [object DedicatedWorkerGlobalScope]
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: Event: [object Event]
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
Not serializable: MessageChannel: [object MessageChannel]
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/IndexedDB/transaction-lifetime-empty.any.htmlTransactions without requests complete in the expected order
The object is in an invalid state.
Multiple transactions without requests complete in the expected order
The object is in an invalid state.
/IndexedDB/transaction-lifetime-empty.any.worker.htmlTransactions without requests complete in the expected order
The object is in an invalid state.
Multiple transactions without requests complete in the expected order
The object is in an invalid state.
/IndexedDB/transaction-lifetime.any.htmlNo Blocked event
assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
Blocked event
assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
/IndexedDB/transaction-lifetime.any.worker.htmlNo Blocked event
assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
Blocked event
assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
/IndexedDB/transaction-scheduling-within-database.any.htmlCheck that read-only transactions within a database can run in parallel.
The object is in an invalid state.
/IndexedDB/transaction-scheduling-within-database.any.worker.htmlCheck that read-only transactions within a database can run in parallel.
The object is in an invalid state.
/IndexedDB/upgrade-transaction-deactivation-timing.any.htmlUpgrade transactions are active in upgradeneeded callbackUpgrade transactions are active in upgradeneeded callback and microtasksUpgrade transactions are deactivated before next task/IndexedDB/upgrade-transaction-deactivation-timing.any.worker.htmlUpgrade transactions are active in upgradeneeded callbackUpgrade transactions are active in upgradeneeded callback and microtasksUpgrade transactions are deactivated before next task/IndexedDB/worker-termination-aborts-upgrade.window.htmlWorker Termination Aborts a Pending Upgrade
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
/wasm/webapi/historical.any.htmlhistorical
assert_throws_dom: function "() => store.put(mod, module_key)" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataCloneError: property "code" is equal to 11, expected 25
/wasm/webapi/historical.any.worker.htmlhistorical
assert_throws_dom: function "() => store.put(mod, module_key)" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataCloneError: property "code" is equal to 11, expected 25
⚠️ Try run (#19896250328) failed.
Ok so the problem is that the new async worflow creates two database, one during upgrade, one when it finishes, and so any object stores created during upgrade are not found on the second one. Previously this wasn't an issue because the entire worflow was one atomic step(blocking script), so only one db was created.
Solution: store the DB that is created in the first async step and use it later. Highlights the need to have a script-side persistent and stateful IPC message handler(now the OpenRequestListener, but could just be one struct per global keeping track of everything). Useful besides just saving on IPC routes.
EDIT: actually it's not the IPC handler that should be stateful, since it cannot manipulate script objects: what is needed is state per global; I'm guessing the IDBFactory will do.
Solution: store the DB that is created in the first async step and use it later. Highlights the need to have a script-side persistent and stateful IPC message handler(now the
OpenRequestListener, but could just be one struct per global keeping track of everything). Useful besides just saving on IPC routes.
Is that something like a persistent back channel from the backend to the script/global (and the script would add a route for it)? That would actually align with my plans. :) The only difference is that I’d like to maintain state across multiple structs and also support more message types.
Is that something like
Yes something like that, as in we don't need one callback per operation, like is now done at
https://github.com/servo/servo/blob/1aab8186b7c984a80f23e65dd31bb70b4f632cc0/components/script/dom/indexeddb/idbrequest.rs#L412
The only difference is that I’d like to maintain state across multiple structs and also support more message types.
You can use whatever data structure you need, but the "root" of it needs to be stored somewhere accessible from code on the script-thread; for example the idb factory is available via global.IndexedDB().
Note that there is a difference between "one IPC route/callback for all indexeddb stuff per global", and "stateful data used in script", because the route/callback handler is a struct on the IPC router thread, and all it can do is queue a task back on the script-thread to run some logic. And running that logic, if stateful, requires some other data(usually dom objects).
So in this PR, what I will do is the following:
- Use
OpenRequestListeneras a callback for all the stuff related to opening/upgrading a db. That means I use it as a kind of persistent callback, in the sense that in the case of an upgrade it will handle first the upgrade message, and later the final upgraded connection. - I will then store some state on
IDBFactory, because I need it in the case of an upgrade to since that is now an async workflow involving multiple messages. The state is the Db that is being upgraded, so I'll just add a map ofIDBDatabaseon the factory.
But this can be applied to all async operations using a single IPC channel/route. Those can still contain nested data and messages. So you can have multiple types of structs and messages, but if you want to use only a single IPC route you need to nest those within one global data and one global message structure.
Thanks for detailed explanation!
I've applied the transformation mentioned above, and it fixes at least one test(which I think is representative) from the list of failures in the last run, so let's see what it does now.
🔨 Triggering try run (#19964127059) for Linux (WPT)
⚠️ Try run (#19964127059) failed.
🔨 Triggering try run (#19970159612) for Linux (WPT)
Test results for linux-wpt from try job (#19970159612):Flaky unexpected result (36)
/IndexedDB/idbobjectstore_count.any.htmlReturns the number of records that have keys with the key/IndexedDB/transaction-deactivation-timing.any.worker.html (#38808)New transactions are deactivated before next task/_mozilla/css/linear_gradients_reverse_a.html/_mozilla/shadow-dom/move-element-with-ua-shadow-tree-crash.html (#39473)/_mozilla/webxr/create_session.https.htmlcreate_session
can't access property "simulateDeviceConnection", navigator.xr.test is undefined
/_mozilla/webxr/obtain_frame.https.htmlobtain_frame
promise_test: Unhandled rejection with value: object "TypeError: can't access property "simulateDeviceConnection", navigator.xr.test is undefined"
/_mozilla/webxr/sessionavailable.https.html/_webgl/conformance/context/context-hidden-alpha.html/_webgl/conformance2/canvas/to-data-url-with-pack-params.html/css/css-animations/event-order.tentative.html (#39000)Same events on pseudo-elements follow the prescribed order/css/css-fonts/generic-family-keywords-002.html (#40929)font-family: -webkit-serif treated as <font-family>, not <generic-name>font-family: -webkit-sans-serif treated as <font-family>, not <generic-name>font-family: -webkit-cursive treated as <font-family>, not <generic-name>font-family: -webkit-fantasy treated as <font-family>, not <generic-name>font-family: -webkit-monospace treated as <font-family>, not <generic-name>font-family: -webkit-system-ui treated as <font-family>, not <generic-name>font-family: -webkit-math treated as <font-family>, not <generic-name>font-family: -webkit-generic(fangsong) treated as <font-family>, not <generic-name>
assert_equals: expected 50 but got 30
font-family: -webkit-generic(kai) treated as <font-family>, not <generic-name>
assert_equals: expected 50 but got 30
font-family: -webkit-generic(khmer-mul) treated as <font-family>, not <generic-name>
assert_equals: expected 50 but got 30
/css/css-fonts/generic-family-keywords-003.html (#38994)@font-face matching for quoted and unquoted ui-serif (drawing text in a canvas)@font-face matching for quoted and unquoted ui-rounded (drawing text in a canvas)/css/css-fonts/variations/font-weight-matching.html (#38577)Test @font-face matching for weight 400
assert_approx_equals: @font-face should be mapped to CSSTest Weights 700. expected 90 +/- 2 but got 180
Test @font-face matching for weight 420
assert_approx_equals: @font-face should be mapped to CSSTest Weights 600. expected 90 +/- 2 but got 180
/custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)Null value should submit nothingsetFormValue with an empty FormData should submit nothing/fetch/api/redirect/redirect-keepalive.https.any.html (#32153)[keepalive][iframe][load] mixed content redirect; setting up/fetch/metadata/generated/css-images.sub.tentative.html (#29047)background-image sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
Test timed out
/focus/focus-event-after-switching-iframes.sub.html (#40368)/html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)Link with onclick navigation and href navigation /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html (#28681)load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank'
assert_unreached: load should not be fired Reached unreachable code
/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin-fragment.html (#20768)Tests that a fragment navigation in the unload handler will not block the initial navigation/html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)Multiple history traversals, last would be aborted
assert_array_equals: Pages opened during history navigation expected property 1 to be 5 but got 3 (expected array [6, 5] got [6, 3])
/html/browsers/windows/browsing-context-names/duplicate-name-order.html (#34623)Duplicate name lookup order/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.transform.html/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html (#39694)Meta refresh is blocked by the allow-scripts sandbox flag at its creation time, not when refresh comes due/html/semantics/embedded-content/the-canvas-element/security.drawImage.canvas.cross.html/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-assign.html (#32863)Navigating iframe loading='lazy' before it is loaded: location.assign
uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
/html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)multipart/form-data: Basic test (formdata event)
assert_equals: expected "\r\nContent-Disposition: form-data; name=\"basic\"\r\n\r\ntest\r\n--\r\n" but got ""
multipart/form-data: 0x00 in name (formdata event)multipart/form-data: 0x00 in value (normal form)multipart/form-data: \n in value (normal form)/html/semantics/forms/form-submission-0/text-plain.window.html (#28687)text/plain: Basic test (formdata event)
assert_equals: expected "basic=test\r\n" but got ""
text/plain: Basic File test (normal form)
assert_equals: expected "basic=file-test.txt\r\n" but got ""
text/plain: backslash in filename (formdata event)/preload/preload-xhr.html (#39092)Make an XHR request immediately after creating link rel=preload.
assert_equals: resources/dummy.xml?token=36e7d92d-ce25-44e2-bff1-8d4076a11950 expected 1 but got 0
/preload/subresource-integrity-partial-image.html/trusted-types/Element-setAttribute-setAttributeNS-sinks.tentative.html/trusted-types/SharedWorker-importScripts.html/trusted-types/trusted-types-navigation.html?06-10 (#37920)Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in enforcing mode.
promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in report-only mode.
promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
/wasm/webapi/empty-body.any.serviceworker.html/wasm/webapi/empty-body.any.worker.html/websockets/unload-a-document/003.htmlStable unexpected results that are known to be intermittent (29)
/FileAPI/url/url-in-tags-revoke.window.html (#19978)Fetching a blob URL immediately before revoking it works in <script> tags.
Test timed out
/IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)IDBCursor continuePrimaryKey() on object store cursor
assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
cursor.continuePrimaryKey(2, 2);
}" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
/IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)IDBCursor continuePrimaryKey() on object store cursor
assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
cursor.continuePrimaryKey(2, 2);
}" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
/IndexedDB/idbobjectstore_delete.any.worker.html (#39069)delete() key doesn't match any records/IndexedDB/idbobjectstore_getAll.any.html (#39276)Get all values with transaction.commit()/IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)Get all values with transaction.commit()/IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)indexedDB.delete called from upgradeneeded handler
assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
transaction oncomplete ordering relative to open request onsuccess/IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)indexedDB.delete called from upgradeneeded handler
assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
transaction oncomplete ordering relative to open request onsuccess/IndexedDB/key-conversion-exceptions.any.html (#39305)IDBCursor continue() method with throwing/invalid keys
assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
receiver[method](key);
}" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
IDBCursor update() method with throwing/invalid keys
assert_throws_exactly: throwing getter should rethrow during clone function "() => {
cursor.update(value);
}" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
/IndexedDB/key-conversion-exceptions.any.worker.html (#39284)IDBCursor continue() method with throwing/invalid keys
assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
receiver[method](key);
}" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
IDBCursor update() method with throwing/invalid keys
assert_throws_exactly: throwing getter should rethrow during clone function "() => {
cursor.update(value);
}" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
/_mozilla/mozilla/sslfail.html (#10760)/_mozilla/mozilla/window_resize_event.html (#36741)Popup onresize event fires after resizeTo
Test timed out
/_webgl/conformance/textures/misc/texture-upload-size.html (#21770)WebGL test #45WebGL test #47WebGL test #49WebGL test #51WebGL test #53
assert_true: Texture was smaller than the expected size 2x2 expected true got false
WebGL test #55
assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
WebGL test #57
assert_true: Texture was smaller than the expected size 2x2 expected true got false
WebGL test #59
assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
WebGL test #61WebGL test #63/css/css-fonts/generic-family-keywords-001.html (#37467)@font-face matching for quoted and unquoted generic(fangsong)
assert_equals: quoted generic(fangsong) matches @font-face rule expected 50 but got 30
@font-face matching for quoted and unquoted generic(khmer-mul)
assert_equals: quoted generic(khmer-mul) matches @font-face rule expected 50 but got 30
/fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)sec-fetch-storage-access - Cross-site
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
/fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
/fetch/metadata/generated/element-iframe.https.sub.html (#40341)/fetch/metadata/generated/element-img-environment-change.https.sub.html (#30111)sec-fetch-site - Same-Origin -> Same Origin, no attributes
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
sec-fetch-site - Same-Origin -> Cross-Site, no attributessec-fetch-site - Same-Site -> Same Origin, no attributes
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
sec-fetch-site - Same-Site -> Same-Site, no attributessec-fetch-mode - no attributessec-fetch-dest - no attributes/fetch/metadata/generated/element-img-environment-change.sub.html (#30111)sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributessec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributessec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributessec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributessec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes/fetch/metadata/generated/serviceworker.https.sub.html (#36247)sec-fetch-site - Same origin, no options - registration
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
/fetch/metadata/window-open.https.sub.html (#40339)Same-site window, forced, reloaded
The operation is insecure.
/html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)/html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)Multiple history traversals, last would be aborted/html/infrastructure/common-dom-interfaces/collections/domstringlist.html (#40665)/html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)Element with tabindex should support autofocus
Test timed out
Host element with delegatesFocus should support autofocusHost element with delegatesFocus including no focusable descendants should be skippedArea element should support autofocus/navigation-timing/test-navigation-type-reload.html (#33334)Reload domComplete > Original domCompleteReload domContentLoadedEventStart > Original domContentLoadedEventStartReload domInteractive > Original domInteractiveReload fetchStart > Original fetchStartReload loadEventEnd > Original loadEventEndReload loadEventStart > Original loadEventStart/preload/preload-error.sub.html (#37177)success (fetch): main
assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?label=fetch should be loaded expected a number greater than 0 but got 0
404 (fetch): mainCORS (fetch): main
assert_greater_than: http://not-web-platform.test:8000/preload/resources/dummy.xml?pipe=header%28Access-Control-Allow-Origin%2C*%29&label=fetch should be loaded expected a number greater than 0 but got 0
/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)StorageKey: test 3P about:blank window opened from a 3P iframe
Test timed out
/webxr/render_state_update.https.html (#27535)Stable unexpected results (15)
/IndexedDB/delete-request-queue.any.htmlDeletes are processed as a FIFO queue
saw is not a function
/IndexedDB/delete-request-queue.any.worker.htmlDeletes are processed as a FIFO queue
saw is not a function
/IndexedDB/idbdatabase-createObjectStore-exception-order.any.htmlIDBDatabase.createObjectStore exception order: TransactionInactiveError vs. SyntaxError/IndexedDB/idbdatabase-createObjectStore-exception-order.any.worker.htmlIDBDatabase.createObjectStore exception order: TransactionInactiveError vs. SyntaxError/IndexedDB/idbdatabase-deleteObjectStore-exception-order.any.htmlIDBDatabase.deleteObjectStore exception order: TransactionInactiveError vs. NotFoundError/IndexedDB/idbdatabase-deleteObjectStore-exception-order.any.worker.htmlIDBDatabase.deleteObjectStore exception order: TransactionInactiveError vs. NotFoundError/IndexedDB/idbfactory_open.any.htmlIDBFactory.open() - no version opens current database
assert_unreached: Unexpected upgradeneeded Reached unreachable code
Calling open() with version argument 1.5 should not throw.
Test timed out
IDBFactory.open() - upgradeneeded gets VersionChangeEvent
assert_equals: oldVersion expected 0 but got 9
/IndexedDB/idbfactory_open.any.worker.htmlIDBFactory.open() - no version opens current database
assert_unreached: Unexpected upgradeneeded Reached unreachable code
Calling open() with version argument 1.5 should not throw.
Test timed out
IDBFactory.open() - upgradeneeded gets VersionChangeEvent
assert_equals: oldVersion expected 0 but got 9
/IndexedDB/idbobjectstore_delete.any.htmldelete() key doesn't match any records/IndexedDB/idbobjectstore_get.any.worker.htmlAttempts to retrieve a record that doesn't exist/IndexedDB/idbtransaction-oncomplete.any.htmlIDBTransaction - complete event/IndexedDB/idbtransaction-oncomplete.any.worker.htmlIDBTransaction - complete event/IndexedDB/open-request-queue.any.htmlIndexedDB: open and delete requests are processed as a FIFO queue
Test timed out
/IndexedDB/open-request-queue.any.worker.htmlIndexedDB: open and delete requests are processed as a FIFO queue
Test timed out
/IndexedDB/worker-termination-aborts-upgrade.window.htmlWorker Termination Aborts a Pending Upgrade
promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
⚠️ Try run (#19970159612) failed.
Current status re tests:
/IndexedDB/delete-request-queue.any.html saw is not a function
If I remove the this from the below:
https://github.com/servo/servo/blob/1e8d1cf08184336cbfa137d55bd5cb5dfe32f39e/tests/wpt/tests/IndexedDB/delete-request-queue.any.js#L10
The test passes.
My changes remove a task queueing(because we are already in a task); I have tried to re-introduce it but the test still fails. Don't know what could have changed the behavior of this. cc @jdm
/IndexedDB/idbfactory_open.any.html
This one goes to the hearth of our lack of db connections. The test does a close, which currently is a sync operation that deletes the database, but the spec reads: to clone the connection, not the db.
I have debugged it and confirmed the problem: Test passes if I remove the code handling the close, and have added a TODO and updated the WPT expectations.
EDIT: the above is not completely correct. The current code does not delete the database, it only deletes the IndexedDBEnvironment, and so even if a new one is created, it re-uses the same underlying physical database. The test fails after my changes because I assume that if no IndexedDBEnvironment is found, then the we hit the "db is null" part of the spec. But in fact there is no way to know whether the db is physically present or not. I've added a beginning of tracking that state.
All other tests that are new fails: I have only looked at their names and they all seem to involve the same problem of not managing transactions lifecycle. So I have updated them all to the results noted above.
There are new passes: I have updated them as well but haven't looked into the details of why they are passing. Could be a case of "if you change anything, some tests will pass".
So I've marked this one as ready for review, taking into account:
- The WPT regressions should be seen in the light of their explanation and the follow-ups noted at https://github.com/servo/servo/issues/40983(which are unblocked once this first refactoring merges).
- Various data structures introduced in this PR will probably be merged into more coherent ones as part of the various items in https://github.com/servo/servo/issues/40983. Example:
pending_upgrades: HashMap<(String, u64), PendingUpgrade>, the tuple is not ideal, but the thing is that I don't even know yet exactly what this will look like when we move it to a full transaction lifecyle, and so it doesn't seem worth sweating it now. - I've tried to make the smallest change possible while still having something that basically works(example: async open and upgrade, but a full transaction lifecyle is left as a follow-up, hence many WPT regressions because previously open/upgrade was done as one blocking step).
- the problem with
thismentioned above is the one WPT regression I don't understand. I think it's a script context/realm thing...
cc @janvarga @Taym95 @jdm
:warning: JUnit XML file not found
The CLI was unable to find any JUnit XML files to upload. For more help, visit our troubleshooting guide.
Setting this back to draft because there are a few things with the failing WPT tests that I still want to check out.
Ok I ended fixing what were various simple bugs in the new architecture.
There are still a few WPT regressions:
Calling open() with version argument 1.5 should not throw.I think this is about implementing abort as part of the new async architecture.Deletes are processed as a FIFO queue: request/transaction lifecyle.open and delete requests are processed as a FIFO queue: request/transaction lifecyle.Worker Termination Aborts a Pending Upgrade: request/transaction lifecyle.
The regressions are I think a result of moving to an async workflow, which requires more bookkeeping than the blocking equivalent.
Ready for review.
@Taym95 @arihant2math Thanks for the reviews.
I'll take a look today as well, although I already said that this makes sense from a high level point of view.
@janvarga thanks for the review.