"""Framing, with no sockets involved. These are the cases that cost real debugging time on the live aircraft: a datagram carrying several frames, a size field that would never advance the cursor, and the command id being two bytes rather than one. """ import struct import pytest from mcbebop.arsdk.types import COMMAND_HEADER, FRAME_HEADER, BufferId, DataType, Frame def test_header_is_seven_bytes(): # Everything about the size field depends on this, including the sim. assert FRAME_HEADER.size == 7 assert COMMAND_HEADER.size == 4 def test_encode_declares_size_including_header(): frame = Frame(DataType.DATA, BufferId.C2D_NON_ACK, 3, b"abcd") raw = frame.encode() data_type, buffer_id, seq, size = FRAME_HEADER.unpack_from(raw) assert (data_type, buffer_id, seq) == (2, 10, 3) assert size == len(raw) == 11 def test_round_trip(): frame = Frame(DataType.DATA_WITH_ACK, BufferId.C2D_ACK, 255, bytes(range(16))) assert Frame.decode_all(frame.encode()) == [frame] def test_empty_payload_round_trips(): frame = Frame(DataType.ACK, 139, 0, b"") assert Frame.decode_all(frame.encode()) == [frame] def test_several_frames_in_one_datagram(): frames = [ Frame(DataType.DATA, BufferId.D2C_NON_ACK, 1, b"\x01\x02"), Frame(DataType.DATA_WITH_ACK, BufferId.D2C_ACK, 2, b"xyz"), Frame(DataType.DATA, BufferId.PING, 3, struct.pack("