def test_bad_interface_address(self): config = send.StreamConfig() udp_ibv_config = send.UdpIbvConfig( endpoints=[('239.255.88.88', 8888)], interface_address='this is not an interface address') with pytest.raises(RuntimeError, match='Host not found'): send.UdpIbvStream(spead2.ThreadPool(), config, udp_ibv_config)
def test_ipv6_interface_address(self): config = send.StreamConfig() udp_ibv_config = send.UdpIbvConfig( endpoints=[('239.255.88.88', 8888)], interface_address='::1') with pytest.raises(ValueError, match='interface address'): send.UdpIbvStream(spead2.ThreadPool(), config, udp_ibv_config)
def test_unicast_endpoints(self): config = send.StreamConfig() udp_ibv_config = send.UdpIbvConfig(endpoints=[('10.0.0.1', 8888)], interface_address='10.0.0.1') with pytest.raises(ValueError, match='endpoint is not an IPv4 multicast address'): send.UdpIbvStream(spead2.ThreadPool(), config, udp_ibv_config)
def test_shared_ringbuffer(self, send_stream, recv_stream, item_group): recv_stream2 = spead2.recv.ChunkRingStream( spead2.ThreadPool(), spead2.recv.StreamConfig(stream_id=1), spead2.recv.ChunkStreamConfig( items=[0x1000, spead2.HEAP_LENGTH_ID], max_chunks=4, place=place_plain_llc), recv_stream.data_ringbuffer, recv_stream.free_ringbuffer) queue2 = spead2.InprocQueue() recv_stream2.add_inproc_reader(queue2) send_stream2 = send.InprocStream(spead2.ThreadPool(), [queue2], send.StreamConfig()) n_heaps = [17, 23] self.send_heaps(send_stream, item_group, range(n_heaps[0])) self.send_heaps(send_stream2, item_group, range(n_heaps[1])) seen = [0, 0] for chunk in recv_stream.data_ringbuffer: assert 0 <= chunk.stream_id < 2 expected_present = np.ones(HEAPS_PER_CHUNK, np.uint8) if chunk.chunk_id == n_heaps[chunk.stream_id] // HEAPS_PER_CHUNK: # It's the last chunk for the stream expected_present[n_heaps[chunk.stream_id] % HEAPS_PER_CHUNK:] = 0 self.check_chunk(chunk, seen[chunk.stream_id], expected_present) seen[chunk.stream_id] += 1 recv_stream.add_free_chunk(chunk) assert seen[0] == n_heaps[0] // HEAPS_PER_CHUNK + 1 assert seen[1] == n_heaps[1] // HEAPS_PER_CHUNK + 1
def test_default_construct(self): config = send.StreamConfig() assert config.max_packet_size == config.DEFAULT_MAX_PACKET_SIZE assert config.rate == 0.0 assert config.burst_size == config.DEFAULT_BURST_SIZE assert config.max_heaps == config.DEFAULT_MAX_HEAPS assert config.burst_rate_ratio == config.DEFAULT_BURST_RATE_RATIO assert config.rate_method == config.DEFAULT_RATE_METHOD
def test_empty_memory_region(self): data = bytearray(0) config = send.StreamConfig() udp_ibv_config = send.UdpIbvConfig(endpoints=[('239.255.88.88', 8888)], interface_address='10.0.0.1', memory_regions=[data]) with pytest.raises(ValueError, match='memory region must have non-zero size'): send.UdpIbvStream(spead2.ThreadPool(), config, udp_ibv_config)
def test_send_error(self): """An error in sending must be reported.""" # Create a stream with a packet size that is bigger than the likely # MTU. It should cause an error. stream = send.UdpStream(spead2.ThreadPool(), [("localhost", 8888)], send.StreamConfig(max_packet_size=100000), buffer_size=0) with pytest.raises(IOError): stream.send_heap(self.heap)
def test_overlapping_memory_regions(self): data = memoryview(bytearray(10)) part1 = data[:6] part2 = data[5:] config = send.StreamConfig() udp_ibv_config = send.UdpIbvConfig(endpoints=[('239.255.88.88', 8888)], interface_address='10.0.0.1', memory_regions=[part1, part2]) with pytest.raises(ValueError, match='memory regions overlap'): send.UdpIbvStream(spead2.ThreadPool(), config, udp_ibv_config)
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 = []
def test_setters(self): config = send.StreamConfig() config.max_packet_size = 1234 config.rate = 1e9 config.burst_size = 12345 config.max_heaps = 5 config.burst_rate_ratio = 1.5 config.rate_method = send.RateMethod.SW assert config.max_packet_size == 1234 assert config.rate == 1e9 assert config.burst_size == 12345 assert config.max_heaps == 5 assert config.burst_rate_ratio == 1.5 assert config.rate_method == send.RateMethod.SW assert config.burst_rate == 1.5e9
def test_no_endpoints(self): config = send.StreamConfig() udp_ibv_config = send.UdpIbvConfig(interface_address='10.0.0.1') with pytest.raises(ValueError, match='endpoints is empty'): send.UdpIbvStream(spead2.ThreadPool(), config, udp_ibv_config)
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)
def test_bad_max_heaps(self): with pytest.raises(TypeError): send.StreamConfig(max_heaps=-1) with pytest.raises(ValueError): send.StreamConfig(max_heaps=0)
def test_bad_rate(self): with pytest.raises(ValueError): send.StreamConfig(rate=-1.0) with pytest.raises(ValueError): send.StreamConfig(rate=math.nan)
def test_construct_kwargs(self): config = send.StreamConfig(max_packet_size=1234, max_heaps=5) assert config.max_packet_size == 1234 assert config.max_heaps == 5 assert config.rate == 0.0
def send_stream(self, queue): return send.InprocStream(spead2.ThreadPool(), [queue], send.StreamConfig())