diff --git a/tests/test_arsdk_session.py b/tests/test_arsdk_session.py index a7c814f..1e0ef6e 100644 --- a/tests/test_arsdk_session.py +++ b/tests/test_arsdk_session.py @@ -397,3 +397,40 @@ def test_an_explicit_address_is_trusted_without_probing(): assert found is not None assert (found.ip, found.via) == ("10.1.2.3", "given") assert found.address == ("10.1.2.3", 44444) + + +# -- an event we cannot name --------------------------------------------- +async def test_an_undecodable_event_is_counted_not_fatal(sim): + """`decode_event` raises on an id triple the XML does not have. + + The XML is demonstrably incomplete, so this happens on a real aircraft. + One such event must not take the receive thread, and therefore the link, + down with it. + """ + battery = _SPECS["common.CommonState.BatteryStateChanged"].ids + + def decoder(payload): + ids = COMMAND_HEADER.unpack_from(payload) + if ids == battery: + raise ValueError(f"no command with ids {ids}") + return fake_decode(payload) + + drone = DroneSession( + "127.0.0.1", + discovery_port=sim.discovery_port, + d2c_port=0, + timeouts=quick_timeouts(), + encoder=fake_encode, + decoder=decoder, + ) + await drone.connect() + try: + assert await until(drone, "AttitudeChanged_roll") is not None + stats = drone.link_stats() + assert stats["undecodable_events"] > 0 + assert "BatteryStateChanged_percent" not in drone.values() + # The rest of the stream kept arriving, and commands still work. + result = await drone.send(VIDEO_ENABLE, {"enable": 1}, confirm=False) + assert result["acked"] is True + finally: + await drone.disconnect()