boardd: SPI corruption test (#32404)
* simple test
* little more
---------
Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: dcfb206a38
pull/32199/head
parent
da105b759c
commit
5e2cc23cec
4 changed files with 132 additions and 40 deletions
@ -0,0 +1,72 @@ |
||||
#!/usr/bin/env python3 |
||||
import os |
||||
import time |
||||
import numpy as np |
||||
import pytest |
||||
|
||||
import cereal.messaging as messaging |
||||
from cereal.services import SERVICE_LIST |
||||
from openpilot.system.hardware import HARDWARE |
||||
from openpilot.selfdrive.test.helpers import phone_only, with_processes |
||||
from openpilot.selfdrive.boardd.tests.test_boardd_loopback import setup_boardd |
||||
|
||||
|
||||
@pytest.mark.tici |
||||
class TestBoarddSpi: |
||||
@classmethod |
||||
def setup_class(cls): |
||||
if HARDWARE.get_device_type() == 'tici': |
||||
pytest.skip("only for spi pandas") |
||||
os.environ['STARTED'] = '1' |
||||
os.environ['BOARDD_LOOPBACK'] = '1' |
||||
os.environ['SPI_ERR_PROB'] = '0.001' |
||||
|
||||
@phone_only |
||||
@with_processes(['pandad']) |
||||
def test_spi_corruption(self, subtests): |
||||
setup_boardd(1) |
||||
|
||||
socks = {s: messaging.sub_sock(s, conflate=False, timeout=100) for s in ('can', 'pandaStates', 'peripheralState')} |
||||
time.sleep(2) |
||||
for s in socks.values(): |
||||
messaging.drain_sock_raw(s) |
||||
|
||||
st = time.monotonic() |
||||
ts = {s: list() for s in socks.keys()} |
||||
for _ in range(20): |
||||
for service, sock in socks.items(): |
||||
for m in messaging.drain_sock(sock): |
||||
ts[service].append(m.logMonoTime) |
||||
|
||||
# sanity check for corruption |
||||
assert m.valid |
||||
if service == "can": |
||||
assert len(m.can) == 0 |
||||
elif service == "pandaStates": |
||||
assert len(m.pandaStates) == 1 |
||||
ps = m.pandaStates[0] |
||||
assert ps.uptime < 100 |
||||
assert ps.pandaType == "tres" |
||||
assert ps.ignitionLine |
||||
assert not ps.ignitionCan |
||||
assert ps.voltage < 14000 |
||||
elif service == "peripheralState": |
||||
ps = m.peripheralState |
||||
assert ps.pandaType == "tres" |
||||
assert 4000 < ps.voltage < 14000 |
||||
assert 100 < ps.current < 1000 |
||||
assert ps.fanSpeedRpm < 8000 |
||||
|
||||
time.sleep(0.5) |
||||
et = time.monotonic() - st |
||||
|
||||
print("\n======== timing report ========") |
||||
for service, times in ts.items(): |
||||
dts = np.diff(times)/1e6 |
||||
print(service.ljust(17), f"{np.mean(dts):7.2f} {np.min(dts):7.2f} {np.max(dts):7.2f}") |
||||
with subtests.test(msg="timing check", service=service): |
||||
edt = 1e3 / SERVICE_LIST[service].frequency |
||||
assert edt*0.9 < np.mean(dts) < edt*1.1 |
||||
assert np.max(dts) < edt*3 |
||||
assert np.min(dts) < edt |
||||
assert len(dts) >= ((et-0.5)*SERVICE_LIST[service].frequency*0.8) |
Loading…
Reference in new issue