Server isolation and detailed errors

Isolated the JsonServer to server.py inside protocols/json

Added specific errors for server startup timeout and server startup
failed

Refactored errors for Core to CoreError generic and refactored
StateError to CoreStateMismatchError derived from CoreError
This commit is contained in:
2026-08-03 17:17:33 +01:00
parent 321ccb178e
commit 482c093f38
11 changed files with 418 additions and 65 deletions
View File
+27
View File
@@ -0,0 +1,27 @@
import socket
def find_available_port(
preferred_port: int | None = None,
host: str = "127.0.0.1",
) -> int:
"""Return an available TCP port on the given host.
The preferred port is returned when available. Otherwise, the operating
system selects an available ephemeral port.
"""
if preferred_port is not None:
if not 1 <= preferred_port <= 65535:
raise ValueError("preferred_port must be between 1 and 65535")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
try:
sock.bind((host, preferred_port))
except OSError:
pass
else:
return preferred_port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind((host, 0))
return int(sock.getsockname()[1])
+17
View File
@@ -0,0 +1,17 @@
from time import sleep
from dynalab_core import Core
from dynalab_core.config import CoreConfig
config = CoreConfig(port=8765)
print(config)
dl_core = Core(config)
dl_core.start()
print("started")
try:
while True:
dl_core.wait(1)
print("waiting")
except KeyboardInterrupt:
dl_core.stop()
+20
View File
@@ -0,0 +1,20 @@
import asyncio
async def main() -> None:
reader, writer = await asyncio.open_connection(
host="127.0.0.1",
port=8765,
)
print("Connected")
try:
await asyncio.sleep(10)
finally:
writer.close()
await writer.wait_closed()
print("Disconnected")
asyncio.run(main())
+18
View File
@@ -0,0 +1,18 @@
import pytest
from dynalab_core import Core
from dynalab_core.config import CoreConfig
from dynalab_core.errors import CoreStateMismatchError
from test.common import find_available_port
def test_core_cannot_start_twice() -> None:
port = find_available_port(8765)
core = Core(CoreConfig(port=port))
core.start()
try:
with pytest.raises(CoreStateMismatchError):
core.start()
finally:
core.stop()
+34
View File
@@ -0,0 +1,34 @@
import pytest
from dynalab_core import Core
from dynalab_core.config import CoreConfig
from dynalab_core.errors import JsonServerStartupError, JsonServerTimeoutError
from test.common import find_available_port
def test_json_server_raises_timeout_error() -> None:
port = find_available_port(8765)
core = Core(CoreConfig(port=port))
core._json_server._debug_timeout_test = True
core._json_server._timeout = 0.01
try:
with pytest.raises(JsonServerTimeoutError):
core.start()
finally:
core.stop()
def test_json_server_raises_startup_error() -> None:
port = find_available_port(8765)
core1 = Core(CoreConfig(port=port))
core2 = Core(CoreConfig(port=port))
core1.start()
try:
with pytest.raises(JsonServerStartupError):
core2.start()
finally:
core1.stop()
core2.stop()