def parse_buffer(self, length): import random import pyvesc.packet.codec as vesc_packet correct_payload_index = None if length < 256: correct_payload_index = 2 else: correct_payload_index = 3 test_payload = bytes(random.getrandbits(8) for i in range(length)) packet = vesc_packet.frame(test_payload) # test on small buffers for n in range(0, 5): in_buffer = bytearray(packet[:n]) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, None) self.assertEqual(in_buffer, out_buffer) # test on buffer almost big enough for n in range(len(packet) - 4, len(packet)): in_buffer = bytearray(packet[:n]) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, None) self.assertEqual(in_buffer, out_buffer) # test on buffer slightly too big extension = b'\x02\x04\x07' extended_packet = packet + b'\x02\x04\x07' for n in range(len(packet) + 1, len(packet) + 4): in_buffer = bytearray(extended_packet[:n]) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, test_payload) self.assertEqual(out_buffer, extension[:n - len(packet)])
def test_corrupt_recovery(self): import pyvesc.packet.codec as vesc_packet # make a good packet test_payload = b'Te!' good_packet = b'\x02\x03Te!B\x92\x03' packet_to_recover = b'\x02\x04!\xe1$ 8\xbb\x03' # goal is to recover this packet payload_to_recover = b'!\xe1$ ' after_goal = b'\x05\x09\x01' # mimic another corrupt packet after corrupt_packets = [] # corrupt first byte corrupt = b'\x01\x03Te!B\x92\x03' corrupt_packets.append(corrupt + packet_to_recover + after_goal) # corrupt payload_length (to be smaller and larger) smaller_corrupt = b'\x02\x02Te!B\x92\x03' larger_corrupt = b'\x02\x04Te!B\x92\x03\x03' corrupt_packets.append(smaller_corrupt + packet_to_recover + after_goal) corrupt_packets.append(larger_corrupt + packet_to_recover + after_goal) # corrupt first byte in payload corrupt = b'\x02\x03se!B\x92\x03' corrupt_packets.append(corrupt + packet_to_recover + after_goal) # corrupt last byte in payload corrupt = b'\x02\x03TeyB\x92\x03' corrupt_packets.append(corrupt + packet_to_recover + after_goal) # corrupt crc corrupt = b'\x02\x03Te!\xaa\x91\x03' corrupt_packets.append(corrupt + packet_to_recover + after_goal) # corrupt terminator corrupt = b'\x02\x03Te!B\x92\x09' corrupt_packets.append(corrupt + packet_to_recover + after_goal) # check that exceptions are given on each corrupt packet for corrupt in corrupt_packets: in_buffer = bytearray(corrupt) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, payload_to_recover) found_packet_start = corrupt.find(packet_to_recover) self.assertTrue(consumed == (found_packet_start + len(packet_to_recover))) # check that the good packet is parsed in_buffer = bytearray(good_packet) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, test_payload) self.assertEqual(out_buffer, b'')
def test_corrupt_detection(self): import pyvesc.packet.codec as vesc_packet # make a good packet test_payload = b'Te!' good_packet = b'\x02\x03Te!B\x92\x03' corrupt_packets = [] # corrupt first byte corrupt = b'\x01\x03Te!B\x92\x03' corrupt_packets.append(corrupt) # corrupt payload_length (to be smaller and larger) smaller_corrupt = b'\x02\x02Te!B\x92\x03' larger_corrupt = b'\x02\x04Te!B\x92\x03\x03' corrupt_packets.append(smaller_corrupt) corrupt_packets.append(larger_corrupt) # corrupt first byte in payload corrupt = b'\x02\x03se!B\x92\x03' corrupt_packets.append(corrupt) # corrupt last byte in payload corrupt = b'\x02\x03TeyB\x92\x03' corrupt_packets.append(corrupt) # corrupt crc corrupt = b'\x02\x03Te!\xaa\x91\x03' corrupt_packets.append(corrupt) # corrupt terminator corrupt = b'\x02\x03Te!B\x92\x09' corrupt_packets.append(corrupt) # check that exceptions are given on each corrupt packet for corrupt in corrupt_packets: in_buffer = bytearray(corrupt) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, None) self.assertTrue( consumed > 0 ) # if a packet is corrupt then at least something should be consumed # get correct out_cuffer (in all of these cases it is just consuming to the next valid start byte (no more no less) self.assertEqual( consumed, vesc_packet.Stateless._next_possible_packet_index(in_buffer)) # check that the good packet is parsed in_buffer = bytearray(good_packet) parsed, consumed = vesc_packet.unframe(in_buffer) out_buffer = in_buffer[consumed:] self.assertEqual(parsed, test_payload) self.assertEqual(out_buffer, b'')
def exact_two_frames(self, length1, length2): """ Check that if there is more than one packet in a buffer, that the unpacker will properly unpack the packets. Size of buffer for this test is exactly two packets. :param length1: Length of first payload :param length2: Length of second payload """ import random import pyvesc.packet.codec as vesc_packet correct_payload_index1 = None correct_payload_index2 = None if length1 < 256: correct_payload_index1 = 2 else: correct_payload_index1 = 3 if length2 < 256: correct_payload_index2 = 2 else: correct_payload_index2 = 3 test_payload1 = bytes(random.getrandbits(8) for i in range(length1)) test_payload2 = bytes(random.getrandbits(8) for i in range(length2)) # test framing packet1 = vesc_packet.frame(test_payload1) packet2 = vesc_packet.frame(test_payload2) self.assertEqual(len(packet1), correct_payload_index1 + length1 + 3, "size of packet") self.assertEqual(len(packet2), correct_payload_index2 + length2 + 3, "size of packet") buffer = bytearray(packet1 + packet2) # test Parser parsed, consumed = vesc_packet.unframe(buffer) buffer = buffer[consumed:] self.assertEqual(parsed, test_payload1) self.assertEqual(len(buffer), len(packet2)) parsed, consumed = vesc_packet.unframe(buffer) buffer = buffer[consumed:] self.assertEqual(parsed, test_payload2) self.assertEqual(len(buffer), 0)
def exact_single_frame(self, length): """ Simplest test possible. Create a packet, then parse a buffer containing this packet. Size of buffer is exactly one packet (no excess). :param length: Number of bytes in payload. """ import random import pyvesc.packet.codec as vesc_packet correct_payload_index = None if length < 256: correct_payload_index = 2 else: correct_payload_index = 3 test_payload = bytes(random.getrandbits(8) for i in range(length)) # test framing packet = vesc_packet.frame(test_payload) self.assertEqual(len(packet), correct_payload_index + length + 3, "size of packet") buffer = bytearray(packet) # test Parser parsed, consumed = vesc_packet.unframe(buffer) buffer = buffer[consumed:] self.assertEqual(parsed, test_payload) self.assertEqual(len(buffer), 0)