diff --git a/selfdrive/car/hyundai/tests/test_hyundai.py b/selfdrive/car/hyundai/tests/test_hyundai.py index 3b82b59d03..77aed9c979 100755 --- a/selfdrive/car/hyundai/tests/test_hyundai.py +++ b/selfdrive/car/hyundai/tests/test_hyundai.py @@ -23,8 +23,9 @@ class TestHyundaiFingerprint(unittest.TestCase): for car_model in CANFD_CAR: ecus = {fw[0] for fw in FW_VERSIONS[car_model].keys()} ecus_not_in_whitelist = ecus - whitelisted_ecus - ecu_strings = ", ".join([f'Ecu.{ECU_NAME[ecu]}' for ecu in ecus_not_in_whitelist]) - self.assertEqual(len(ecus_not_in_whitelist), 0, f'{car_model}: Car model has ECUs not in auxiliary request whitelists: {ecu_strings}') + ecu_strings = ", ".join([f"Ecu.{ECU_NAME[ecu]}" for ecu in ecus_not_in_whitelist]) + self.assertEqual(len(ecus_not_in_whitelist), 0, + f"{car_model}: Car model has ECUs not in auxiliary request whitelists: {ecu_strings}") # Tests for platform codes, part numbers, and FW dates which Hyundai will use to fuzzy # fingerprint in the absence of full FW matches: @@ -43,25 +44,12 @@ class TestHyundaiFingerprint(unittest.TestCase): continue self.assertIn(platform_code_ecu, [e[0] for e in ecus]) - def test_fw_part_numbers(self): - # Hyundai places the ECU part number in their FW versions, assert all parsable - # Some examples of valid formats: '56310-L0010', '56310L0010', '56310/M6300' - for car_model, ecus in FW_VERSIONS.items(): - with self.subTest(car_model=car_model): - if car_model == CAR.HYUNDAI_GENESIS: - raise unittest.SkipTest("No part numbers for car model") - - for ecu, fws in ecus.items(): - if ecu[0] not in PLATFORM_CODE_ECUS: - continue - - for fw in fws: - match = PART_NUMBER_FW_PATTERN.search(fw) - self.assertIsNotNone(match, fw) + def test_fw_format(self): + # Asserts: + # - every supported ECU FW version returns one platform code + # - every supported ECU FW version has a part number + # - expected parsing of ECU FW dates - def test_fw_dates(self): - # Some newer platforms have date codes in a different format we don't yet parse, - # for now assert date format is consistent for all FW across each platform for car_model, ecus in FW_VERSIONS.items(): with self.subTest(car_model=car_model): for ecu, fws in ecus.items(): @@ -70,47 +58,52 @@ class TestHyundaiFingerprint(unittest.TestCase): codes = set() for fw in fws: - codes |= get_platform_codes([fw]) + result = get_platform_codes([fw]) + self.assertEqual(1, len(result), f"Unable to parse FW: {fw}") + codes |= result + + # Some newer platforms have date codes in a different format we don't yet parse, + # for now assert we can parse all FW or none + self.assertEqual(len({b"-" in code for code in codes}), 1, + "Not all FW dates are parsable") - # Either no dates should be parsed or all dates should be parsed - self.assertEqual(len({b'-' in code for code in codes}), 1) + if car_model == CAR.HYUNDAI_GENESIS: + raise unittest.SkipTest("No part numbers for car model") - def test_platform_codes_all_parsable(self): - # Assert every supported ECU FW version returns one platform code - for fw_by_addr in FW_VERSIONS.values(): - for addr, fws in fw_by_addr.items(): - if addr[0] in PLATFORM_CODE_ECUS: - for f in fws: - self.assertEqual(1, len(get_platform_codes([f])), f"Unable to parse FW: {f}") + # Hyundai places the ECU part number in their FW versions, assert all parsable + # Some examples of valid formats: b"56310-L0010", b"56310L0010", b"56310/M6300" + for fw in fws: + match = PART_NUMBER_FW_PATTERN.search(fw) + self.assertIsNotNone(match, fw) def test_platform_codes_spot_check(self): # Asserts basic platform code parsing behavior for a few cases - codes = get_platform_codes([b'\xf1\x00DH LKAS 1.1 -150210']) + codes = get_platform_codes([b"\xf1\x00DH LKAS 1.1 -150210"]) self.assertEqual(codes, {b"DH-1502"}) # Some cameras and all radars do not have dates - codes = get_platform_codes([b'\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2000 ']) + codes = get_platform_codes([b"\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2000 "]) self.assertEqual(codes, {b"AEhe"}) - codes = get_platform_codes([b'\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ']) + codes = get_platform_codes([b"\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 "]) self.assertEqual(codes, {b"CV1"}) codes = get_platform_codes([ - b'\xf1\x00DH LKAS 1.1 -150210', - b'\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2000 ', - b'\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ', + b"\xf1\x00DH LKAS 1.1 -150210", + b"\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2000 ", + b"\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ", ]) self.assertEqual(codes, {b"DH-1502", b"AEhe", b"CV1"}) # Returned platform codes must inclusively contain start/end dates codes = get_platform_codes([ - b'\xf1\x00LX2 MFC AT USA LHD 1.00 1.07 99211-S8100 220222', - b'\xf1\x00LX2 MFC AT USA LHD 1.00 1.08 99211-S8100 211103', - b'\xf1\x00ON MFC AT USA LHD 1.00 1.01 99211-S9100 190405', - b'\xf1\x00ON MFC AT USA LHD 1.00 1.03 99211-S9100 190720', + b"\xf1\x00LX2 MFC AT USA LHD 1.00 1.07 99211-S8100 220222", + b"\xf1\x00LX2 MFC AT USA LHD 1.00 1.08 99211-S8100 211103", + b"\xf1\x00ON MFC AT USA LHD 1.00 1.01 99211-S9100 190405", + b"\xf1\x00ON MFC AT USA LHD 1.00 1.03 99211-S9100 190720", ]) - self.assertEqual(codes, {b'LX2-2111', b'LX2-2112', b'LX2-2201', b'LX2-2202', - b'ON-1904', b'ON-1905', b'ON-1906', b'ON-1907'}) + self.assertEqual(codes, {b"LX2-2111", b"LX2-2112", b"LX2-2201", b"LX2-2202", + b"ON-1904", b"ON-1905", b"ON-1906", b"ON-1907"}) if __name__ == "__main__":