mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-18 13:33:53 +08:00
a19beda327
Add configurable acceleration, braking, following-distance, and advanced smoothness profiles to Galaxy with off-road writes and readback validation. Co-authored-by: AngusBell97 <124716116+AngusBell97@users.noreply.github.com>
105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
import json
|
|
|
|
import pytest
|
|
|
|
from openpilot.common.params import ParamKeyFlag, ParamKeyType
|
|
from openpilot.starpilot.common import param_profiles
|
|
|
|
|
|
class FakeParams:
|
|
def __init__(self):
|
|
persistent = ParamKeyFlag.PERSISTENT
|
|
self.definitions = {
|
|
"BooleanSetting": (True, ParamKeyType.BOOL, persistent),
|
|
"NumericSetting": (1.5, ParamKeyType.FLOAT, persistent),
|
|
"JsonSetting": ({"mode": "default"}, ParamKeyType.JSON, persistent),
|
|
"SecretSetting": ("", ParamKeyType.STRING, persistent | ParamKeyFlag.DONT_LOG),
|
|
"TransientSetting": (False, ParamKeyType.BOOL, ParamKeyFlag.CLEAR_ON_MANAGER_START),
|
|
}
|
|
self.values = {
|
|
"BooleanSetting": False,
|
|
"NumericSetting": 2.75,
|
|
"JsonSetting": {"mode": "custom"},
|
|
"SecretSetting": "secret",
|
|
"TransientSetting": True,
|
|
}
|
|
|
|
def all_keys(self):
|
|
return list(self.definitions)
|
|
|
|
def get(self, key, return_default=False):
|
|
default = self.definitions[key][0] if return_default else None
|
|
return self.values.get(key, default)
|
|
|
|
def get_default_value(self, key):
|
|
return self.definitions[key][0]
|
|
|
|
def get_key_flag(self, key):
|
|
return self.definitions[key][2]
|
|
|
|
def get_type(self, key):
|
|
return self.definitions[key][1]
|
|
|
|
def put(self, key, value):
|
|
self.values[key] = value
|
|
|
|
|
|
def test_profile_slots_round_trip_only_eligible_settings(tmp_path):
|
|
params = FakeParams()
|
|
|
|
status = param_profiles.save_profile(params, "a", profile_root=tmp_path)
|
|
payload = json.loads((tmp_path / ".params-profile-a.json").read_text())
|
|
|
|
assert status["saved"] is True
|
|
assert status["settingsCount"] == 3
|
|
assert set(payload["settings"]) == {"BooleanSetting", "NumericSetting", "JsonSetting"}
|
|
|
|
params.values.update({
|
|
"BooleanSetting": True,
|
|
"NumericSetting": 9.0,
|
|
"JsonSetting": {"mode": "changed"},
|
|
"SecretSetting": "new-secret",
|
|
"TransientSetting": False,
|
|
})
|
|
result = param_profiles.load_profile(params, "a", profile_root=tmp_path)
|
|
|
|
assert result["restoredCount"] == 3
|
|
assert result["skippedCount"] == 0
|
|
assert params.values["BooleanSetting"] is False
|
|
assert params.values["NumericSetting"] == 2.75
|
|
assert params.values["JsonSetting"] == {"mode": "custom"}
|
|
assert params.values["SecretSetting"] == "new-secret"
|
|
assert params.values["TransientSetting"] is False
|
|
|
|
|
|
def test_prepare_profile_decodes_without_writes_and_preserves_type_filtering(tmp_path):
|
|
params = FakeParams()
|
|
param_profiles.save_profile(params, "a", profile_root=tmp_path)
|
|
params.values.clear()
|
|
params.definitions["NumericSetting"] = (0, ParamKeyType.INT, ParamKeyFlag.PERSISTENT)
|
|
|
|
prepared = param_profiles.prepare_profile(params, "a", profile_root=tmp_path)
|
|
|
|
assert params.values == {}
|
|
assert prepared["settings"] == {"BooleanSetting": False, "JsonSetting": {"mode": "custom"}}
|
|
assert prepared["skippedCount"] == 1
|
|
assert prepared["slot"] == "a"
|
|
result = param_profiles.load_profile(params, "a", profile_root=tmp_path)
|
|
assert result["restoredCount"] == 2
|
|
assert result["skippedCount"] == 1
|
|
assert params.values == prepared["settings"]
|
|
|
|
|
|
def test_profile_slots_report_missing_and_damaged_profiles(tmp_path):
|
|
params = FakeParams()
|
|
|
|
with pytest.raises(param_profiles.ParamProfileError, match="has not been saved"):
|
|
param_profiles.load_profile(params, "b", profile_root=tmp_path)
|
|
with pytest.raises(param_profiles.ParamProfileError, match="Unknown"):
|
|
param_profiles.save_profile(params, "c", profile_root=tmp_path)
|
|
|
|
(tmp_path / ".params-profile-b.json").write_text("not json")
|
|
assert param_profiles.profile_status("b", profile_root=tmp_path)["invalid"] is True
|
|
with pytest.raises(param_profiles.ParamProfileError, match="damaged"):
|
|
param_profiles.load_profile(params, "b", profile_root=tmp_path)
|