def testAnyMessage(self): # Creates and sets message. msg = any_test_pb2.TestAny() msg_descriptor = msg.DESCRIPTOR all_types = unittest_pb2.TestAllTypes() all_descriptor = all_types.DESCRIPTOR all_types.repeated_string.append('\u00fc\ua71f') # Packs to Any. msg.value.Pack(all_types) self.assertEqual(msg.value.type_url, 'type.googleapis.com/%s' % all_descriptor.full_name) self.assertEqual(msg.value.value, all_types.SerializeToString()) # Tests Is() method. self.assertTrue(msg.value.Is(all_descriptor)) self.assertFalse(msg.value.Is(msg_descriptor)) # Unpacks Any. unpacked_message = unittest_pb2.TestAllTypes() self.assertTrue(msg.value.Unpack(unpacked_message)) self.assertEqual(all_types, unpacked_message) # Unpacks to different type. self.assertFalse(msg.value.Unpack(msg)) # Only Any messages have Pack method. try: msg.Pack(all_types) except AttributeError: pass else: raise AttributeError('%s should not have Pack method.' % msg_descriptor.full_name)
def testMergeErrors(self): src = unittest_pb2.TestAllTypes() dst = unittest_pb2.TestAllTypes() mask = field_mask_pb2.FieldMask() test_util.SetAllFields(src) mask.FromJsonString('optionalInt32.field') with self.assertRaises(ValueError) as e: mask.MergeMessage(src, dst) self.assertEqual( 'Error: Field optional_int32 in message ' 'protobuf_unittest.TestAllTypes is not a singular ' 'message field and cannot have sub-fields.', str(e.exception))
def setUp(self): self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR self.all_fields = unittest_pb2.TestAllTypes() test_util.SetAllFields(self.all_fields) self.all_fields_data = self.all_fields.SerializeToString() self.empty_message = unittest_pb2.TestEmptyMessage() self.empty_message.ParseFromString(self.all_fields_data)
def testDiscardUnknownFields(self): self.empty_message.DiscardUnknownFields() self.assertEqual(b'', self.empty_message.SerializeToString()) # Test message field and repeated message field. message = unittest_pb2.TestAllTypes() other_message = unittest_pb2.TestAllTypes() other_message.optional_string = 'discard' message.optional_nested_message.ParseFromString( other_message.SerializeToString()) message.repeated_nested_message.add().ParseFromString( other_message.SerializeToString()) self.assertNotEqual( b'', message.optional_nested_message.SerializeToString()) self.assertNotEqual( b'', message.repeated_nested_message[0].SerializeToString()) message.DiscardUnknownFields() self.assertEqual(b'', message.optional_nested_message.SerializeToString()) self.assertEqual( b'', message.repeated_nested_message[0].SerializeToString())
def testPublicImports(self): # Test public imports as embedded message. all_type_proto = unittest_pb2.TestAllTypes() self.assertEqual(0, all_type_proto.optional_public_import_message.e) # PublicImportMessage is actually defined in unittest_import_public_pb2 # module, and is public imported by unittest_import_pb2 module. public_import_proto = unittest_import_pb2.PublicImportMessage() self.assertEqual(0, public_import_proto.e) self.assertTrue(unittest_import_public_pb2.PublicImportMessage is unittest_import_pb2.PublicImportMessage)
def testEnums(self): # We test only module-level enums here. # TODO(robinson): Examine descriptors directly to check # enum descriptor output. self.assertEqual(4, unittest_pb2.FOREIGN_FOO) self.assertEqual(5, unittest_pb2.FOREIGN_BAR) self.assertEqual(6, unittest_pb2.FOREIGN_BAZ) proto = unittest_pb2.TestAllTypes() self.assertEqual(1, proto.FOO) self.assertEqual(1, unittest_pb2.TestAllTypes.FOO) self.assertEqual(2, proto.BAR) self.assertEqual(2, unittest_pb2.TestAllTypes.BAR) self.assertEqual(3, proto.BAZ) self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
def testParseEnumValue(self): message = json_format_proto3_pb2.TestMessage() text = '{"enumValue": 0}' json_format.Parse(text, message) text = '{"enumValue": 1}' json_format.Parse(text, message) self.CheckError( '{"enumValue": "baz"}', 'Failed to parse enumValue field: Invalid enum value baz ' 'for enum type proto3.EnumType.') # Proto3 accepts numeric unknown enums. text = '{"enumValue": 12345}' json_format.Parse(text, message) # Proto2 does not accept unknown enums. message = unittest_pb2.TestAllTypes() self.assertRaisesRegex( json_format.ParseError, 'Failed to parse optionalNestedEnum field: Invalid enum value 12345 ' 'for enum type protobuf_unittest.TestAllTypes.NestedEnum.', json_format.Parse, '{"optionalNestedEnum": 12345}', message)
def testMergeFrom(self): message = unittest_pb2.TestAllTypes() message.optional_int32 = 1 message.optional_uint32 = 2 source = unittest_pb2.TestEmptyMessage() source.ParseFromString(message.SerializeToString()) message.ClearField('optional_int32') message.optional_int64 = 3 message.optional_uint32 = 4 destination = unittest_pb2.TestEmptyMessage() destination.ParseFromString(message.SerializeToString()) destination.MergeFrom(source) # Check that the fields where correctly merged, even stored in the unknown # fields set. message.ParseFromString(destination.SerializeToString()) self.assertEqual(message.optional_int32, 1) self.assertEqual(message.optional_uint32, 2) self.assertEqual(message.optional_int64, 3)
def testUnion(self): mask1 = field_mask_pb2.FieldMask() mask2 = field_mask_pb2.FieldMask() out_mask = field_mask_pb2.FieldMask() mask1.FromJsonString('foo,baz') mask2.FromJsonString('bar,quz') out_mask.Union(mask1, mask2) self.assertEqual('bar,baz,foo,quz', out_mask.ToJsonString()) # Overlap with duplicated paths. mask1.FromJsonString('foo,baz.bb') mask2.FromJsonString('baz.bb,quz') out_mask.Union(mask1, mask2) self.assertEqual('baz.bb,foo,quz', out_mask.ToJsonString()) # Overlap with paths covering some other paths. mask1.FromJsonString('foo.bar.baz,quz') mask2.FromJsonString('foo.bar,bar') out_mask.Union(mask1, mask2) self.assertEqual('bar,foo.bar,quz', out_mask.ToJsonString()) src = unittest_pb2.TestAllTypes() with self.assertRaises(ValueError): out_mask.Union(src, mask2)
def testDefaultValueForCustomMessages(self): """Check the value returned by non-existent fields.""" def _CheckValueAndType(value, expected_value, expected_type): self.assertEqual(value, expected_value) self.assertIsInstance(value, expected_type) def _CheckDefaultValues(msg): try: int64 = int except NameError: # Python3 int64 = int try: unicode_type = str except NameError: # Python3 unicode_type = str _CheckValueAndType(msg.optional_int32, 0, int) _CheckValueAndType(msg.optional_uint64, 0, (int64, int)) _CheckValueAndType(msg.optional_float, 0, (float, int)) _CheckValueAndType(msg.optional_double, 0, (float, int)) _CheckValueAndType(msg.optional_bool, False, bool) _CheckValueAndType(msg.optional_string, '', unicode_type) _CheckValueAndType(msg.optional_bytes, b'', bytes) _CheckValueAndType(msg.optional_nested_enum, msg.FOO, int) # First for the generated message _CheckDefaultValues(unittest_pb2.TestAllTypes()) # Then for a message built with from the DescriptorPool. pool = descriptor_pool.DescriptorPool() pool.Add(descriptor_pb2.FileDescriptorProto.FromString( unittest_import_public_pb2.DESCRIPTOR.serialized_pb)) pool.Add(descriptor_pb2.FileDescriptorProto.FromString( unittest_import_pb2.DESCRIPTOR.serialized_pb)) pool.Add(descriptor_pb2.FileDescriptorProto.FromString( unittest_pb2.DESCRIPTOR.serialized_pb)) message_class = message_factory.MessageFactory(pool).GetPrototype( pool.FindMessageTypeByName( unittest_pb2.TestAllTypes.DESCRIPTOR.full_name)) _CheckDefaultValues(message_class())
def testMergeMessage(self): # Test merge one field. src = unittest_pb2.TestAllTypes() test_util.SetAllFields(src) for field in src.DESCRIPTOR.fields: if field.containing_oneof: continue field_name = field.name dst = unittest_pb2.TestAllTypes() # Only set one path to mask. mask = field_mask_pb2.FieldMask() mask.paths.append(field_name) mask.MergeMessage(src, dst) # The expected result message. msg = unittest_pb2.TestAllTypes() if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: repeated_src = getattr(src, field_name) repeated_msg = getattr(msg, field_name) if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: for item in repeated_src: repeated_msg.add().CopyFrom(item) else: repeated_msg.extend(repeated_src) elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: getattr(msg, field_name).CopyFrom(getattr(src, field_name)) else: setattr(msg, field_name, getattr(src, field_name)) # Only field specified in mask is merged. self.assertEqual(msg, dst) # Test merge nested fields. nested_src = unittest_pb2.NestedTestAllTypes() nested_dst = unittest_pb2.NestedTestAllTypes() nested_src.child.payload.optional_int32 = 1234 nested_src.child.child.payload.optional_int32 = 5678 mask = field_mask_pb2.FieldMask() mask.FromJsonString('child.payload') mask.MergeMessage(nested_src, nested_dst) self.assertEqual(1234, nested_dst.child.payload.optional_int32) self.assertEqual(0, nested_dst.child.child.payload.optional_int32) mask.FromJsonString('child.child.payload') mask.MergeMessage(nested_src, nested_dst) self.assertEqual(1234, nested_dst.child.payload.optional_int32) self.assertEqual(5678, nested_dst.child.child.payload.optional_int32) nested_dst.Clear() mask.FromJsonString('child.child.payload') mask.MergeMessage(nested_src, nested_dst) self.assertEqual(0, nested_dst.child.payload.optional_int32) self.assertEqual(5678, nested_dst.child.child.payload.optional_int32) nested_dst.Clear() mask.FromJsonString('child') mask.MergeMessage(nested_src, nested_dst) self.assertEqual(1234, nested_dst.child.payload.optional_int32) self.assertEqual(5678, nested_dst.child.child.payload.optional_int32) # Test MergeOptions. nested_dst.Clear() nested_dst.child.payload.optional_int64 = 4321 # Message fields will be merged by default. mask.FromJsonString('child.payload') mask.MergeMessage(nested_src, nested_dst) self.assertEqual(1234, nested_dst.child.payload.optional_int32) self.assertEqual(4321, nested_dst.child.payload.optional_int64) # Change the behavior to replace message fields. mask.FromJsonString('child.payload') mask.MergeMessage(nested_src, nested_dst, True, False) self.assertEqual(1234, nested_dst.child.payload.optional_int32) self.assertEqual(0, nested_dst.child.payload.optional_int64) # By default, fields missing in source are not cleared in destination. nested_dst.payload.optional_int32 = 1234 self.assertTrue(nested_dst.HasField('payload')) mask.FromJsonString('payload') mask.MergeMessage(nested_src, nested_dst) self.assertTrue(nested_dst.HasField('payload')) # But they are cleared when replacing message fields. nested_dst.Clear() nested_dst.payload.optional_int32 = 1234 mask.FromJsonString('payload') mask.MergeMessage(nested_src, nested_dst, True, False) self.assertFalse(nested_dst.HasField('payload')) nested_src.payload.repeated_int32.append(1234) nested_dst.payload.repeated_int32.append(5678) # Repeated fields will be appended by default. mask.FromJsonString('payload.repeatedInt32') mask.MergeMessage(nested_src, nested_dst) self.assertEqual(2, len(nested_dst.payload.repeated_int32)) self.assertEqual(5678, nested_dst.payload.repeated_int32[0]) self.assertEqual(1234, nested_dst.payload.repeated_int32[1]) # Change the behavior to replace repeated fields. mask.FromJsonString('payload.repeatedInt32') mask.MergeMessage(nested_src, nested_dst, False, True) self.assertEqual(1, len(nested_dst.payload.repeated_int32)) self.assertEqual(1234, nested_dst.payload.repeated_int32[0]) # Test Merge oneof field. new_msg = unittest_pb2.TestOneof2() dst = unittest_pb2.TestOneof2() dst.foo_message.qux_int = 1 mask = field_mask_pb2.FieldMask() mask.FromJsonString('fooMessage,fooLazyMessage.quxInt') mask.MergeMessage(new_msg, dst) self.assertTrue(dst.HasField('foo_message')) self.assertFalse(dst.HasField('foo_lazy_message'))