Skip to content

test(actor): retry the app-channel listener test on a taken port - #1318

Merged
CasperGN merged 1 commit into
dapr:mainfrom
famarting:fix/actor-test-port-race
Oct 19, 2026
Merged

CasperGN merged 1 commit into
dapr:mainfrom
famarting:fix/actor-test-port-race

Conversation

@famarting

Copy link
Copy Markdown
Contributor

Problem

tests/actor/test_grpc_host.py::test_owns_app_channel_listener fails now and then on CI. For example, the macOS 3.13 job on #1312 failed with:

RuntimeError: Failed to bind to address [::]:49271

The test picks a port by binding 127.0.0.1:0 and then closing that socket. Next, the host binds [::] on that port number. While the port is unbound, any other socket can take it, such as an outgoing connection's source port or another process on the runner.

Fix

The host has to bind the port it is given (port 0 turns the listener off), so it can't bind first and report the port back. Instead, the test now starts the host through a small helper. If the bind fails, the helper tries again on a fresh port, up to 5 times. Any other error still fails the test straight away, and so does a bind that fails on all 5 attempts. The test's assertions are unchanged.

Only the test changes; the SDK code does not.

Verification

  • All 28 tests in tests/actor/test_grpc_host.py pass locally.
  • I forced the retry path with a local-only check that is not committed: a listener holds the first port the test is given. The first bind failed, and the second attempt passed.
  • ruff check and ruff format are clean.

🤖 Generated with Claude Code

test_owns_app_channel_listener picks a port by binding 127.0.0.1:0 and
releasing it, then has the host bind [::] on that number. Anything can
take the port in that gap, which failed the macOS 3.13 job with
"Failed to bind to address [::]:49271". The host must bind the port it
is given, so the test now retries on a fresh port when the bind fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Fabian Martinez <46371672+famarting@users.noreply.github.com>
@famarting
famarting requested review from a team as code owners October 19, 2026 14:09
@codecov

codecov Bot commented Oct 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.98%. Comparing base (b215705) to head (6d7af59).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1318   +/-   ##
=======================================
  Coverage   86.98%   86.98%           
=======================================
  Files         163      163           
  Lines       12997    12997           
=======================================
  Hits        11306    11306           
  Misses       1691     1691           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@CasperGN CasperGN self-assigned this Oct 19, 2026

@CasperGN CasperGN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks good, and CI is green on the head.

The flake comes from _free_port letting go of the port before the host binds [::] on it. Retrying on a fresh port is the right fix, because the host has to bind the port it is given. I checked that a failed attempt leaves nothing behind. start() binds the app-channel listener before it opens the actor stream, so a failed bind never uses up the fake server's stream plan. start() also calls close() on any failure, which stops the half-built listener and closes the channel. The check for Failed to bind matches both the SDK's own error in _start_app_channel_listener and grpc's Failed to bind to address error. Any other error, or a bind that fails on all 5 attempts, still fails the test. Calling register_actor again on a retry just replaces the registration with the new host's client.

I have no findings.

Drafted with AI assistance and reviewed by me.

@CasperGN
CasperGN added this pull request to the merge queue Oct 19, 2026
Merged via the queue into dapr:main with commit d0318b9 Oct 19, 2026
22 checks passed
@sicoyle sicoyle added this to the v1.19 milestone Oct 20, 2026
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.

3 participants