Boardd loopback test (#1840)
* start boardd loopback test
* let's try this in CI
* fix jenkinsfile
* remove old
* rename
* check msgs
* should be reliable now
* send more
old-commit-hash: 3ab0b49656
commatwo_master
parent
cf9b615401
commit
b38c33cc47
4 changed files with 65 additions and 35 deletions
@ -1,47 +1,75 @@ |
||||
#!/usr/bin/env python3 |
||||
"""Run boardd with the BOARDD_LOOPBACK envvar before running this test.""" |
||||
|
||||
import os |
||||
import random |
||||
import time |
||||
from collections import defaultdict |
||||
from functools import wraps |
||||
|
||||
import cereal.messaging as messaging |
||||
from cereal import car |
||||
from common.basedir import PARAMS |
||||
from common.params import Params |
||||
from panda import Panda |
||||
from selfdrive.boardd.boardd import can_list_to_can_capnp |
||||
from cereal.messaging import drain_sock, pub_sock, sub_sock |
||||
|
||||
def get_test_string(): |
||||
return b"test"+os.urandom(10) |
||||
from selfdrive.car import make_can_msg |
||||
from selfdrive.test.helpers import with_processes |
||||
|
||||
BUS = 0 |
||||
|
||||
def main(): |
||||
rcv = sub_sock('can') # port 8006 |
||||
snd = pub_sock('sendcan') # port 8017 |
||||
time.sleep(0.3) # wait to bind before send/recv |
||||
def reset_panda(fn): |
||||
@wraps(fn) |
||||
def wrapper(): |
||||
p = Panda() |
||||
for i in [0, 1, 2, 0xFFFF]: |
||||
p.can_clear(i) |
||||
p.reset() |
||||
p.close() |
||||
fn() |
||||
return wrapper |
||||
|
||||
for i in range(10): |
||||
print("Loop %d" % i) |
||||
at = random.randint(1024, 2000) |
||||
st = get_test_string()[0:8] |
||||
snd.send(can_list_to_can_capnp([[at, 0, st, 0]], msgtype='sendcan').to_bytes()) |
||||
time.sleep(0.1) |
||||
res = drain_sock(rcv, True) |
||||
assert len(res) == 1 |
||||
os.environ['STARTED'] = '1' |
||||
os.environ['BOARDD_LOOPBACK'] = '1' |
||||
os.environ['PARAMS_PATH'] = PARAMS |
||||
@reset_panda |
||||
@with_processes(['boardd']) |
||||
def test_boardd_loopback(): |
||||
|
||||
res = res[0].can |
||||
assert len(res) == 2 |
||||
# wait for boardd to init |
||||
time.sleep(2) |
||||
|
||||
msg0, msg1 = res |
||||
# boardd blocks on CarVin and CarParams |
||||
cp = car.CarParams.new_message() |
||||
cp.safetyModel = car.CarParams.SafetyModel.allOutput |
||||
Params().put("CarVin", b"0"*17) |
||||
Params().put("CarParams", cp.to_bytes()) |
||||
|
||||
assert msg0.dat == st |
||||
assert msg1.dat == st |
||||
sendcan = messaging.pub_sock('sendcan') |
||||
can = messaging.sub_sock('can', conflate=False, timeout=100) |
||||
|
||||
assert msg0.address == at |
||||
assert msg1.address == at |
||||
time.sleep(1) |
||||
|
||||
assert msg0.src == 0x80 | BUS |
||||
assert msg1.src == BUS |
||||
for i in range(1000): |
||||
sent_msgs = defaultdict(set) |
||||
for _ in range(random.randrange(10)): |
||||
to_send = [] |
||||
for __ in range(random.randrange(100)): |
||||
bus = random.randrange(3) |
||||
addr = random.randrange(1, 1<<29) |
||||
dat = bytes([random.getrandbits(8) for _ in range(random.randrange(1, 9))]) |
||||
sent_msgs[bus].add((addr, dat)) |
||||
to_send.append(make_can_msg(addr, dat, bus)) |
||||
sendcan.send(can_list_to_can_capnp(to_send, msgtype='sendcan')) |
||||
|
||||
print("Success") |
||||
max_recv = 10 |
||||
while max_recv > 0 and any(len(sent_msgs[bus]) for bus in range(3)): |
||||
recvd = messaging.drain_sock(can, wait_for_one=True) |
||||
for msg in recvd: |
||||
for m in msg.can: |
||||
if m.src >= 128: |
||||
k = (m.address, m.dat) |
||||
assert k in sent_msgs[m.src-128] |
||||
sent_msgs[m.src-128].discard(k) |
||||
max_recv -= 1 |
||||
|
||||
if __name__ == "__main__": |
||||
main() |
||||
# if a set isn't empty, messages got dropped |
||||
for bus in range(3): |
||||
assert not len(sent_msgs[bus]), f"loop {i}: bus {bus} missing {len(sent_msgs[bus])} messages" |
||||
|
Loading…
Reference in new issue