Skip to content

[ci-fix] Needs review: dual-stack accept-reset socket test fails on Windows/Linux (refs #133778) - #133925

Draft
github-actions[bot] wants to merge 1 commit into
mainfrom
ci-fix/133778-dualstack-accept-reset-a1b2-492c233de43be1d4
Draft

github-actions[bot] wants to merge 1 commit into
mainfrom
ci-fix/133778-dualstack-accept-reset-a1b2-492c233de43be1d4

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Workflow artifact: ci-fix
Artifact kind: help
Linked KBE: #133778

Note

This is an AI/Copilot-generated best-effort fix attempt that I could not fully validate. It is a starting point for a maintainer, not a finished change. Please review the analysis below before merging.

Root cause (best analysis)

System.Net.Sockets.Tests.AcceptDualStackResetTests.Accept_DualStackListener_PeerImmediatelyResets_ListenerStaysHealthy(useAsync: True) fails on windows-x64/linux-x64 (TestReadyToRun_Libraries and the runtime pipeline):

System.Net.Sockets.SocketException : An existing connection was forcibly closed by the remote host.
   at System.Net.Sockets.Tests.AcceptDualStackResetTests.Accept_DualStackListener_PeerImmediatelyResets_ListenerStaysHealthy(Boolean useAsync) in /_/src/libraries/System.Net.Sockets/tests/FunctionalTests/Accept.cs:line 527

Line 527 is the AcceptAsync/Accept call, not the receive. The test (added by #131869) closes an IPv4 peer with SO_LINGER=0 so the kernel sends an immediate RST, then expects the listener to still deliver the healthy IPv6 peer's byte. The try { ... } catch (SocketException) block only wraps the ReceiveAsync; the accept that precedes it sits outside the try. On Windows and Linux the reset is surfaced by accept itself (WSAECONNRESET / "connection forcibly closed"), which escapes the catch and fails the test, even though the very next accept iteration would return the healthy peer. macOS discards the reset at accept (which #131869 hardened EndPoint.Create for), so it doesn't hit this path — which is why the test passed there but not on Windows/Linux.

The test comment already anticipates this ("Some platforms surface the reset connection from accept()"), but the code doesn't guard the accept accordingly.

Attempted fix

Move the accept inside the existing try block so a SocketException from either the accept or the following receive is tolerated, and the loop retries to accept the healthy peer on the next iteration (the loop already runs up to 2 accepts). No production code changes; the listener-stays-healthy assertion is preserved. This is not a test-disable — the test still runs and still asserts the healthy peer's message is received.

What is unverified / where I need help

  • I could not build and run System.Net.Sockets.Tests in this environment, so I have not confirmed the test now passes on windows-x64/linux-x64 while still catching a genuine listener regression.
  • Please confirm the intended contract: on Windows/Linux, should the RST be observable at accept (making tolerating it here correct), or should the runtime itself suppress the reset connection from the accept loop the way macOS does? If the latter, the real fix belongs in the socket accept path rather than the test.

Validation

  • Command: not run because the sockets functional test suite could not be built/executed within the run budget
  • Result: not run

Evidence

Help wanted


Filed by ci-failure-fix. Comment here or on the workflow file to suggest changes; ci-failure-scan-feedback reads in-scope feedback daily and opens (or updates) a PR with prompt edits.

Structured data:

{
  "artifact_kind": "help",
  "linked_kbe": 133778,
  "workflow_artifact": "ci-fix"
}

Generated by CI Outer-Loop Failure Fixer · opus48 · 764.8 AIC · ⌖ 20.8 AIC · ⊞ 19.6K ·

The AcceptDualStackResetTests test only wrapped ReceiveAsync in the
SocketException catch, but on Windows and Linux the peer's immediate
reset is surfaced by AcceptAsync itself (An existing connection was
forcibly closed by the remote host). Move the accept inside the try so
the reset from either accept or receive is tolerated and the healthy
peer is accepted on a subsequent iteration.

Refs #133778

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @karelz, @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants