mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-09-30 19:33:49 +08:00
ea241bf3dc
* get_fw_versions returns all fw versions with request's brand * keep track of everything received * debug * need to regen or write a hack in build_fw_dict * to be safe, still replace old responses within same brands (hyundai responds to two queries, can fix later) to be safe, still replace old responses within same brands (hyundai responds to two queries, can fix later) * update test_fw_query_on_routes * clean up * better name * slightly cleaner * fix test_startup unit test del * fix imports * fix test_fw_fingerprint fix test_fw_fingerprint fix * fingerprint on all FW_VERSIONS, not just brands with requests * support old routes in test_fw_query_on_routes * regen and update refs * similar function style to before * better comment * space switch name * try to exact match first * useless else * fix debug script * simpler dictionary * bump cereal to master
80 lines
3.0 KiB
Python
Executable File
80 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import random
|
|
import unittest
|
|
from parameterized import parameterized
|
|
|
|
from cereal import car
|
|
from selfdrive.car.car_helpers import get_interface_attr, interfaces
|
|
from selfdrive.car.fingerprints import FW_VERSIONS
|
|
from selfdrive.car.fw_versions import REQUESTS, match_fw_to_car
|
|
|
|
CarFw = car.CarParams.CarFw
|
|
Ecu = car.CarParams.Ecu
|
|
|
|
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
|
VERSIONS = get_interface_attr("FW_VERSIONS", ignore_none=True)
|
|
|
|
|
|
class TestFwFingerprint(unittest.TestCase):
|
|
def assertFingerprints(self, candidates, expected):
|
|
candidates = list(candidates)
|
|
self.assertEqual(len(candidates), 1, f"got more than one candidate: {candidates}")
|
|
self.assertEqual(candidates[0], expected)
|
|
|
|
@parameterized.expand([(b, c, e[c]) for b, e in VERSIONS.items() for c in e])
|
|
def test_fw_fingerprint(self, brand, car_model, ecus):
|
|
CP = car.CarParams.new_message()
|
|
for _ in range(200):
|
|
fw = []
|
|
for ecu, fw_versions in ecus.items():
|
|
ecu_name, addr, sub_addr = ecu
|
|
fw.append({"ecu": ecu_name, "fwVersion": random.choice(fw_versions), 'brand': brand,
|
|
"address": addr, "subAddress": 0 if sub_addr is None else sub_addr})
|
|
CP.carFw = fw
|
|
_, matches = match_fw_to_car(CP.carFw)
|
|
self.assertFingerprints(matches, car_model)
|
|
|
|
def test_no_duplicate_fw_versions(self):
|
|
passed = True
|
|
for car_model, ecus in FW_VERSIONS.items():
|
|
for ecu, ecu_fw in ecus.items():
|
|
duplicates = {fw for fw in ecu_fw if ecu_fw.count(fw) > 1}
|
|
if len(duplicates):
|
|
print(car_model, ECU_NAME[ecu[0]], duplicates)
|
|
passed = False
|
|
|
|
self.assertTrue(passed, "Duplicate FW versions found")
|
|
|
|
def test_blacklisted_ecus(self):
|
|
passed = True
|
|
blacklisted_addrs = (0x7c4, 0x7d0) # includes A/C ecu and an unknown ecu
|
|
for car_model, ecus in FW_VERSIONS.items():
|
|
CP = interfaces[car_model][0].get_params(car_model)
|
|
if CP.carName == 'subaru':
|
|
for ecu in ecus.keys():
|
|
if ecu[1] in blacklisted_addrs:
|
|
print(f'{car_model}: Blacklisted ecu: (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])})')
|
|
passed = False
|
|
|
|
self.assertTrue(passed, "Blacklisted FW versions found")
|
|
|
|
def test_fw_request_ecu_whitelist(self):
|
|
passed = True
|
|
brands = set(r.brand for r in REQUESTS)
|
|
for brand in brands:
|
|
whitelisted_ecus = [ecu for r in REQUESTS for ecu in r.whitelist_ecus if r.brand == brand]
|
|
brand_ecus = set([fw[0] for car_fw in VERSIONS[brand].values() for fw in car_fw])
|
|
|
|
# each ecu in brand's fw versions needs to be whitelisted at least once
|
|
ecus_not_whitelisted = set(brand_ecus) - set(whitelisted_ecus)
|
|
if len(whitelisted_ecus) and len(ecus_not_whitelisted):
|
|
ecu_strings = ", ".join([f'Ecu.{ECU_NAME[ecu]}' for ecu in ecus_not_whitelisted])
|
|
print(f'{brand.title()}: FW query whitelist missing ecus: {ecu_strings}')
|
|
passed = False
|
|
|
|
self.assertTrue(passed, "Not all ecus in FW versions found in query whitelists")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|