Skip to content

Retry telemetry receiver test setup when a probed port is taken - #146

Merged
Views2k merged 5 commits into
mainfrom
fix/telemetry-test-port-race
Oct 21, 2026
Merged

Views2k merged 5 commits into
mainfrom
fix/telemetry-test-port-race

Conversation

@Views2k

@Views2k Views2k commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

What changed

  • TelemetryUdpReceiverTests: every test that started or restarted the receiver on a probed port now goes through StartOnAvailablePortAsync / RestartOnAvailablePortAsync. They probe a fresh port and retry only on SocketError.AddressAlreadyInUse, up to 8 attempts; the last failure and every other error still fail the test. This is the same pattern RunDatagramCaptureTests and TelemetryValidatedStateObserverTests already use.
  • FailedRestartKeepsExistingListenerAndSettingsStateAlive now creates its occupied-port reservation before starting the receiver, so the reservation's own port-0 bind can no longer land on the receiver's probed port. The restart onto the occupied port is unchanged and must still throw SocketException.
  • TelemetryPacketDiagnosticsTests: the two receiver starts use the same retrying helper.
  • The released-port probes in SuccessfulRestartClearsSessionStateAndReleasesOldPort and DisposeReleasesPortAndPreventsRestart are unchanged.
  • Test-only change: no product code, no version files, no CHANGELOG entry. TelemetryUdpReceiver.ValidatePort still rejects port 0, so the receiver cannot pick its own port, and this change does not alter that.

Why

These tests bind a UDP socket to port 0, read the assigned port, close the socket and then call StartAsync(port). Other test classes in the same assembly run in parallel and bind their own loopback sockets (port probes and receivers). One of them can bind the released port before the receiver does. CI run 39523189748, attempt 1 (job "Build and test", step "Check critical behavior and affected tests"), failed this way in PacketSubscriberFailureDoesNotTerminateListener: SocketException: Only one usage of each socket address from TelemetryUdpReceiver.CreateBoundSession (line 272), called from StartAsync. The Telemetry project was the only test project running at that point, and the PR did not touch telemetry.

A loopback socket was checked on Windows 11 against the receiver's exclusive loopback bind:

  • It refuses that bind with AddressAlreadyInUse.
  • A UdpClient sender auto-bound on the wildcard address does not block it.

So the competing socket is another loopback probe or listener.

Checked (Windows 11, pinned SDK 8.0.426, Release, head 0629bb5 = e366e1a + main ab8ac13)

  • dotnet build tests/Wisp.Telemetry.Tests -c Release: 0 warnings, 0 errors.
  • dotnet test tests/Wisp.Telemetry.Tests -c Release: 96 of 96 passed, five runs in a row.
  • dotnet format whitespace --verify-no-changes on both changed files and git diff --check: clean.
  • Scanned the failed-test logs of the latest 52 failed CI and nightly runs. No Wisp.Telemetry.Tests failures among them; runs that passed on a rerun are not in that list.

Not verified

  • The race cannot be forced on demand, so these runs show that the tests still pass but cannot show that the flake is gone.
  • The retry path itself did not run locally: no port collision happened in the five runs.

The receiver and packet diagnostics tests probe a free UDP port, close the
probe, then start the receiver on that port. A parallel test can bind the
port in between, so the start fails with AddressAlreadyInUse even though
nothing is wrong with the receiver.

Start and restart now pick a fresh port and retry on that error only,
matching the existing helpers in the capture and observer tests. The
occupied-port cases still bind the port they reserve. The released-port
checks accept a refused probe when the port is no longer bound on loopback,
since another test can take a released port on the wildcard address.
@Views2k
Views2k marked this pull request as ready for review October 21, 2026 09:23
@Views2k
Views2k merged commit 6921ce0 into main Oct 21, 2026
10 checks passed
@Views2k
Views2k deleted the fix/telemetry-test-port-race branch October 21, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant