diff --git a/selfdrive/boardd/tests/test_boardd_loopback.py b/selfdrive/boardd/tests/test_boardd_loopback.py index 3ee4d957c2..43053b6b1a 100755 --- a/selfdrive/boardd/tests/test_boardd_loopback.py +++ b/selfdrive/boardd/tests/test_boardd_loopback.py @@ -14,17 +14,19 @@ from common.timeout import Timeout from panda import Panda from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import make_can_msg +from selfdrive.hardware import TICI from selfdrive.test.helpers import phone_only, with_processes -def reset_panda(f): +def reset_pandas(f): @wraps(f) def wrapper(*args, **kwargs): - p = Panda() - for i in [0, 1, 2, 0xFFFF]: - p.can_clear(i) - p.reset() - p.close() + for serial in Panda.list(): + p = Panda(serial) + for i in [0, 1, 2, 3, 0xFFFF]: + p.can_clear(i) + p.reset() + p.close() f(*args, **kwargs) return wrapper @@ -42,7 +44,7 @@ class TestBoardd(unittest.TestCase): cls.spinner.close() @phone_only - @reset_panda + @reset_pandas @with_processes(['pandad']) def test_loopback(self): # wait for boardd to init @@ -50,15 +52,19 @@ class TestBoardd(unittest.TestCase): with Timeout(60, "boardd didn't start"): sm = messaging.SubMaster(['pandaStates']) - while sm.rcv_frame['pandaStates'] < 1: + while sm.rcv_frame['pandaStates'] < 1 and len(sm['pandaStates']) == 0: sm.update(1000) + num_pandas = len(sm['pandaStates']) + if TICI: + self.assertGreater(num_pandas, 1, "connect another panda for multipanda tests") + # boardd blocks on CarVin and CarParams cp = car.CarParams.new_message() safety_config = car.CarParams.SafetyConfig.new_message() safety_config.safetyModel = car.CarParams.SafetyModel.allOutput - cp.safetyConfigs = [safety_config] + cp.safetyConfigs = [safety_config]*num_pandas params = Params() params.put("CarVin", b"0"*17) @@ -67,8 +73,7 @@ class TestBoardd(unittest.TestCase): sendcan = messaging.pub_sock('sendcan') can = messaging.sub_sock('can', conflate=False, timeout=100) - - time.sleep(1) + time.sleep(0.2) n = 1000 for i in range(n): @@ -78,26 +83,27 @@ class TestBoardd(unittest.TestCase): for _ in range(random.randrange(10)): to_send = [] for __ in range(random.randrange(100)): - bus = random.randrange(3) + bus = random.choice([b for b in range(3*num_pandas) if b % 4 != 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')) - max_recv = 10 - while max_recv > 0 and any(len(sent_msgs[bus]) for bus in range(3)): + for _ in range(100 * 2): 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 + key = (m.address, m.dat) + assert key in sent_msgs[m.src-128], f"got unexpected msg: {m.src=} {m.address=} {m.dat=}" + sent_msgs[m.src-128].discard(key) + + if all(len(v) == 0 for v in sent_msgs.values()): + break # if a set isn't empty, messages got dropped - for bus in range(3): + for bus in sent_msgs.keys(): assert not len(sent_msgs[bus]), f"loop {i}: bus {bus} missing {len(sent_msgs[bus])} messages"