Fix onboard WebKit preview and archive board telemetry locally
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
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())
|
||||
Reference in New Issue
Block a user