Files
StarPilot/openpilot/starpilot/flm/tests/test_event_subset_prefix.py
T
2026-10-17 23:26:55 -05:00

106 lines
5.8 KiB
Python

"""Subset controller prefix only: no native-result/token/admission transfer."""
from dataclasses import replace
import pickle
from types import MappingProxyType
from unittest import mock
import pytest
from openpilot.starpilot.flm.canonical_surface_adapter import GROUPS
from openpilot.starpilot.flm.controller_replay import _run
from openpilot.starpilot.flm.event_controller_replay import EventControllerReplay
from openpilot.starpilot.flm.event_objective import EffectObjective
from openpilot.starpilot.flm.tests.test_event_controller_prefix import fixture, observed
def full_and_subset(domain='torque', nonzero=True, epsilon=.01):
original = fixture(domain, nonzero=nonzero)
envelope = original.records[0].effect_trace.envelope.for_trial(GROUPS['ff.left'])
objective = EffectObjective('ff.left', envelope.trial_names, envelope.trial_anchor, envelope.context_key)
full = EventControllerReplay(original.engine, objective, envelope.replay_anchor(), activation_plan=original.activation_plan)
full.rebuild_causal_features(epsilon=epsilon)
small = envelope.for_trial(('ff_gain_left',))
selected = EffectObjective('ff.left', small.trial_names, small.trial_anchor, small.context_key)
subset = EventControllerReplay(original.engine, selected, small.replay_anchor(), activation_plan=original.activation_plan)
return full, subset
@pytest.mark.parametrize('domain', ('torque', 'starpilot', 'pid'))
@pytest.mark.parametrize('nonzero', (False, True))
@pytest.mark.parametrize('shadow,delta', ((False, .000000001), (True, .01), (True, -.01)))
def test_actual_full_to_subset_prefix_matches_independent_tail_state_logs_maps_and_native(domain, nonzero, shadow, delta):
full, subset = full_and_subset(domain, nonzero=nonzero)
source = full._EventControllerReplay__controller_prefix
assert source is not None and len(source[1]) == 30
independent = EventControllerReplay(subset.engine, subset.objective, subset.original_anchor, activation_plan=subset.activation_plan)
assert subset.reuse_subset_causal_features(full) is True
rebound = subset._EventControllerReplay__controller_prefix
assert rebound is not None and rebound[0] == subset._causal_input_key(.01)
assert rebound[0] != source[0] and rebound[1:] == source[1:]
assert all(type(part) is MappingProxyType and part is not old for part, old in zip(rebound[1:], source[1:], strict=True))
assert subset._EventControllerReplay__strict_rollouts is None
assert subset._EventControllerReplay__identification_token is not full._EventControllerReplay__identification_token
with pytest.raises(TypeError):
rebound[1][0] = 1.
coordinates = (subset.reference[0] + delta,)
expected, before, native_before = observed(independent, coordinates, shadow=shadow)
actual, after, native_after = observed(subset, coordinates, shadow=shadow)
assert pickle.dumps(actual, protocol=5) == pickle.dumps(expected, protocol=5)
assert len(before) == 60 and len(after) == 30 and after == before[30:]
assert native_after == native_before
@pytest.mark.parametrize('defect', ('missing', 'stale', 'mutable', 'bad_raw_type', 'bad_snapshot', 'nondefault_epsilon'))
def test_missing_stale_unknown_prefix_does_not_change_valid_fd_transfer(defect):
epsilon = .02 if defect == 'nondefault_epsilon' else .01
full, subset = full_and_subset(epsilon=epsilon)
source = full._EventControllerReplay__controller_prefix
if defect == 'missing':
full._EventControllerReplay__controller_prefix = None
elif defect == 'stale':
full._EventControllerReplay__controller_prefix = (b'not-current', *source[1:])
elif defect == 'mutable':
full._EventControllerReplay__controller_prefix = (source[0], dict(source[1]), *source[2:])
elif defect == 'bad_raw_type':
raw = dict(source[1])
raw[next(iter(raw))] = 0 # Must not alias raw Float64 output.
full._EventControllerReplay__controller_prefix = (source[0], MappingProxyType(raw), *source[2:])
elif defect == 'bad_snapshot':
snapshots = dict(source[3])
snapshots[next(iter(snapshots))] = object()
full._EventControllerReplay__controller_prefix = (*source[:3], MappingProxyType(snapshots))
assert subset.reuse_subset_causal_features(full, epsilon=epsilon) is True
assert subset._EventControllerReplay__controller_prefix is None
assert subset.projected and subset._EventControllerReplay__strict_rollouts is None
with mock.patch('openpilot.starpilot.flm.event_controller_replay._run', wraps=_run) as run:
subset._rollout((subset.reference[0] + .000000001,),
_identification_token=subset._EventControllerReplay__identification_token)
assert run.call_count == 60
@pytest.mark.parametrize('change', ('prior', 'foreign_engine', 'plan', 'late_fault', 'native'))
def test_existing_fd_guard_failure_never_transfers_controller_certificate(change):
full, subset = full_and_subset()
if change == 'prior':
subset.prior_full['ff_gain_right'] = .002
elif change == 'foreign_engine':
other, _ = full_and_subset()
subset.engine = other.engine
elif change == 'plan':
subset.activation_plan = replace(subset.activation_plan, physical_context='c' * 64)
elif change == 'late_fault':
full.records[-1] = replace(full.records[-1], healthy=False)
else:
stamp, event = next(iter(full.emissions.events.items()))
full.emissions.events[stamp] = replace(event, witness=event.witness._replace(final_raw=event.witness.final_raw + 1))
assert subset.reuse_subset_causal_features(full) is False
assert subset._EventControllerReplay__controller_prefix is None
assert subset._EventControllerReplay__strict_rollouts is None
def test_source_shadow_token_cannot_become_destination_permission():
full, subset = full_and_subset()
assert subset.reuse_subset_causal_features(full)
with pytest.raises(ValueError, match='identification scope'):
subset._rollout((.01,), _identification_token=full._EventControllerReplay__identification_token)