Files
StarPilot/openpilot/starpilot/tests/test_ford_alpha_reverse_intent.py

68 lines
2.9 KiB
Python

"""Alpha CP may retain only a proven LAT-only Reverse intent, never LONG."""
from dataclasses import replace
import pytest
from openpilot.starpilot.tests.ford_alpha_test_support import NOW, PRODUCER, baseline, change, native_change, receipt
from opendbc.car import structs
from openpilot.starpilot.car.ford.reverse_intent import retain_reverse_intent
NEGATIVES = (
'lat-only-origin',
'axis-long-desire',
'axis-long-active',
'native-long-request',
'native-long-grant',
'native-controls',
'raw-controls',
'native-rx',
'native-heartbeat',
'expired',
'event',
'epoch',
)
def setup():
cp, cs, f = baseline(combined=False)
cs.gearShifter = structs.CarState.GearShifter.reverse
sm, native = receipt(cp, NOW + 10_000_000, NOW + 20_000_000, 2, reverse=True)
return cp, cs, f, sm, native
def test_alpha_reverse_uses_original_lat_only_proof_with_zero_long_and_no_renewal():
cp, cs, f, sm, _ = setup()
before = dict(vars(f))
assert retain_reverse_intent(f, sm, cp, cs, sm['aolAxisState'], NOW + 20_000_000, latched=True, producer=PRODUCER)
assert vars(f) == before
assert not f.observe(sm, cp, cs, NOW + 20_000_000, latched=True, intent_producer_session=PRODUCER)
assert f.sequence == before['sequence'] and f.signature == before['signature']
assert f.healthy_native_ns == before['healthy_native_ns'] and f.lateral_source_ns == before['lateral_source_ns']
@pytest.mark.parametrize('fault', NEGATIVES)
def test_alpha_reverse_cannot_borrow_combined_permission_or_mask_native_fault(fault):
cp, cs, f, sm, native = setup()
now = NOW + 20_000_000
if fault == 'lat-only-origin':
f.lateral_only_baseline = False
elif fault in ('axis-long-desire', 'axis-long-active'):
change(sm, 'aolAxisState', lambda a: setattr(a, 'desiredLongitudinal' if fault == 'axis-long-desire' else 'longitudinalActive', True))
elif fault in ('native-long-request', 'native-long-grant'):
native_change(sm, native, **{'requestedLongitudinal' if fault == 'native-long-request' else 'longitudinalAllowed': True})
elif fault in ('native-controls', 'native-rx', 'native-heartbeat'):
field = {'native-controls': 'controlsAllowed', 'native-rx': 'safetyRxChecksInvalid', 'native-heartbeat': 'heartbeatLost'}[fault]
native_change(sm, native, pandaInventory=(replace(native.pandaInventory[0], **{field: True}),))
elif fault == 'raw-controls':
change(sm, 'pandaStates', lambda ps: setattr(ps[0], 'controlsAllowed', True))
elif fault == 'expired':
now = NOW + 40_000_000
sm, _ = receipt(cp, NOW + 30_000_000, now, 3, reverse=True)
elif fault == 'event':
change(sm, 'onroadEvents', lambda es: setattr(es[0], 'immediateDisable', True))
elif fault == 'epoch':
change(sm, 'aolAxisState', lambda a: setattr(a, 'intentIntegrityEpoch', 2))
else:
raise AssertionError(fault)
assert not retain_reverse_intent(f, sm, cp, cs, sm['aolAxisState'], now, latched=True, producer=PRODUCER)