Пример #1
0
    def test_full_stop(self):
        """Must be able to stop even if the consumer is not consuming
        anything."""
        thread_pool = spead2.ThreadPool(1)
        sender = send.BytesStream(thread_pool)
        ig = send.ItemGroup()
        data = np.array([[6, 7, 8], [10, 11, 12000]], dtype=np.uint16)
        ig.add_item(id=0x2345,
                    name='name',
                    description='description',
                    shape=data.shape,
                    dtype=data.dtype,
                    value=data)
        gen = send.HeapGenerator(ig)
        for i in range(10):
            sender.send_heap(gen.get_heap(data='all'))
        receiver = spead2.recv.Stream(thread_pool, ring_heaps=4)
        receiver.add_buffer_reader(sender.getvalue())
        # Wait for the ring buffer to block
        while receiver.stats.worker_blocked == 0:
            time.sleep(0.0)
        # Can't usefully check the stats here, because they're only
        # updated at the end of a batch.
        assert_equal(4, receiver.ringbuffer.capacity())
        assert_equal(4, receiver.ringbuffer.size())

        receiver.stop()  # This unblocks all remaining heaps
        stats = receiver.stats
        assert_equal(10, stats.heaps)
        assert_equal(10, stats.packets)
        assert_equal(0, stats.incomplete_heaps_evicted)
        assert_equal(0, stats.incomplete_heaps_flushed)
        assert_equal(1, stats.worker_blocked)
        assert_equal(4, receiver.ringbuffer.capacity())
        assert_equal(4, receiver.ringbuffer.size())
Пример #2
0
    def test_no_stop_heap(self):
        """A heap containing a stop is not passed to the ring"""
        thread_pool = spead2.ThreadPool(1)
        sender = send.BytesStream(thread_pool)
        ig = send.ItemGroup()
        data = np.array([[6, 7, 8], [10, 11, 12000]], dtype=np.uint16)
        ig.add_item(id=0x2345,
                    name='name',
                    description='description',
                    shape=data.shape,
                    dtype=data.dtype,
                    value=data)
        gen = send.HeapGenerator(ig)
        sender.send_heap(gen.get_heap(data='all'))
        sender.send_heap(gen.get_end())
        receiver = spead2.recv.Stream(thread_pool)
        receiver.add_buffer_reader(sender.getvalue())
        heaps = list(receiver)
        assert_equal(1, len(heaps))

        stats = receiver.stats
        assert_equal(1, stats.heaps)
        assert_equal(2, stats.packets)
        assert_equal(0, stats.incomplete_heaps_evicted)
        assert_equal(0, stats.incomplete_heaps_flushed)
        assert_equal(0, stats.worker_blocked)
Пример #3
0
    def test_send_heaps_unwind(self):
        """Second or later heap is invalid: must reset original state."""
        ig = send.ItemGroup(flavour=self.flavour)
        self.stream.send_heap(ig.get_start(), substream_index=0)
        with pytest.raises(OSError):
            self.stream.send_heaps([
                send.HeapReference(ig.get_start(), substream_index=0),
                send.HeapReference(ig.get_start(), substream_index=100)
            ], send.GroupMode.ROUND_ROBIN)
        self.stream.send_heap(ig.get_end(), substream_index=0)

        expected_cnts = [1, 2]
        expected_ctrl = [spead2.CTRL_STREAM_START, spead2.CTRL_STREAM_STOP]
        expected = b''
        for cnt, ctrl in zip(expected_cnts, expected_ctrl):
            expected = b''.join([
                expected,
                self.flavour.make_header(6),
                self.flavour.make_immediate(spead2.HEAP_CNT_ID, cnt),
                self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 1),
                self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
                self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 1),
                self.flavour.make_immediate(spead2.STREAM_CTRL_ID, ctrl),
                self.flavour.make_address(spead2.NULL_ID, 0),
                struct.pack('B', 0)
            ])
        assert hexlify(self.stream.getvalue()) == hexlify(expected)
Пример #4
0
    def test_send_explicit_cnt(self):
        """An explicit set heap ID must be respected, and not increment the
        implicit sequence.

        The implicit sequencing is also tested.
        """
        ig = send.ItemGroup(flavour=self.flavour)
        self.stream.send_heap(ig.get_start())
        self.stream.set_cnt_sequence(0x1111111111, 0x1234512345)
        self.stream.send_heap(ig.get_start())
        self.stream.send_heap(ig.get_start(), 0x9876543210ab)
        self.stream.send_heap(ig.get_start())
        expected_cnts = [1, 0x1111111111, 0x9876543210ab, 0x2345623456]
        expected = b''
        for cnt in expected_cnts:
            expected = b''.join([
                expected,
                self.flavour.make_header(6),
                self.flavour.make_immediate(spead2.HEAP_CNT_ID, cnt),
                self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 1),
                self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
                self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 1),
                self.flavour.make_immediate(spead2.STREAM_CTRL_ID,
                                            spead2.CTRL_STREAM_START),
                self.flavour.make_address(spead2.NULL_ID, 0),
                struct.pack('B', 0)
            ])
        assert_equal(hexlify(expected), hexlify(self.stream.getvalue()))
