1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 package com.google.protobuf.test;
32 import com.google.protobuf.*;
34 import protobuf_unittest.UnittestProto;
35 import protobuf_unittest.UnittestProto.TestAllExtensions;
36 import protobuf_unittest.UnittestProto.TestAllTypes;
37 import protobuf_unittest.UnittestProto.TestEmptyMessage;
38 import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
40 import junit.framework.TestCase;
42 import java.util.Arrays;
46 * Tests related to unknown field handling.
48 * @author kenton@google.com (Kenton Varda)
50 public class UnknownFieldSetTest extends TestCase {
51 public void setUp() throws Exception {
52 descriptor = TestAllTypes.getDescriptor();
53 allFields = TestUtil.getAllSet();
54 allFieldsData = allFields.toByteString();
55 emptyMessage = TestEmptyMessage.parseFrom(allFieldsData);
56 unknownFields = emptyMessage.getUnknownFields();
59 UnknownFieldSet.Field getField(String name) {
60 Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
62 return unknownFields.getField(field.getNumber());
65 // Constructs a protocol buffer which contains fields with all the same
66 // numbers as allFieldsData except that each field is some other wire
68 ByteString getBizarroData() throws Exception {
69 UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder();
71 UnknownFieldSet.Field varintField =
72 UnknownFieldSet.Field.newBuilder().addVarint(1).build();
73 UnknownFieldSet.Field fixed32Field =
74 UnknownFieldSet.Field.newBuilder().addFixed32(1).build();
76 for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
77 unknownFields.asMap().entrySet()) {
78 if (entry.getValue().getVarintList().isEmpty()) {
79 // Original field is not a varint, so use a varint.
80 bizarroFields.addField(entry.getKey(), varintField);
82 // Original field *is* a varint, so use something else.
83 bizarroFields.addField(entry.getKey(), fixed32Field);
87 return bizarroFields.build().toByteString();
90 Descriptors.Descriptor descriptor;
91 TestAllTypes allFields;
92 ByteString allFieldsData;
94 // An empty message that has been parsed from allFieldsData. So, it has
95 // unknown fields of every type.
96 TestEmptyMessage emptyMessage;
97 UnknownFieldSet unknownFields;
99 // =================================================================
101 public void testVarint() throws Exception {
102 UnknownFieldSet.Field field = getField("optional_int32");
103 assertEquals(1, field.getVarintList().size());
104 assertEquals(allFields.getOptionalInt32(),
105 (long) field.getVarintList().get(0));
108 public void testFixed32() throws Exception {
109 UnknownFieldSet.Field field = getField("optional_fixed32");
110 assertEquals(1, field.getFixed32List().size());
111 assertEquals(allFields.getOptionalFixed32(),
112 (int) field.getFixed32List().get(0));
115 public void testFixed64() throws Exception {
116 UnknownFieldSet.Field field = getField("optional_fixed64");
117 assertEquals(1, field.getFixed64List().size());
118 assertEquals(allFields.getOptionalFixed64(),
119 (long) field.getFixed64List().get(0));
122 public void testLengthDelimited() throws Exception {
123 UnknownFieldSet.Field field = getField("optional_bytes");
124 assertEquals(1, field.getLengthDelimitedList().size());
125 assertEquals(allFields.getOptionalBytes(),
126 field.getLengthDelimitedList().get(0));
129 public void testGroup() throws Exception {
130 Descriptors.FieldDescriptor nestedFieldDescriptor =
131 TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a");
132 assertNotNull(nestedFieldDescriptor);
134 UnknownFieldSet.Field field = getField("optionalgroup");
135 assertEquals(1, field.getGroupList().size());
137 UnknownFieldSet group = field.getGroupList().get(0);
138 assertEquals(1, group.asMap().size());
139 assertTrue(group.hasField(nestedFieldDescriptor.getNumber()));
141 UnknownFieldSet.Field nestedField =
142 group.getField(nestedFieldDescriptor.getNumber());
143 assertEquals(1, nestedField.getVarintList().size());
144 assertEquals(allFields.getOptionalGroup().getA(),
145 (long) nestedField.getVarintList().get(0));
148 public void testSerialize() throws Exception {
149 // Check that serializing the UnknownFieldSet produces the original data
151 ByteString data = emptyMessage.toByteString();
152 assertEquals(allFieldsData, data);
155 public void testCopyFrom() throws Exception {
156 TestEmptyMessage message =
157 TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build();
159 assertEquals(emptyMessage.toString(), message.toString());
162 public void testMergeFrom() throws Exception {
163 TestEmptyMessage source =
164 TestEmptyMessage.newBuilder()
166 UnknownFieldSet.newBuilder()
168 UnknownFieldSet.Field.newBuilder()
169 .addVarint(2).build())
171 UnknownFieldSet.Field.newBuilder()
172 .addVarint(4).build())
175 TestEmptyMessage destination =
176 TestEmptyMessage.newBuilder()
178 UnknownFieldSet.newBuilder()
180 UnknownFieldSet.Field.newBuilder()
181 .addVarint(1).build())
183 UnknownFieldSet.Field.newBuilder()
184 .addVarint(3).build())
194 destination.toString());
197 public void testClear() throws Exception {
198 UnknownFieldSet fields =
199 UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
200 assertTrue(fields.asMap().isEmpty());
203 public void testClearMessage() throws Exception {
204 TestEmptyMessage message =
205 TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
206 assertEquals(0, message.getSerializedSize());
209 public void testParseKnownAndUnknown() throws Exception {
210 // Test mixing known and unknown fields when parsing.
212 UnknownFieldSet fields =
213 UnknownFieldSet.newBuilder(unknownFields)
215 UnknownFieldSet.Field.newBuilder().addVarint(654321).build())
218 ByteString data = fields.toByteString();
219 TestAllTypes destination = TestAllTypes.parseFrom(data);
221 TestUtil.assertAllFieldsSet(destination);
222 assertEquals(1, destination.getUnknownFields().asMap().size());
224 UnknownFieldSet.Field field =
225 destination.getUnknownFields().getField(123456);
226 assertEquals(1, field.getVarintList().size());
227 assertEquals(654321, (long) field.getVarintList().get(0));
230 public void testWrongTypeTreatedAsUnknown() throws Exception {
231 // Test that fields of the wrong wire type are treated like unknown fields
234 ByteString bizarroData = getBizarroData();
235 TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
236 TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
238 // All fields should have been interpreted as unknown, so the debug strings
239 // should be the same.
240 assertEquals(emptyMessage.toString(), allTypesMessage.toString());
243 public void testUnknownExtensions() throws Exception {
244 // Make sure fields are properly parsed to the UnknownFieldSet even when
245 // they are declared as extension numbers.
247 TestEmptyMessageWithExtensions message =
248 TestEmptyMessageWithExtensions.parseFrom(allFieldsData);
250 assertEquals(unknownFields.asMap().size(),
251 message.getUnknownFields().asMap().size());
252 assertEquals(allFieldsData, message.toByteString());
255 public void testWrongExtensionTypeTreatedAsUnknown() throws Exception {
256 // Test that fields of the wrong wire type are treated like unknown fields
257 // when parsing extensions.
259 ByteString bizarroData = getBizarroData();
260 TestAllExtensions allExtensionsMessage =
261 TestAllExtensions.parseFrom(bizarroData);
262 TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
264 // All fields should have been interpreted as unknown, so the debug strings
265 // should be the same.
266 assertEquals(emptyMessage.toString(),
267 allExtensionsMessage.toString());
270 public void testParseUnknownEnumValue() throws Exception {
271 Descriptors.FieldDescriptor singularField =
272 TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
273 Descriptors.FieldDescriptor repeatedField =
274 TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
275 assertNotNull(singularField);
276 assertNotNull(repeatedField);
279 UnknownFieldSet.newBuilder()
280 .addField(singularField.getNumber(),
281 UnknownFieldSet.Field.newBuilder()
282 .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
283 .addVarint(5) // not valid
285 .addField(repeatedField.getNumber(),
286 UnknownFieldSet.Field.newBuilder()
287 .addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
288 .addVarint(4) // not valid
289 .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
290 .addVarint(6) // not valid
296 TestAllTypes message = TestAllTypes.parseFrom(data);
297 assertEquals(TestAllTypes.NestedEnum.BAR,
298 message.getOptionalNestedEnum());
300 Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
301 message.getRepeatedNestedEnumList());
302 assertEquals(Arrays.asList(5L),
303 message.getUnknownFields()
304 .getField(singularField.getNumber())
306 assertEquals(Arrays.asList(4L, 6L),
307 message.getUnknownFields()
308 .getField(repeatedField.getNumber())
313 TestAllExtensions message =
314 TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
315 assertEquals(TestAllTypes.NestedEnum.BAR,
316 message.getExtension(UnittestProto.optionalNestedEnumExtension));
318 Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
319 message.getExtension(UnittestProto.repeatedNestedEnumExtension));
320 assertEquals(Arrays.asList(5L),
321 message.getUnknownFields()
322 .getField(singularField.getNumber())
324 assertEquals(Arrays.asList(4L, 6L),
325 message.getUnknownFields()
326 .getField(repeatedField.getNumber())
331 public void testLargeVarint() throws Exception {
333 UnknownFieldSet.newBuilder()
335 UnknownFieldSet.Field.newBuilder()
336 .addVarint(0x7FFFFFFFFFFFFFFFL)
340 UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data);
341 UnknownFieldSet.Field field = parsed.getField(1);
342 assertEquals(1, field.getVarintList().size());
343 assertEquals(0x7FFFFFFFFFFFFFFFL, (long)field.getVarintList().get(0));
346 public void testEqualsAndHashCode() {
347 UnknownFieldSet.Field fixed32Field =
348 UnknownFieldSet.Field.newBuilder()
351 UnknownFieldSet.Field fixed64Field =
352 UnknownFieldSet.Field.newBuilder()
355 UnknownFieldSet.Field varIntField =
356 UnknownFieldSet.Field.newBuilder()
359 UnknownFieldSet.Field lengthDelimitedField =
360 UnknownFieldSet.Field.newBuilder()
361 .addLengthDelimited(ByteString.EMPTY)
363 UnknownFieldSet.Field groupField =
364 UnknownFieldSet.Field.newBuilder()
365 .addGroup(unknownFields)
369 UnknownFieldSet.newBuilder()
370 .addField(1, fixed32Field)
373 UnknownFieldSet.newBuilder()
374 .addField(1, fixed64Field)
377 UnknownFieldSet.newBuilder()
378 .addField(1, varIntField)
381 UnknownFieldSet.newBuilder()
382 .addField(1, lengthDelimitedField)
385 UnknownFieldSet.newBuilder()
386 .addField(1, groupField)
389 checkEqualsIsConsistent(a);
390 checkEqualsIsConsistent(b);
391 checkEqualsIsConsistent(c);
392 checkEqualsIsConsistent(d);
393 checkEqualsIsConsistent(e);
408 * Asserts that the given field sets are not equal and have different
411 * @warning It's valid for non-equal objects to have the same hash code, so
412 * this test is stricter than it needs to be. However, this should happen
415 private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) {
416 String equalsError = String.format("%s should not be equal to %s", s1, s2);
417 assertFalse(equalsError, s1.equals(s2));
418 assertFalse(equalsError, s2.equals(s1));
421 String.format("%s should have a different hash code from %s", s1, s2),
422 s1.hashCode() == s2.hashCode());
426 * Asserts that the given field sets are equal and have identical hash codes.
428 private void checkEqualsIsConsistent(UnknownFieldSet set) {
429 // Object should be equal to itself.
430 assertEquals(set, set);
432 // Object should be equal to a copy of itself.
433 UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build();
434 assertEquals(set, copy);
435 assertEquals(copy, set);
436 assertEquals(set.hashCode(), copy.hashCode());