mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
95 lines
3.9 KiB
Python
95 lines
3.9 KiB
Python
"""Jetlink's home icon and Android Auto card read one status, off the drawing thread, never keeping stale latency."""
|
|
import json
|
|
import threading
|
|
import time
|
|
from types import SimpleNamespace as NS
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from openpilot.starpilot.models import jetlink_adapter as adapter, jetlink_status
|
|
from openpilot.starpilot.models.jetlink_status import JetlinkStatus, JetlinkStatusFeed, read_status
|
|
|
|
|
|
def status(**kw):
|
|
base = {'enabled': True, 'mode': 'usb', 'present': True, 'port_state': 'connected', 'active': False, 'reason': None, 'running': None, 'ready': False}
|
|
return NS(**{**base, **kw})
|
|
|
|
|
|
def read(value, latency=24.6):
|
|
with patch.object(adapter, 'link_on', return_value=True), \
|
|
patch.object(adapter, 'hooks', return_value=NS(status=lambda: value)), \
|
|
patch.object(jetlink_status, 'read_latency', return_value=latency):
|
|
return read_status()
|
|
|
|
|
|
def test_off_reads_nothing_of_jetlink():
|
|
with patch.object(adapter, 'link_on', return_value=False), patch.object(adapter, 'hooks') as hooks:
|
|
assert read_status() == JetlinkStatus()
|
|
hooks.assert_not_called()
|
|
|
|
|
|
@pytest.mark.parametrize('kw,expected', [
|
|
({'active': True, 'running': 'running'}, JetlinkStatus('Computer', 'active', 24.6, 'connected')),
|
|
({'running': 'ready'}, JetlinkStatus('Computer', 'ready', port='connected')),
|
|
({'running': 'joining'}, JetlinkStatus('Computer', 'connecting', port='connected')),
|
|
({'running': 'retrying'}, JetlinkStatus('Computer', 'connecting', port='connected')),
|
|
({'running': None, 'ready': False}, JetlinkStatus('Computer', 'connected', port='connected')),
|
|
({'reason': 'service stopped'}, JetlinkStatus('Computer', 'unavailable', port='connected')),
|
|
({'present': False, 'port_state': 'device'}, JetlinkStatus('Computer', 'disconnected', port='device')),
|
|
({'present': False, 'port_state': 'empty'}, JetlinkStatus('Computer', 'disconnected')),
|
|
({'present': False, 'port_state': None}, JetlinkStatus('Computer', 'disconnected')),
|
|
({'mode': 'ios', 'active': True}, JetlinkStatus('iPhone', 'active', 24.6, 'connected')),
|
|
({'enabled': False}, JetlinkStatus()),
|
|
])
|
|
def test_states(kw, expected):
|
|
assert read(status(**kw)) == expected
|
|
|
|
|
|
def test_no_usable_jetlink_is_unavailable():
|
|
assert read(None) == JetlinkStatus(state='unavailable')
|
|
|
|
|
|
def test_latency_record_round_trip_and_staleness(tmp_path):
|
|
path = str(tmp_path / 'jetlink' / 'latency.json')
|
|
jetlink_status._write_latency(NS(client=NS(last_timings=(1, 2, 24600))), path)
|
|
assert jetlink_status.read_latency(path) == pytest.approx(24.6)
|
|
jetlink_status._write_latency(NS(client=None), path) # the small model drives
|
|
assert jetlink_status.read_latency(path) is None
|
|
with open(path, 'w') as f:
|
|
json.dump({'at': time.monotonic() - jetlink_status.LATENCY_FRESH_S - 1, 'server_ms': 24.6}, f)
|
|
assert jetlink_status.read_latency(path) is None
|
|
assert jetlink_status.read_latency(str(tmp_path / 'missing.json')) is None
|
|
|
|
|
|
def test_feed_polls_off_thread_expires_and_disables():
|
|
arrived = threading.Event()
|
|
threads = []
|
|
def fake():
|
|
threads.append(threading.get_ident())
|
|
arrived.set()
|
|
return JetlinkStatus('iPhone', 'active', 24.6, 'connected')
|
|
feed = JetlinkStatusFeed(read=fake, period=0.01)
|
|
try:
|
|
assert feed.snapshot() == JetlinkStatus()
|
|
feed.set_enabled(True)
|
|
assert arrived.wait(2)
|
|
assert threading.get_ident() not in threads
|
|
assert feed.snapshot().latency_ms == 24.6
|
|
feed.set_enabled(False)
|
|
assert feed.snapshot() == JetlinkStatus()
|
|
finally:
|
|
feed.close()
|
|
|
|
|
|
def test_feed_stale_and_failed_reads_drop_latency_and_port():
|
|
feed = JetlinkStatusFeed(read=lambda: JetlinkStatus('iPhone', 'active', 24.6, 'connected'))
|
|
feed._enabled = True
|
|
feed.poll()
|
|
assert feed.snapshot().port == 'connected'
|
|
feed._read_at = 0
|
|
assert feed.snapshot() == JetlinkStatus('iPhone', 'unavailable')
|
|
feed.read = lambda: 1 / 0
|
|
feed.poll()
|
|
assert feed.snapshot() == JetlinkStatus(state='unavailable')
|