Files
dp/tests/test_sync.py
2026-07-17 02:10:08 +08:00

87 lines
2.8 KiB
Python

from led_platform.domain import CommandEnvelope, CommandType, PerformanceSample
from led_platform.services.sync_coordinator import SyncCoordinator
def test_sync_coordinator_marks_command_complete_after_both_tiles_ack():
coordinator = SyncCoordinator(["left", "right"], command_ttl_seconds=30)
message = CommandEnvelope(
type=CommandType.COMMIT_SCENE,
payload={"apply_at_ms": 2000, "state": {"active_scene_id": "overview"}},
)
record = coordinator.register_command(message, message.payload)
assert not record.complete
coordinator.ack(
{
"command_id": message.command_id,
"node_id": "left-node",
"tile_id": "left",
"status": "committed",
}
)
assert not coordinator.status()["commands"][0]["complete"]
coordinator.ack(
{
"command_id": message.command_id,
"node_id": "right-node",
"tile_id": "right",
"status": "committed",
}
)
assert coordinator.status()["commands"][0]["complete"]
def test_sync_coordinator_releases_scene_commit_after_both_tiles_prepare():
coordinator = SyncCoordinator(["left", "right"], command_ttl_seconds=30)
message = CommandEnvelope(
type=CommandType.COMMIT_SCENE,
payload={"apply_at_ms": 2000, "state": {"active_scene_id": "overview"}},
)
coordinator.register_command(message, message.payload)
coordinator.ack(
{
"command_id": message.command_id,
"node_id": "left-node",
"tile_id": "left",
"status": "prepared",
}
)
assert coordinator.release_if_prepared(message.command_id) is None
coordinator.ack(
{
"command_id": message.command_id,
"node_id": "right-node",
"tile_id": "right",
"status": "prepared",
}
)
released = coordinator.release_if_prepared(message.command_id)
assert released is not None
assert released.released_at_ms is not None
assert coordinator.release_if_prepared(message.command_id) is None
def test_sync_coordinator_tracks_node_clock_and_frame_metrics():
coordinator = SyncCoordinator(["left", "right"], command_ttl_seconds=30)
coordinator.connect_node(node_id="left-node", tile_id="left", app_version="test")
coordinator.clock_quality("left-node", clock_offset_ms=2.5, rtt_ms=6.0)
coordinator.telemetry(
PerformanceSample(
node_id="left-node",
tile_id="left",
fps=59.4,
frame_time_ms=16.1,
dropped_frames=1,
)
)
node = coordinator.status()["nodes"][0]
assert node["clock_offset_ms"] == 2.5
assert node["rtt_ms"] == 6.0
assert node["fps"] == 59.4
assert node["frame_time_ms"] == 16.1