OLD | NEW |
| (Empty) |
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 } | |
OLD | NEW |