Example #1
0
 def test_replicate_pointers(self):
     """Tests sending a heap with replicate_pointers set to true"""
     id = 0x2345
     data = np.arange(32, dtype=np.uint8)
     item1 = spead2.Item(id=id, name='item1', description='addressed item',
                         shape=data.shape, dtype=data.dtype, value=data)
     item2 = spead2.Item(id=id + 1, name='item2', description='inline item',
                         shape=(), format=[('u', self.flavour.heap_address_bits)],
                         value=0xdeadbeef)
     expected = [
         b''.join([
             self.flavour.make_header(6),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 32),
             self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
             self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 16),
             self.flavour.make_address(id, 0),
             self.flavour.make_immediate(id + 1, 0xdeadbeef),
             data.tobytes()[0:16]
         ]),
         b''.join([
             self.flavour.make_header(6),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             self.flavour.make_immediate(spead2.HEAP_LENGTH_ID, 32),
             self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 16),
             self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID, 16),
             self.flavour.make_address(id, 0),
             self.flavour.make_immediate(id + 1, 0xdeadbeef),
             data.tobytes()[16:32]
         ])
     ]
     packets = self.flavour.items_to_bytes([item1, item2], [], max_packet_size=72,
                                           repeat_pointers=True)
     assert hexlify(packets) == hexlify(expected)
Example #2
0
 def test_nonascii_value(self):
     """Using a non-ASCII unicode character raises a
     :py:exc:`UnicodeEncodeError`."""
     item1 = spead2.Item(0x1000, 'name1', 'description',
                         (None,), format=[('c', 8)], value='\u0200')
     item2 = spead2.Item(0x1001, 'name2', 'description2', (),
                         dtype='S5', value='\u0201')
     with pytest.raises(UnicodeEncodeError):
         item1.to_buffer()
     with pytest.raises(UnicodeEncodeError):
         item2.to_buffer()
Example #3
0
 def test_small_variable(self):
     """Sending a small item with dynamic shape must not use an immediate."""
     id = 0x2345
     shape = (1, None)
     data = np.array([[4, 5]], dtype=np.uint8)
     payload = struct.pack('>2B', 4, 5)
     expected = [
         b''.join([
             self.flavour.make_header(5),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             self.flavour.make_immediate(spead2.HEAP_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
             self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_address(id, 0), payload
         ])
     ]
     item = spead2.Item(id=id,
                        name='name',
                        description='description',
                        shape=shape,
                        format=[('u', 8)])
     item.value = data
     packet = self.flavour.items_to_bytes([item], [])
     assert_equal(hexlify(expected), hexlify(packet))
Example #4
0
    def test_numpy_simple(self):
        """A single numpy-format item with descriptor"""
        id = 0x2345
        shape = (2, 3)
        data = np.array([[6, 7, 8], [10, 11, 12000]], dtype=np.uint16)
        payload_fields = [
            self.make_descriptor_numpy(id, 'name', 'description', shape, '<u2',
                                       False),
            struct.pack('<6H', 6, 7, 8, 10, 11, 12000)
        ]
        payload = b''.join(payload_fields)
        offsets = offset_generator(payload_fields)
        expected = [
            b''.join([
                self.flavour.make_header(6),
                self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
                self.flavour.make_immediate(spead2.HEAP_LENGTH_ID,
                                            len(payload)),
                self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
                self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID,
                                            len(payload)),
                self.flavour.make_address(spead2.DESCRIPTOR_ID, next(offsets)),
                self.flavour.make_address(id, next(offsets)), payload
            ])
        ]

        item = spead2.Item(id=id,
                           name='name',
                           description='description',
                           shape=shape,
                           dtype=np.uint16)
        item.value = data
        packet = self.flavour.items_to_bytes([item])
        assert_equal(hexlify(expected), hexlify(packet))
