Files
StarPilot/openpilot/starpilot/ui/tests/test_profile_ev_seed.py
T
firestar5683 a82935f326 User interfaces and Android Auto
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services.

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
Co-authored-by: Daniel Koepping <elkoled@gmail.com>
Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com>
Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com>
Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: Shane Smiskol <shane@smiskol.com>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com>
Co-authored-by: stef <19478336+stefpi@users.noreply.github.com>
Co-authored-by: whoisdomi <dcantu83@gmail.com>

Co-authored-by: Intelli <contact@intelli.software>
Co-authored-by: pharmacomaniac <blittle65@gmail.com>

Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

97 lines
4.5 KiB
Python

from pathlib import Path
from types import SimpleNamespace
import os
import tempfile
import unittest
from unittest.mock import patch
from opendbc.car.structs import car
from openpilot.common.params import Params
from openpilot.starpilot import saved_document
from openpilot.starpilot.longitudinal.profile_document import migrate_profile_document
from openpilot.starpilot.ui.feature_settings_owner import FeatureSettingsOwner
from openpilot.starpilot.ui.feature_settings_state import FeatureSettingsRequest
class NamedAccelerationSeedTests(unittest.TestCase):
def setUp(self):
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
self.params = Params(temporary.name)
self.cp = SimpleNamespace(carFingerprint="HYUNDAI IONIQ 6", openpilotLongitudinalControl=True, pcmCruise=False,
passive=False, notCar=False, dashcamOnly=False, carVin="VIN1",
transmissionType=car.CarParams.TransmissionType.automatic)
self.owner = FeatureSettingsOwner(self.params, lambda group: group == "long",
vehicle_fingerprint=lambda: "HYUNDAI IONIQ 6",
vehicle_params=lambda: self.cp)
def select(self, value):
row = self.owner.snapshot("standard/acceleration", parked=True, system_long=True,
lateral_context=False, metric=False).rows[0]
request = FeatureSettingsRequest(row.key, row.source, value, vehicle_fingerprint=row.vehicle_fingerprint,
capability=row.capability)
return row, request
def curve(self):
raw = Path(self.params.get_param_path("LongitudinalPersonalityProfiles")).read_bytes()
document = migrate_profile_document(raw)
self.assertIsNotNone(document)
if document is None:
self.fail("the saved profile document did not decode")
return document["profiles"]["standard"]["acceleration"]["curve"]
def test_named_to_custom_uses_actual_ev_or_non_ev_curve(self):
for transmission, last in ((car.CarParams.TransmissionType.automatic, 0.35),
(car.CarParams.TransmissionType.direct, 0.58)):
with self.subTest(transmission=transmission):
self.cp.transmissionType = transmission
self.assertTrue(self.owner.apply(self.select("eco")[1]))
row, request = self.select("Custom")
self.assertIsNotNone(row.capability)
self.assertTrue(self.owner.apply(request))
self.assertEqual(self.curve()[-1], last)
Path(self.params.get_param_path("LongitudinalPersonalityProfiles")).unlink()
def test_named_seed_rejects_missing_or_changed_cp_before_and_after_staging(self):
self.assertTrue(self.owner.apply(self.select("eco")[1]))
row, request = self.select("Custom")
path = Path(self.params.get_param_path("LongitudinalPersonalityProfiles"))
original = path.read_bytes()
self.cp.transmissionType = car.CarParams.TransmissionType.direct
self.assertFalse(self.owner.apply(request))
self.cp.transmissionType = car.CarParams.TransmissionType.automatic
with patch.object(self, "cp", None):
self.assertNotIn("Custom", self.select("Custom")[0].choices)
self.assertFalse(self.owner.apply(request))
self.assertEqual(path.read_bytes(), original)
row, request = self.select("custom")
real_fsync = os.fsync
def change(fd):
real_fsync(fd)
self.cp.transmissionType = car.CarParams.TransmissionType.direct
with patch.object(saved_document.os, "fsync", side_effect=change):
self.assertFalse(self.owner.apply(request))
self.assertEqual(path.read_bytes(), original)
def test_selected_profile_to_custom_requires_current_vehicle_seed(self):
with patch.object(self, "cp", None):
row, request = self.select("Custom")
self.assertIsNone(row.capability)
self.assertNotIn("Custom", row.choices)
self.assertFalse(self.owner.apply(request))
self.assertFalse(Path(self.params.get_param_path("LongitudinalPersonalityProfiles")).exists())
def test_named_preset_restores_dormant_custom_without_new_vehicle_seed(self):
self.assertTrue(self.owner.apply(self.select("custom")[1]))
original_curve = self.curve()
self.assertTrue(self.owner.apply(self.select("eco")[1]))
with patch.object(self, "cp", None):
row, request = self.select("custom")
self.assertIn("Custom", row.choices)
self.assertTrue(self.owner.apply(request))
self.assertEqual(self.curve(), original_curve)
if __name__ == "__main__":
unittest.main()