servo icon indicating copy to clipboard operation
servo copied to clipboard

Base: Implement GenericReceiverSet

Open Narfinger opened this issue 2 weeks ago • 1 comments

This implements GenericReceiverSet similar to IpcReceiverSet. This allows us to wa it on a group of channels.

IpcReceiverSet was allowed to use IpcReceivers of different type, i.e., IpcReceiver<Foo> and IpcReceiver<Bar> in the same select query. This changes with GenericReceiverSet to only allow one type, i.e., GenericReceiver<Foo>. As this functionality was only used in the CoreResourceThread, we changed the setup slightly for the memory reporter.

With this we also change the implementation of CoreResourceThread to now use the GenericReceiverSet.

Signed-off-by: Narfinger [email protected]

Testing: New testcases were added to GenericReceiverSet and browsing works normally.

Narfinger avatar Dec 05 '25 09:12 Narfinger

FYI, you need to use backticks, with single quotes Foo<bar> will render as 'Foo' (note the missing <bar>). I edited the description for you.

jschwe avatar Dec 06 '25 10:12 jschwe

:x: 1 Tests Failed:

Tests completed Failed Passed Skipped
831 1 830 0
View the top 1 failed test(s) by shortest run time
libservo::site_data::test_clear_cookies
Stack Traces | 0.277s run time
thread 'test_clear_cookies' (25738) panicked at .../servo/tests/site_data.rs:57:5:
assertion `left == right` failed
  left: Err(EvaluationFailure(None))
 right: Ok(String(""))
stack backtrace:
   0: __rustc::rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
   4: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

To view more test analytics, go to the Test Analytics Dashboard 📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

codecov-commenter avatar Dec 15 '25 16:12 codecov-commenter

The UT is stuck.. I've rerun multiple times but still...

yezhizhen avatar Dec 16 '25 14:12 yezhizhen

I clicked "update branch" in UI. UT finally starts to run.

yezhizhen avatar Dec 16 '25 14:12 yezhizhen

Emm the same test is still failing. TRY 3 FAIL [ 0.176s] (223/831) libservo::site_data test_clear_cookies:

stderr ───
    error: XDG_RUNTIME_DIR not set in the environment.
    libEGL warning: egl: failed to create dri2 screen

    thread 'ResourceManager' (28112) panicked at components/net/resource_thread.rs:278:33:
    assertion `left == right` failed
      left: 0
     right: 2
    stack backtrace:
       0: __rustc::rust_begin_unwind
       1: core::panicking::panic_fmt
       2: core::panicking::assert_failed_inner
       3: core::panicking::assert_failed
       4: net::resource_thread::ResourceChannelManager::start
       5: profile_traits::mem::ProfilerChan::run_with_memory_reporting
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

    thread 'Script#1' (28158) panicked at components/script/dom/document.rs:5565:33:
    called `Result::unwrap()` on an `Err` value: Disconnected

yezhizhen avatar Dec 16 '25 14:12 yezhizhen

Ok let me check out the test.

Narfinger avatar Dec 16 '25 14:12 Narfinger

Ok it should be fixed. There was a problem with how I calculated the indices. I also adjusted the tests so that this should be caught in the future.

Narfinger avatar Dec 16 '25 15:12 Narfinger

