Files
StarPilot/openpilot/starpilot/aol/tests/test_availability_warning_eligibility.py
T

70 lines
3.6 KiB
Python

"""Presentation distinguishes cold faults from a real acknowledged AOL pause."""
from contextlib import ExitStack
import pytest
from opendbc.car.hyundai.values import CAR
from opendbc.car.structs import car
from openpilot.cereal import log
from openpilot.common.prefix import OpenpilotPrefix
from openpilot.starpilot.aol.tests import test_ioniq_availability as fixture
from openpilot.starpilot.aol.tests.test_canfd_stock_profiles import params
@pytest.mark.parametrize('context', ['cold_model', 'park', 'unarmed'])
def test_never_active_fault_does_not_claim_steering_was_paused(context):
case = fixture.IoniqAvailabilityTests(methodName='runTest')
with OpenpilotPrefix(), ExitStack() as cleanup:
cleanup.callback(case.doCleanups)
sd, _, step = case._authority_callers(False, cp=params(CAR.KIA_EV6), genuine_events=True)
if context == 'cold_model':
sd.initialized = False
observed = fixture.car_state()
if context == 'park':
observed.gearShifter = car.CarState.GearShifter.park
observed.vEgo = 0.
observed.standstill = True
for tick in range(3):
axis, state, command = step(tick, observed_state=observed, calibrated=context != 'cold_model',
latched=context != 'unarmed', allowed=context != 'unarmed',
critical_event=log.OnroadEvent.EventName.lowMemory)
assert str(axis.faultReason) == 'availabilityPause'
assert not axis.desiredLateral and not axis.lateralActive
assert not state.enabled and not state.active and not command.latActive and not command.longActive
assert state.alertType != 'aolAvailability/warning'
assert 'aolAvailability/warning' not in sd.AM.alerts
assert log.OnroadEvent.EventName.lowMemory in sd.events.names
assert sd.events.contains(fixture.ET.SOFT_DISABLE)
def test_acknowledged_disabled_aol_pause_warns_then_cold_transition_retires_only_custom_entry():
case = fixture.IoniqAvailabilityTests(methodName='runTest')
with OpenpilotPrefix(), ExitStack() as cleanup:
cleanup.callback(case.doCleanups)
sd, _, step, _, _ = case._ioniq_availability_callers(full_op=False)
axis, state, command = step(2, car_output_valid=False)
assert axis.desiredLateral and axis.nativeAcknowledged
assert not axis.lateralActive and not command.latActive
assert not state.enabled and not state.active
queued = sd.AM.alerts['aolAvailability/warning'].alert
assert queued is not None
assert (queued.alert_text_1, queued.alert_text_2) == ('Steering Paused', 'Communication Issue')
# A genuine original communication takeover may outrank the custom notice.
if state.alertType != 'aolAvailability/warning':
assert state.alertType == 'commIssue/softDisable'
assert state.alertStatus == log.SelfdriveState.AlertStatus.critical
# The real fixture publishes calibration at its service cadence, not every
# control tick. Wait for the actual delivered state without forging health.
for tick in range(3, 103):
axis, state, command = step(tick, calibrated=False, car_output_valid=False)
assert not axis.lateralActive and not command.latActive and not command.longActive
if str(sd.sm['extrinsicsCalibration'].calStatus) == 'uncalibrated':
break
else:
raise AssertionError('Uncalibrated state was not genuinely delivered within one second')
assert str(sd.sm['extrinsicsCalibration'].calStatus) == 'uncalibrated'
assert not axis.desiredLateral and not axis.lateralActive and not command.latActive
assert state.alertType != 'aolAvailability/warning'
assert 'aolAvailability/warning' not in sd.AM.alerts
assert not state.enabled and not state.active and not command.longActive