From 69a91e22ce2b0a4729bf06cf79fa8f51330c3f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=98=89=E5=91=88?= Date: Wed, 20 May 2026 09:48:25 +0800 Subject: [PATCH 1/2] selfdrive: add tx safety fuzzy test over control-state transitions --- selfdrive/car/tests/test_models.py | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index a7f3d68c149788..ec3e6b3c9951af 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -294,6 +294,54 @@ def test_car_controller(car_control): CC = structs.CarControl(cruiseControl=structs.CarControl.CruiseControl(resume=True)) test_car_controller(CC.as_reader()) + @pytest.mark.nocapture + @settings(max_examples=max(50, MAX_EXAMPLES // 3), deadline=None, + phases=(Phase.reuse, Phase.generate, Phase.shrink)) + @given(data=st.data()) + def test_panda_safety_tx_fuzzy(self, data): + """Fuzz tx control-state transitions and assert all generated tx CAN passes safety hooks.""" + if self.CP.dashcamOnly: + self.skipTest("no need to check panda safety for dashcamOnly") + + if self.CP.notCar: + self.skipTest("Skipping test for notCar") + + CI = self.CarInterface(self.CP) + now_nanos = 0 + + steps = data.draw(st.integers(min_value=10, max_value=60)) + seen_msgs = 0 + for _ in range(steps): + controls_allowed = data.draw(st.booleans()) + cruise_engaged = data.draw(st.booleans()) + cancel = data.draw(st.booleans()) + resume = data.draw(st.booleans()) + + self.safety.set_controls_allowed(controls_allowed) + self.safety.set_cruise_engaged_prev(cruise_engaged) + + # Keep button states mutually exclusive to match typical real-world use. + if cancel: + resume = False + + CC = structs.CarControl( + enabled=controls_allowed, + latActive=data.draw(st.booleans()), + longActive=data.draw(st.booleans()), + cruiseControl=structs.CarControl.CruiseControl(cancel=cancel, resume=resume), + ) + + CI.update([]) + _, sendcan = CI.apply(CC.as_reader(), now_nanos) + now_nanos += DT_CTRL * 1e9 + + seen_msgs += len(sendcan) + for addr, dat, bus in sendcan: + to_send = libsafety_py.make_CANPacket(addr, bus % 4, dat) + self.assertTrue(self.safety.safety_tx_hook(to_send), (addr, dat, bus)) + + self.assertGreater(seen_msgs, 0) + # Skip stdout/stderr capture with pytest, causes elevated memory usage @pytest.mark.nocapture @settings(max_examples=MAX_EXAMPLES, deadline=None, From d8a7c9ce2ff5bdf14852a159d00a287163888e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=98=89=E5=91=88?= Date: Wed, 20 May 2026 21:07:54 +0800 Subject: [PATCH 2/2] ci: rerun checks