Files
IQ.Pilot/artifacts/package_runtime/iqdbc/car/tests/test_disable_ecu.py
2026-09-03 18:23:24 -05:00

94 lines
2.9 KiB
Python

from iqdbc.car.can_definitions import CanData
from iqdbc.car.disable_ecu import (CLEAR_DTC_ISOTP_SF, CLEAR_DTC_REQUEST, EXT_DIAG_REQUEST,
FUNCTIONAL_ADDR_29BIT, clear_all_dtcs, clear_ecu_dtcs, disable_ecu)
RADAR_ADDR = 0x18DAB0F1
COM_CONT_REQUEST = b'\x28\x83\x03'
class QueryRecorder:
def __init__(self):
self.requests = []
def make_fake_query(self):
recorder = self
class FakeIsoTpParallelQuery:
def __init__(self, can_send, can_recv, bus, addrs, requests, responses, response_offset=0x8):
self.bus = bus
self.addrs = addrs
self.request = requests[0]
recorder.requests.append((bus, addrs[0][0], requests[0]))
def get_data(self, timeout):
return {(self.addrs[0][0], None): b''}
return FakeIsoTpParallelQuery
def test_clear_all_dtcs_broadcasts_single_frame():
sent = []
clear_all_dtcs(lambda msgs: sent.extend(msgs), [0, 2])
assert sent == [
CanData(FUNCTIONAL_ADDR_29BIT, CLEAR_DTC_ISOTP_SF, 0),
CanData(FUNCTIONAL_ADDR_29BIT, CLEAR_DTC_ISOTP_SF, 2),
]
def test_clear_dtc_isotp_framing():
assert len(CLEAR_DTC_ISOTP_SF) == 8
assert CLEAR_DTC_ISOTP_SF[0] == len(CLEAR_DTC_REQUEST)
assert CLEAR_DTC_ISOTP_SF[1:1 + len(CLEAR_DTC_REQUEST)] == CLEAR_DTC_REQUEST
assert CLEAR_DTC_REQUEST == b'\x14\xff\xff\xff'
def test_clear_ecu_dtcs_sequence(mocker):
recorder = QueryRecorder()
mocker.patch("iqdbc.car.disable_ecu.IsoTpParallelQuery", recorder.make_fake_query())
assert clear_ecu_dtcs(None, None, bus=0, addr=RADAR_ADDR)
assert recorder.requests == [
(0, RADAR_ADDR, EXT_DIAG_REQUEST),
(0, RADAR_ADDR, CLEAR_DTC_REQUEST),
]
def test_disable_ecu_sequence(mocker):
recorder = QueryRecorder()
mocker.patch("iqdbc.car.disable_ecu.IsoTpParallelQuery", recorder.make_fake_query())
assert disable_ecu(None, None, bus=1, addr=RADAR_ADDR, com_cont_req=COM_CONT_REQUEST)
assert recorder.requests == [
(1, RADAR_ADDR, EXT_DIAG_REQUEST),
(1, RADAR_ADDR, COM_CONT_REQUEST),
]
def test_disable_ecu_clears_dtcs_before_comm_control(mocker):
recorder = QueryRecorder()
mocker.patch("iqdbc.car.disable_ecu.IsoTpParallelQuery", recorder.make_fake_query())
assert disable_ecu(None, None, bus=1, addr=RADAR_ADDR, com_cont_req=COM_CONT_REQUEST, clear_dtc=True)
assert recorder.requests == [
(1, RADAR_ADDR, EXT_DIAG_REQUEST),
(1, RADAR_ADDR, CLEAR_DTC_REQUEST),
(1, RADAR_ADDR, COM_CONT_REQUEST),
]
def test_disable_ecu_retries_then_fails(mocker):
attempts = []
class NoResponseQuery:
def __init__(self, can_send, can_recv, bus, addrs, requests, responses, response_offset=0x8):
attempts.append(requests[0])
def get_data(self, timeout):
return {}
mocker.patch("iqdbc.car.disable_ecu.IsoTpParallelQuery", NoResponseQuery)
assert not disable_ecu(None, None, addr=RADAR_ADDR, retry=3)
assert attempts == [EXT_DIAG_REQUEST] * 3