Files
NODEDC_MISSION_CORE/tests/test_node_local_media.py
T

99 lines
3.2 KiB
Python

import asyncio
import json
from uuid import uuid4
import pytest
from k1link.viewer.node_local_media import acknowledge, admit_local, read_local, start_local
from k1link.viewer.node_media import NodeMediaPeers
def test_local_stream_fragments_ack_resume_and_releases_before_reconnect():
payload = b"RRF2" + bytes(range(256)) * 256
released = []
subscriptions = []
class Subscription:
pending = None
def __init__(self, after):
self.after = after
self.sent = False
def next_batch(self, **_):
if self.sent:
return b""
self.sent = True
self.pending = (self.after + 1, payload, None)
return self.pending
def snapshot(self, _):
return dict(sequence=self.after + 1, age_ms=0, points=5000)
def acknowledge(self, seq):
if seq == self.after + 1:
self.pending = None
def release(self):
released.append(self.after)
class Hub:
def subscribe(self, view_id, after):
sub = Subscription(after)
subscriptions.append((view_id, sub))
return sub
class Camera:
def snapshot(self):
return {"recording": {"source_end_expected": True}}
async def run():
peers = NodeMediaPeers(Hub(), Camera())
view = str(uuid4())
for after in (0, 1):
peer = await start_local(peers, dict(view_id=view, after=after))
if after:
assert released == [0] # Lost response/reconnect retires the old lease.
collected = []
while sum(map(len, collected)) < len(payload):
response = await asyncio.wait_for(read_local(peers, peer, after), 1.2)
assert len(response) <= 196608
offset = 0
while offset < len(response):
kind = response[offset]
size = int.from_bytes(response[offset + 1 : offset + 5], "big")
data = response[offset + 5 : offset + 5 + size]
if kind == 0:
assert json.loads(data)["peer_id"] == peer
if kind == 2:
if data.startswith(b"MCF1"):
assert int.from_bytes(data[4:], "big") == len(payload)
else:
collected.append(data)
offset += size + 5
assert b"".join(collected) == payload
acknowledge(peers, peer, after + 1)
assert subscriptions[-1][1].pending is None
await peers.close_all()
assert not peers.items and released == [0, 1]
assert subscriptions[0][0] == subscriptions[1][0] == view
asyncio.run(run())
@pytest.mark.parametrize("after", [True, -1, 2**53, "1"])
def test_local_cursor_rejects_noncanonical_values(after):
with pytest.raises(ValueError):
admit_local(dict(view_id=str(uuid4()), after=after))
def test_local_carrier_does_not_exceed_peer_capacity():
async def run():
class Peers:
items = {"a": {}, "b": {}}
with pytest.raises(ValueError):
await start_local(Peers(), dict(view_id=str(uuid4()), after=0))
asyncio.run(run())