7452872620b750a1fe3109746c852c0e543fe9f0
[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 junit.framework.TestCase;
35
36 import java.io.ByteArrayInputStream;
37 import java.io.ByteArrayOutputStream;
38 import java.util.List;
39
40 import protobuf_unittest.UnittestProto;
41 import protobuf_unittest.UnittestProto.TestAllExtensions;
42 import protobuf_unittest.UnittestProto.TestAllTypes;
43 import protobuf_unittest.UnittestProto.TestFieldOrderings;
44 import protobuf_unittest.UnittestProto.TestPackedExtensions;
45 import protobuf_unittest.UnittestProto.TestPackedTypes;
46 import protobuf_unittest.UnittestMset.TestMessageSet;
47 import protobuf_unittest.UnittestMset.RawMessageSet;
48 import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
49 import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
50
51 /**
52  * Tests related to parsing and serialization.
53  *
54  * @author kenton@google.com (Kenton Varda)
55  */
56 public class WireFormatTest extends TestCase {
57   public void testSerialization() throws Exception {
58     TestAllTypes message = TestUtil.getAllSet();
59
60     ByteString rawBytes = message.toByteString();
61     assertEquals(rawBytes.size(), message.getSerializedSize());
62
63     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
64
65     TestUtil.assertAllFieldsSet(message2);
66   }
67
68   public void testSerializationPacked() throws Exception {
69     TestPackedTypes message = TestUtil.getPackedSet();
70
71     ByteString rawBytes = message.toByteString();
72     assertEquals(rawBytes.size(), message.getSerializedSize());
73
74     TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
75
76     TestUtil.assertPackedFieldsSet(message2);
77   }
78
79   public void testSerializeExtensions() throws Exception {
80     // TestAllTypes and TestAllExtensions should have compatible wire formats,
81     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
82     // it should work.
83
84     TestAllExtensions message = TestUtil.getAllExtensionsSet();
85     ByteString rawBytes = message.toByteString();
86     assertEquals(rawBytes.size(), message.getSerializedSize());
87
88     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
89
90     TestUtil.assertAllFieldsSet(message2);
91   }
92
93   public void testSerializePackedExtensions() throws Exception {
94     // TestPackedTypes and TestPackedExtensions should have compatible wire
95     // formats; check that they serialize to the same string.
96     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
97     ByteString rawBytes = message.toByteString();
98
99     TestPackedTypes message2 = TestUtil.getPackedSet();
100     ByteString rawBytes2 = message2.toByteString();
101
102     assertEquals(rawBytes, rawBytes2);
103   }
104
105   public void testSerializationPackedWithoutGetSerializedSize()
106       throws Exception {
107     // Write directly to an OutputStream, without invoking getSerializedSize()
108     // This used to be a bug where the size of a packed field was incorrect,
109     // since getSerializedSize() was never invoked.
110     TestPackedTypes message = TestUtil.getPackedSet();
111
112     // Directly construct a CodedOutputStream around the actual OutputStream,
113     // in case writeTo(OutputStream output) invokes getSerializedSize();
114     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
115     CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream);
116
117     message.writeTo(codedOutput);
118
119     codedOutput.flush();
120
121     TestPackedTypes message2 = TestPackedTypes.parseFrom(
122         outputStream.toByteArray());
123
124     TestUtil.assertPackedFieldsSet(message2);
125   }
126
127   public void testParseExtensions() throws Exception {
128     // TestAllTypes and TestAllExtensions should have compatible wire formats,
129     // so if we serialize a TestAllTypes then parse it as TestAllExtensions
130     // it should work.
131
132     TestAllTypes message = TestUtil.getAllSet();
133     ByteString rawBytes = message.toByteString();
134
135     ExtensionRegistry registry = TestUtil.getExtensionRegistry();
136
137     TestAllExtensions message2 =
138       TestAllExtensions.parseFrom(rawBytes, registry);
139
140     TestUtil.assertAllExtensionsSet(message2);
141   }
142
143   public void testParsePackedExtensions() throws Exception {
144     // Ensure that packed extensions can be properly parsed.
145     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
146     ByteString rawBytes = message.toByteString();
147
148     ExtensionRegistry registry = TestUtil.getExtensionRegistry();
149
150     TestPackedExtensions message2 =
151         TestPackedExtensions.parseFrom(rawBytes, registry);
152
153     TestUtil.assertPackedExtensionsSet(message2);
154   }
155
156   public void testExtensionsSerializedSize() throws Exception {
157     assertEquals(TestUtil.getAllSet().getSerializedSize(),
158                  TestUtil.getAllExtensionsSet().getSerializedSize());
159   }
160
161   public void testSerializeDelimited() throws Exception {
162     ByteArrayOutputStream output = new ByteArrayOutputStream();
163     TestUtil.getAllSet().writeDelimitedTo(output);
164     output.write(12);
165     TestUtil.getPackedSet().writeDelimitedTo(output);
166     output.write(34);
167
168     ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
169
170     TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input));
171     assertEquals(12, input.read());
172     TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input));
173     assertEquals(34, input.read());
174     assertEquals(-1, input.read());
175
176     // We're at EOF, so parsing again should return null.
177     assertTrue(TestAllTypes.parseDelimitedFrom(input) == null);
178   }
179
180   private void assertFieldsInOrder(ByteString data) throws Exception {
181     CodedInputStream input = data.newCodedInput();
182     int previousTag = 0;
183
184     while (true) {
185       int tag = input.readTag();
186       if (tag == 0) {
187         break;
188       }
189
190       assertTrue(tag > previousTag);
191       previousTag = tag;
192       input.skipField(tag);
193     }
194   }
195
196   public void testInterleavedFieldsAndExtensions() throws Exception {
197     // Tests that fields are written in order even when extension ranges
198     // are interleaved with field numbers.
199     ByteString data =
200       TestFieldOrderings.newBuilder()
201         .setMyInt(1)
202         .setMyString("foo")
203         .setMyFloat(1.0F)
204         .setExtension(UnittestProto.myExtensionInt, 23)
205         .setExtension(UnittestProto.myExtensionString, "bar")
206         .build().toByteString();
207     assertFieldsInOrder(data);
208
209     Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
210     ByteString dynamic_data =
211       DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
212         .setField(descriptor.findFieldByName("my_int"), 1L)
213         .setField(descriptor.findFieldByName("my_string"), "foo")
214         .setField(descriptor.findFieldByName("my_float"), 1.0F)
215         .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
216         .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
217         .build().toByteString();
218     assertFieldsInOrder(dynamic_data);
219   }
220
221   private ExtensionRegistry getTestFieldOrderingsRegistry() {
222     ExtensionRegistry result = ExtensionRegistry.newInstance();
223     result.add(UnittestProto.myExtensionInt);
224     result.add(UnittestProto.myExtensionString);
225     return result;
226   }
227
228   public void testParseMultipleExtensionRanges() throws Exception {
229     // Make sure we can parse a message that contains multiple extensions
230     // ranges.
231     TestFieldOrderings source =
232       TestFieldOrderings.newBuilder()
233         .setMyInt(1)
234         .setMyString("foo")
235         .setMyFloat(1.0F)
236         .setExtension(UnittestProto.myExtensionInt, 23)
237         .setExtension(UnittestProto.myExtensionString, "bar")
238         .build();
239     TestFieldOrderings dest =
240       TestFieldOrderings.parseFrom(source.toByteString(),
241                                    getTestFieldOrderingsRegistry());
242     assertEquals(source, dest);
243   }
244
245   public void testParseMultipleExtensionRangesDynamic() throws Exception {
246     // Same as above except with DynamicMessage.
247     Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
248     DynamicMessage source =
249       DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
250         .setField(descriptor.findFieldByName("my_int"), 1L)
251         .setField(descriptor.findFieldByName("my_string"), "foo")
252         .setField(descriptor.findFieldByName("my_float"), 1.0F)
253         .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
254         .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
255         .build();
256     DynamicMessage dest =
257       DynamicMessage.parseFrom(descriptor, source.toByteString(),
258                                getTestFieldOrderingsRegistry());
259     assertEquals(source, dest);
260   }
261
262   private static final int UNKNOWN_TYPE_ID = 1550055;
263   private static final int TYPE_ID_1 =
264     TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber();
265   private static final int TYPE_ID_2 =
266     TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber();
267
268   public void testSerializeMessageSetEagerly() throws Exception {
269     testSerializeMessageSetWithFlag(true);
270   }
271
272   public void testSerializeMessageSetNotEagerly() throws Exception {
273     testSerializeMessageSetWithFlag(false);
274   }
275
276   private void testSerializeMessageSetWithFlag(boolean eagerParsing)
277       throws Exception {
278     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
279     // Set up a TestMessageSet with two known messages and an unknown one.
280     TestMessageSet messageSet =
281       TestMessageSet.newBuilder()
282         .setExtension(
283           TestMessageSetExtension1.messageSetExtension,
284           TestMessageSetExtension1.newBuilder().setI(123).build())
285         .setExtension(
286           TestMessageSetExtension2.messageSetExtension,
287           TestMessageSetExtension2.newBuilder().setStr("foo").build())
288         .setUnknownFields(
289           UnknownFieldSet.newBuilder()
290             .addField(UNKNOWN_TYPE_ID,
291               UnknownFieldSet.Field.newBuilder()
292                 .addLengthDelimited(ByteString.copyFromUtf8("bar"))
293                 .build())
294             .build())
295         .build();
296
297     ByteString data = messageSet.toByteString();
298
299     // Parse back using RawMessageSet and check the contents.
300     RawMessageSet raw = RawMessageSet.parseFrom(data);
301
302     assertTrue(raw.getUnknownFields().asMap().isEmpty());
303
304     assertEquals(3, raw.getItemCount());
305     assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId());
306     assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId());
307     assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId());
308
309     TestMessageSetExtension1 message1 =
310       TestMessageSetExtension1.parseFrom(
311         raw.getItem(0).getMessage().toByteArray());
312     assertEquals(123, message1.getI());
313
314     TestMessageSetExtension2 message2 =
315       TestMessageSetExtension2.parseFrom(
316         raw.getItem(1).getMessage().toByteArray());
317     assertEquals("foo", message2.getStr());
318
319     assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
320   }
321
322   public void testParseMessageSetEagerly() throws Exception {
323     testParseMessageSetWithFlag(true);
324   }
325
326   public void testParseMessageSetNotEagerly()throws Exception {
327     testParseMessageSetWithFlag(false);
328   }
329
330   private void testParseMessageSetWithFlag(boolean eagerParsing)
331       throws Exception {
332     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
333     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
334     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
335     extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
336
337     // Set up a RawMessageSet with two known messages and an unknown one.
338     RawMessageSet raw =
339       RawMessageSet.newBuilder()
340         .addItem(
341           RawMessageSet.Item.newBuilder()
342             .setTypeId(TYPE_ID_1)
343             .setMessage(
344               TestMessageSetExtension1.newBuilder()
345                 .setI(123)
346                 .build().toByteString())
347             .build())
348         .addItem(
349           RawMessageSet.Item.newBuilder()
350             .setTypeId(TYPE_ID_2)
351             .setMessage(
352               TestMessageSetExtension2.newBuilder()
353                 .setStr("foo")
354                 .build().toByteString())
355             .build())
356         .addItem(
357           RawMessageSet.Item.newBuilder()
358             .setTypeId(UNKNOWN_TYPE_ID)
359             .setMessage(ByteString.copyFromUtf8("bar"))
360             .build())
361         .build();
362
363     ByteString data = raw.toByteString();
364
365     // Parse as a TestMessageSet and check the contents.
366     TestMessageSet messageSet =
367       TestMessageSet.parseFrom(data, extensionRegistry);
368
369     assertEquals(123, messageSet.getExtension(
370       TestMessageSetExtension1.messageSetExtension).getI());
371     assertEquals("foo", messageSet.getExtension(
372       TestMessageSetExtension2.messageSetExtension).getStr());
373
374     // Check for unknown field with type LENGTH_DELIMITED,
375     //   number UNKNOWN_TYPE_ID, and contents "bar".
376     UnknownFieldSet unknownFields = messageSet.getUnknownFields();
377     assertEquals(1, unknownFields.asMap().size());
378     assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID));
379
380     UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID);
381     assertEquals(1, field.getLengthDelimitedList().size());
382     assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
383   }
384
385   public void testParseMessageSetExtensionEagerly() throws Exception {
386     testParseMessageSetExtensionWithFlag(true);
387   }
388
389   public void testParseMessageSetExtensionNotEagerly() throws Exception {
390     testParseMessageSetExtensionWithFlag(false);
391   }
392
393   private void testParseMessageSetExtensionWithFlag(boolean eagerParsing)
394       throws Exception {
395     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
396     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
397     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
398
399     // Set up a RawMessageSet with a known messages.
400     int TYPE_ID_1 =
401         TestMessageSetExtension1
402             .getDescriptor().getExtensions().get(0).getNumber();
403     RawMessageSet raw =
404       RawMessageSet.newBuilder()
405         .addItem(
406           RawMessageSet.Item.newBuilder()
407             .setTypeId(TYPE_ID_1)
408             .setMessage(
409               TestMessageSetExtension1.newBuilder()
410                 .setI(123)
411                 .build().toByteString())
412             .build())
413         .build();
414
415     ByteString data = raw.toByteString();
416
417     // Parse as a TestMessageSet and check the contents.
418     TestMessageSet messageSet =
419         TestMessageSet.parseFrom(data, extensionRegistry);
420     assertEquals(123, messageSet.getExtension(
421         TestMessageSetExtension1.messageSetExtension).getI());
422   }
423
424   public void testMergeLazyMessageSetExtensionEagerly() throws Exception {
425     testMergeLazyMessageSetExtensionWithFlag(true);
426   }
427
428   public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception {
429     testMergeLazyMessageSetExtensionWithFlag(false);
430   }
431
432   private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)
433       throws Exception {
434     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
435     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
436     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
437
438     // Set up a RawMessageSet with a known messages.
439     int TYPE_ID_1 =
440         TestMessageSetExtension1
441             .getDescriptor().getExtensions().get(0).getNumber();
442     RawMessageSet raw =
443       RawMessageSet.newBuilder()
444         .addItem(
445           RawMessageSet.Item.newBuilder()
446             .setTypeId(TYPE_ID_1)
447             .setMessage(
448               TestMessageSetExtension1.newBuilder()
449                 .setI(123)
450                 .build().toByteString())
451             .build())
452         .build();
453
454     ByteString data = raw.toByteString();
455
456     // Parse as a TestMessageSet and store value into lazy field
457     TestMessageSet messageSet =
458         TestMessageSet.parseFrom(data, extensionRegistry);
459     // Merge lazy field check the contents.
460     messageSet =
461         messageSet.toBuilder().mergeFrom(data, extensionRegistry).build();
462     assertEquals(123, messageSet.getExtension(
463         TestMessageSetExtension1.messageSetExtension).getI());
464   }
465 }