mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-07 13:03:42 +08:00
96 lines
4.9 KiB
Python
96 lines
4.9 KiB
Python
"""Regression checks for qualified values, saved geometry and request feedback."""
|
|
from dataclasses import replace
|
|
from unittest.mock import Mock
|
|
|
|
from openpilot.starpilot.ui.onroad_state import ObservationKind, OnroadInput, OnroadState, SlcActionKind, SlcUiRequest, SpeedLimitObservation
|
|
from openpilot.starpilot.ui.onroad_customization import default_document, validate_document, rgba
|
|
from openpilot.starpilot.ui.slc_action_dispatch import SlcActionDispatcher
|
|
from openpilot.starpilot.ui.tests.test_slc_ui_actions import native_state, NOW
|
|
from openpilot.starpilot.speed_limits.speed_domain import adjusted_limit, OffsetBand, OffsetSchedule
|
|
from openpilot.starpilot.speed_limits.runtime import Runtime
|
|
from openpilot.starpilot.speed_limits.runtime_settings import parse
|
|
from openpilot.starpilot.ui.tests.test_slc_ui_runtime import START, replay_inputs, publish_request
|
|
|
|
|
|
def road(document=None):
|
|
obs = SpeedLimitObservation(ObservationKind.VALID, 'dashboard', 20, accepted_speed_limit_mps=20,
|
|
accepted_adjusted_limit_mps=22, session_id='drive-session', presentation_id=9,
|
|
decision_id=7, action_enabled=True)
|
|
return OnroadState(True, False, 20, 100, obs, longitudinal_active=True, slc_system_long_available=True,
|
|
customization=document or default_document())
|
|
|
|
|
|
def test_offset_proposals_use_their_own_band_and_reject_invalid_values():
|
|
schedule = OffsetSchedule((OffsetBand(0, 20, 1), OffsetBand(20, None, 3)))
|
|
assert adjusted_limit(19, schedule) == 20
|
|
assert adjusted_limit(20, schedule) == 23
|
|
assert adjusted_limit(float('nan'), schedule) is None
|
|
assert adjusted_limit(10, OffsetSchedule((OffsetBand(0, None, -20),))) == 10
|
|
|
|
|
|
def test_numeric_card_and_sources_row_are_not_tap_targets_while_pending():
|
|
state = road()
|
|
state = replace(state, speed_limit=replace(state.speed_limit, pending_speed_limit_mps=25))
|
|
emitted = []
|
|
touch = OnroadInput(emitted.append)
|
|
touch.press(120, 320, state)
|
|
touch.release(120, 320, state)
|
|
assert not emitted
|
|
# Where the removed "View sources" row used to sit; sources now follow the Galaxy setting only.
|
|
touch.press(100, 709, state)
|
|
assert not touch.claimed
|
|
touch.release(100, 709, state)
|
|
assert not emitted
|
|
|
|
|
|
def test_v4_migration_preserves_settings_and_clamps_only_enlarged_widgets():
|
|
doc = default_document()
|
|
doc['version'] = 4
|
|
doc['palette']['cardFill'] = '#12345678'
|
|
doc['speedSources'] = True
|
|
doc['layouts']['large']['cruise_limits'].update(x=1654, y=75)
|
|
doc['layouts']['large']['speed_limit_actions'].update(x=1654, y=500)
|
|
old_speed = dict(doc['layouts']['large']['current_speed'])
|
|
migrated = validate_document(doc)
|
|
assert migrated['version'] == 12
|
|
assert migrated['layouts']['large']['cruise_limits']['x'] == 1539
|
|
assert migrated['layouts']['large']['speed_limit_actions'] == {'x': 1678, 'y': 267, 'enabled': True}
|
|
assert migrated['layouts']['large']['current_speed'] == old_speed
|
|
assert migrated['speedSources'] is True
|
|
assert rgba(migrated, 'cardFill', 'large', 'cruise_limits') == (18, 52, 86, 120)
|
|
assert validate_document(migrated) == migrated
|
|
|
|
|
|
def test_feedback_requires_matching_receipts_and_command_application():
|
|
now = [NOW]
|
|
dispatcher = SlcActionDispatcher(Mock(), lambda _: native_state(), lambda: now[0])
|
|
assert dispatcher.dispatch(SlcUiRequest(SlcActionKind.ACCEPT, 'drive-session', 7, 9, 22))
|
|
obs = road().speed_limit
|
|
assert dispatcher.feedback(obs) == 'Waiting…'
|
|
obs = replace(obs, action_sequence_id=NOW, action_status='accept')
|
|
assert dispatcher.feedback(obs) == 'Limit accepted'
|
|
obs = replace(obs, command_action_sequence_id=NOW, command_status='issued')
|
|
assert dispatcher.feedback(obs) == 'Applying…'
|
|
assert dispatcher.feedback(replace(obs, command_status='applied')) == 'Applied'
|
|
assert dispatcher.feedback(replace(obs, command_status='expired')) == 'Setpoint not applied'
|
|
assert dispatcher.feedback(replace(obs, session_id='next-drive')) == ''
|
|
|
|
|
|
def test_publisher_receipt_survives_next_cycle_and_resets_with_session():
|
|
sm, cp = replay_inputs()
|
|
runtime = Runtime(parse({'SpeedLimitController': True, 'SLCConfirmation': True, 'SLCConfirmationHigher': True}), session_id='drive')
|
|
pending = runtime.step(sm, cp, now_ns=START).message.slcState
|
|
request = SlcUiRequest(SlcActionKind.ACCEPT, 'drive', pending.decisionId, pending.presentationId, pending.pendingSpeedLimit)
|
|
action = publish_request(pending, request, START)
|
|
sm.advance(START + 50_000_000)
|
|
accepted = runtime.step(sm, cp, now_ns=START + 50_000_000, request=action).message.slcState
|
|
sm.advance(START + 100_000_000)
|
|
next_frame = runtime.step(sm, cp, now_ns=START + 100_000_000).message.slcState
|
|
assert accepted.actionSequenceId == next_frame.actionSequenceId == action.sequence_id
|
|
assert accepted.actionStatus == next_frame.actionStatus == 'accept'
|
|
assert accepted.commandActionSequenceId == next_frame.commandActionSequenceId == action.sequence_id
|
|
runtime.reset()
|
|
assert runtime._ui_receipt is None
|
|
assert runtime._command_ui_sequence == 0
|
|
|