- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / protobuf / src / google / protobuf / message_unittest.cc
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 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/message.h>
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #ifdef _MSC_VER
41 #include <io.h>
42 #else
43 #include <unistd.h>
44 #endif
45 #include <sstream>
46 #include <fstream>
47
48 #include <google/protobuf/stubs/common.h>
49 #include <google/protobuf/io/zero_copy_stream_impl.h>
50 #include <google/protobuf/io/coded_stream.h>
51 #include <google/protobuf/descriptor.h>
52 #include <google/protobuf/descriptor.pb.h>
53 #include <google/protobuf/unittest.pb.h>
54 #include <google/protobuf/test_util.h>
55
56 #include <google/protobuf/testing/googletest.h>
57 #include <gtest/gtest.h>
58
59 namespace google {
60 namespace protobuf {
61
62 #ifndef O_BINARY
63 #ifdef _O_BINARY
64 #define O_BINARY _O_BINARY
65 #else
66 #define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
67 #endif
68 #endif
69
70 TEST(MessageTest, SerializeHelpers) {
71   // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
72   //   like a waste of time.
73
74   protobuf_unittest::TestAllTypes message;
75   TestUtil::SetAllFields(&message);
76   stringstream stream;
77
78   string str1("foo");
79   string str2("bar");
80
81   EXPECT_TRUE(message.SerializeToString(&str1));
82   EXPECT_TRUE(message.AppendToString(&str2));
83   EXPECT_TRUE(message.SerializeToOstream(&stream));
84
85   EXPECT_EQ(str1.size() + 3, str2.size());
86   EXPECT_EQ("bar", str2.substr(0, 3));
87   // Don't use EXPECT_EQ because we don't want to dump raw binary data to
88   // stdout.
89   EXPECT_TRUE(str2.substr(3) == str1);
90
91   // GCC gives some sort of error if we try to just do stream.str() == str1.
92   string temp = stream.str();
93   EXPECT_TRUE(temp == str1);
94
95   EXPECT_TRUE(message.SerializeAsString() == str1);
96
97 }
98
99 TEST(MessageTest, SerializeToBrokenOstream) {
100   ofstream out;
101   protobuf_unittest::TestAllTypes message;
102   message.set_optional_int32(123);
103
104   EXPECT_FALSE(message.SerializeToOstream(&out));
105 }
106
107 TEST(MessageTest, ParseFromFileDescriptor) {
108   string filename = TestSourceDir() +
109                     "/google/protobuf/testdata/golden_message";
110   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
111
112   unittest::TestAllTypes message;
113   EXPECT_TRUE(message.ParseFromFileDescriptor(file));
114   TestUtil::ExpectAllFieldsSet(message);
115
116   EXPECT_GE(close(file), 0);
117 }
118
119 TEST(MessageTest, ParsePackedFromFileDescriptor) {
120   string filename =
121       TestSourceDir() +
122       "/google/protobuf/testdata/golden_packed_fields_message";
123   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
124
125   unittest::TestPackedTypes message;
126   EXPECT_TRUE(message.ParseFromFileDescriptor(file));
127   TestUtil::ExpectPackedFieldsSet(message);
128
129   EXPECT_GE(close(file), 0);
130 }
131
132 TEST(MessageTest, ParseHelpers) {
133   // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
134   //   like a waste of time.
135   string data;
136
137   {
138     // Set up.
139     protobuf_unittest::TestAllTypes message;
140     TestUtil::SetAllFields(&message);
141     message.SerializeToString(&data);
142   }
143
144   {
145     // Test ParseFromString.
146     protobuf_unittest::TestAllTypes message;
147     EXPECT_TRUE(message.ParseFromString(data));
148     TestUtil::ExpectAllFieldsSet(message);
149   }
150
151   {
152     // Test ParseFromIstream.
153     protobuf_unittest::TestAllTypes message;
154     stringstream stream(data);
155     EXPECT_TRUE(message.ParseFromIstream(&stream));
156     EXPECT_TRUE(stream.eof());
157     TestUtil::ExpectAllFieldsSet(message);
158   }
159
160   {
161     // Test ParseFromBoundedZeroCopyStream.
162     string data_with_junk(data);
163     data_with_junk.append("some junk on the end");
164     io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
165     protobuf_unittest::TestAllTypes message;
166     EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
167     TestUtil::ExpectAllFieldsSet(message);
168   }
169
170   {
171     // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
172     // EOF is reached before the expected number of bytes.
173     io::ArrayInputStream stream(data.data(), data.size());
174     protobuf_unittest::TestAllTypes message;
175     EXPECT_FALSE(
176       message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
177   }
178 }
179
180 TEST(MessageTest, ParseFailsIfNotInitialized) {
181   unittest::TestRequired message;
182   vector<string> errors;
183
184   {
185     ScopedMemoryLog log;
186     EXPECT_FALSE(message.ParseFromString(""));
187     errors = log.GetMessages(ERROR);
188   }
189
190   ASSERT_EQ(1, errors.size());
191   EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" "
192             "because it is missing required fields: a, b, c",
193             errors[0]);
194 }
195
196 TEST(MessageTest, BypassInitializationCheckOnParse) {
197   unittest::TestRequired message;
198   io::ArrayInputStream raw_input(NULL, 0);
199   io::CodedInputStream input(&raw_input);
200   EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
201 }
202
203 TEST(MessageTest, InitializationErrorString) {
204   unittest::TestRequired message;
205   EXPECT_EQ("a, b, c", message.InitializationErrorString());
206 }
207
208 #ifdef PROTOBUF_HAS_DEATH_TEST
209
210 TEST(MessageTest, SerializeFailsIfNotInitialized) {
211   unittest::TestRequired message;
212   string data;
213   EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
214     "Can't serialize message of type \"protobuf_unittest.TestRequired\" because "
215     "it is missing required fields: a, b, c");
216 }
217
218 TEST(MessageTest, CheckInitialized) {
219   unittest::TestRequired message;
220   EXPECT_DEATH(message.CheckInitialized(),
221     "Message of type \"protobuf_unittest.TestRequired\" is missing required "
222     "fields: a, b, c");
223 }
224
225 #endif  // PROTOBUF_HAS_DEATH_TEST
226
227 TEST(MessageTest, BypassInitializationCheckOnSerialize) {
228   unittest::TestRequired message;
229   io::ArrayOutputStream raw_output(NULL, 0);
230   io::CodedOutputStream output(&raw_output);
231   EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
232 }
233
234 TEST(MessageTest, FindInitializationErrors) {
235   unittest::TestRequired message;
236   vector<string> errors;
237   message.FindInitializationErrors(&errors);
238   ASSERT_EQ(3, errors.size());
239   EXPECT_EQ("a", errors[0]);
240   EXPECT_EQ("b", errors[1]);
241   EXPECT_EQ("c", errors[2]);
242 }
243
244 TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
245   unittest::TestAllTypes message;
246
247   // Control case.
248   EXPECT_TRUE(message.ParseFromArray("", 0));
249
250   // The byte is a valid varint, but not a valid tag (zero).
251   EXPECT_FALSE(message.ParseFromArray("\0", 1));
252
253   // The byte is a malformed varint.
254   EXPECT_FALSE(message.ParseFromArray("\200", 1));
255
256   // The byte is an endgroup tag, but we aren't parsing a group.
257   EXPECT_FALSE(message.ParseFromArray("\014", 1));
258 }
259
260 namespace {
261
262 void ExpectMessageMerged(const unittest::TestAllTypes& message) {
263   EXPECT_EQ(3, message.optional_int32());
264   EXPECT_EQ(2, message.optional_int64());
265   EXPECT_EQ("hello", message.optional_string());
266 }
267
268 void AssignParsingMergeMessages(
269     unittest::TestAllTypes* msg1,
270     unittest::TestAllTypes* msg2,
271     unittest::TestAllTypes* msg3) {
272   msg1->set_optional_int32(1);
273   msg2->set_optional_int64(2);
274   msg3->set_optional_int32(3);
275   msg3->set_optional_string("hello");
276 }
277
278 }  // namespace
279
280 // Test that if an optional or required message/group field appears multiple
281 // times in the input, they need to be merged.
282 TEST(MessageTest, ParsingMerge) {
283   unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
284   unittest::TestAllTypes* msg1;
285   unittest::TestAllTypes* msg2;
286   unittest::TestAllTypes* msg3;
287
288 #define ASSIGN_REPEATED_FIELD(FIELD)                \
289   msg1 = generator.add_##FIELD();                   \
290   msg2 = generator.add_##FIELD();                   \
291   msg3 = generator.add_##FIELD();                   \
292   AssignParsingMergeMessages(msg1, msg2, msg3)
293
294   ASSIGN_REPEATED_FIELD(field1);
295   ASSIGN_REPEATED_FIELD(field2);
296   ASSIGN_REPEATED_FIELD(field3);
297   ASSIGN_REPEATED_FIELD(ext1);
298   ASSIGN_REPEATED_FIELD(ext2);
299
300 #undef ASSIGN_REPEATED_FIELD
301 #define ASSIGN_REPEATED_GROUP(FIELD)                \
302   msg1 = generator.add_##FIELD()->mutable_field1(); \
303   msg2 = generator.add_##FIELD()->mutable_field1(); \
304   msg3 = generator.add_##FIELD()->mutable_field1(); \
305   AssignParsingMergeMessages(msg1, msg2, msg3)
306
307   ASSIGN_REPEATED_GROUP(group1);
308   ASSIGN_REPEATED_GROUP(group2);
309
310 #undef ASSIGN_REPEATED_GROUP
311
312   string buffer;
313   generator.SerializeToString(&buffer);
314   unittest::TestParsingMerge parsing_merge;
315   parsing_merge.ParseFromString(buffer);
316
317   // Required and optional fields should be merged.
318   ExpectMessageMerged(parsing_merge.required_all_types());
319   ExpectMessageMerged(parsing_merge.optional_all_types());
320   ExpectMessageMerged(
321       parsing_merge.optionalgroup().optional_group_all_types());
322   ExpectMessageMerged(
323       parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
324
325   // Repeated fields should not be merged.
326   EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
327   EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
328   EXPECT_EQ(3, parsing_merge.ExtensionSize(
329       unittest::TestParsingMerge::repeated_ext));
330 }
331
332 TEST(MessageFactoryTest, GeneratedFactoryLookup) {
333   EXPECT_EQ(
334     MessageFactory::generated_factory()->GetPrototype(
335       protobuf_unittest::TestAllTypes::descriptor()),
336     &protobuf_unittest::TestAllTypes::default_instance());
337 }
338
339 TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
340   // Construct a new descriptor.
341   DescriptorPool pool;
342   FileDescriptorProto file;
343   file.set_name("foo.proto");
344   file.add_message_type()->set_name("Foo");
345   const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
346
347   // Trying to construct it should return NULL.
348   EXPECT_TRUE(
349     MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
350 }
351
352
353 }  // namespace protobuf
354 }  // namespace google