Example #5
0
 def test_numpy_noncontiguous(self):
     """A numpy item with a discontiguous item value is sent correctly"""
     id = 0x2345
     shape = (2, 3)
     store = np.array(
         [[6, 7, 8, 0, 1], [10, 11, 12000, 2, 3], [9, 9, 9, 9, 9]],
         dtype=np.uint16)
     data = store[:2, :3]
     payload = struct.pack('<6H', 6, 7, 8, 10, 11, 12000)
     expected = [
         b''.join([
             self.flavour.make_header(5),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             self.flavour.make_immediate(spead2.HEAP_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
             self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_address(id, 0), payload
         ])
     ]
     item = spead2.Item(id=id,
                        name='name',
                        description='description',
                        shape=shape,
                        dtype=np.uint16)
     item.value = data
     packet = self.flavour.items_to_bytes([item], [])
     assert_equal(hexlify(expected), hexlify(packet))
Example #6
0
 def test_numpy_fortran_order(self):
     """A numpy item with Fortran-order descriptor must be sent in Fortran order"""
     id = 0x2345
     shape = (2, 3)
     data = np.array([[6, 7, 8], [10, 11, 12000]], order='F')
     assert_false(data.flags.c_contiguous)
     payload_fields = [
         self.make_descriptor_numpy(id, 'name', 'description', shape, '<u2',
                                    True),
         struct.pack('<6H', 6, 10, 7, 11, 8, 12000)
     ]
     payload = b''.join(payload_fields)
     offsets = offset_generator(payload_fields)
     expected = [
         b''.join([
             self.flavour.make_header(6),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             self.flavour.make_immediate(spead2.HEAP_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
             self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_address(spead2.DESCRIPTOR_ID, next(offsets)),
             self.flavour.make_address(id, next(offsets)), payload
         ])
     ]
     item = spead2.Item(id=id,
                        name='name',
                        description='description',
                        shape=shape,
                        dtype=np.uint16,
                        order='F')
     item.value = data
     packet = self.flavour.items_to_bytes([item])
     assert_equal(hexlify(expected), hexlify(packet))
Example #7
0
 def test_small_fixed(self):
     """Sending a small item with fixed shape must use an immediate."""
     id = 0x2345
     data = 0x7654
     payload = struct.pack('>I', data)
     expected = [
         b''.join([
             self.flavour.make_header(6),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             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(id, data),
             self.flavour.make_address(spead2.NULL_ID, 0),
             struct.pack('B', 0)
         ])
     ]
     item = spead2.Item(id=id,
                        name='name',
                        description='description',
                        shape=(),
                        format=[('u', 16)])
     item.value = data
     packet = self.flavour.items_to_bytes([item], [])
     assert_equal(hexlify(expected), hexlify(packet))
Example #8
0
 def test_fallback_types(self):
     """Send an array with mixed types and strange packing"""
     id = 0x2345
     format = [('b', 1), ('i', 7), ('c', 8), ('f', 32)]
     shape = (2, )
     data = [(True, 17, 'y', 1.0), (False, -23.0, 'n', -1.0)]
     payload_fields = [
         self.make_descriptor_fallback(id, 'name', 'description', shape,
                                       format),
         b'\x91y\x3F\x80\x00\x00' + b'\x69n\xBF\x80\x00\x00'
     ]
     payload = b''.join(payload_fields)
     offsets = offset_generator(payload_fields)
     expected = [
         b''.join([
             self.flavour.make_header(6),
             self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
             self.flavour.make_immediate(spead2.HEAP_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_immediate(spead2.PAYLOAD_OFFSET_ID, 0),
             self.flavour.make_immediate(spead2.PAYLOAD_LENGTH_ID,
                                         len(payload)),
             self.flavour.make_address(spead2.DESCRIPTOR_ID, next(offsets)),
             self.flavour.make_address(id, next(offsets)), payload
         ])
     ]
     item = spead2.Item(id=id,
                        name='name',
                        description='description',
                        shape=shape,
                        format=format)
     item.value = data
     packet = self.flavour.items_to_bytes([item])
     assert_equal(hexlify(expected), hexlify(packet))
Example #9
0
 def test_numpy_zero_length(self):
     """A zero-length numpy type raises :exc:`ValueError`"""
     with pytest.raises(ValueError):
         spead2.Item(id=0x2345,
                     name='name',
                     description='description',
                     shape=(),
                     dtype=np.str_)
Example #10
0
 def test_fallback_zero_length(self):
     """A zero-length type raises :exc:`ValueError`"""
     with pytest.raises(ValueError):
         spead2.Item(id=0x2345,
                     name='name',
                     description='description',
                     shape=(),
                     format=[('u', 0)])
Example #11
0
    def test_zero_copy(self):
        """Test that heaps can reference original data.

        This allows heaps to be updated by just changing the data.
        """
        id = 0x2345
        data = np.arange(8, dtype=np.uint8)
        imm = np.zeros((), dtype='>u8')
        item1 = spead2.Item(id=id, name='item1', description='addressed item',
                            shape=data.shape, dtype=data.dtype, value=data)
        item2 = spead2.Item(id=id + 1, name='item2', description='inline item',
                            shape=(), format=[('u', self.flavour.heap_address_bits)],
                            value=imm)
        heap = spead2.send.Heap(self.flavour)
        heap.add_item(item1)
        heap.add_item(item2)
        # Now change the values after they've been added to the heap.
        data *= 2
        imm[()] = 0xdeadbeef

        expected = [
            b''.join([
                self.flavour.make_header(6),
                self.flavour.make_immediate(spead2.HEAP_CNT_ID, 0x123456),
                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(id, 0),
                self.flavour.make_immediate(id + 1, 0xdeadbeef),
                data.tobytes()
            ])
        ]

        gen = send.PacketGenerator(heap, 0x123456, 1500)
        packets = list(gen)
        assert hexlify(packets) == hexlify(expected)
Example #12
0
 def test_lifetime(self):
     """Heap must hold references to item values"""
     item = spead2.Item(id=0x2345, name='name', description='description',
                        shape=(2, 3), dtype=np.uint16)
     item.value = np.array([[6, 7, 8], [10, 11, 12000]], dtype=np.uint16)
     weak = weakref.ref(item.value)
     heap = send.Heap(self.flavour)
     heap.add_item(item)
     del item
     packets = list(send.PacketGenerator(heap, 0x123456, 1472))   # noqa: F841
     assert weak() is not None
     del heap
     # pypy needs multiple gc passes to wind it all up
     for i in range(10):
         gc.collect()
     assert weak() is None
Example #13
0
 def test_lifetime(self):
     """Heap must hold references to item values"""
     item = spead2.Item(id=0x2345,
                        name='name',
                        description='description',
                        shape=(2, 3),
                        dtype=np.uint16)
     item.value = np.array([[6, 7, 8], [10, 11, 12000]], dtype=np.uint16)
     weak = weakref.ref(item.value)
     heap = send.Heap(self.flavour)
     heap.add_item(item)
     del item
     packets = list(send.PacketGenerator(heap, 0x123456, 1472))
     assert_is_not_none(weak())
     del heap
     assert_is_none(weak())
Example #14
0
 def test_fortran_fallback(self):
     """The `order` parameter must be 'C' for legacy formats."""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description', (1, 2), format=[('u', 32)], order='F')
Example #15
0
 def test_assign_none(self):
     """Changing a value back to `None` raises :py:exc:`ValueError`."""
     item = spead2.Item(0x1000, 'name', 'description', (), np.int32)
     with pytest.raises(ValueError):
         item.value = None
Example #16
0
 def test_empty_format(self):
     """Format must not be empty"""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description', (1, 2), format=[])
Example #17
0
 def test_multiple_unknown(self):
     """Multiple unknown dimensions are not allowed."""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description', (5, None, 3, None), format=[('u', 32)])
Example #18
0
 def test_numpy_unknown(self):
     """Unknown dimensions are not permitted when using a numpy descriptor"""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description', (5, None), np.int32)
Example #19
0
 def test_nonascii_description(self):
     """Description with non-ASCII characters must fail"""
     with pytest.raises(UnicodeEncodeError):
         item = spead2.Item(0x1000, 'name', '\u0200', (), np.int32)
         item.to_raw(spead2.Flavour())
Example #20
0
 def test_invalid_order(self):
     """The `order` parameter must be either 'C' or 'F'."""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description', (1, 2), np.int32, order='K')
Example #21
0
 def test_nonascii_name(self):
     """Name with non-ASCII characters must fail"""
     with assert_raises(UnicodeEncodeError):
         item = spead2.Item(0x1000, '\u0200', 'description', (), np.int32)
         item.to_raw(spead2.Flavour())
Example #22
0
 def test_format_and_dtype(self):
     """Specifying both a format and dtype raises :py:exc:`ValueError`."""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description',
                     (1, 2), format=[('c', 8)], dtype='S1')
Example #23
0
 def test_no_format_or_dtype(self):
     """At least one of format and dtype must be specified."""
     with pytest.raises(ValueError):
         spead2.Item(0x1000, 'name', 'description', (1, 2), format=None)