[Test] Assert co-located RayExecutorV2 stores publish distinct ports (#54310)
Signed-off-by: aoshen02 <aoshen02@users.noreply.github.com> Co-authored-by: aoshen02 <aoshen02@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
aoshen02 committed
Aug 29, 2026 at 13:13 UTC
f4f3bcd4b48c375badea2a4e7aeaeb3e3b9f3d13
1 file changed
+32
-6
tests/distributed/test_ray_v2_executor.py
+32
-6
@@ -107,20 +107,29 @@ def assert_executor(executor, tp_size, pp_size):
107
assert handle.node_id is not None
108
109
110
-def test_dist_init_store_owns_port(monkeypatch):
111
- """The rank-0 actor keeps the selected TCPStore port bound."""
110
+def _detached_rank0_worker() -> ray_executor_v2.RayWorkerProc:
111
+ """A RayWorkerProc that can create its dist-init store without Ray."""
112
worker = ray_executor_v2.RayWorkerProc.__new__(ray_executor_v2.RayWorkerProc)
113
worker._parallel_config = SimpleNamespace(world_size=1)
114
- monkeypatch.setattr(ray.util, "get_node_ip_address", lambda: "127.0.0.1")
114
+ return worker
115
116
- init_method = worker.create_dist_init_method()
117
- port = urlsplit(init_method).port
118
- assert port is not None and port != 0
116
117
+def _assert_port_held(port: int):
118
with socket.socket() as contender, pytest.raises(OSError) as exc_info:
119
contender.bind(("127.0.0.1", port))
120
assert exc_info.value.errno == errno.EADDRINUSE
121
122
+
123
+def test_dist_init_store_owns_port(monkeypatch):
124
+ """The rank-0 actor keeps the selected TCPStore port bound."""
125
+ monkeypatch.setattr(ray.util, "get_node_ip_address", lambda: "127.0.0.1")
126
+ worker = _detached_rank0_worker()
127
+
128
+ init_method = worker.create_dist_init_method()
129
+ port = urlsplit(init_method).port
130
+ assert port is not None and port != 0
131
+ _assert_port_held(port)
132
+
133
reused_store = TCPStore(
134
"127.0.0.1",
135
port,
@@ -133,6 +142,23 @@ def test_dist_init_store_owns_port(monkeypatch):
142
assert reused_store.get("key") == b"value"
143
144
145
+def test_colocated_dist_init_stores_hold_distinct_ports(monkeypatch):
146
+ """Replicas sharing a host must never publish the same TCPStore port.
147
+
148
+ Each rank-0 store binds a kernel-assigned ephemeral port and keeps it
149
+ for the actor's lifetime, so concurrently live replicas cannot collide.
150
+ """
151
+ monkeypatch.setattr(ray.util, "get_node_ip_address", lambda: "127.0.0.1")
152
+ workers = [_detached_rank0_worker() for _ in range(3)]
153
+
154
+ ports = [urlsplit(w.create_dist_init_method()).port for w in workers]
155
+ assert len(set(ports)) == len(workers)
156
+ for worker, port in zip(workers, ports):
157
+ assert port == worker._dist_init_store.port
158
+ assert port >= 1024
159
+ _assert_port_held(port)
160
+
161
+
162
@pytest.mark.parametrize("tp_size, pp_size", [(1, 1), (2, 1), (4, 1), (2, 2)])
163
def test_ray_v2_executor(tp_size, pp_size):
164
"""Validate RayExecutorV2 with various TP/PP configs."""