b9bfb691b1ef3c6571a9abe1a5db9cc05d959683
[tools/dynpart-tools.git] /
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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.test;
32 import com.google.protobuf.*;
33
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;
39
40 import junit.framework.TestCase;
41
42 import java.util.Arrays;
43 import java.util.Map;
44
45 /**
46  * Tests related to unknown field handling.
47  *
48  * @author kenton@google.com (Kenton Varda)
49  */
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();
57   }
58
59   UnknownFieldSet.Field getField(String name) {
60     Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
61     assertNotNull(field);
62     return unknownFields.getField(field.getNumber());
63   }
64
65   // Constructs a protocol buffer which contains fields with all the same
66   // numbers as allFieldsData except that each field is some other wire
67   // type.
68   ByteString getBizarroData() throws Exception {
69     UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder();
70
71     UnknownFieldSet.Field varintField =
72       UnknownFieldSet.Field.newBuilder().addVarint(1).build();
73     UnknownFieldSet.Field fixed32Field =
74       UnknownFieldSet.Field.newBuilder().addFixed32(1).build();
75
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);
81       } else {
82         // Original field *is* a varint, so use something else.
83         bizarroFields.addField(entry.getKey(), fixed32Field);
84       }
85     }
86
87     return bizarroFields.build().toByteString();
88   }
89
90   Descriptors.Descriptor descriptor;
91   TestAllTypes allFields;
92   ByteString allFieldsData;
93
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;
98
99   // =================================================================
100
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));
106   }
107
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));
113   }
114
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));
120   }
121
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));
127   }
128
129   public void testGroup() throws Exception {
130     Descriptors.FieldDescriptor nestedFieldDescriptor =
131       TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a");
132     assertNotNull(nestedFieldDescriptor);
133
134     UnknownFieldSet.Field field = getField("optionalgroup");
135     assertEquals(1, field.getGroupList().size());
136
137     UnknownFieldSet group = field.getGroupList().get(0);
138     assertEquals(1, group.asMap().size());
139     assertTrue(group.hasField(nestedFieldDescriptor.getNumber()));
140
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));
146   }
147
148   public void testSerialize() throws Exception {
149     // Check that serializing the UnknownFieldSet produces the original data
150     // again.
151     ByteString data = emptyMessage.toByteString();
152     assertEquals(allFieldsData, data);
153   }
154
155   public void testCopyFrom() throws Exception {
156     TestEmptyMessage message =
157       TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build();
158
159     assertEquals(emptyMessage.toString(), message.toString());
160   }
161
162   public void testMergeFrom() throws Exception {
163     TestEmptyMessage source =
164       TestEmptyMessage.newBuilder()
165         .setUnknownFields(
166           UnknownFieldSet.newBuilder()
167             .addField(2,
168               UnknownFieldSet.Field.newBuilder()
169                 .addVarint(2).build())
170             .addField(3,
171               UnknownFieldSet.Field.newBuilder()
172                 .addVarint(4).build())
173             .build())
174         .build();
175     TestEmptyMessage destination =
176       TestEmptyMessage.newBuilder()
177         .setUnknownFields(
178           UnknownFieldSet.newBuilder()
179             .addField(1,
180               UnknownFieldSet.Field.newBuilder()
181                 .addVarint(1).build())
182             .addField(3,
183               UnknownFieldSet.Field.newBuilder()
184                 .addVarint(3).build())
185             .build())
186         .mergeFrom(source)
187         .build();
188
189     assertEquals(
190       "1: 1\n" +
191       "2: 2\n" +
192       "3: 3\n" +
193       "3: 4\n",
194       destination.toString());
195   }
196
197   public void testClear() throws Exception {
198     UnknownFieldSet fields =
199       UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
200     assertTrue(fields.asMap().isEmpty());
201   }
202
203   public void testClearMessage() throws Exception {
204     TestEmptyMessage message =
205       TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
206     assertEquals(0, message.getSerializedSize());
207   }
208
209   public void testParseKnownAndUnknown() throws Exception {
210     // Test mixing known and unknown fields when parsing.
211
212     UnknownFieldSet fields =
213       UnknownFieldSet.newBuilder(unknownFields)
214         .addField(123456,
215           UnknownFieldSet.Field.newBuilder().addVarint(654321).build())
216         .build();
217
218     ByteString data = fields.toByteString();
219     TestAllTypes destination = TestAllTypes.parseFrom(data);
220
221     TestUtil.assertAllFieldsSet(destination);
222     assertEquals(1, destination.getUnknownFields().asMap().size());
223
224     UnknownFieldSet.Field field =
225       destination.getUnknownFields().getField(123456);
226     assertEquals(1, field.getVarintList().size());
227     assertEquals(654321, (long) field.getVarintList().get(0));
228   }
229
230   public void testWrongTypeTreatedAsUnknown() throws Exception {
231     // Test that fields of the wrong wire type are treated like unknown fields
232     // when parsing.
233
234     ByteString bizarroData = getBizarroData();
235     TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
236     TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
237
238     // All fields should have been interpreted as unknown, so the debug strings
239     // should be the same.
240     assertEquals(emptyMessage.toString(), allTypesMessage.toString());
241   }
242
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.
246
247     TestEmptyMessageWithExtensions message =
248       TestEmptyMessageWithExtensions.parseFrom(allFieldsData);
249
250     assertEquals(unknownFields.asMap().size(),
251                  message.getUnknownFields().asMap().size());
252     assertEquals(allFieldsData, message.toByteString());
253   }
254
255   public void testWrongExtensionTypeTreatedAsUnknown() throws Exception {
256     // Test that fields of the wrong wire type are treated like unknown fields
257     // when parsing extensions.
258
259     ByteString bizarroData = getBizarroData();
260     TestAllExtensions allExtensionsMessage =
261       TestAllExtensions.parseFrom(bizarroData);
262     TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
263
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());
268   }
269
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);
277
278     ByteString data =
279       UnknownFieldSet.newBuilder()
280         .addField(singularField.getNumber(),
281           UnknownFieldSet.Field.newBuilder()
282             .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
283             .addVarint(5)   // not valid
284             .build())
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
291             .build())
292         .build()
293         .toByteString();
294
295     {
296       TestAllTypes message = TestAllTypes.parseFrom(data);
297       assertEquals(TestAllTypes.NestedEnum.BAR,
298                    message.getOptionalNestedEnum());
299       assertEquals(
300         Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
301         message.getRepeatedNestedEnumList());
302       assertEquals(Arrays.asList(5L),
303                    message.getUnknownFields()
304                           .getField(singularField.getNumber())
305                           .getVarintList());
306       assertEquals(Arrays.asList(4L, 6L),
307                    message.getUnknownFields()
308                           .getField(repeatedField.getNumber())
309                           .getVarintList());
310     }
311
312     {
313       TestAllExtensions message =
314         TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
315       assertEquals(TestAllTypes.NestedEnum.BAR,
316         message.getExtension(UnittestProto.optionalNestedEnumExtension));
317       assertEquals(
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())
323                           .getVarintList());
324       assertEquals(Arrays.asList(4L, 6L),
325                    message.getUnknownFields()
326                           .getField(repeatedField.getNumber())
327                           .getVarintList());
328     }
329   }
330
331   public void testLargeVarint() throws Exception {
332     ByteString data =
333       UnknownFieldSet.newBuilder()
334         .addField(1,
335           UnknownFieldSet.Field.newBuilder()
336             .addVarint(0x7FFFFFFFFFFFFFFFL)
337             .build())
338         .build()
339         .toByteString();
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));
344   }
345
346   public void testEqualsAndHashCode() {
347     UnknownFieldSet.Field fixed32Field =
348         UnknownFieldSet.Field.newBuilder()
349             .addFixed32(1)
350             .build();
351     UnknownFieldSet.Field fixed64Field =
352         UnknownFieldSet.Field.newBuilder()
353             .addFixed64(1)
354             .build();
355     UnknownFieldSet.Field varIntField =
356         UnknownFieldSet.Field.newBuilder()
357             .addVarint(1)
358             .build();
359     UnknownFieldSet.Field lengthDelimitedField =
360         UnknownFieldSet.Field.newBuilder()
361             .addLengthDelimited(ByteString.EMPTY)
362             .build();
363     UnknownFieldSet.Field groupField =
364         UnknownFieldSet.Field.newBuilder()
365             .addGroup(unknownFields)
366             .build();
367
368     UnknownFieldSet a =
369         UnknownFieldSet.newBuilder()
370             .addField(1, fixed32Field)
371             .build();
372     UnknownFieldSet b =
373         UnknownFieldSet.newBuilder()
374             .addField(1, fixed64Field)
375             .build();
376     UnknownFieldSet c =
377         UnknownFieldSet.newBuilder()
378             .addField(1, varIntField)
379             .build();
380     UnknownFieldSet d =
381         UnknownFieldSet.newBuilder()
382             .addField(1, lengthDelimitedField)
383             .build();
384     UnknownFieldSet e =
385         UnknownFieldSet.newBuilder()
386             .addField(1, groupField)
387             .build();
388
389     checkEqualsIsConsistent(a);
390     checkEqualsIsConsistent(b);
391     checkEqualsIsConsistent(c);
392     checkEqualsIsConsistent(d);
393     checkEqualsIsConsistent(e);
394
395     checkNotEqual(a, b);
396     checkNotEqual(a, c);
397     checkNotEqual(a, d);
398     checkNotEqual(a, e);
399     checkNotEqual(b, c);
400     checkNotEqual(b, d);
401     checkNotEqual(b, e);
402     checkNotEqual(c, d);
403     checkNotEqual(c, e);
404     checkNotEqual(d, e);
405   }
406
407   /**
408    * Asserts that the given field sets are not equal and have different
409    * hash codes.
410    *
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
413    *   relatively rarely.
414    */
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));
419
420     assertFalse(
421         String.format("%s should have a different hash code from %s", s1, s2),
422         s1.hashCode() == s2.hashCode());
423   }
424
425   /**
426    * Asserts that the given field sets are equal and have identical hash codes.
427    */
428   private void checkEqualsIsConsistent(UnknownFieldSet set) {
429     // Object should be equal to itself.
430     assertEquals(set, set);
431
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());
437   }
438 }