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 // Since the reflection interface for DynamicMessage is implemented by
     36 // GenericMessageReflection, the only thing we really have to test is
     37 // that DynamicMessage correctly sets up the information that
     38 // GenericMessageReflection needs to use.  So, we focus on that in this
     39 // test.  Other tests, such as generic_message_reflection_unittest and
     40 // reflection_ops_unittest, cover the rest of the functionality used by
     41 // DynamicMessage.
     42 
     43 #include <google/protobuf/stubs/common.h>
     44 #include <google/protobuf/dynamic_message.h>
     45 #include <google/protobuf/descriptor.h>
     46 #include <google/protobuf/descriptor.pb.h>
     47 #include <google/protobuf/test_util.h>
     48 #include <google/protobuf/unittest.pb.h>
     49 
     50 #include <google/protobuf/testing/googletest.h>
     51 #include <gtest/gtest.h>
     52 
     53 namespace google {
     54 namespace protobuf {
     55 
     56 class DynamicMessageTest : public testing::Test {
     57  protected:
     58   DescriptorPool pool_;
     59   DynamicMessageFactory factory_;
     60   const Descriptor* descriptor_;
     61   const Message* prototype_;
     62   const Descriptor* extensions_descriptor_;
     63   const Message* extensions_prototype_;
     64   const Descriptor* packed_descriptor_;
     65   const Message* packed_prototype_;
     66   const Descriptor* oneof_descriptor_;
     67   const Message* oneof_prototype_;
     68 
     69   DynamicMessageTest(): factory_(&pool_) {}
     70 
     71   virtual void SetUp() {
     72     // We want to make sure that DynamicMessage works (particularly with
     73     // extensions) even if we use descriptors that are *not* from compiled-in
     74     // types, so we make copies of the descriptors for unittest.proto and
     75     // unittest_import.proto.
     76     FileDescriptorProto unittest_file;
     77     FileDescriptorProto unittest_import_file;
     78     FileDescriptorProto unittest_import_public_file;
     79 
     80     unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
     81     unittest_import::ImportMessage::descriptor()->file()->CopyTo(
     82       &unittest_import_file);
     83     unittest_import::PublicImportMessage::descriptor()->file()->CopyTo(
     84       &unittest_import_public_file);
     85 
     86     ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL);
     87     ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL);
     88     ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL);
     89 
     90     descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
     91     ASSERT_TRUE(descriptor_ != NULL);
     92     prototype_ = factory_.GetPrototype(descriptor_);
     93 
     94     extensions_descriptor_ =
     95       pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
     96     ASSERT_TRUE(extensions_descriptor_ != NULL);
     97     extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_);
     98 
     99     packed_descriptor_ =
    100       pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
    101     ASSERT_TRUE(packed_descriptor_ != NULL);
    102     packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
    103 
    104     oneof_descriptor_ =
    105       pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2");
    106     ASSERT_TRUE(oneof_descriptor_ != NULL);
    107     oneof_prototype_ = factory_.GetPrototype(oneof_descriptor_);
    108   }
    109 };
    110 
    111 TEST_F(DynamicMessageTest, Descriptor) {
    112   // Check that the descriptor on the DynamicMessage matches the descriptor
    113   // passed to GetPrototype().
    114   EXPECT_EQ(prototype_->GetDescriptor(), descriptor_);
    115 }
    116 
    117 TEST_F(DynamicMessageTest, OnePrototype) {
    118   // Check that requesting the same prototype twice produces the same object.
    119   EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_));
    120 }
    121 
    122 TEST_F(DynamicMessageTest, Defaults) {
    123   // Check that all default values are set correctly in the initial message.
    124   TestUtil::ReflectionTester reflection_tester(descriptor_);
    125   reflection_tester.ExpectClearViaReflection(*prototype_);
    126 }
    127 
    128 TEST_F(DynamicMessageTest, IndependentOffsets) {
    129   // Check that all fields have independent offsets by setting each
    130   // one to a unique value then checking that they all still have those
    131   // unique values (i.e. they don't stomp each other).
    132   scoped_ptr<Message> message(prototype_->New());
    133   TestUtil::ReflectionTester reflection_tester(descriptor_);
    134 
    135   reflection_tester.SetAllFieldsViaReflection(message.get());
    136   reflection_tester.ExpectAllFieldsSetViaReflection(*message);
    137 }
    138 
    139 TEST_F(DynamicMessageTest, Extensions) {
    140   // Check that extensions work.
    141   scoped_ptr<Message> message(extensions_prototype_->New());
    142   TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
    143 
    144   reflection_tester.SetAllFieldsViaReflection(message.get());
    145   reflection_tester.ExpectAllFieldsSetViaReflection(*message);
    146 }
    147 
    148 TEST_F(DynamicMessageTest, PackedFields) {
    149   // Check that packed fields work properly.
    150   scoped_ptr<Message> message(packed_prototype_->New());
    151   TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
    152 
    153   reflection_tester.SetPackedFieldsViaReflection(message.get());
    154   reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
    155 }
    156 
    157 TEST_F(DynamicMessageTest, Oneof) {
    158   // Check that oneof fields work properly.
    159   scoped_ptr<Message> message(oneof_prototype_->New());
    160 
    161   // Check default values.
    162   const Descriptor* descriptor = message->GetDescriptor();
    163   const Reflection* reflection = message->GetReflection();
    164   EXPECT_EQ(0, reflection->GetInt32(
    165       *message, descriptor->FindFieldByName("foo_int")));
    166   EXPECT_EQ("", reflection->GetString(
    167       *message, descriptor->FindFieldByName("foo_string")));
    168   EXPECT_EQ("", reflection->GetString(
    169       *message, descriptor->FindFieldByName("foo_cord")));
    170   EXPECT_EQ("", reflection->GetString(
    171       *message, descriptor->FindFieldByName("foo_string_piece")));
    172   EXPECT_EQ("", reflection->GetString(
    173       *message, descriptor->FindFieldByName("foo_bytes")));
    174   EXPECT_EQ(unittest::TestOneof2::FOO, reflection->GetEnum(
    175       *message, descriptor->FindFieldByName("foo_enum"))->number());
    176   const Descriptor* nested_descriptor;
    177   const Message* nested_prototype;
    178   nested_descriptor =
    179       pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.NestedMessage");
    180   nested_prototype = factory_.GetPrototype(nested_descriptor);
    181   EXPECT_EQ(nested_prototype,
    182             &reflection->GetMessage(
    183                 *message, descriptor->FindFieldByName("foo_message")));
    184   const Descriptor* foogroup_descriptor;
    185   const Message* foogroup_prototype;
    186   foogroup_descriptor =
    187       pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.FooGroup");
    188   foogroup_prototype = factory_.GetPrototype(foogroup_descriptor);
    189   EXPECT_EQ(foogroup_prototype,
    190             &reflection->GetMessage(
    191                 *message, descriptor->FindFieldByName("foogroup")));
    192   EXPECT_NE(foogroup_prototype,
    193             &reflection->GetMessage(
    194                 *message, descriptor->FindFieldByName("foo_lazy_message")));
    195   EXPECT_EQ(5, reflection->GetInt32(
    196       *message, descriptor->FindFieldByName("bar_int")));
    197   EXPECT_EQ("STRING", reflection->GetString(
    198       *message, descriptor->FindFieldByName("bar_string")));
    199   EXPECT_EQ("CORD", reflection->GetString(
    200       *message, descriptor->FindFieldByName("bar_cord")));
    201   EXPECT_EQ("SPIECE", reflection->GetString(
    202       *message, descriptor->FindFieldByName("bar_string_piece")));
    203   EXPECT_EQ("BYTES", reflection->GetString(
    204       *message, descriptor->FindFieldByName("bar_bytes")));
    205   EXPECT_EQ(unittest::TestOneof2::BAR, reflection->GetEnum(
    206       *message, descriptor->FindFieldByName("bar_enum"))->number());
    207 
    208   // Check set functions.
    209   TestUtil::ReflectionTester reflection_tester(oneof_descriptor_);
    210   reflection_tester.SetOneofViaReflection(message.get());
    211   reflection_tester.ExpectOneofSetViaReflection(*message);
    212 }
    213 
    214 TEST_F(DynamicMessageTest, SpaceUsed) {
    215   // Test that SpaceUsed() works properly
    216 
    217   // Since we share the implementation with generated messages, we don't need
    218   // to test very much here.  Just make sure it appears to be working.
    219 
    220   scoped_ptr<Message> message(prototype_->New());
    221   TestUtil::ReflectionTester reflection_tester(descriptor_);
    222 
    223   int initial_space_used = message->SpaceUsed();
    224 
    225   reflection_tester.SetAllFieldsViaReflection(message.get());
    226   EXPECT_LT(initial_space_used, message->SpaceUsed());
    227 }
    228 
    229 }  // namespace protobuf
    230 }  // namespace google
    231