🔨 Triggering try run (#20290670700) for Windows

github-actions[bot] avatar Dec 17 '25 03:12 github-actions[bot]

Windows UT keeps panicking. (The Windows try label does not run UT tho..)

thread 'generic_channel::generic_receiversets_tests::test_ipc_side_multiple' (8436) panicked at components\shared\base\generic_channel.rs:681:9:
    assertion `left == right` failed
      left: 1
     right: 2
    stack backtrace:
       0: std::panicking::panic_handler
                 at /rustc/f8297e351a40c1439a467bbbb6879088047f50b3/library\std\src\panicking.rs:698
       1: core::panicking::panic_fmt
                 at /rustc/f8297e351a40c1439a467bbbb6879088047f50b3/library\core\src\panicking.rs:75
       2: core::panicking::assert_failed_inner
                 at /rustc/f8297e351a40c1439a467bbbb6879088047f50b3/library\core\src\panicking.rs:434
       3: core::panicking::assert_failed<usize,usize>
                 at /rustc/f8297e351a40c1439a467bbbb6879088047f50b3/library\core\src\panicking.rs:394
       4: base::generic_channel::generic_receiversets_tests::test_ipc_side_multiple
       5: base::main
       6: core::ops::function::FnOnce::call_once
                 at /rustc/f8297e351a40c1439a467bbbb6879088047f50b3/library\core\src\ops\function.rs:250

yezhizhen avatar Dec 17 '25 03:12 yezhizhen

✨ Try run (#20290670700) succeeded.

github-actions[bot] avatar Dec 17 '25 03:12 github-actions[bot]

Ok let me look at it on a windows machine, just to make sure that it is not another error.

Narfinger avatar Dec 17 '25 08:12 Narfinger

Ok should be fixed now. It seems that on windows ipc-channel does not return multiple messages if there are multiple messages in queue. So I removed the test that was expecting it.

Narfinger avatar Dec 17 '25 09:12 Narfinger

@Narfinger We are probably still cursed😅

yezhizhen avatar Dec 17 '25 12:12 yezhizhen

It's very interesting that three separate cookiestore tests reported new results.

jdm avatar Dec 17 '25 12:12 jdm

I am not quite sure how we should proceed. I don't see how these tests could be failing now with the changes. Anybody an idea?

Narfinger avatar Dec 17 '25 14:12 Narfinger

🔨 Triggering try run (#20309559658) for Linux (WPT)

github-actions[bot] avatar Dec 17 '25 16:12 github-actions[bot]

Test results for linux-wpt from try job (#20309559658):

Flaky unexpected result (30)
  • OK /_mozilla/css/offset_properties_inline.html (#40543)
    • PASS [expected FAIL] subtest: offsetTop
    • PASS [expected FAIL] subtest: offsetLeft
  • OK /_mozilla/mozilla/getBoundingClientRect.html (#39668)
    • FAIL [expected PASS] subtest: getBoundingClientRect 1
      assert_equals: expected 62 but got 60.35
      

  • OK /_mozilla/webxr/create_session.https.html
    • FAIL [expected PASS] subtest: create_session
      can't access property "simulateDeviceConnection", navigator.xr.test is undefined
      

  • ERROR [expected TIMEOUT] /_mozilla/webxr/sessionavailable.https.html
  • CRASH [expected OK] /_webgl/conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html
  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • PASS [expected FAIL] subtest: WebGL test #45
    • PASS [expected FAIL] subtest: WebGL test #47
    • PASS [expected FAIL] subtest: WebGL test #49
    • PASS [expected FAIL] subtest: WebGL test #51
    • FAIL [expected PASS] subtest: WebGL test #53
      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: 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
      

    • FAIL [expected PASS] subtest: WebGL test #57
      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: 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
      

    • PASS [expected FAIL] subtest: WebGL test #61
    • PASS [expected FAIL] subtest: WebGL test #63
    • And 22 more unexpected results...
  • CRASH [expected ERROR] /_webgl/conformance2/textures/misc/tex-input-validation.html (#38890)
  • CRASH [expected OK] /_webgl/conformance2/wasm/readpixels-2gb-in-4gb-wasm-memory.html
  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-serif (drawing text in a canvas)
  • OK /fetch/content-length/api-and-duplicate-headers.any.worker.html (#35197)
    • FAIL [expected PASS] subtest: fetch() and duplicate Content-Length/Content-Type headers
      promise_test: Unhandled rejection with value: object "TypeError: Network error occurred"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/refresh/same-document-refresh.html (#34597)
    • FAIL [expected PASS] subtest: Same-Document Referrer from Refresh
      assert_equals: original page loads expected "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section#section"
      

  • TIMEOUT [expected OK] /html/semantics/embedded-content/media-elements/audio_loop_base.html (#41122)
    • NOTRUN [expected PASS] subtest: Check if audio.loop is set to true that expecting the seeking event is fired more than once
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-assign.html (#32863)
    • FAIL [expected PASS] subtest: 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"
      

  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigate_other_frame_popup.sub.html (#39702)
    • TIMEOUT [expected FAIL] subtest: Sandboxed iframe can not navigate other frame's popup
      Test timed out
      

  • CRASH [expected OK] /html/semantics/forms/form-submission-0/form-submit-iframe-then-location-navigate.html (#29634)
  • OK /html/semantics/forms/form-submission-0/jsurl-form-submit.tentative.html (#36489)
    • PASS [expected FAIL] subtest: Verifies that form submissions scheduled inside javascript: urls take precedence over the javascript: url's return value.
  • CRASH [expected OK] /imagebitmap-renderingcontext/toBlob-origin-clean-offscreen.sub.html
  • OK /mixed-content/tentative/autoupgrades/mixed-content-cors.https.sub.html (#41123)
    • FAIL [expected PASS] subtest: Cross-Origin audio should get upgraded even if CORS is set
      assert_equals: Length of other host audio is correct expected 1 but got Infinity
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • FAIL [expected PASS] subtest: Reload domContentLoadedEventEnd &gt; Original domContentLoadedEventEnd
      assert_true: Reload domContentLoadedEventEnd &gt; Original domContentLoadedEventEnd expected true got false
      

  • PASS [expected FAIL] /png/apng/acTL-plays-one.html (#41218)
  • OK /preload/prefetch-document.html (#37210)
    • FAIL [expected PASS] subtest: different-site document prefetch with 'as=document' should not be consumed
      assert_equals: expected 2 but got 1
      

  • OK /preload/preload-xhr.html (#39092)
    • FAIL [expected PASS] subtest: Make an XHR request immediately after creating link rel=preload.
      assert_equals: resources/dummy.xml?token=235ce333-ff64-41af-afdc-e7cf47f62822 expected 1 but got 0
      

  • CRASH [expected ERROR] /trusted-types/SharedWorker-setTimeout-setInterval.html
  • CRASH [expected OK] /trusted-types/should-trusted-type-policy-creation-be-blocked-by-csp-001.html
  • CRASH [expected OK] /trusted-types/trusted-types-reporting-for-Document-execCommand.html
  • CRASH [expected TIMEOUT] /wasm/webapi/empty-body.any.worker.html
  • CRASH [expected OK] /webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html
  • CRASH [expected OK] /webxr/xrBoundedReferenceSpace_updates.https.html
  • CRASH [expected OK] /webxr/xrSession_sameObject.https.html
  • CRASH [expected OK] /workers/Worker_ErrorEvent_bubbles_cancelable.htm
Stable unexpected results that are known to be intermittent (32)
  • TIMEOUT /FileAPI/url/url-in-tags-revoke.window.html (#19978)
    • PASS [expected TIMEOUT] subtest: Fetching a blob URL immediately before revoking it works in &lt;script&gt; tags.
  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)
    • FAIL [expected PASS] subtest: 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
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: 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
      

  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)
    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)
    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys
      assert_throws_exactly: key conversion with throwing getter should rethrow function "() =&gt; {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys
      assert_throws_exactly: throwing getter should rethrow during clone function "() =&gt; {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys
      assert_throws_exactly: key conversion with throwing getter should rethrow function "() =&gt; {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys
      assert_throws_exactly: throwing getter should rethrow during clone function "() =&gt; {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo
      Test timed out
      

  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • FAIL [expected PASS] subtest: Insert layer invalidates @font-face
      assert_equals: expected "220px" but got "133px"
      

  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 1
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 2
  • OK [expected TIMEOUT] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • PASS [expected TIMEOUT] subtest: [keepalive][iframe][load] mixed content redirect; setting up
  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • OK /html/browsers/history/the-history-interface/traverse_the_history_2.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • FAIL [expected PASS] subtest: 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])
      

  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • FAIL [expected NOTRUN] subtest: Area element should support autofocus
      promise_test: Unhandled rejection with value: object "TypeError: can't access property "appendChild", w.document.querySelector(...) is null"
      

  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-default-feature-policy.https.sub.html (#41193)
    • TIMEOUT [expected PASS] subtest: Default "autoplay" feature policy ["self"] allows same-origin iframes.
      Test timed out
      

  • OK /html/semantics/embedded-content/media-elements/media_fragment_seek.html (#24114)
    • PASS [expected FAIL] subtest: Video should seek to time specified in media fragment syntax
  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • FAIL [expected PASS] subtest: 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 ""
      

  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • FAIL [expected PASS] subtest: text/plain: Basic test (formdata event)
      assert_equals: expected "basic=test\r\n" but got ""
      

    • FAIL [expected PASS] subtest: text/plain: Basic File test (normal form)
      assert_equals: expected "basic=file-test.txt\r\n" but got ""
      

    • PASS [expected FAIL] subtest: text/plain: 0x00 in filename (normal form)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: Basic File test (normal form)
      assert_equals: expected "basic=file-test.txt" but got ""
      

    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in value (formdata event)
  • OK /html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)
    • FAIL [expected PASS] subtest: 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"])
      

  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • FAIL [expected PASS] subtest: print() during unload
      assert_array_equals: expected property 1 to be "destination" but got "error: window.print is not a function" (expected array ["start", "destination"] got ["start", "error: window.print is not a function"])
      

  • OK /preload/preload-error.sub.html (#37177)
    • FAIL [expected PASS] subtest: 404 (fetch): main
      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?pipe=status%28404%29&amp;label=fetch should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: CORS (fetch): main
  • OK /service-workers/service-worker/fetch-event.https.html (#36234)
    • PASS [expected FAIL] subtest: Service Worker falls back to network in fetch event with POST form
  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • TIMEOUT [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.
      Test timed out
      

    • NOTRUN [expected TIMEOUT] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.
  • TIMEOUT [expected OK] /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • TIMEOUT [expected PASS] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.
      Test timed out
      

    • NOTRUN [expected PASS] subtest: Navigate a window via form-submission with javascript:-urls w/ default policy in report-only mode.
    • NOTRUN [expected PASS] subtest: Navigate a frame via form-submission with javascript:-urls in enforcing mode.
    • NOTRUN [expected PASS] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in enforcing mode.
  • OK [expected TIMEOUT] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • PASS [expected TIMEOUT] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe
Stable unexpected results (3)
  • OK [expected TIMEOUT] /cookiestore/cookieStore_delete_arguments.https.any.html
    • PASS [expected TIMEOUT] subtest: cookieStore.delete with positional empty name
    • PASS [expected NOTRUN] subtest: cookieStore.delete with empty name in options
    • PASS [expected NOTRUN] subtest: cookieStore.delete with maximum cookie name size
    • FAIL [expected NOTRUN] subtest: cookieStore.delete with a __Host- prefix should not have a domain
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • PASS [expected NOTRUN] subtest: cookieStore.delete with whitespace
  • CRASH [expected TIMEOUT] /cookiestore/cookieStore_set_arguments.https.any.html
  • OK [expected TIMEOUT] /cookiestore/cookieStore_special_names.https.any.html
    • FAIL [expected TIMEOUT] subtest: cookieStore.set a nameless cookie cannot have __Host- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Secure- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Http- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Host-Http- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Host- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Host- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Secure- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Secure- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Http- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • FAIL [expected NOTRUN] subtest: cookieStore.set a nameless cookie cannot have __Http- prefix
      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • And 2 more unexpected results...

github-actions[bot] avatar Dec 17 '25 16:12 github-actions[bot]

⚠️ Try run (#20309559658) failed.

github-actions[bot] avatar Dec 17 '25 16:12 github-actions[bot]

So I updated some cookie test which were going from timeout to error. I am not sure about the other tests that showed different values.

Narfinger avatar Dec 18 '25 13:12 Narfinger

There's something very strange going on here. I've been stepping through a test that times out with these changes, and https://github.com/servo/servo/blob/main/components/script/dom/cookiestore.rs#L63 only appears to be called once despite multiple send operations being made from the resource thread.

jdm avatar Dec 19 '25 20:12 jdm

Specifically, this subtest times out waiting for the get operation to resolve: https://github.com/servo/servo/blob/a926260fb07340710fe786685c7f2d89f0bf1b77/tests/wpt/tests/cookiestore/cookieStore_set_limit.https.any.js#L62

jdm avatar Dec 19 '25 20:12 jdm

Oh wait, that's probably related to 0:02.19 pid:87629 [2025-12-19T20:15:12Z WARN script::dom::cookiestore] Error receiving a CookieStore message: Custom("EmptyName")

jdm avatar Dec 19 '25 20:12 jdm

Ok, so here's one behaviour change that leads to the test results changing: by switching from IpcSender to GenericSender for the ResourceThreads, in single process mode we now transfer ownership of message types instead of serializing and deserializing them. https://github.com/servo/servo/blob/f106f1f0d0ff5d7fbf5a230b4f40202e020aac94/components/script/dom/cookiestore.rs#L429-L435 constructs a cookie value that gets sent across this channel, but in multiprocess mode this is serialized and then parsed during deserialization, which can lead to unexpected errors when values are used for construction that are not allowed during parsing.

jdm avatar Dec 20 '25 16:12 jdm

I propose:

diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs
index c49f308772d..71904214f6f 100644
--- a/components/net/resource_thread.rs
+++ b/components/net/resource_thread.rs
@@ -258,7 +258,7 @@ impl ResourceChannelManager {
                 // Handles case where profiler thread shuts down before resource thread.
                 match received {
                     GenericSelectionResult::ChannelClosed(_) => continue,
-                    GenericSelectionResult::Error => log::error!("Found selection error"),
+                    GenericSelectionResult::Error(error) => log::error!("Found selection error: {error}"),
                     GenericSelectionResult::MessageReceived(id, msg) => {
                         if id == reporter_id {
                             if let CoreResourceMsg::CollectMemoryReport(report_chan) = msg {
diff --git a/components/shared/base/generic_channel/generic_channelset.rs b/components/shared/base/generic_channel/generic_channelset.rs
index e36bf1596be..d9d489eb1cd 100644
--- a/components/shared/base/generic_channel/generic_channelset.rs
+++ b/components/shared/base/generic_channel/generic_channelset.rs
@@ -62,7 +62,7 @@ pub enum GenericSelectionResult<T> {
     /// The channel has been closed for the [GenericReceiver] identified by the `u64` value.
     ChannelClosed(u64),
     /// An error occured decoding the message.
-    Error,
+    Error(String),
 }

 impl<T: Serialize + for<'de> serde::Deserialize<'de>> From<IpcSelectionResult>
@@ -73,7 +73,7 @@ impl<T: Serialize + for<'de> serde::Deserialize<'de>> From<IpcSelectionResult>
             IpcSelectionResult::MessageReceived(channel_id, ipc_message) => {
                 match ipc_message.to() {
                     Ok(value) => GenericSelectionResult::MessageReceived(channel_id, value),
-                    Err(_) => GenericSelectionResult::Error,
+                    Err(error) => GenericSelectionResult::Error(error.to_string()),
                 }
             },
             IpcSelectionResult::ChannelClosed(channel_id) => {
@@ -133,8 +133,7 @@ impl<T: Serialize + for<'de> Deserialize<'de>> GenericReceiverSet<T> {
                         .collect()
                 })
                 .unwrap_or_else(|e| {
-                    log::info!("GenericError {:?}", e);
-                    vec![GenericSelectionResult::Error]
+                    vec![GenericSelectionResult::Error(e.to_string())]
                 }),
             GenericReceiverSetVariants::Crossbeam(receivers) => {
                 let mut sel = crossbeam_channel::Select::new();

This helps highlight in the logs when there's something funky going on that should be investigated.

jdm avatar Dec 20 '25 17:12 jdm

So, this explains:

  • TIMEOUT->OK (the IPC messages containing invalid cookies were previously dropped by the resource thread)
  • TIMEOUT->CRASH (same, except now the invalid cookie gets set in an HTTP request and hyper doesn't like that)
  • NOTRUN->FAIL/PASS (same; the tests have not had a chance to run before and now they run)

I can't reproduce the TIMEOUT->ERROR changes locally, though. I didn't see that happening in CI, either. Where did you observe those changes?

jdm avatar Dec 20 '25 17:12 jdm