b35af689cd2c62fbfa301fc13c7f6efeb2bc85bf
[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.UnittestOptimizeFor.TestOptimizedForSize;
35 import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
36 import protobuf_unittest.UnittestOptimizeFor;
37 import protobuf_unittest.UnittestProto.ForeignMessage;
38 import protobuf_unittest.UnittestProto.TestAllTypes;
39 import protobuf_unittest.UnittestProto.TestEmptyMessage;
40 import protobuf_unittest.UnittestProto.TestRequired;
41 import protobuf_unittest.UnittestProto.TestParsingMerge;
42 import protobuf_unittest.UnittestProto;
43
44 import junit.framework.TestCase;
45
46 import java.io.ByteArrayInputStream;
47 import java.io.ByteArrayOutputStream;
48 import java.io.IOException;
49 import java.io.InputStream;
50
51 /**
52  * Unit test for {@link Parser}.
53  *
54  * @author liujisi@google.com (Pherl Liu)
55  */
56 public class ParserTest extends TestCase {
57   public void testGeneratedMessageParserSingleton() throws Exception {
58     for (int i = 0; i < 10; i++) {
59       assertEquals(TestAllTypes.PARSER,
60                    TestUtil.getAllSet().getParserForType());
61     }
62   }
63
64   private void assertRoundTripEquals(MessageLite message,
65                                      ExtensionRegistryLite registry)
66       throws Exception {
67     final byte[] data = message.toByteArray();
68     final int offset = 20;
69     final int length = data.length;
70     final int padding = 30;
71     Parser<? extends MessageLite> parser = message.getParserForType();
72     assertMessageEquals(message, parser.parseFrom(data, registry));
73     assertMessageEquals(message, parser.parseFrom(
74         generatePaddingArray(data, offset, padding),
75         offset, length, registry));
76     assertMessageEquals(message, parser.parseFrom(
77         message.toByteString(), registry));
78     assertMessageEquals(message, parser.parseFrom(
79         new ByteArrayInputStream(data), registry));
80     assertMessageEquals(message, parser.parseFrom(
81         CodedInputStream.newInstance(data), registry));
82   }
83
84   private void assertRoundTripEquals(MessageLite message) throws Exception {
85     final byte[] data = message.toByteArray();
86     final int offset = 20;
87     final int length = data.length;
88     final int padding = 30;
89     Parser<? extends MessageLite> parser = message.getParserForType();
90     assertMessageEquals(message, parser.parseFrom(data));
91     assertMessageEquals(message, parser.parseFrom(
92         generatePaddingArray(data, offset, padding),
93         offset, length));
94     assertMessageEquals(message, parser.parseFrom(message.toByteString()));
95     assertMessageEquals(message, parser.parseFrom(
96         new ByteArrayInputStream(data)));
97     assertMessageEquals(message, parser.parseFrom(
98         CodedInputStream.newInstance(data)));
99   }
100
101   private void assertMessageEquals(MessageLite expected, MessageLite actual)
102       throws Exception {
103     if (expected instanceof Message) {
104       assertEquals(expected, actual);
105     } else {
106       assertEquals(expected.toByteString(), actual.toByteString());
107     }
108   }
109
110   private byte[] generatePaddingArray(byte[] data, int offset, int padding) {
111     byte[] result = new byte[offset + data.length + padding];
112     System.arraycopy(data, 0, result, offset, data.length);
113     return result;
114   }
115
116   public void testNormalMessage() throws Exception {
117     assertRoundTripEquals(TestUtil.getAllSet());
118   }
119
120   public void testParsePartial() throws Exception {
121     Parser<TestRequired> parser = TestRequired.PARSER;
122     final String errorString =
123         "Should throw exceptions when the parsed message isn't initialized.";
124
125     // TestRequired.b and TestRequired.c are not set.
126     TestRequired partialMessage = TestRequired.newBuilder()
127         .setA(1).buildPartial();
128
129     // parsePartialFrom should pass.
130     byte[] data = partialMessage.toByteArray();
131     assertEquals(partialMessage, parser.parsePartialFrom(data));
132     assertEquals(partialMessage, parser.parsePartialFrom(
133         partialMessage.toByteString()));
134     assertEquals(partialMessage, parser.parsePartialFrom(
135         new ByteArrayInputStream(data)));
136     assertEquals(partialMessage, parser.parsePartialFrom(
137         CodedInputStream.newInstance(data)));
138
139     // parseFrom(ByteArray)
140     try {
141       parser.parseFrom(partialMessage.toByteArray());
142       fail(errorString);
143     } catch (InvalidProtocolBufferException e) {
144       // pass.
145     }
146
147     // parseFrom(ByteString)
148     try {
149       parser.parseFrom(partialMessage.toByteString());
150       fail(errorString);
151     } catch (InvalidProtocolBufferException e) {
152       // pass.
153     }
154
155     // parseFrom(InputStream)
156     try {
157       parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray()));
158       fail(errorString);
159     } catch (IOException e) {
160       // pass.
161     }
162
163     // parseFrom(CodedInputStream)
164     try {
165       parser.parseFrom(CodedInputStream.newInstance(
166           partialMessage.toByteArray()));
167       fail(errorString);
168     } catch (IOException e) {
169       // pass.
170     }
171   }
172
173   public void testParseDelimitedTo() throws Exception {
174     // Write normal Message.
175     TestAllTypes normalMessage = TestUtil.getAllSet();
176     ByteArrayOutputStream output = new ByteArrayOutputStream();
177     normalMessage.writeDelimitedTo(output);
178
179     InputStream input = new ByteArrayInputStream(output.toByteArray());
180     assertMessageEquals(
181         normalMessage,
182         normalMessage.getParserForType().parseDelimitedFrom(input));
183   }
184
185   public void testParseUnknownFields() throws Exception {
186     // All fields will be treated as unknown fields in emptyMessage.
187     TestEmptyMessage emptyMessage = TestEmptyMessage.PARSER.parseFrom(
188         TestUtil.getAllSet().toByteString());
189     assertEquals(
190         TestUtil.getAllSet().toByteString(),
191         emptyMessage.toByteString());
192   }
193
194   public void testOptimizeForSize() throws Exception {
195     TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
196     builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build());
197     builder.setExtension(TestOptimizedForSize.testExtension, 56);
198     builder.setExtension(TestOptimizedForSize.testExtension2,
199         TestRequiredOptimizedForSize.newBuilder().setX(78).build());
200
201     TestOptimizedForSize message = builder.build();
202     ExtensionRegistry registry = ExtensionRegistry.newInstance();
203     UnittestOptimizeFor.registerAllExtensions(registry);
204
205     assertRoundTripEquals(message, registry);
206   }
207
208   /** Helper method for {@link #testParsingMerge()}.*/
209   private void assertMessageMerged(TestAllTypes allTypes)
210       throws Exception {
211     assertEquals(3, allTypes.getOptionalInt32());
212     assertEquals(2, allTypes.getOptionalInt64());
213     assertEquals("hello", allTypes.getOptionalString());
214   }
215
216   public void testParsingMerge() throws Exception {
217     // Build messages.
218     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
219     TestAllTypes msg1 = builder.setOptionalInt32(1).build();
220     builder.clear();
221     TestAllTypes msg2 = builder.setOptionalInt64(2).build();
222     builder.clear();
223     TestAllTypes msg3 = builder.setOptionalInt32(3)
224         .setOptionalString("hello").build();
225
226     // Build groups.
227     TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG1 =
228         TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
229         .setField1(msg1).build();
230     TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG2 =
231         TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
232         .setField1(msg2).build();
233     TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG3 =
234         TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
235         .setField1(msg3).build();
236     TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG1 =
237         TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
238         .setField1(msg1).build();
239     TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG2 =
240         TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
241         .setField1(msg2).build();
242     TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG3 =
243         TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
244         .setField1(msg3).build();
245
246     // Assign and serialize RepeatedFieldsGenerator.
247     ByteString data = TestParsingMerge.RepeatedFieldsGenerator.newBuilder()
248         .addField1(msg1).addField1(msg2).addField1(msg3)
249         .addField2(msg1).addField2(msg2).addField2(msg3)
250         .addField3(msg1).addField3(msg2).addField3(msg3)
251         .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
252         .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
253         .addExt1(msg1).addExt1(msg2).addExt1(msg3)
254         .addExt2(msg1).addExt2(msg2).addExt2(msg3)
255         .build().toByteString();
256
257     // Parse TestParsingMerge.
258     ExtensionRegistry registry = ExtensionRegistry.newInstance();
259     UnittestProto.registerAllExtensions(registry);
260     TestParsingMerge parsingMerge =
261         TestParsingMerge.PARSER.parseFrom(data, registry);
262
263     // Required and optional fields should be merged.
264     assertMessageMerged(parsingMerge.getRequiredAllTypes());
265     assertMessageMerged(parsingMerge.getOptionalAllTypes());
266     assertMessageMerged(
267         parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
268     assertMessageMerged(parsingMerge.getExtension(
269         TestParsingMerge.optionalExt));
270
271     // Repeated fields should not be merged.
272     assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
273     assertEquals(3, parsingMerge.getRepeatedGroupCount());
274     assertEquals(3, parsingMerge.getExtensionCount(
275         TestParsingMerge.repeatedExt));
276   }
277
278 }