move some car interface tests into opendbc (#33352)

* bump

* this is in opendbc

* so is radar interface

* clean up

* bump

* can import from opendbc

* bump
pull/33355/head
Shane Smiskol 8 months ago committed by GitHub
parent d8c9822421
commit 7af3c6dfee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      opendbc_repo
  2. 74
      selfdrive/car/tests/test_car_interfaces.py

@ -1 +1 @@
Subproject commit 3229aa2e9c5dfefe6acb827e829fd3f43215bdf1 Subproject commit 06c51c1db49c3b4ffb9144ba010b84ce186d5c5b

@ -2,24 +2,22 @@ import os
import math import math
import hypothesis.strategies as st import hypothesis.strategies as st
from hypothesis import Phase, given, settings from hypothesis import Phase, given, settings
import importlib
from parameterized import parameterized from parameterized import parameterized
from cereal import car, messaging from cereal import car
from opendbc.car import DT_CTRL, gen_empty_fingerprint from opendbc.car import DT_CTRL
from opendbc.car.car_helpers import interfaces from opendbc.car.car_helpers import interfaces
from opendbc.car.structs import CarParams from opendbc.car.structs import CarParams
from opendbc.car.tests.test_car_interfaces import get_fuzzy_car_interface_args
from opendbc.car.fingerprints import all_known_cars from opendbc.car.fingerprints import all_known_cars
from opendbc.car.fw_versions import FW_VERSIONS, FW_QUERY_CONFIGS from opendbc.car.fw_versions import FW_VERSIONS, FW_QUERY_CONFIGS
from opendbc.car.interfaces import get_interface_attr
from opendbc.car.mock.values import CAR as MOCK from opendbc.car.mock.values import CAR as MOCK
from openpilot.selfdrive.car.card import convert_carControl, convert_to_capnp from openpilot.selfdrive.car.card import convert_carControl, convert_to_capnp
from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
from openpilot.selfdrive.controls.lib.longcontrol import LongControl from openpilot.selfdrive.controls.lib.longcontrol import LongControl
from openpilot.selfdrive.pandad import can_capnp_to_list from openpilot.selfdrive.test.fuzzy_generation import FuzzyGenerator
from openpilot.selfdrive.test.fuzzy_generation import DrawType, FuzzyGenerator
ALL_ECUS = {ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()} ALL_ECUS = {ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()}
ALL_ECUS |= {ecu for config in FW_QUERY_CONFIGS.values() for ecu in config.extra_ecus} ALL_ECUS |= {ecu for config in FW_QUERY_CONFIGS.values() for ecu in config.extra_ecus}
@ -29,28 +27,6 @@ ALL_REQUESTS = {tuple(r.request) for config in FW_QUERY_CONFIGS.values() for r i
MAX_EXAMPLES = int(os.environ.get('MAX_EXAMPLES', '60')) MAX_EXAMPLES = int(os.environ.get('MAX_EXAMPLES', '60'))
def get_fuzzy_car_interface_args(draw: DrawType) -> dict:
# Fuzzy CAN fingerprints and FW versions to test more states of the CarInterface
fingerprint_strategy = st.fixed_dictionaries({key: st.dictionaries(st.integers(min_value=0, max_value=0x800),
st.integers(min_value=0, max_value=64)) for key in
gen_empty_fingerprint()})
# only pick from possible ecus to reduce search space
car_fw_strategy = st.lists(st.sampled_from(sorted(ALL_ECUS)))
params_strategy = st.fixed_dictionaries({
'fingerprints': fingerprint_strategy,
'car_fw': car_fw_strategy,
'experimental_long': st.booleans(),
})
params: dict = draw(params_strategy)
params['car_fw'] = [CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0,
request=draw(st.sampled_from(sorted(ALL_REQUESTS))))
for fw in params['car_fw']]
return params
class TestCarInterfaces: class TestCarInterfaces:
# FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause # FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause
# many generated examples to overrun when max_examples > ~20, don't use it # many generated examples to overrun when max_examples > ~20, don't use it
@ -121,45 +97,3 @@ class TestCarInterfaces:
LatControlPID(car_params_capnp, car_interface) LatControlPID(car_params_capnp, car_interface)
elif car_params.lateralTuning.which() == 'torque': elif car_params.lateralTuning.which() == 'torque':
LatControlTorque(car_params_capnp, car_interface) LatControlTorque(car_params_capnp, car_interface)
# Test radar interface
RadarInterface = importlib.import_module(f'opendbc.car.{car_params.carName}.radar_interface').RadarInterface
radar_interface = RadarInterface(car_params)
assert radar_interface
# Run radar interface once
radar_interface.update([])
if not car_params.radarUnavailable and radar_interface.rcp is not None and \
hasattr(radar_interface, '_update') and hasattr(radar_interface, 'trigger_msg'):
radar_interface._update([radar_interface.trigger_msg])
# Test radar fault
if not car_params.radarUnavailable and radar_interface.rcp is not None:
cans = can_capnp_to_list([messaging.new_message('can', 1).to_bytes() for _ in range(5)])
rr = radar_interface.update(cans)
assert rr is None or len(rr.errors) > 0
def test_interface_attrs(self):
"""Asserts basic behavior of interface attribute getter"""
num_brands = len(get_interface_attr('CAR'))
assert num_brands >= 12
# Should return value for all brands when not combining, even if attribute doesn't exist
ret = get_interface_attr('FAKE_ATTR')
assert len(ret) == num_brands
# Make sure we can combine dicts
ret = get_interface_attr('DBC', combine_brands=True)
assert len(ret) >= 160
# We don't support combining non-dicts
ret = get_interface_attr('CAR', combine_brands=True)
assert len(ret) == 0
# If brand has None value, it shouldn't return when ignore_none=True is specified
none_brands = {b for b, v in get_interface_attr('FINGERPRINTS').items() if v is None}
assert len(none_brands) >= 1
ret = get_interface_attr('FINGERPRINTS', ignore_none=True)
none_brands_in_ret = none_brands.intersection(ret)
assert len(none_brands_in_ret) == 0, f'Brands with None values in ignore_none=True result: {none_brands_in_ret}'

Loading…
Cancel
Save