def test_sub_type(self): schema = self.loader.struct_schemas['unittest.test_2:TestSubType'] converter = objects.DataclassConverter(schema, TestSubType) dataobject = TestSubType( int_sub_type=IntSubType(1), int_sub_type_union=TestSubType.IntSubTypeUnion( int_sub_type=IntSubType(2), irrelevant=None, ), ) def do_test(reader): actual = converter.from_reader(reader) self.assertEqual(actual, dataobject) self.assertIs(type(actual.int_sub_type), IntSubType) self.assertEqual(actual.int_sub_type, 1) self.assertIs(type(actual.int_sub_type_union.int_sub_type), IntSubType) self.assertEqual(actual.int_sub_type_union.int_sub_type, 2) self.assertIsNone(actual.int_sub_type_union.irrelevant) message = capnp.MessageBuilder() builder = message.init_root(schema) converter.to_builder(dataobject, builder) do_test(builder.as_reader()) mr = capnp.MessageReader.from_message_bytes(message.to_message_bytes()) do_test(mr.get_root(schema))
def test_pointer_struct(self): name = 'unittest.test_2:TestPointerStruct' schema = self.loader.struct_schemas[name] converter = objects.DataclassConverter(schema, TestPointerStruct) dataobject = TestPointerStruct( group_field=None, tuple_field_1=None, tuple_field_2=None, exception_field_1=None, exception_field_2=None, exception_field_3=None, struct_field=None, ) message = capnp.MessageBuilder() builder = message.init_root(schema) self.do_test( schema, converter, dataobject, dataclasses.replace( dataobject, group_field=TestPointerStruct.GroupField(group_int_field=0), tuple_field_2=(0, ), exception_field_2=TestPointerStruct.TestException2(0), ), message, ) self.assertIsNone(builder['tupleField1']) self.assertIsNone(builder['exceptionField1']) self.assertIsNone(builder['structField']) self.do_test( schema, converter, dataclasses.replace( dataobject, tuple_field_1=(13, ), tuple_field_2=(42, ), exception_field_1=TestPointerStruct.TestException(), exception_field_3=TestPointerStruct.TestException3('x', 42), struct_field=TestPointerStruct.EmptyStruct(), ), dataclasses.replace( dataobject, group_field=TestPointerStruct.GroupField(group_int_field=0), tuple_field_1=(13, ), tuple_field_2=(42, ), exception_field_1=TestPointerStruct.TestException(), exception_field_2=TestPointerStruct.TestException2(0), exception_field_3=TestPointerStruct.TestException3('x', 42), struct_field=TestPointerStruct.EmptyStruct(), ), message, ) self.assertIsNotNone(builder['tupleField1']) self.assertIsNotNone(builder['exceptionField1']) self.assertIsNotNone(builder['structField'])
def test_nested_union_struct(self): schema = self.loader.struct_schemas[ 'unittest.test_2:TestNestedUnionStruct'] converter = objects.DataclassConverter(schema, TestNestedUnionStruct) message = capnp.MessageBuilder() builder = message.init_root(schema) self.do_test( schema, converter, TestNestedUnionStruct( u0=None, u1=None, ), TestNestedUnionStruct( u0=TestNestedUnionStruct.U0(m0=False, m1=None, m2=None), u1=None, ), message, ) self.assertIsNotNone(builder['u0']) self.assertIsNone(builder['u1']) builder.init('u1') self.assertIsNone(builder['u0']) self.assertIsNotNone(builder['u1']) self.do_test( schema, converter, TestNestedUnionStruct( u0=TestNestedUnionStruct.U0(m0=True, m1=None, m2=None), u1=None, ), TestNestedUnionStruct( u0=TestNestedUnionStruct.U0(m0=True, m1=None, m2=None), u1=None, ), message, ) self.do_test( schema, converter, TestNestedUnionStruct( u0=None, u1=TestNestedUnionStruct.U1(m3='', m4=None), ), TestNestedUnionStruct( u0=None, u1=TestNestedUnionStruct.U1(m3='', m4=None), ), message, )
def test_zero(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) msg = capnp.MessageBuilder() msg.init_root(self.schema) obj1 = SomeStruct( void_field=None, int_field=0, int_with_default=42, str_field=None, int_timestamp=dt, float_timestamp=dt, enum_field=SomeEnum.ENUM_MEMBER_0, struct_field=None, error_field=None, union_int_field=0, union_error_field=None, union_field=UnionField( bool_field=False, bytes_field=None, ), int_list_field=None, tuple_field=(0, False), none_field=None, union_void_field=UnionVoidField( union_void_field=None, union_bytes_field=None, ), str_with_default=None, ) obj2 = dataclasses.replace( obj1, union_void_field=UnionVoidField( union_void_field=None, union_bytes_field=None, ), str_with_default='default message', ) for to_testdata, wd in ( (msg.to_message_bytes, self.wire_data), (msg.to_packed_message_bytes, self.packed_wire_data), ): with self.subTest((to_testdata, wd)): testdata = to_testdata() self.assertEqual(wd.to_lower(obj1), testdata) self.assertEqual(wd.to_upper(SomeStruct, testdata), obj2)
def test_recursive_struct(self): schema = self.loader.struct_schemas['unittest.test_2:RecursiveStruct'] dataobject = RecursiveStruct(struct_field=None) dataobject = RecursiveStruct(struct_field=dataobject) dataobject = RecursiveStruct(struct_field=dataobject) dataobject = RecursiveStruct(struct_field=dataobject) message = capnp.MessageBuilder() builder = message.init_root(schema) with self.assertLogs(level='DEBUG') as cm: converter = objects.DataclassConverter(schema, RecursiveStruct) self.assertEqual(len(cm.output), 1) self.assertRegex( cm.output[0], r'compile struct converter for: .*RecursiveStruct', ) self.do_test(schema, converter, dataobject, dataobject, message) self.assertEqual( str(builder), '(structField = (structField = (structField = ())))', )
def test_forward_compatibility(self): # New data, old converter. message_new = capnp.MessageBuilder() self.converter_new.to_builder( TestStructNew( enum_field=TestStructNew.TestEnum.new_member, no_optional_enum_field=None, optional_enum_field=TestStructNew.TestEnum.new_member, extra_field=True, ), message_new.init_root(self.schema_new), ) message_old = capnp.MessageReader.from_message_bytes( message_new.to_message_bytes()) self.assertEqual( self.converter_old.from_reader( message_old.get_root(self.schema_old)), TestStructOld( enum_field=1, no_optional_enum_field=None, optional_enum_field=1, ), )
def test_backward_compatibility(self): # Old data, new converter. message_old = capnp.MessageBuilder() self.converter_old.to_builder( TestStructOld( enum_field=TestStructOld.TestEnum.old_member, no_optional_enum_field=None, optional_enum_field=TestStructOld.TestEnum.old_member, ), message_old.init_root(self.schema_old), ) message_new = capnp.MessageReader.from_message_bytes( message_old.to_message_bytes()) self.assertEqual( self.converter_new.from_reader( message_new.get_root(self.schema_new)), TestStructNew( enum_field=TestStructNew.TestEnum.old_member, no_optional_enum_field=None, optional_enum_field=TestStructNew.TestEnum.old_member, extra_field=False, ), )
def test_union_struct(self): schema = self.loader.struct_schemas['unittest.test_2:TestUnionStruct'] converter = objects.DataclassConverter(schema, TestUnionStruct) message = capnp.MessageBuilder() message.init_root(schema) self.do_test( schema, converter, TestUnionStruct( u0=None, u1=None, u2=None, m7=None, m8=None, ), TestUnionStruct( u0=TestUnionStruct.U0(m0=None, m1=None), u1=TestUnionStruct.U1(m2=0, m3=None, m4=None), u2=TestUnionStruct.U2(m5=None, m6=None), m7=None, m8=None, ), message, ) self.do_test( schema, converter, TestUnionStruct( u0=None, u1=TestUnionStruct.U1(m2=None, m3=capnp.VOID, m4=None), u2=None, m7=None, m8=None, ), TestUnionStruct( u0=TestUnionStruct.U0(m0=None, m1=None), u1=TestUnionStruct.U1(m2=None, m3=None, m4=None), u2=TestUnionStruct.U2(m5=None, m6=None), m7=None, m8=None, ), message, ) self.do_test( schema, converter, TestUnionStruct( u0=TestUnionStruct.U0(m0=None, m1='spam'), u1=TestUnionStruct.U1(m2=None, m3=None, m4=b'egg'), u2=TestUnionStruct.U2( m5=None, m6=TestPointerStruct.EmptyStruct(), ), m7=None, m8=False, ), TestUnionStruct( u0=TestUnionStruct.U0(m0=None, m1='spam'), u1=TestUnionStruct.U1(m2=None, m3=None, m4=b'egg'), u2=TestUnionStruct.U2( m5=None, m6=TestPointerStruct.EmptyStruct(), ), m7=None, m8=False, ), message, ) self.do_test( schema, converter, TestUnionStruct( u0=None, u1=None, u2=None, m7=None, m8=None, ), TestUnionStruct( u0=TestUnionStruct.U0(m0=None, m1=None), u1=TestUnionStruct.U1(m2=0, m3=None, m4=None), u2=TestUnionStruct.U2(m5=None, m6=None), m7=None, m8=False, ), message, )
def test_simple_struct(self): dt = datetime.datetime(2000, 1, 2, 3, 4, 5, 6, datetime.timezone.utc) self.assertNotEqual(dt.microsecond, 0) schema = self.loader.struct_schemas['unittest.test_2:TestSimpleStruct'] converter = objects.DataclassConverter(schema, TestSimpleStruct) dataobject = TestSimpleStruct( void_field=capnp.VOID, bool_field=False, int8_field=0, int16_field=0, int32_field=0, int64_field=0, uint8_field=0, uint16_field=0, uint32_field=0, uint64_field=0, float32_field=0.0, float64_field=0.0, text_field_1=None, text_field_2=None, data_field_1=None, data_field_2=None, int_list_field=None, text_list_field=None, enum_field=TestSimpleStruct.TestEnum.member1, datetime_int_field=dt.replace(microsecond=0), datetime_float_field=dt, nested_list=None, ) message = capnp.MessageBuilder() builder = message.init_root(schema) def do_test(**kwargs): obj = dataclasses.replace(dataobject, **kwargs) self.do_test( schema, converter, obj, obj, message, ) def do_test_error(exc_type, regex, **kwargs): self.do_test_error( schema, converter, dataclasses.replace(dataobject, **kwargs), exc_type, regex, ) do_test() do_test(bool_field=True) self.assertEqual(builder['int32Field'], 0) builder['int32Field'] = 42 self.assertIsNone(builder['nestedList']) do_test( text_field_1='hello', text_field_2='world', data_field_1=b'\x00\x01\x02', data_field_2=b'\x03\x04\x05', nested_list=[ [ [], ], [ [], [(0, )], ], [ [(1, ), (2, )], ], ], ) self.assertEqual(builder['int32Field'], 0) self.assertEqual(len(builder['nestedList']), 3) do_test( int_list_field=[1, 2, 3], text_list_field=[], ) self.assertEqual(len(builder['intListField']), 3) self.assertEqual(len(builder['textListField']), 0) do_test( int_list_field=[1], text_list_field=['a', 'b', 'c'], ) self.assertEqual(len(builder['intListField']), 1) self.assertEqual(len(builder['textListField']), 3) self.assertEqual(builder['enumField'], 1) do_test(enum_field=TestSimpleStruct.TestEnum.member2) self.assertEqual(builder['enumField'], 2) do_test_error( AssertionError, r'expect .*VoidType.*, not 1', void_field=1, ) do_test_error( AssertionError, r'expect .*VoidType.*, not None', void_field=None, ) do_test_error( AssertionError, r'expect .*str.*-typed value', text_field_1=b'', ) do_test_error( RuntimeError, r'Value out-of-range for requested type.; value = 129', int8_field=129, )
def do_test_error(self, schema, converter, illegal_input, exc_type, regex): with self.subTest(illegal_input): mb = capnp.MessageBuilder() builder = mb.init_root(schema) with self.assertRaisesRegex(exc_type, regex): converter.to_builder(illegal_input, builder)
def to_lower(self, message): ASSERT.predicate(message, wiredata.is_message) with capnp.MessageBuilder() as builder: self._get_converter(type(message)).to_message(message, builder) return self._to_bytes(builder)
def test_wiredata(self): dt = datetime.datetime(2000, 1, 2, 3, 4, 5, 6, datetime.timezone.utc) self.assertNotEqual(dt.microsecond, 0) msg = capnp.MessageBuilder() builder = msg.init_root(self.schema) builder['voidField'] = capnp.VOID builder['intField'] = 13 builder['strField'] = 'hello world' builder['intTimestamp'] = int(dt.timestamp()) builder['floatTimestamp'] = dt.timestamp() builder['enumField'] = SomeEnum.ENUM_MEMBER_1 builder.init('structField') b = builder.init('errorField') b['code'] = 7 b['reason'] = 'some error' builder.init('unionErrorField') builder.init('unionField')['bytesField'] = b'hello world' b = builder.init('intListField', 3) b[0] = 2 b[1] = 3 b[2] = 5 b = builder.init('tupleField') b['intGroupField'] = 99 b['boolGroupField'] = True builder['noneField'] = capnp.VOID builder.init('unionVoidField')['unionBytesField'] = b'' builder['strWithDefault'] = 'spam egg' obj = SomeStruct( void_field=None, int_field=13, int_with_default=42, str_field='hello world', int_timestamp=dt.replace(microsecond=0), float_timestamp=dt, enum_field=SomeEnum.ENUM_MEMBER_1, struct_field=NestedEmptyStruct(), error_field=SomeError(7, 'some error'), union_int_field=None, union_error_field=SomeError(0, None), union_field=UnionField( bool_field=None, bytes_field=b'hello world', ), int_list_field=[2, 3, 5], tuple_field=(99, True), none_field=None, union_void_field=UnionVoidField( union_void_field=None, union_bytes_field=b'', ), str_with_default='spam egg', ) for to_testdata, wd in ( (msg.to_message_bytes, self.wire_data), (msg.to_packed_message_bytes, self.packed_wire_data), ): with self.subTest((to_testdata, wd)): testdata = to_testdata() self.assertEqual(wd.to_lower(obj), testdata) self.assertEqual(wd.to_upper(SomeStruct, testdata), obj)