1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import com.google.protobuf.Descriptors.EnumDescriptor; 34 import com.google.protobuf.Descriptors.FieldDescriptor; 35 import com.google.protobuf.Descriptors.OneofDescriptor; 36 import protobuf_unittest.UnittestProto; 37 import protobuf_unittest.UnittestProto.TestAllExtensions; 38 import protobuf_unittest.UnittestProto.TestAllTypes; 39 import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage; 40 import protobuf_unittest.UnittestProto.TestEmptyMessage; 41 import protobuf_unittest.UnittestProto.TestPackedTypes; 42 import java.util.Arrays; 43 import junit.framework.TestCase; 44 45 /** 46 * Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which tests some {@link 47 * DynamicMessage} functionality. 48 * 49 * @author kenton@google.com Kenton Varda 50 */ 51 public class DynamicMessageTest extends TestCase { 52 TestUtil.ReflectionTester reflectionTester = 53 new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null); 54 55 TestUtil.ReflectionTester extensionsReflectionTester = 56 new TestUtil.ReflectionTester( 57 TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry()); 58 TestUtil.ReflectionTester packedReflectionTester = 59 new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null); 60 testDynamicMessageAccessors()61 public void testDynamicMessageAccessors() throws Exception { 62 Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 63 reflectionTester.setAllFieldsViaReflection(builder); 64 Message message = builder.build(); 65 reflectionTester.assertAllFieldsSetViaReflection(message); 66 } 67 testSettersAfterBuild()68 public void testSettersAfterBuild() throws Exception { 69 Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 70 Message firstMessage = builder.build(); 71 // double build() 72 builder.build(); 73 // clear() after build() 74 builder.clear(); 75 // setters after build() 76 reflectionTester.setAllFieldsViaReflection(builder); 77 Message message = builder.build(); 78 reflectionTester.assertAllFieldsSetViaReflection(message); 79 // repeated setters after build() 80 reflectionTester.modifyRepeatedFieldsViaReflection(builder); 81 message = builder.build(); 82 reflectionTester.assertRepeatedFieldsModifiedViaReflection(message); 83 // firstMessage shouldn't have been modified. 84 reflectionTester.assertClearViaReflection(firstMessage); 85 } 86 testUnknownFields()87 public void testUnknownFields() throws Exception { 88 Message.Builder builder = DynamicMessage.newBuilder(TestEmptyMessage.getDescriptor()); 89 builder.setUnknownFields( 90 UnknownFieldSet.newBuilder() 91 .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(1).build()) 92 .addField(2, UnknownFieldSet.Field.newBuilder().addFixed32(1).build()) 93 .build()); 94 Message message = builder.build(); 95 assertEquals(2, message.getUnknownFields().asMap().size()); 96 // clone() with unknown fields 97 Message.Builder newBuilder = builder.clone(); 98 assertEquals(2, newBuilder.getUnknownFields().asMap().size()); 99 // clear() with unknown fields 100 newBuilder.clear(); 101 assertTrue(newBuilder.getUnknownFields().asMap().isEmpty()); 102 // serialize/parse with unknown fields 103 newBuilder.mergeFrom(message.toByteString()); 104 assertEquals(2, newBuilder.getUnknownFields().asMap().size()); 105 } 106 testDynamicMessageSettersRejectNull()107 public void testDynamicMessageSettersRejectNull() throws Exception { 108 Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 109 reflectionTester.assertReflectionSettersRejectNull(builder); 110 } 111 testDynamicMessageExtensionAccessors()112 public void testDynamicMessageExtensionAccessors() throws Exception { 113 // We don't need to extensively test DynamicMessage's handling of 114 // extensions because, frankly, it doesn't do anything special with them. 115 // It treats them just like any other fields. 116 Message.Builder builder = DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); 117 extensionsReflectionTester.setAllFieldsViaReflection(builder); 118 Message message = builder.build(); 119 extensionsReflectionTester.assertAllFieldsSetViaReflection(message); 120 } 121 testDynamicMessageExtensionSettersRejectNull()122 public void testDynamicMessageExtensionSettersRejectNull() throws Exception { 123 Message.Builder builder = DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); 124 extensionsReflectionTester.assertReflectionSettersRejectNull(builder); 125 } 126 testDynamicMessageRepeatedSetters()127 public void testDynamicMessageRepeatedSetters() throws Exception { 128 Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 129 reflectionTester.setAllFieldsViaReflection(builder); 130 reflectionTester.modifyRepeatedFieldsViaReflection(builder); 131 Message message = builder.build(); 132 reflectionTester.assertRepeatedFieldsModifiedViaReflection(message); 133 } 134 testDynamicMessageRepeatedSettersRejectNull()135 public void testDynamicMessageRepeatedSettersRejectNull() throws Exception { 136 Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 137 reflectionTester.assertReflectionRepeatedSettersRejectNull(builder); 138 } 139 testDynamicMessageDefaults()140 public void testDynamicMessageDefaults() throws Exception { 141 reflectionTester.assertClearViaReflection( 142 DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor())); 143 reflectionTester.assertClearViaReflection( 144 DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build()); 145 } 146 testDynamicMessageSerializedSize()147 public void testDynamicMessageSerializedSize() throws Exception { 148 TestAllTypes message = TestUtil.getAllSet(); 149 150 Message.Builder dynamicBuilder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 151 reflectionTester.setAllFieldsViaReflection(dynamicBuilder); 152 Message dynamicMessage = dynamicBuilder.build(); 153 154 assertEquals(message.getSerializedSize(), dynamicMessage.getSerializedSize()); 155 } 156 testDynamicMessageSerialization()157 public void testDynamicMessageSerialization() throws Exception { 158 Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 159 reflectionTester.setAllFieldsViaReflection(builder); 160 Message message = builder.build(); 161 162 ByteString rawBytes = message.toByteString(); 163 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes); 164 165 TestUtil.assertAllFieldsSet(message2); 166 167 // In fact, the serialized forms should be exactly the same, byte-for-byte. 168 assertEquals(TestUtil.getAllSet().toByteString(), rawBytes); 169 } 170 testDynamicMessageParsing()171 public void testDynamicMessageParsing() throws Exception { 172 TestAllTypes.Builder builder = TestAllTypes.newBuilder(); 173 TestUtil.setAllFields(builder); 174 TestAllTypes message = builder.build(); 175 176 ByteString rawBytes = message.toByteString(); 177 178 Message message2 = DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes); 179 reflectionTester.assertAllFieldsSetViaReflection(message2); 180 181 // Test Parser interface. 182 Message message3 = message2.getParserForType().parseFrom(rawBytes); 183 reflectionTester.assertAllFieldsSetViaReflection(message3); 184 } 185 testDynamicMessageExtensionParsing()186 public void testDynamicMessageExtensionParsing() throws Exception { 187 ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString(); 188 Message message = 189 DynamicMessage.parseFrom( 190 TestAllExtensions.getDescriptor(), rawBytes, TestUtil.getFullExtensionRegistry()); 191 extensionsReflectionTester.assertAllFieldsSetViaReflection(message); 192 193 // Test Parser interface. 194 Message message2 = 195 message.getParserForType().parseFrom(rawBytes, TestUtil.getExtensionRegistry()); 196 extensionsReflectionTester.assertAllFieldsSetViaReflection(message2); 197 } 198 testDynamicMessagePackedSerialization()199 public void testDynamicMessagePackedSerialization() throws Exception { 200 Message.Builder builder = DynamicMessage.newBuilder(TestPackedTypes.getDescriptor()); 201 packedReflectionTester.setPackedFieldsViaReflection(builder); 202 Message message = builder.build(); 203 204 ByteString rawBytes = message.toByteString(); 205 TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes); 206 207 TestUtil.assertPackedFieldsSet(message2); 208 209 // In fact, the serialized forms should be exactly the same, byte-for-byte. 210 assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes); 211 } 212 testDynamicMessagePackedParsing()213 public void testDynamicMessagePackedParsing() throws Exception { 214 TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); 215 TestUtil.setPackedFields(builder); 216 TestPackedTypes message = builder.build(); 217 218 ByteString rawBytes = message.toByteString(); 219 220 Message message2 = DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes); 221 packedReflectionTester.assertPackedFieldsSetViaReflection(message2); 222 223 // Test Parser interface. 224 Message message3 = message2.getParserForType().parseFrom(rawBytes); 225 packedReflectionTester.assertPackedFieldsSetViaReflection(message3); 226 } 227 testGetBuilderForExtensionField()228 public void testGetBuilderForExtensionField() { 229 DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllExtensions.getDescriptor()); 230 Message.Builder fieldBuilder = 231 builder.newBuilderForField(UnittestProto.optionalNestedMessageExtension.getDescriptor()); 232 final int expected = 7432; 233 FieldDescriptor field = 234 NestedMessage.getDescriptor().findFieldByNumber(NestedMessage.BB_FIELD_NUMBER); 235 fieldBuilder.setField(field, expected); 236 assertEquals(expected, fieldBuilder.build().getField(field)); 237 } 238 testDynamicMessageCopy()239 public void testDynamicMessageCopy() throws Exception { 240 TestAllTypes.Builder builder = TestAllTypes.newBuilder(); 241 TestUtil.setAllFields(builder); 242 TestAllTypes message = builder.build(); 243 244 DynamicMessage copy = DynamicMessage.newBuilder(message).build(); 245 reflectionTester.assertAllFieldsSetViaReflection(copy); 246 247 // Test oneof behavior 248 FieldDescriptor bytesField = TestAllTypes.getDescriptor().findFieldByName("oneof_bytes"); 249 FieldDescriptor uint32Field = TestAllTypes.getDescriptor().findFieldByName("oneof_uint32"); 250 assertTrue(copy.hasField(bytesField)); 251 assertFalse(copy.hasField(uint32Field)); 252 DynamicMessage copy2 = DynamicMessage.newBuilder(message).setField(uint32Field, 123).build(); 253 assertFalse(copy2.hasField(bytesField)); 254 assertTrue(copy2.hasField(uint32Field)); 255 assertEquals(123, copy2.getField(uint32Field)); 256 } 257 testToBuilder()258 public void testToBuilder() throws Exception { 259 DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 260 reflectionTester.setAllFieldsViaReflection(builder); 261 int unknownFieldNum = 9; 262 long unknownFieldVal = 90; 263 builder.setUnknownFields( 264 UnknownFieldSet.newBuilder() 265 .addField( 266 unknownFieldNum, 267 UnknownFieldSet.Field.newBuilder().addVarint(unknownFieldVal).build()) 268 .build()); 269 DynamicMessage message = builder.build(); 270 271 DynamicMessage derived = message.toBuilder().build(); 272 reflectionTester.assertAllFieldsSetViaReflection(derived); 273 assertEquals( 274 Arrays.asList(unknownFieldVal), 275 derived.getUnknownFields().getField(unknownFieldNum).getVarintList()); 276 } 277 testDynamicOneofMessage()278 public void testDynamicOneofMessage() throws Exception { 279 DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 280 OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0); 281 assertFalse(builder.hasOneof(oneof)); 282 assertSame(null, builder.getOneofFieldDescriptor(oneof)); 283 284 reflectionTester.setAllFieldsViaReflection(builder); 285 assertTrue(builder.hasOneof(oneof)); 286 FieldDescriptor field = oneof.getField(3); 287 assertSame(field, builder.getOneofFieldDescriptor(oneof)); 288 289 DynamicMessage message = builder.buildPartial(); 290 assertTrue(message.hasOneof(oneof)); 291 292 DynamicMessage.Builder mergedBuilder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 293 FieldDescriptor mergedField = oneof.getField(0); 294 mergedBuilder.setField(mergedField, 123); 295 assertTrue(mergedBuilder.hasField(mergedField)); 296 mergedBuilder.mergeFrom(message); 297 assertTrue(mergedBuilder.hasField(field)); 298 assertFalse(mergedBuilder.hasField(mergedField)); 299 300 builder.clearOneof(oneof); 301 assertSame(null, builder.getOneofFieldDescriptor(oneof)); 302 message = builder.build(); 303 assertSame(null, message.getOneofFieldDescriptor(oneof)); 304 } 305 306 // Regression test for a bug that makes setField() not work for repeated 307 // enum fields. testSettersForRepeatedEnumField()308 public void testSettersForRepeatedEnumField() throws Exception { 309 DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); 310 FieldDescriptor repeatedEnumField = 311 TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum"); 312 EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor(); 313 builder.setField(repeatedEnumField, enumDescriptor.getValues()); 314 DynamicMessage message = builder.build(); 315 assertEquals(enumDescriptor.getValues(), message.getField(repeatedEnumField)); 316 } 317 } 318