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
Adeeb Shihadeh 5 years ago committed by GitHub
parent cf9b615401
commit b38c33cc47
  1. 6
      Jenkinsfile
  2. 2
      selfdrive/boardd/tests/boardd_old.py
  3. 90
      selfdrive/boardd/tests/test_boardd_loopback.py
  4. 2
      selfdrive/debug/cpu_usage_stat.py

6
Jenkinsfile vendored

@ -68,13 +68,15 @@ pipeline {
} }
} }
stage('Sound Test') { stage('HW Tests') {
steps { steps {
lock(resource: "", label: 'eon', inversePrecedence: true, variable: 'eon_ip', quantity: 1){ lock(resource: "", label: 'eon', inversePrecedence: true, variable: 'eon_ip', quantity: 1){
timeout(time: 30, unit: 'MINUTES') { timeout(time: 30, unit: 'MINUTES') {
dir(path: 'selfdrive/test') { dir(path: 'selfdrive/test') {
sh 'pip install paramiko' sh 'pip install paramiko'
sh 'python phone_ci.py "SCONS_CACHE=1 scons -j3 cereal/ && cd selfdrive/test && nosetests -s test_sounds.py"' sh 'python phone_ci.py "SCONS_CACHE=1 scons -j3 cereal/ && \
nosetests -s selfdrive/test/test_sounds.py && \
nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"'
} }
} }
} }

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# pylint: skip-file # pylint: skip-file
# This file is not used by OpenPilot. Only boardd.cc is used. # This file is not used by openpilot. Only boardd.cc is used.
# The python version is slower, but has more options for development. # The python version is slower, but has more options for development.
# TODO: merge the extra functionalities of this file (like MOCK) in boardd.c and # TODO: merge the extra functionalities of this file (like MOCK) in boardd.c and

@ -1,47 +1,75 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Run boardd with the BOARDD_LOOPBACK envvar before running this test."""
import os import os
import random import random
import time 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 selfdrive.boardd.boardd import can_list_to_can_capnp
from cereal.messaging import drain_sock, pub_sock, sub_sock from selfdrive.car import make_can_msg
from selfdrive.test.helpers import with_processes
def get_test_string():
return b"test"+os.urandom(10)
BUS = 0
def main(): def reset_panda(fn):
rcv = sub_sock('can') # port 8006 @wraps(fn)
snd = pub_sock('sendcan') # port 8017 def wrapper():
time.sleep(0.3) # wait to bind before send/recv 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): os.environ['STARTED'] = '1'
print("Loop %d" % i) os.environ['BOARDD_LOOPBACK'] = '1'
at = random.randint(1024, 2000) os.environ['PARAMS_PATH'] = PARAMS
st = get_test_string()[0:8] @reset_panda
snd.send(can_list_to_can_capnp([[at, 0, st, 0]], msgtype='sendcan').to_bytes()) @with_processes(['boardd'])
time.sleep(0.1) def test_boardd_loopback():
res = drain_sock(rcv, True)
assert len(res) == 1
res = res[0].can # wait for boardd to init
assert len(res) == 2 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 sendcan = messaging.pub_sock('sendcan')
assert msg1.dat == st can = messaging.sub_sock('can', conflate=False, timeout=100)
assert msg0.address == at time.sleep(1)
assert msg1.address == at
assert msg0.src == 0x80 | BUS for i in range(1000):
assert msg1.src == BUS 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__": # if a set isn't empty, messages got dropped
main() for bus in range(3):
assert not len(sent_msgs[bus]), f"loop {i}: bus {bus} missing {len(sent_msgs[bus])} messages"

@ -3,7 +3,7 @@
''' '''
System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs. System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs.
Features: Features:
Use psutil library to sample cpu usage(avergage for all cores) of OpenPilot processes, at a rate of 5 samples/sec. Use psutil library to sample cpu usage(avergage for all cores) of openpilot processes, at a rate of 5 samples/sec.
Do cpu usage statistics periodically, 5 seconds as a cycle. Do cpu usage statistics periodically, 5 seconds as a cycle.
Caculate the average cpu usage within this cycle. Caculate the average cpu usage within this cycle.
Caculate minumium/maximium/accumulated_average cpu usage as long term inspections. Caculate minumium/maximium/accumulated_average cpu usage as long term inspections.

Loading…
Cancel
Save