Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      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 (at) 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/test_util.h>
     49 #include <google/protobuf/unittest.pb.h>
     50 #include <google/protobuf/io/coded_stream.h>
     51 #include <google/protobuf/io/zero_copy_stream_impl.h>
     52 #include <google/protobuf/descriptor.pb.h>
     53 #include <google/protobuf/descriptor.h>
     54 #include <google/protobuf/generated_message_reflection.h>
     55 
     56 #include <google/protobuf/stubs/logging.h>
     57 #include <google/protobuf/stubs/common.h>
     58 #include <google/protobuf/stubs/logging.h>
     59 #include <google/protobuf/testing/googletest.h>
     60 #include <gtest/gtest.h>
     61 
     62 namespace google {
     63 namespace protobuf {
     64 
     65 #ifndef O_BINARY
     66 #ifdef _O_BINARY
     67 #define O_BINARY _O_BINARY
     68 #else
     69 #define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
     70 #endif
     71 #endif
     72 
     73 TEST(MessageTest, SerializeHelpers) {
     74   // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
     75   //   like a waste of time.
     76 
     77   protobuf_unittest::TestAllTypes message;
     78   TestUtil::SetAllFields(&message);
     79   stringstream stream;
     80 
     81   string str1("foo");
     82   string str2("bar");
     83 
     84   EXPECT_TRUE(message.SerializeToString(&str1));
     85   EXPECT_TRUE(message.AppendToString(&str2));
     86   EXPECT_TRUE(message.SerializeToOstream(&stream));
     87 
     88   EXPECT_EQ(str1.size() + 3, str2.size());
     89   EXPECT_EQ("bar", str2.substr(0, 3));
     90   // Don't use EXPECT_EQ because we don't want to dump raw binary data to
     91   // stdout.
     92   EXPECT_TRUE(str2.substr(3) == str1);
     93 
     94   // GCC gives some sort of error if we try to just do stream.str() == str1.
     95   string temp = stream.str();
     96   EXPECT_TRUE(temp == str1);
     97 
     98   EXPECT_TRUE(message.SerializeAsString() == str1);
     99 
    100 }
    101 
    102 TEST(MessageTest, SerializeToBrokenOstream) {
    103   ofstream out;
    104   protobuf_unittest::TestAllTypes message;
    105   message.set_optional_int32(123);
    106 
    107   EXPECT_FALSE(message.SerializeToOstream(&out));
    108 }
    109 
    110 TEST(MessageTest, ParseFromFileDescriptor) {
    111   string filename = TestSourceDir() +
    112                     "/google/protobuf/testdata/golden_message";
    113   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
    114 
    115   unittest::TestAllTypes message;
    116   EXPECT_TRUE(message.ParseFromFileDescriptor(file));
    117   TestUtil::ExpectAllFieldsSet(message);
    118 
    119   EXPECT_GE(close(file), 0);
    120 }
    121 
    122 TEST(MessageTest, ParsePackedFromFileDescriptor) {
    123   string filename =
    124       TestSourceDir() +
    125       "/google/protobuf/testdata/golden_packed_fields_message";
    126   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
    127 
    128   unittest::TestPackedTypes message;
    129   EXPECT_TRUE(message.ParseFromFileDescriptor(file));
    130   TestUtil::ExpectPackedFieldsSet(message);
    131 
    132   EXPECT_GE(close(file), 0);
    133 }
    134 
    135 TEST(MessageTest, ParseHelpers) {
    136   // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
    137   //   like a waste of time.
    138   string data;
    139 
    140   {
    141     // Set up.
    142     protobuf_unittest::TestAllTypes message;
    143     TestUtil::SetAllFields(&message);
    144     message.SerializeToString(&data);
    145   }
    146 
    147   {
    148     // Test ParseFromString.
    149     protobuf_unittest::TestAllTypes message;
    150     EXPECT_TRUE(message.ParseFromString(data));
    151     TestUtil::ExpectAllFieldsSet(message);
    152   }
    153 
    154   {
    155     // Test ParseFromIstream.
    156     protobuf_unittest::TestAllTypes message;
    157     stringstream stream(data);
    158     EXPECT_TRUE(message.ParseFromIstream(&stream));
    159     EXPECT_TRUE(stream.eof());
    160     TestUtil::ExpectAllFieldsSet(message);
    161   }
    162 
    163   {
    164     // Test ParseFromBoundedZeroCopyStream.
    165     string data_with_junk(data);
    166     data_with_junk.append("some junk on the end");
    167     io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
    168     protobuf_unittest::TestAllTypes message;
    169     EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
    170     TestUtil::ExpectAllFieldsSet(message);
    171   }
    172 
    173   {
    174     // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
    175     // EOF is reached before the expected number of bytes.
    176     io::ArrayInputStream stream(data.data(), data.size());
    177     protobuf_unittest::TestAllTypes message;
    178     EXPECT_FALSE(
    179       message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
    180   }
    181 }
    182 
    183 TEST(MessageTest, ParseFailsIfNotInitialized) {
    184   unittest::TestRequired message;
    185   vector<string> errors;
    186 
    187   {
    188     ScopedMemoryLog log;
    189     EXPECT_FALSE(message.ParseFromString(""));
    190     errors = log.GetMessages(ERROR);
    191   }
    192 
    193   ASSERT_EQ(1, errors.size());
    194   EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" "
    195             "because it is missing required fields: a, b, c",
    196             errors[0]);
    197 }
    198 
    199 TEST(MessageTest, BypassInitializationCheckOnParse) {
    200   unittest::TestRequired message;
    201   io::ArrayInputStream raw_input(NULL, 0);
    202   io::CodedInputStream input(&raw_input);
    203   EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
    204 }
    205 
    206 TEST(MessageTest, InitializationErrorString) {
    207   unittest::TestRequired message;
    208   EXPECT_EQ("a, b, c", message.InitializationErrorString());
    209 }
    210 
    211 TEST(MessageTest, DynamicCastToGenerated) {
    212   unittest::TestAllTypes test_all_types;
    213 
    214   google::protobuf::Message* test_all_types_pointer = &test_all_types;
    215   EXPECT_EQ(&test_all_types,
    216             google::protobuf::internal::DynamicCastToGenerated<unittest::TestAllTypes>(
    217                 test_all_types_pointer));
    218   EXPECT_EQ(NULL,
    219             google::protobuf::internal::DynamicCastToGenerated<unittest::TestRequired>(
    220                 test_all_types_pointer));
    221 
    222   const google::protobuf::Message* test_all_types_pointer_const = &test_all_types;
    223   EXPECT_EQ(
    224       &test_all_types,
    225       google::protobuf::internal::DynamicCastToGenerated<const unittest::TestAllTypes>(
    226           test_all_types_pointer_const));
    227   EXPECT_EQ(
    228       NULL,
    229       google::protobuf::internal::DynamicCastToGenerated<const unittest::TestRequired>(
    230           test_all_types_pointer_const));
    231 }
    232 
    233 #ifdef PROTOBUF_HAS_DEATH_TEST  // death tests do not work on Windows yet.
    234 
    235 TEST(MessageTest, SerializeFailsIfNotInitialized) {
    236   unittest::TestRequired message;
    237   string data;
    238   EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
    239     "Can't serialize message of type \"protobuf_unittest.TestRequired\" because "
    240     "it is missing required fields: a, b, c");
    241 }
    242 
    243 TEST(MessageTest, CheckInitialized) {
    244   unittest::TestRequired message;
    245   EXPECT_DEATH(message.CheckInitialized(),
    246     "Message of type \"protobuf_unittest.TestRequired\" is missing required "
    247     "fields: a, b, c");
    248 }
    249 
    250 TEST(MessageTest, CheckOverflow) {
    251   unittest::TestAllTypes message;
    252   // Create a message with size just over 2GB. This triggers integer overflow
    253   // when computing message size.
    254   const string data(1024, 'x');
    255   Cord one_megabyte;
    256   for (int i = 0; i < 1024; i++) {
    257     one_megabyte.Append(data);
    258   }
    259 
    260   for (int i = 0; i < 2 * 1024 + 1; ++i) {
    261     message.add_repeated_cord()->CopyFrom(one_megabyte);
    262   }
    263 
    264   Cord serialized;
    265   EXPECT_FALSE(message.AppendToCord(&serialized));
    266 }
    267 
    268 #endif  // PROTOBUF_HAS_DEATH_TEST
    269 
    270 namespace {
    271 
    272 class NegativeByteSize : public unittest::TestRequired {
    273  public:
    274   virtual int ByteSize() const { return -1; }
    275 };
    276 
    277 }  // namespace
    278 
    279 TEST(MessageTest, SerializationFailsOnNegativeByteSize) {
    280   NegativeByteSize message;
    281   string string_output;
    282   EXPECT_FALSE(message.AppendPartialToString(&string_output));
    283 
    284   io::ArrayOutputStream coded_raw_output(NULL, 100);
    285   io::CodedOutputStream coded_output(&coded_raw_output);
    286   EXPECT_FALSE(message.SerializePartialToCodedStream(&coded_output));
    287 }
    288 
    289 TEST(MessageTest, BypassInitializationCheckOnSerialize) {
    290   unittest::TestRequired message;
    291   io::ArrayOutputStream raw_output(NULL, 0);
    292   io::CodedOutputStream output(&raw_output);
    293   EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
    294 }
    295 
    296 TEST(MessageTest, FindInitializationErrors) {
    297   unittest::TestRequired message;
    298   vector<string> errors;
    299   message.FindInitializationErrors(&errors);
    300   ASSERT_EQ(3, errors.size());
    301   EXPECT_EQ("a", errors[0]);
    302   EXPECT_EQ("b", errors[1]);
    303   EXPECT_EQ("c", errors[2]);
    304 }
    305 
    306 TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
    307   unittest::TestAllTypes message;
    308 
    309   // Control case.
    310   EXPECT_TRUE(message.ParseFromArray("", 0));
    311 
    312   // The byte is a valid varint, but not a valid tag (zero).
    313   EXPECT_FALSE(message.ParseFromArray("\0", 1));
    314 
    315   // The byte is a malformed varint.
    316   EXPECT_FALSE(message.ParseFromArray("\200", 1));
    317 
    318   // The byte is an endgroup tag, but we aren't parsing a group.
    319   EXPECT_FALSE(message.ParseFromArray("\014", 1));
    320 }
    321 
    322 namespace {
    323 
    324 void ExpectMessageMerged(const unittest::TestAllTypes& message) {
    325   EXPECT_EQ(3, message.optional_int32());
    326   EXPECT_EQ(2, message.optional_int64());
    327   EXPECT_EQ("hello", message.optional_string());
    328 }
    329 
    330 void AssignParsingMergeMessages(
    331     unittest::TestAllTypes* msg1,
    332     unittest::TestAllTypes* msg2,
    333     unittest::TestAllTypes* msg3) {
    334   msg1->set_optional_int32(1);
    335   msg2->set_optional_int64(2);
    336   msg3->set_optional_int32(3);
    337   msg3->set_optional_string("hello");
    338 }
    339 
    340 }  // namespace
    341 
    342 // Test that if an optional or required message/group field appears multiple
    343 // times in the input, they need to be merged.
    344 TEST(MessageTest, ParsingMerge) {
    345   unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
    346   unittest::TestAllTypes* msg1;
    347   unittest::TestAllTypes* msg2;
    348   unittest::TestAllTypes* msg3;
    349 
    350 #define ASSIGN_REPEATED_FIELD(FIELD)                \
    351   msg1 = generator.add_##FIELD();                   \
    352   msg2 = generator.add_##FIELD();                   \
    353   msg3 = generator.add_##FIELD();                   \
    354   AssignParsingMergeMessages(msg1, msg2, msg3)
    355 
    356   ASSIGN_REPEATED_FIELD(field1);
    357   ASSIGN_REPEATED_FIELD(field2);
    358   ASSIGN_REPEATED_FIELD(field3);
    359   ASSIGN_REPEATED_FIELD(ext1);
    360   ASSIGN_REPEATED_FIELD(ext2);
    361 
    362 #undef ASSIGN_REPEATED_FIELD
    363 #define ASSIGN_REPEATED_GROUP(FIELD)                \
    364   msg1 = generator.add_##FIELD()->mutable_field1(); \
    365   msg2 = generator.add_##FIELD()->mutable_field1(); \
    366   msg3 = generator.add_##FIELD()->mutable_field1(); \
    367   AssignParsingMergeMessages(msg1, msg2, msg3)
    368 
    369   ASSIGN_REPEATED_GROUP(group1);
    370   ASSIGN_REPEATED_GROUP(group2);
    371 
    372 #undef ASSIGN_REPEATED_GROUP
    373 
    374   string buffer;
    375   generator.SerializeToString(&buffer);
    376   unittest::TestParsingMerge parsing_merge;
    377   parsing_merge.ParseFromString(buffer);
    378 
    379   // Required and optional fields should be merged.
    380   ExpectMessageMerged(parsing_merge.required_all_types());
    381   ExpectMessageMerged(parsing_merge.optional_all_types());
    382   ExpectMessageMerged(
    383       parsing_merge.optionalgroup().optional_group_all_types());
    384   ExpectMessageMerged(
    385       parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
    386 
    387   // Repeated fields should not be merged.
    388   EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
    389   EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
    390   EXPECT_EQ(3, parsing_merge.ExtensionSize(
    391       unittest::TestParsingMerge::repeated_ext));
    392 }
    393 
    394 TEST(MessageTest, MergeFrom) {
    395   unittest::TestAllTypes source;
    396   unittest::TestAllTypes dest;
    397 
    398   // Optional fields
    399   source.set_optional_int32(1);  // only source
    400   source.set_optional_int64(2);  // both source and dest
    401   dest.set_optional_int64(3);
    402   dest.set_optional_uint32(4);   // only dest
    403 
    404   // Optional fields with defaults
    405   source.set_default_int32(13);  // only source
    406   source.set_default_int64(14);  // both source and dest
    407   dest.set_default_int64(15);
    408   dest.set_default_uint32(16);   // only dest
    409 
    410   // Repeated fields
    411   source.add_repeated_int32(5);  // only source
    412   source.add_repeated_int32(6);
    413   source.add_repeated_int64(7);  // both source and dest
    414   source.add_repeated_int64(8);
    415   dest.add_repeated_int64(9);
    416   dest.add_repeated_int64(10);
    417   dest.add_repeated_uint32(11);  // only dest
    418   dest.add_repeated_uint32(12);
    419 
    420   dest.MergeFrom(source);
    421 
    422   // Optional fields: source overwrites dest if source is specified
    423   EXPECT_EQ(1, dest.optional_int32());  // only source: use source
    424   EXPECT_EQ(2, dest.optional_int64());  // source and dest: use source
    425   EXPECT_EQ(4, dest.optional_uint32());  // only dest: use dest
    426   EXPECT_EQ(0, dest.optional_uint64());  // neither: use default
    427 
    428   // Optional fields with defaults
    429   EXPECT_EQ(13, dest.default_int32());  // only source: use source
    430   EXPECT_EQ(14, dest.default_int64());  // source and dest: use source
    431   EXPECT_EQ(16, dest.default_uint32());  // only dest: use dest
    432   EXPECT_EQ(44, dest.default_uint64());  // neither: use default
    433 
    434   // Repeated fields: concatenate source onto the end of dest
    435   ASSERT_EQ(2, dest.repeated_int32_size());
    436   EXPECT_EQ(5, dest.repeated_int32(0));
    437   EXPECT_EQ(6, dest.repeated_int32(1));
    438   ASSERT_EQ(4, dest.repeated_int64_size());
    439   EXPECT_EQ(9,  dest.repeated_int64(0));
    440   EXPECT_EQ(10, dest.repeated_int64(1));
    441   EXPECT_EQ(7,  dest.repeated_int64(2));
    442   EXPECT_EQ(8,  dest.repeated_int64(3));
    443   ASSERT_EQ(2, dest.repeated_uint32_size());
    444   EXPECT_EQ(11, dest.repeated_uint32(0));
    445   EXPECT_EQ(12, dest.repeated_uint32(1));
    446   ASSERT_EQ(0, dest.repeated_uint64_size());
    447 }
    448 
    449 TEST(MessageFactoryTest, GeneratedFactoryLookup) {
    450   EXPECT_EQ(
    451     MessageFactory::generated_factory()->GetPrototype(
    452       protobuf_unittest::TestAllTypes::descriptor()),
    453     &protobuf_unittest::TestAllTypes::default_instance());
    454 }
    455 
    456 TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
    457   // Construct a new descriptor.
    458   DescriptorPool pool;
    459   FileDescriptorProto file;
    460   file.set_name("foo.proto");
    461   file.add_message_type()->set_name("Foo");
    462   const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
    463 
    464   // Trying to construct it should return NULL.
    465   EXPECT_TRUE(
    466     MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
    467 }
    468 
    469 
    470 }  // namespace protobuf
    471 }  // namespace google
    472