jungle HITL tests setup (#1665)

* setup new zoo

* run

* fix

---------

Co-authored-by: Bruce Wayne <batman@comma.ai>
This commit is contained in:
Adeeb Shihadeh 2023-09-30 23:19:06 -07:00 committed by GitHub
parent b6e37f25b6
commit 43bed1aa47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 72 deletions

8
Jenkinsfile vendored
View File

@ -99,7 +99,6 @@ pipeline {
}
}
/*
stage ('Acquire resource locks') {
options {
lock(resource: "pandas")
@ -115,15 +114,16 @@ pipeline {
}
}
}
stage('prep') {
stage('jungle tests') {
steps {
script {
retry (3) {
docker_run("reset hardware", 3, "python ./tests/ci_reset_hw.py")
docker_run("reset hardware", 3, "python ./tests/hitl/reset_jungles.py")
}
}
}
}
/*
stage('pedal tests') {
steps {
script {
@ -146,9 +146,9 @@ pipeline {
}
}
}
*/
}
}
*/
}
}
}

View File

@ -11,6 +11,7 @@ class McuConfig(NamedTuple):
mcu: str
mcu_idcode: int
sector_sizes: List[int]
sector_count: int # total sector count, used for MCU identification in DFU mode
uid_address: int
block_size: int
serial_number_address: int
@ -32,13 +33,14 @@ Fx = (
0x8000000,
"bootstub.panda.bin",
)
F2Config = McuConfig("STM32F2", 0x411, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(7)], *Fx)
F4Config = McuConfig("STM32F4", 0x463, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(11)], *Fx)
F2Config = McuConfig("STM32F2", 0x411, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(7)], 12, *Fx)
F4Config = McuConfig("STM32F4", 0x463, [0x4000 for _ in range(4)] + [0x10000] + [0x20000 for _ in range(11)], 16, *Fx)
H7Config = McuConfig(
"STM32H7",
0x483,
[0x20000 for _ in range(7)],
8,
0x1FF1E800,
0x400,
# there is an 8th sector, but we use that for the provisioning chunk, so don't program over that!

View File

@ -34,13 +34,14 @@ class STBootloaderUSBHandle(BaseSTBootloaderHandle):
def __init__(self, libusb_device, libusb_handle):
self._libusb_handle = libusb_handle
# lsusb -v | grep Flash
# example from F4: lsusb -v | grep Flash
# iInterface 4 @Internal Flash /0x08000000/04*016Kg,01*064Kg,011*128Kg
out = libusb_handle.controlRead(0x80, 0x06, 0x0300 | 4, 0, 255)
flash_desc = bytes(out[2:]).decode('utf-16le')
sector_count = sum([int(s.split('*')[0]) for s in flash_desc.split('/')[-1].split(',')])
mcu_by_sector_count = {len(m.config.sector_sizes): m for m in McuType}
for i in range(20):
desc = libusb_handle.getStringDescriptor(i, 0)
if desc is not None and desc.startswith("@Internal Flash"):
sector_count = sum([int(s.split('*')[0]) for s in desc.split('/')[-1].split(',')])
break
mcu_by_sector_count = {m.config.sector_count: m for m in McuType}
assert sector_count in mcu_by_sector_count, f"Unkown MCU: {sector_count=}"
self._mcu_type = mcu_by_sector_count[sector_count]

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python3
import concurrent.futures
from panda import Panda, PandaDFU, PandaJungle
from panda.tests.libs.resetter import Resetter
# all jungles used in the HITL tests
JUNGLES = [
"058010800f51363038363036",
"23002d000851393038373731"
]
# Reset + flash all CI hardware to get it into a consistent state
# * ports 1-2 are jungles
# * port 3 is for the USB hubs
if __name__ == "__main__":
r = Resetter()
r.enable_boot(True)
r.cycle_power(delay=7, ports=[1, 2, 3])
r.enable_boot(False)
pandas = PandaDFU.list()
print("DFU pandas:", pandas)
assert len(pandas) == 7
with concurrent.futures.ProcessPoolExecutor(max_workers=len(pandas)) as exc:
def recover(serial):
PandaDFU(serial).recover()
list(exc.map(recover, pandas, timeout=20))
r.cycle_power(delay=7, ports=[1, 2])
pandas = Panda.list()
print(pandas)
assert len(pandas) >= 7
with concurrent.futures.ProcessPoolExecutor(max_workers=len(pandas)) as exc:
def flash(serial):
with Panda(serial) as pf:
if pf.bootstub:
pf.flash()
list(exc.map(flash, pandas, timeout=20))
print("flashing jungle")
# flash jungles
pjs = PandaJungle.list()
assert set(pjs) == set(JUNGLES), f"Got different jungles than expected:\ngot {set(pjs)}\nexpected {set(JUNGLES)}"
for s in pjs:
with PandaJungle(serial=s) as pj:
print(f"- flashing {s}")
pj.flash()
r.cycle_power(delay=0, ports=[1, 2])
r.close()

39
tests/hitl/reset_jungles.py Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env python3
import concurrent.futures
from panda import PandaJungle, PandaJungleDFU, McuType
from panda.tests.libs.resetter import Resetter
def recover(s):
with PandaJungleDFU(s) as pd:
pd.recover()
def flash(s):
with PandaJungle(s) as p:
p.flash()
return p.get_mcu_type()
# Reset + flash all CI hardware to get it into a consistent state
# * port 1: jungles-under-test
# * port 2: USB hubs
# * port 3: HITL pandas and their jungles
if __name__ == "__main__":
with Resetter() as r:
# everything off
for i in range(1, 4):
r.enable_power(i, 0)
r.cycle_power(ports=[1, 2], dfu=True)
dfu_serials = PandaJungleDFU.list()
assert len(dfu_serials) == 2
with concurrent.futures.ProcessPoolExecutor(max_workers=len(dfu_serials)) as exc:
list(exc.map(recover, dfu_serials, timeout=30))
# power cycle for H7 bootloader bug
r.cycle_power(ports=[1, 2])
serials = PandaJungle.list()
assert len(serials) == len(dfu_serials)
mcu_types = list(exc.map(flash, serials, timeout=20))
assert set(mcu_types) == {McuType.F4, McuType.H7}

View File

@ -7,6 +7,12 @@ class Resetter():
self._handle = None
self.connect()
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
def close(self):
self._handle.close()
self._context.close()
@ -36,16 +42,16 @@ class Resetter():
def enable_boot(self, enabled):
self._handle.controlWrite((usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE), 0xff, 0, enabled, b'')
def cycle_power(self, delay=5, ports=None):
def cycle_power(self, delay=5, dfu=False, ports=None):
if ports is None:
ports = [1, 2, 3]
self.enable_boot(dfu)
for port in ports:
self.enable_power(port, False)
time.sleep(1)
time.sleep(0.5)
for port in ports:
self.enable_power(port, True)
time.sleep(delay)
self.enable_boot(False)