SPI: add more test cases (#2462)

(cherry picked from commit 09d742cdf2b415ca6218cee2c5f58238069337fb)
This commit is contained in:
Adeeb Shihadeh
2026-10-13 16:30:41 -07:00
committed by firestar5683
parent ccea771642
commit a0c5371835
2 changed files with 51 additions and 1 deletions
+1 -1
View File
@@ -710,7 +710,7 @@ class Panda:
@ensure_can_packet_version
def can_send_many(self, arr, *, fd=False, timeout=CAN_SEND_TIMEOUT_MS):
snds = pack_can_buffer(arr, chunk=(not self.spi), fd=fd)
snds = pack_can_buffer(arr, chunk=True, fd=fd)
for tx in snds:
while len(tx) > 0:
bs = self._handle.bulkWrite(3, tx, timeout=timeout)
+50
View File
@@ -1,7 +1,12 @@
import binascii
import random
import struct
import threading
import time
import unittest
from unittest.mock import patch
from opendbc.car.structs import CarParams
from panda.tests.hitl.base import PandaTestCase
from panda import Panda
from panda.python.spi import PandaProtocolMismatch, PandaSpiNackResponse
@@ -84,3 +89,48 @@ class TestSpi(PandaTestCase):
p._handle.bulkWrite(ep, b"abc", timeout=50)
self._ping(p)
def test_multiple_clients(self):
# every client's request runs, even when it's identical to another client's
self.p.set_safety_mode(CarParams.SafetyModel.allOutput)
self.p.set_can_loopback(True)
with Panda(self.p._serial) as p1, Panda(self.p._serial) as p2:
for _ in range(100):
p1.can_send(0x123, b"\x01" * 8, 0)
p2.can_send(0x123, b"\x01" * 8, 0)
time.sleep(0.1)
assert len([m for m in self.p.can_recv() if m[2] == 0]) == 200
def test_can_exactly_once(self):
# more than a full transfer each way, so writes and reads are split into chunks
self.p.set_safety_mode(CarParams.SafetyModel.allOutput)
self.p.set_can_loopback(True)
sent = [struct.pack(">Q", i) for i in range(600)]
self.p.can_send_many([(0x123, dat, 0) for dat in sent], timeout=0)
time.sleep(0.5)
got = []
while len(r := self.p.can_recv()):
got += [m[1] for m in r if m[2] == 0]
assert sorted(got) == sent
def test_thread_safe(self):
# one handle shared by threads, like pandad
errors = []
def hammer():
try:
for _ in range(200):
self.p.health()
except Exception as e:
errors.append(e)
threads = [threading.Thread(target=hammer) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
assert errors == []
@unittest.expectedFailure # SPI bulkRead ignores length on the old protocol
def test_max_sizes(self):
# around the first read size and the max transfer size
for n in (1, 1013, 1014, 4032):
assert len(self.p._handle.bulkRead(0xAB, n)) == n