Skip to content

Commit bb721f8

Browse files
authored
Replace fixed test ports with free port helper (#157)
* Replace fixed test ports with free port helper * Make tests a module, use absolute imports * Probe IPv6 first * Probe loopback interface only
1 parent 0401859 commit bb721f8

15 files changed

Lines changed: 85 additions & 24 deletions

tests/durabletask/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.

tests/durabletask/_port_utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
"""Shared test helpers for picking network ports.
5+
6+
Tests start an in-memory backend that binds a TCP port. Hard-coding
7+
fixed ports causes intermittent failures on Windows because Hyper-V (and
8+
other components) reserve large, dynamic ranges of TCP ports. Asking the
9+
OS for a free port avoids those collisions.
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import socket
15+
16+
17+
def find_free_port() -> int:
18+
"""Return a free TCP port by binding to port 0 and reading the assignment.
19+
20+
Probes IPv6 loopback first to match the backend's ``[::]`` bind (so an
21+
IPv6-occupied port isn't wrongly reported free), falling back to IPv4.
22+
"""
23+
if socket.has_ipv6:
24+
try:
25+
with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s:
26+
s.bind(("::1", 0))
27+
return s.getsockname()[1]
28+
except OSError:
29+
pass # IPv6 not usable on this host; fall back to IPv4.
30+
31+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
32+
s.bind(("127.0.0.1", 0))
33+
return s.getsockname()[1]

tests/durabletask/entities/test_class_based_entities_e2e.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
from durabletask import client, entities, task, worker
1313
from durabletask.testing import create_test_backend
1414

15-
HOST = "localhost:50059"
15+
from tests.durabletask._port_utils import find_free_port
16+
17+
PORT = find_free_port()
18+
HOST = f"localhost:{PORT}"
1619

1720

1821
@pytest.fixture(autouse=True)
1922
def backend():
2023
"""Create an in-memory backend for entity testing."""
21-
b = create_test_backend(port=50059)
24+
b = create_test_backend(port=PORT)
2225
yield b
2326
b.stop()
2427
b.reset()

tests/durabletask/entities/test_entity_failure_handling.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
from durabletask import client, entities, task, worker
1313
from durabletask.testing import create_test_backend
1414

15-
HOST = "localhost:50057"
15+
from tests.durabletask._port_utils import find_free_port
16+
17+
PORT = find_free_port()
18+
HOST = f"localhost:{PORT}"
1619

1720

1821
@pytest.fixture(autouse=True)
1922
def backend():
2023
"""Create an in-memory backend for entity testing."""
21-
b = create_test_backend(port=50057)
24+
b = create_test_backend(port=PORT)
2225
yield b
2326
b.stop()
2427
b.reset()

tests/durabletask/entities/test_function_based_entities_e2e.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
from durabletask import client, entities, task, worker
1313
from durabletask.testing import create_test_backend
1414

15-
HOST = "localhost:50056"
15+
from tests.durabletask._port_utils import find_free_port
16+
17+
PORT = find_free_port()
18+
HOST = f"localhost:{PORT}"
1619

1720

1821
@pytest.fixture(autouse=True)
1922
def backend():
2023
"""Create an in-memory backend for entity testing."""
21-
b = create_test_backend(port=50056)
24+
b = create_test_backend(port=PORT)
2225
yield b
2326
b.stop()
2427
b.reset()

tests/durabletask/extensions/history_export/test_activities.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@
3636
)
3737
from durabletask.testing import create_test_backend
3838

39+
from tests.durabletask._port_utils import find_free_port
3940

40-
PORT = 50261
41+
PORT = find_free_port()
4142
HOST = f"localhost:{PORT}"
4243

4344

tests/durabletask/extensions/history_export/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
from durabletask.testing import create_test_backend
3636

3737
from ._test_helpers import wait_until
38+
from tests.durabletask._port_utils import find_free_port
3839

39-
40-
PORT = 50263
40+
PORT = find_free_port()
4141
HOST = f"localhost:{PORT}"
4242

4343

tests/durabletask/extensions/history_export/test_entity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
from durabletask.testing import create_test_backend
3232

3333
from ._test_helpers import wait_until
34+
from tests.durabletask._port_utils import find_free_port
3435

35-
36-
PORT = 50260
36+
PORT = find_free_port()
3737
HOST = f"localhost:{PORT}"
3838

3939
_WINDOW_START = datetime(2025, 1, 1, tzinfo=timezone.utc)

tests/durabletask/extensions/history_export/test_orchestrator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
from durabletask.testing import create_test_backend
3434

3535
from ._test_helpers import wait_until
36+
from tests.durabletask._port_utils import find_free_port
3637

37-
38-
PORT = 50262
38+
PORT = find_free_port()
3939
HOST = f"localhost:{PORT}"
4040

4141

tests/durabletask/test_batch_actions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
from durabletask.testing import create_test_backend
1616
from durabletask.worker import TaskHubGrpcWorker
1717

18-
BATCH_TEST_PORT = 50058
18+
from tests.durabletask._port_utils import find_free_port
19+
20+
BATCH_TEST_PORT = find_free_port()
1921
HOST = f"localhost:{BATCH_TEST_PORT}"
2022

2123

0 commit comments

Comments
 (0)