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 junit.framework.TestCase;
36 import java.io.ByteArrayInputStream;
37 import java.io.ByteArrayOutputStream;
38 import java.util.List;
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;
52 * Tests related to parsing and serialization.
54 * @author kenton@google.com (Kenton Varda)
56 public class WireFormatTest extends TestCase {
57 public void testSerialization() throws Exception {
58 TestAllTypes message = TestUtil.getAllSet();
60 ByteString rawBytes = message.toByteString();
61 assertEquals(rawBytes.size(), message.getSerializedSize());
63 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
65 TestUtil.assertAllFieldsSet(message2);
68 public void testSerializationPacked() throws Exception {
69 TestPackedTypes message = TestUtil.getPackedSet();
71 ByteString rawBytes = message.toByteString();
72 assertEquals(rawBytes.size(), message.getSerializedSize());
74 TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
76 TestUtil.assertPackedFieldsSet(message2);
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
84 TestAllExtensions message = TestUtil.getAllExtensionsSet();
85 ByteString rawBytes = message.toByteString();
86 assertEquals(rawBytes.size(), message.getSerializedSize());
88 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
90 TestUtil.assertAllFieldsSet(message2);
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();
99 TestPackedTypes message2 = TestUtil.getPackedSet();
100 ByteString rawBytes2 = message2.toByteString();
102 assertEquals(rawBytes, rawBytes2);
105 public void testSerializationPackedWithoutGetSerializedSize()
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();
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);
117 message.writeTo(codedOutput);
121 TestPackedTypes message2 = TestPackedTypes.parseFrom(
122 outputStream.toByteArray());
124 TestUtil.assertPackedFieldsSet(message2);
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
132 TestAllTypes message = TestUtil.getAllSet();
133 ByteString rawBytes = message.toByteString();
135 ExtensionRegistry registry = TestUtil.getExtensionRegistry();
137 TestAllExtensions message2 =
138 TestAllExtensions.parseFrom(rawBytes, registry);
140 TestUtil.assertAllExtensionsSet(message2);
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();
148 ExtensionRegistry registry = TestUtil.getExtensionRegistry();
150 TestPackedExtensions message2 =
151 TestPackedExtensions.parseFrom(rawBytes, registry);
153 TestUtil.assertPackedExtensionsSet(message2);
156 public void testExtensionsSerializedSize() throws Exception {
157 assertEquals(TestUtil.getAllSet().getSerializedSize(),
158 TestUtil.getAllExtensionsSet().getSerializedSize());
161 public void testSerializeDelimited() throws Exception {
162 ByteArrayOutputStream output = new ByteArrayOutputStream();
163 TestUtil.getAllSet().writeDelimitedTo(output);
165 TestUtil.getPackedSet().writeDelimitedTo(output);
168 ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
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());
176 // We're at EOF, so parsing again should return null.
177 assertTrue(TestAllTypes.parseDelimitedFrom(input) == null);
180 private void assertFieldsInOrder(ByteString data) throws Exception {
181 CodedInputStream input = data.newCodedInput();
185 int tag = input.readTag();
190 assertTrue(tag > previousTag);
192 input.skipField(tag);
196 public void testInterleavedFieldsAndExtensions() throws Exception {
197 // Tests that fields are written in order even when extension ranges
198 // are interleaved with field numbers.
200 TestFieldOrderings.newBuilder()
204 .setExtension(UnittestProto.myExtensionInt, 23)
205 .setExtension(UnittestProto.myExtensionString, "bar")
206 .build().toByteString();
207 assertFieldsInOrder(data);
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);
221 private ExtensionRegistry getTestFieldOrderingsRegistry() {
222 ExtensionRegistry result = ExtensionRegistry.newInstance();
223 result.add(UnittestProto.myExtensionInt);
224 result.add(UnittestProto.myExtensionString);
228 public void testParseMultipleExtensionRanges() throws Exception {
229 // Make sure we can parse a message that contains multiple extensions
231 TestFieldOrderings source =
232 TestFieldOrderings.newBuilder()
236 .setExtension(UnittestProto.myExtensionInt, 23)
237 .setExtension(UnittestProto.myExtensionString, "bar")
239 TestFieldOrderings dest =
240 TestFieldOrderings.parseFrom(source.toByteString(),
241 getTestFieldOrderingsRegistry());
242 assertEquals(source, dest);
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")
256 DynamicMessage dest =
257 DynamicMessage.parseFrom(descriptor, source.toByteString(),
258 getTestFieldOrderingsRegistry());
259 assertEquals(source, dest);
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();
268 public void testSerializeMessageSetEagerly() throws Exception {
269 testSerializeMessageSetWithFlag(true);
272 public void testSerializeMessageSetNotEagerly() throws Exception {
273 testSerializeMessageSetWithFlag(false);
276 private void testSerializeMessageSetWithFlag(boolean eagerParsing)
278 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
279 // Set up a TestMessageSet with two known messages and an unknown one.
280 TestMessageSet messageSet =
281 TestMessageSet.newBuilder()
283 TestMessageSetExtension1.messageSetExtension,
284 TestMessageSetExtension1.newBuilder().setI(123).build())
286 TestMessageSetExtension2.messageSetExtension,
287 TestMessageSetExtension2.newBuilder().setStr("foo").build())
289 UnknownFieldSet.newBuilder()
290 .addField(UNKNOWN_TYPE_ID,
291 UnknownFieldSet.Field.newBuilder()
292 .addLengthDelimited(ByteString.copyFromUtf8("bar"))
297 ByteString data = messageSet.toByteString();
299 // Parse back using RawMessageSet and check the contents.
300 RawMessageSet raw = RawMessageSet.parseFrom(data);
302 assertTrue(raw.getUnknownFields().asMap().isEmpty());
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());
309 TestMessageSetExtension1 message1 =
310 TestMessageSetExtension1.parseFrom(
311 raw.getItem(0).getMessage().toByteArray());
312 assertEquals(123, message1.getI());
314 TestMessageSetExtension2 message2 =
315 TestMessageSetExtension2.parseFrom(
316 raw.getItem(1).getMessage().toByteArray());
317 assertEquals("foo", message2.getStr());
319 assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
322 public void testParseMessageSetEagerly() throws Exception {
323 testParseMessageSetWithFlag(true);
326 public void testParseMessageSetNotEagerly()throws Exception {
327 testParseMessageSetWithFlag(false);
330 private void testParseMessageSetWithFlag(boolean eagerParsing)
332 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
333 ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
334 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
335 extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
337 // Set up a RawMessageSet with two known messages and an unknown one.
339 RawMessageSet.newBuilder()
341 RawMessageSet.Item.newBuilder()
342 .setTypeId(TYPE_ID_1)
344 TestMessageSetExtension1.newBuilder()
346 .build().toByteString())
349 RawMessageSet.Item.newBuilder()
350 .setTypeId(TYPE_ID_2)
352 TestMessageSetExtension2.newBuilder()
354 .build().toByteString())
357 RawMessageSet.Item.newBuilder()
358 .setTypeId(UNKNOWN_TYPE_ID)
359 .setMessage(ByteString.copyFromUtf8("bar"))
363 ByteString data = raw.toByteString();
365 // Parse as a TestMessageSet and check the contents.
366 TestMessageSet messageSet =
367 TestMessageSet.parseFrom(data, extensionRegistry);
369 assertEquals(123, messageSet.getExtension(
370 TestMessageSetExtension1.messageSetExtension).getI());
371 assertEquals("foo", messageSet.getExtension(
372 TestMessageSetExtension2.messageSetExtension).getStr());
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));
380 UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID);
381 assertEquals(1, field.getLengthDelimitedList().size());
382 assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
385 public void testParseMessageSetExtensionEagerly() throws Exception {
386 testParseMessageSetExtensionWithFlag(true);
389 public void testParseMessageSetExtensionNotEagerly() throws Exception {
390 testParseMessageSetExtensionWithFlag(false);
393 private void testParseMessageSetExtensionWithFlag(boolean eagerParsing)
395 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
396 ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
397 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
399 // Set up a RawMessageSet with a known messages.
401 TestMessageSetExtension1
402 .getDescriptor().getExtensions().get(0).getNumber();
404 RawMessageSet.newBuilder()
406 RawMessageSet.Item.newBuilder()
407 .setTypeId(TYPE_ID_1)
409 TestMessageSetExtension1.newBuilder()
411 .build().toByteString())
415 ByteString data = raw.toByteString();
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());
424 public void testMergeLazyMessageSetExtensionEagerly() throws Exception {
425 testMergeLazyMessageSetExtensionWithFlag(true);
428 public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception {
429 testMergeLazyMessageSetExtensionWithFlag(false);
432 private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)
434 ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
435 ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
436 extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
438 // Set up a RawMessageSet with a known messages.
440 TestMessageSetExtension1
441 .getDescriptor().getExtensions().get(0).getNumber();
443 RawMessageSet.newBuilder()
445 RawMessageSet.Item.newBuilder()
446 .setTypeId(TYPE_ID_1)
448 TestMessageSetExtension1.newBuilder()
450 .build().toByteString())
454 ByteString data = raw.toByteString();
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.
461 messageSet.toBuilder().mergeFrom(data, extensionRegistry).build();
462 assertEquals(123, messageSet.getExtension(
463 TestMessageSetExtension1.messageSetExtension).getI());