Пример #5
0
 def setup(self):
     # A slow stream, so that we can test overflowing the queue
     self.flavour = Flavour(4, 64, 48, 0)
     self.stream = send.BytesStream(
         spead2.ThreadPool(),
         send.StreamConfig(rate=1e6, max_heaps=2))
     # A large heap
     ig = send.ItemGroup(flavour=self.flavour)
     ig.add_item(0x1000, 'test', 'A large item', shape=(256 * 1024,), dtype=np.uint8)
     ig['test'].value = np.zeros((256 * 1024,), np.uint8)
     self.heap = ig.get_heap()
     self.threads = []
Пример #6
0
 def test_full_stop(self):
     """Must be able to stop even if the consumer is not consuming
     anything."""
     thread_pool = spead2.ThreadPool(1)
     sender = send.BytesStream(thread_pool)
     ig = send.ItemGroup()
     data = np.array([[6, 7, 8], [10, 11, 12000]], dtype=np.uint16)
     ig.add_item(id=0x2345,
                 name='name',
                 description='description',
                 shape=data.shape,
                 dtype=data.dtype,
                 value=data)
     gen = send.HeapGenerator(ig)
     for i in range(10):
         sender.send_heap(gen.get_heap(data='all'))
     receiver = spead2.recv.Stream(thread_pool)
     receiver.add_buffer_reader(sender.getvalue())
     receiver.stop()
Пример #7
0
 def test_stopped_queue(self):
     self.queue.stop()
     ig = send.ItemGroup()
     with pytest.raises(IOError):
         self.stream.send_heap(ig.get_end())
Пример #8
0
 def test_interleave(self):
     n = 3
     igs = [send.ItemGroup(flavour=self.flavour) for i in range(n)]
     for i in range(n):
         data = np.arange(i, i + i * 64 + 8).astype(np.uint8)
         igs[i].add_item(0x1000 + i,
                         'test',
                         'Test item',
                         shape=data.shape,
                         dtype=data.dtype,
                         value=data)
     self.stream = send.BytesStream(
         spead2.ThreadPool(),
         send.StreamConfig(max_heaps=n, max_packet_size=88))
     self.stream.send_heaps([
         send.HeapReference(ig.get_heap(descriptors='none', data='all'))
         for ig in igs
     ], send.GroupMode.ROUND_ROBIN)
     expected = b''.join([
         # Heap 0, packet 0 (only packet)
         self.flavour.make_header(5),
         self.flavour.make_immediate(spead2.HEAP_CNT_ID, 1),
         self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 8),
         self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
         self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 8),
         self.flavour.make_address(0x1000, 0),
         igs[0]['test'].value.tobytes(),
         # Heap 1, packet 0
         self.flavour.make_header(5),
         self.flavour.make_immediate(spead2.HEAP_CNT_ID, 2),
         self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 72),
         self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
         self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 40),
         self.flavour.make_address(0x1001, 0),
         igs[1]['test'].value.tobytes()[0:40],
         # Heap 2, packet 0
         self.flavour.make_header(5),
         self.flavour.make_immediate(spead2.HEAP_CNT_ID, 3),
         self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 136),
         self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
         self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 40),
         self.flavour.make_address(0x1002, 0),
         igs[2]['test'].value.tobytes()[0:40],
         # Heap 1, packet 1
         self.flavour.make_header(4),
         self.flavour.make_immediate(spead2.HEAP_CNT_ID, 2),
         self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 72),
         self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 40),
         self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 32),
         igs[1]['test'].value.tobytes()[40:72],
         # Heap 2, packet 1
         self.flavour.make_header(4),
         self.flavour.make_immediate(spead2.HEAP_CNT_ID, 3),
         self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 136),
         self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 40),
         self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 48),
         igs[2]['test'].value.tobytes()[40:88],
         # Heap 2, packet 2
         self.flavour.make_header(4),
         self.flavour.make_immediate(spead2.HEAP_CNT_ID, 3),
         self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 136),
         self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 88),
         self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 48),
         igs[2]['test'].value.tobytes()[88:136]
     ])
     assert hexlify(self.stream.getvalue()) == hexlify(expected)
Пример #9
0
 def test_invalid_cnt(self):
     """An explicit heap ID that overflows must raise an error."""
     ig = send.ItemGroup(flavour=self.flavour)
     with pytest.raises(IOError):
         self.stream.send_heap(ig.get_start(), 2**48)