コード例 #1
0
    def test_maxlen(self):
        desired_queue_size = 3
        data = [0, 1, 2, 3]
        queue1 = CircularQueue(desired_queue_size)
        queue2 = CircularQueue.from_iterable(data)

        assert queue1.maxlen == desired_queue_size
        assert queue2.maxlen == len(data)
コード例 #2
0
    def test_append(self):
        desired_queue_size = 3
        queue = CircularQueue(desired_queue_size)

        for i in range(desired_queue_size):
            assert queue.append(i)
            assert queue[-1] == i

        assert not queue.append(4)
コード例 #3
0
    def test_extend(self):
        desired_queue_size = 3
        data = [0, 1, 2]
        queue = CircularQueue(desired_queue_size)

        queue.extend(data)

        assert queue.extend([1, 2]) == 0

        assert len(queue) == len(data)
        assert queue[::] == data
コード例 #4
0
    def test_copy(self):
        data = [0, 1, 2, 3]
        queue = CircularQueue.from_iterable(data)

        queue_copy = queue.copy()

        assert queue[::] == queue_copy[::]
コード例 #5
0
    def test_init_from_iterable(self):
        iterable = [1, 2, 3, 4, 5]
        queue = CircularQueue.from_iterable(iterable)

        assert len(queue) == len(iterable)
        assert queue[::] == iterable
        assert isinstance(queue, CircularQueue)
コード例 #6
0
    def test_no_crc(self):
        data = [1, 2, 3, 4, 5]
        cq = CircularQueue.from_iterable(data)

        state = SerialCrcState(cq)
        state.parse()

        assert not state.is_succesful
コード例 #7
0
    def test_no_packet(self):
        data = [1, 2, 3, 4, 5]
        cq = CircularQueue.from_iterable(data)

        state = SerialStartState(cq)

        state.parse()

        assert state.find_next_state() == state
コード例 #8
0
    def test__iter__(self):
        data = [1, 2, 3, 4, 5]
        queue = CircularQueue(5)
        for x in queue:
            # nothing is in queue, should not be reached
            assert 0

        queue.extend(data)
        for ind, x in enumerate(queue):
            assert x == data[ind]

        # test for circularity
        poped_item = queue.popleft()
        queue.append(poped_item)
        poped_item = queue.popleft()
        queue.append(poped_item)
        new_data = [3, 4, 5, 1, 2]

        for ind, x in enumerate(queue):
            assert x == new_data[ind]
コード例 #9
0
    def test__len__(self):
        desired_queue_size = 3
        queue = CircularQueue(desired_queue_size)
        assert len(queue) == 0

        for i in range(3):
            queue.append(i)
            assert len(queue) == i + 1

        queue.append(4)
        assert len(queue) == desired_queue_size

        for i in range(3, 0, -1):
            queue.pop()
            assert len(queue) == i - 1
コード例 #10
0
    def test_popleft(self):
        desired_queue_size = 3
        queue = CircularQueue(desired_queue_size)

        assert queue.popleft() is None

        for i in range(desired_queue_size):
            queue.append(i)

        for i in range(desired_queue_size):
            assert queue.popleft() == i

        assert queue.popleft() is None
コード例 #11
0
    def test__getitem__list(self):
        data = [0, 1, 2, 3]
        queue = CircularQueue.from_iterable(data)
        with pytest.raises(TypeError):
            _ = queue[1.1::]
        with pytest.raises(TypeError):
            _ = queue[:1.1:]
        with pytest.raises(TypeError):
            _ = queue[::1.1]

        for i in range(4):
            assert queue[:i] == data[:i]

        assert queue[2:-1] == data[2:-1]
        assert queue[2:] == data[2:]
        assert queue[::-1] == data[::-1]
コード例 #12
0
    def test_overflow_packet(self):
        packet = []
        for i in range(256):
            packet.append(i)

        packet[1] = 256

        cq = CircularQueue.from_iterable(packet)
        state = SerialLenState(cq)

        with pytest.raises(PacketStateError) as err:
            state.parse()

        err_str = err.value.message
        assert (
            err_str ==
            "PACKET STATE ERROR: Packet overflow, message is bigger than 256 bytes\n"
        )
コード例 #13
0
    def test_is_full(self):
        desired_queue_size = 3
        queue = CircularQueue(desired_queue_size)

        for i in range(desired_queue_size):
            assert not queue.is_full
            queue.append(i)

        assert queue.is_full

        for i in range(desired_queue_size):
            queue.pop()
            assert not queue.is_full
コード例 #14
0
    def test_is_empty(self):
        desired_queue_size = 3
        queue = CircularQueue(desired_queue_size)

        assert queue.is_empty

        for i in range(desired_queue_size):
            queue.append(i)
            assert not queue.is_empty

        for i in range(desired_queue_size):
            queue.pop()

        assert queue.is_empty
