""" Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/ """ import pytest from iqpilot.selfdrive.longitudinal_settings import ( LONGITUDINAL_MODE_CHILL, LONGITUDINAL_MODE_DYNAMIC, LONGITUDINAL_MODE_PILOT, LONGITUDINAL_MODE_STOCK, PERSONALITY_AGGRESSIVE, PERSONALITY_RELAXED, PERSONALITY_STANDARD, PERSONALITY_VALUES, apply_longitudinal_mode, get_follow_distance_state, get_longitudinal_mode, get_runtime_personality, longitudinal_mode_needs_cycle, next_longitudinal_mode, set_valid_personality, ) class Params: def __init__(self, personality=PERSONALITY_STANDARD): self.values = { "AlphaLongitudinalEnabled": True, "ExperimentalMode": True, "IQDynamicMode": True, "LongitudinalPersonality": personality, } self.personality_writes = [] def get(self, key, return_default=False): return self.values[key] def get_bool(self, key): return bool(self.values[key]) def put(self, key, value): self.values[key] = value if key == "LongitudinalPersonality": self.personality_writes.append(value) def put_bool(self, key, value): self.values[key] = bool(value) def test_personality_writer_rejects_stock_value(): params = Params() with pytest.raises(ValueError): set_valid_personality(params, 3) assert params.personality_writes == [] def test_mode_paths_only_write_valid_personalities(): params = Params(PERSONALITY_AGGRESSIVE) for mode in range(4): apply_longitudinal_mode(params, mode) assert all(value in PERSONALITY_VALUES for value in params.personality_writes) def test_stock_mode_preserves_personality_and_dynamic_restores_it(): params = Params(PERSONALITY_AGGRESSIVE) apply_longitudinal_mode(params, LONGITUDINAL_MODE_STOCK) assert get_follow_distance_state(params) == (None, False) assert get_runtime_personality(params) == PERSONALITY_AGGRESSIVE assert params.values["LongitudinalPersonality"] == PERSONALITY_AGGRESSIVE assert params.personality_writes == [] apply_longitudinal_mode(params, LONGITUDINAL_MODE_DYNAMIC) assert get_longitudinal_mode(params) == LONGITUDINAL_MODE_DYNAMIC assert get_follow_distance_state(params) == (PERSONALITY_AGGRESSIVE, True) def test_stock_mode_sanitizes_legacy_stock_personality_value(): params = Params(3) apply_longitudinal_mode(params, LONGITUDINAL_MODE_STOCK) assert get_follow_distance_state(params) == (None, False) assert params.values["LongitudinalPersonality"] == PERSONALITY_RELAXED assert params.personality_writes == [PERSONALITY_RELAXED] def test_chill_mode_forces_relaxed_personality(): params = Params(PERSONALITY_AGGRESSIVE) apply_longitudinal_mode(params, LONGITUDINAL_MODE_CHILL) assert get_follow_distance_state(params) == (PERSONALITY_RELAXED, False) assert get_runtime_personality(params) == PERSONALITY_RELAXED assert params.values["LongitudinalPersonality"] == PERSONALITY_RELAXED assert params.personality_writes == [PERSONALITY_RELAXED] def test_dynamic_and_pilot_enable_valid_personality_selection(): params = Params(PERSONALITY_STANDARD) assert get_follow_distance_state(params) == (PERSONALITY_STANDARD, True) params.values["IQDynamicMode"] = False assert get_follow_distance_state(params) == (PERSONALITY_STANDARD, True) def test_onroad_cycles_only_between_iq_modes(): assert next_longitudinal_mode(LONGITUDINAL_MODE_CHILL, True, True) == LONGITUDINAL_MODE_DYNAMIC assert next_longitudinal_mode(LONGITUDINAL_MODE_DYNAMIC, True, True) == LONGITUDINAL_MODE_PILOT assert next_longitudinal_mode(LONGITUDINAL_MODE_PILOT, True, True) == LONGITUDINAL_MODE_CHILL def test_onroad_stock_acc_is_locked(): assert next_longitudinal_mode(LONGITUDINAL_MODE_STOCK, True, True) == LONGITUDINAL_MODE_STOCK assert next_longitudinal_mode(LONGITUDINAL_MODE_STOCK, True, False) == LONGITUDINAL_MODE_STOCK def test_offroad_cycles_through_stock_acc(): assert next_longitudinal_mode(LONGITUDINAL_MODE_PILOT, False, True) == LONGITUDINAL_MODE_STOCK assert next_longitudinal_mode(LONGITUDINAL_MODE_STOCK, False, True) == LONGITUDINAL_MODE_CHILL def test_offroad_without_iq_modes_only_offers_stock_acc(): assert next_longitudinal_mode(LONGITUDINAL_MODE_STOCK, False, False) == LONGITUDINAL_MODE_STOCK assert next_longitudinal_mode(LONGITUDINAL_MODE_PILOT, False, False) == LONGITUDINAL_MODE_STOCK def test_cycle_only_when_crossing_stock_boundary(): assert longitudinal_mode_needs_cycle(LONGITUDINAL_MODE_STOCK, LONGITUDINAL_MODE_CHILL) assert longitudinal_mode_needs_cycle(LONGITUDINAL_MODE_PILOT, LONGITUDINAL_MODE_STOCK) assert not longitudinal_mode_needs_cycle(LONGITUDINAL_MODE_CHILL, LONGITUDINAL_MODE_PILOT) assert not longitudinal_mode_needs_cycle(LONGITUDINAL_MODE_DYNAMIC, LONGITUDINAL_MODE_CHILL)