Skip to content

Commit 3ab0b49

Browse files
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
1 parent 7c4fbb9 commit 3ab0b49

File tree

4 files changed

+65
-35
lines changed

4 files changed

+65
-35
lines changed

Jenkinsfile

+4-2
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ pipeline {
6868
}
6969
}
7070

71-
stage('Sound Test') {
71+
stage('HW Tests') {
7272
steps {
7373
lock(resource: "", label: 'eon', inversePrecedence: true, variable: 'eon_ip', quantity: 1){
7474
timeout(time: 30, unit: 'MINUTES') {
7575
dir(path: 'selfdrive/test') {
7676
sh 'pip install paramiko'
77-
sh 'python phone_ci.py "SCONS_CACHE=1 scons -j3 cereal/ && cd selfdrive/test && nosetests -s test_sounds.py"'
77+
sh 'python phone_ci.py "SCONS_CACHE=1 scons -j3 cereal/ && \
78+
nosetests -s selfdrive/test/test_sounds.py && \
79+
nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"'
7880
}
7981
}
8082
}

selfdrive/boardd/tests/boardd_old.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python3
22
# pylint: skip-file
33

4-
# This file is not used by OpenPilot. Only boardd.cc is used.
4+
# This file is not used by openpilot. Only boardd.cc is used.
55
# The python version is slower, but has more options for development.
66

77
# TODO: merge the extra functionalities of this file (like MOCK) in boardd.c and

selfdrive/boardd/tests/test_boardd_loopback.py

100755100644
+59-31
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,75 @@
11
#!/usr/bin/env python3
2-
"""Run boardd with the BOARDD_LOOPBACK envvar before running this test."""
3-
42
import os
53
import random
64
import time
5+
from collections import defaultdict
6+
from functools import wraps
77

8+
import cereal.messaging as messaging
9+
from cereal import car
10+
from common.basedir import PARAMS
11+
from common.params import Params
12+
from panda import Panda
813
from selfdrive.boardd.boardd import can_list_to_can_capnp
9-
from cereal.messaging import drain_sock, pub_sock, sub_sock
10-
11-
def get_test_string():
12-
return b"test"+os.urandom(10)
14+
from selfdrive.car import make_can_msg
15+
from selfdrive.test.helpers import with_processes
1316

14-
BUS = 0
1517

16-
def main():
17-
rcv = sub_sock('can') # port 8006
18-
snd = pub_sock('sendcan') # port 8017
19-
time.sleep(0.3) # wait to bind before send/recv
18+
def reset_panda(fn):
19+
@wraps(fn)
20+
def wrapper():
21+
p = Panda()
22+
for i in [0, 1, 2, 0xFFFF]:
23+
p.can_clear(i)
24+
p.reset()
25+
p.close()
26+
fn()
27+
return wrapper
2028

21-
for i in range(10):
22-
print("Loop %d" % i)
23-
at = random.randint(1024, 2000)
24-
st = get_test_string()[0:8]
25-
snd.send(can_list_to_can_capnp([[at, 0, st, 0]], msgtype='sendcan').to_bytes())
26-
time.sleep(0.1)
27-
res = drain_sock(rcv, True)
28-
assert len(res) == 1
29+
os.environ['STARTED'] = '1'
30+
os.environ['BOARDD_LOOPBACK'] = '1'
31+
os.environ['PARAMS_PATH'] = PARAMS
32+
@reset_panda
33+
@with_processes(['boardd'])
34+
def test_boardd_loopback():
2935

30-
res = res[0].can
31-
assert len(res) == 2
36+
# wait for boardd to init
37+
time.sleep(2)
3238

33-
msg0, msg1 = res
39+
# boardd blocks on CarVin and CarParams
40+
cp = car.CarParams.new_message()
41+
cp.safetyModel = car.CarParams.SafetyModel.allOutput
42+
Params().put("CarVin", b"0"*17)
43+
Params().put("CarParams", cp.to_bytes())
3444

35-
assert msg0.dat == st
36-
assert msg1.dat == st
45+
sendcan = messaging.pub_sock('sendcan')
46+
can = messaging.sub_sock('can', conflate=False, timeout=100)
3747

38-
assert msg0.address == at
39-
assert msg1.address == at
48+
time.sleep(1)
4049

41-
assert msg0.src == 0x80 | BUS
42-
assert msg1.src == BUS
50+
for i in range(1000):
51+
sent_msgs = defaultdict(set)
52+
for _ in range(random.randrange(10)):
53+
to_send = []
54+
for __ in range(random.randrange(100)):
55+
bus = random.randrange(3)
56+
addr = random.randrange(1, 1<<29)
57+
dat = bytes([random.getrandbits(8) for _ in range(random.randrange(1, 9))])
58+
sent_msgs[bus].add((addr, dat))
59+
to_send.append(make_can_msg(addr, dat, bus))
60+
sendcan.send(can_list_to_can_capnp(to_send, msgtype='sendcan'))
4361

44-
print("Success")
62+
max_recv = 10
63+
while max_recv > 0 and any(len(sent_msgs[bus]) for bus in range(3)):
64+
recvd = messaging.drain_sock(can, wait_for_one=True)
65+
for msg in recvd:
66+
for m in msg.can:
67+
if m.src >= 128:
68+
k = (m.address, m.dat)
69+
assert k in sent_msgs[m.src-128]
70+
sent_msgs[m.src-128].discard(k)
71+
max_recv -= 1
4572

46-
if __name__ == "__main__":
47-
main()
73+
# if a set isn't empty, messages got dropped
74+
for bus in range(3):
75+
assert not len(sent_msgs[bus]), f"loop {i}: bus {bus} missing {len(sent_msgs[bus])} messages"

selfdrive/debug/cpu_usage_stat.py

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

0 commit comments

Comments
 (0)