コード例 #15
0
    def test__getitem__single(self):
        data = [0, 1, 2, 3]
        queue = CircularQueue.from_iterable(data)

        with pytest.raises(IndexError):
            _ = queue[4]
        with pytest.raises(IndexError):
            _ = queue[-5]

        for i in range(4):
            assert queue[i] == data[i]

        # test for circularity
        queue.popleft()
        queue.append(11)
        queue.popleft()
        queue.append(12)
        new_data = [2, 3, 11, 12]

        for i in range(4):
            assert queue[i] == new_data[i]
コード例 #16
0
    def test_clear(self):
        data = [0, 1, 2, 3]
        queue = CircularQueue.from_iterable(data)

        queue.clear()
        assert len(queue) == 0
    def __init__(self):
        """ Create an empty SerialPacketQueue of constant size 512
        """

        self._byte_queue = CircularQueue(maxlen=self._MAX_BYTE_QUEUE_SIZE)
        self._has_a_packet = 0
コード例 #18
0
    def test_init(self):
        desired_queue_size = 5
        queue = CircularQueue(desired_queue_size)

        assert queue.maxlen == desired_queue_size
コード例 #19
0
    def test__str__(self):
        data = [1, 2, 3]
        queue = CircularQueue.from_iterable(data)

        assert data.__str__() == queue.__str__()
class SerialPacketQueue(PacketQueue):
    """ SerialPacketQueue enables extraction of well formed, crc-verified packets from its circular byte queue

    It is a specialized circular queue which takes in raw bytes and returns the packet's message.
    The packet's message is a byte array consisting of a type byte followed by payload bytes.

    General Packet Format:
        | 0x55 | length | type | ---payload--- | crcL | crcH |
        'length' is the (uint8) number of bytes in 'data'
        'type' is the (uint8) message type
        'payload' is a series of (uint8) bytes, serialized Little-Endian
        'crc' is the (uint16) CRC value for 'length'+'type'+'data', Little-Endian
    """

    # Don't forget to change the __init__ descriptiton
    _MAX_BYTE_QUEUE_SIZE = (255 + 5) * 2  # size of max packet * 2

    def __init__(self):
        """ Create an empty SerialPacketQueue of constant size 512
        """

        self._byte_queue = CircularQueue(maxlen=self._MAX_BYTE_QUEUE_SIZE)
        self._has_a_packet = 0

    def __len__(self):
        return len(self._byte_queue)

    @property
    def is_empty(self):
        """ Check if queue is empty

        Returns:
            true: if the queue is empty
            false: if the queue has some bytes in it
        """
        return self._byte_queue.is_empty

    @property
    def free_space(self):
        current_size = len(self._byte_queue)
        return self._byte_queue.maxlen - current_size

    def put_bytes(self, new_bytes):
        """ Append bytes to the queue

        Args:
            new_bytes: bytes you want to append.

        Returns:
            true: if succesful

        Raise:
            PacketQueueError("Byte Queue Overflow")
        """
        try:
            iter(new_bytes)
        except TypeError:
            # not iterable
            if not self._byte_queue.append(new_bytes):
                raise PacketQueueError("Byte Queue Overflow")
        else:
            # iterable
            if not self._byte_queue.extend(new_bytes):
                raise PacketQueueError("Byte Queue Overflow")

        return 1

    def peek(self):
        """ Peeks for the first available packet in the queue and extract its message

        Returns:
            bytearray: The first available message
            None: There was no well form packet in the queue

        Raise:
        When the queue is empty
            PacketQueueError("Serial packet queue is empty")
        """
        if self._byte_queue.is_empty:
            raise PacketQueueError("Serial packet queue is empty")

        return self._parse_bytes()

    def _parse_bytes(self):
        packet_state = SerialStartState(self._byte_queue)

        packet_parser = PacketParser(packet_state)
        packet_parser.parse()

        if not packet_parser.succesful:
            self._has_a_packet = 0
            return None

        self._has_a_packet = 1
        return packet_parser.message

    def clear(self):
        """ Clears the queue """
        self._byte_queue.clear()

    def drop_packet(self):
        """ Drops the first packet available in the queue

        Returns:
            True: a packet was droped
            False: no packet was droped
        """
        # no need to parse if you know there is a packet
        if self._has_a_packet:
            self._pop_packet_bytes()
            self._has_a_packet = 0
            return True

        self._parse_bytes()
        if self._has_a_packet:
            self._pop_packet_bytes()
            self._has_a_packet = 0
            return True

        return False

    def _pop_packet_bytes(self):
        msg_len = self._byte_queue[1]

        # + start byte, len, type, crch, crcl
        packet_len = msg_len + 5

        for _ in range(packet_len):
            self._byte_queue.popleft()
コード例 #21
0
def circular_queue_with_packet(request):
    packet = make_fake_packet(request.param)
    cq = CircularQueue.from_iterable(packet)

    return [cq, packet]