Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <limits>
     18 #include <memory>
     19 #include <vector>
     20 
     21 #include "gtest/gtest.h"
     22 #include "perfetto/protozero/message_handle.h"
     23 #include "src/protozero/test/fake_scattered_buffer.h"
     24 
     25 // Autogenerated headers in out/*/gen/
     26 #include "src/protozero/test/example_proto/library.pbzero.h"
     27 #include "src/protozero/test/example_proto/test_messages.pb.h"
     28 #include "src/protozero/test/example_proto/test_messages.pbzero.h"
     29 
     30 namespace pbtest = foo::bar::pbzero;  // Generated by the protozero plugin.
     31 namespace pbgold = foo::bar;  // Generated by the official protobuf compiler.
     32 
     33 namespace protozero {
     34 namespace {
     35 
     36 constexpr size_t kChunkSize = 42;
     37 
     38 class ProtoZeroConformanceTest : public ::testing::Test {
     39  public:
     40   void SetUp() override {
     41     buffer_.reset(new FakeScatteredBuffer(kChunkSize));
     42     stream_writer_.reset(new ScatteredStreamWriter(buffer_.get()));
     43   }
     44 
     45   void TearDown() override {
     46     root_messages_.clear();
     47     stream_writer_.reset();
     48     buffer_.reset();
     49   }
     50 
     51  protected:
     52   template <class T>
     53   T* CreateMessage() {
     54     T* message = new T();
     55     root_messages_.push_back(std::unique_ptr<T>(message));
     56     message->Reset(stream_writer_.get());
     57     return message;
     58   }
     59 
     60   size_t GetNumSerializedBytes() {
     61     return buffer_->chunks().size() * kChunkSize -
     62            stream_writer_->bytes_available();
     63   }
     64 
     65   void GetSerializedBytes(size_t start, size_t length, uint8_t* buffer) {
     66     return buffer_->GetBytes(start, length, buffer);
     67   }
     68 
     69  private:
     70   std::unique_ptr<FakeScatteredBuffer> buffer_;
     71   std::unique_ptr<ScatteredStreamWriter> stream_writer_;
     72   std::vector<std::unique_ptr<Message>> root_messages_;
     73 };
     74 
     75 TEST_F(ProtoZeroConformanceTest, SimpleFieldsNoNesting) {
     76   auto* msg = CreateMessage<pbtest::EveryField>();
     77 
     78   msg->set_field_int32(-1);
     79   msg->set_field_int64(-333123456789ll);
     80   msg->set_field_uint32(600);
     81   msg->set_field_uint64(333123456789ll);
     82   msg->set_field_sint32(-5);
     83   msg->set_field_sint64(-9000);
     84   msg->set_field_fixed32(12345);
     85   msg->set_field_fixed64(444123450000ll);
     86   msg->set_field_sfixed32(-69999);
     87   msg->set_field_sfixed64(-200);
     88   msg->set_field_float(3.14f);
     89   msg->set_field_double(0.5555);
     90   msg->set_field_bool(true);
     91   msg->set_small_enum(pbtest::SmallEnum::TO_BE);
     92   msg->set_signed_enum(pbtest::SignedEnum::NEGATIVE);
     93   msg->set_big_enum(pbtest::BigEnum::BEGIN);
     94   msg->set_field_string("FizzBuzz");
     95   msg->set_field_bytes(reinterpret_cast<const uint8_t*>("\x11\x00\xBE\xEF"), 4);
     96   msg->add_repeated_int32(1);
     97   msg->add_repeated_int32(-1);
     98   msg->add_repeated_int32(100);
     99   msg->add_repeated_int32(2000000);
    100 
    101   size_t msg_size = GetNumSerializedBytes();
    102   EXPECT_EQ(126u, msg_size);
    103 
    104   std::unique_ptr<uint8_t[]> msg_binary(new uint8_t[msg_size]);
    105   GetSerializedBytes(0, msg_size, msg_binary.get());
    106 
    107   pbgold::EveryField gold_msg;
    108   gold_msg.ParseFromArray(msg_binary.get(), static_cast<int>(msg_size));
    109   EXPECT_EQ(-1, gold_msg.field_int32());
    110   EXPECT_EQ(-333123456789ll, gold_msg.field_int64());
    111   EXPECT_EQ(600u, gold_msg.field_uint32());
    112   EXPECT_EQ(333123456789ull, gold_msg.field_uint64());
    113   EXPECT_EQ(-5, gold_msg.field_sint32());
    114   EXPECT_EQ(-9000, gold_msg.field_sint64());
    115   EXPECT_EQ(12345u, gold_msg.field_fixed32());
    116   EXPECT_EQ(444123450000ull, gold_msg.field_fixed64());
    117   EXPECT_EQ(-69999, gold_msg.field_sfixed32());
    118   EXPECT_EQ(-200, gold_msg.field_sfixed64());
    119   EXPECT_FLOAT_EQ(3.14f, gold_msg.field_float());
    120   EXPECT_DOUBLE_EQ(0.5555, gold_msg.field_double());
    121   EXPECT_EQ(true, gold_msg.field_bool());
    122   EXPECT_EQ(pbgold::SmallEnum::TO_BE, gold_msg.small_enum());
    123   EXPECT_EQ(pbgold::SignedEnum::NEGATIVE, gold_msg.signed_enum());
    124   EXPECT_EQ(pbgold::BigEnum::BEGIN, gold_msg.big_enum());
    125   EXPECT_EQ("FizzBuzz", gold_msg.field_string());
    126   EXPECT_EQ(std::string("\x11\x00\xBE\xEF", 4), gold_msg.field_bytes());
    127   EXPECT_EQ(4, gold_msg.repeated_int32_size());
    128   EXPECT_EQ(1, gold_msg.repeated_int32(0));
    129   EXPECT_EQ(-1, gold_msg.repeated_int32(1));
    130   EXPECT_EQ(100, gold_msg.repeated_int32(2));
    131   EXPECT_EQ(2000000, gold_msg.repeated_int32(3));
    132 }
    133 
    134 TEST_F(ProtoZeroConformanceTest, NestedMessages) {
    135   auto* msg_a = CreateMessage<pbtest::NestedA>();
    136 
    137   pbtest::NestedA::NestedB* msg_b = msg_a->add_repeated_a();
    138   pbtest::NestedA::NestedB::NestedC* msg_c = msg_b->set_value_b();
    139   msg_c->set_value_c(321);
    140   msg_b = msg_a->add_repeated_a();
    141   msg_c = msg_a->set_super_nested();
    142   msg_c->set_value_c(1000);
    143   msg_a->Finalize();
    144 
    145   size_t msg_size = GetNumSerializedBytes();
    146   EXPECT_EQ(26u, msg_size);
    147 
    148   std::unique_ptr<uint8_t[]> msg_binary(new uint8_t[msg_size]);
    149   GetSerializedBytes(0, msg_size, msg_binary.get());
    150 
    151   pbgold::NestedA gold_msg_a;
    152   gold_msg_a.ParseFromArray(msg_binary.get(), static_cast<int>(msg_size));
    153   EXPECT_EQ(2, gold_msg_a.repeated_a_size());
    154   EXPECT_EQ(321, gold_msg_a.repeated_a(0).value_b().value_c());
    155   EXPECT_FALSE(gold_msg_a.repeated_a(1).has_value_b());
    156   EXPECT_EQ(1000, gold_msg_a.super_nested().value_c());
    157 }
    158 
    159 TEST(ProtoZeroTest, Simple) {
    160   // Test the includes for indirect public import: library.pbzero.h ->
    161   // library_internals/galaxies.pbzero.h -> upper_import.pbzero.h .
    162   EXPECT_LE(0u, sizeof(pbtest::TrickyPublicImport));
    163 }
    164 
    165 TEST(ProtoZeroTest, Reflection) {
    166   // Tests camel case conversion as well.
    167   EXPECT_EQ(1, pbtest::CamelCaseFields::kFooBarBazFieldNumber);
    168   EXPECT_EQ(2, pbtest::CamelCaseFields::kBarBazFieldNumber);
    169   EXPECT_EQ(3, pbtest::CamelCaseFields::kMooMooFieldNumber);
    170   EXPECT_EQ(4, pbtest::CamelCaseFields::kURLEncoderFieldNumber);
    171   EXPECT_EQ(5, pbtest::CamelCaseFields::kXMapFieldNumber);
    172   EXPECT_EQ(6, pbtest::CamelCaseFields::kUrLENcoDerFieldNumber);
    173   EXPECT_EQ(7, pbtest::CamelCaseFields::kBigBangFieldNumber);
    174   EXPECT_EQ(8, pbtest::CamelCaseFields::kU2FieldNumber);
    175   EXPECT_EQ(9, pbtest::CamelCaseFields::kBangBigFieldNumber);
    176 
    177   const ProtoFieldDescriptor* reflection =
    178       pbtest::EveryField::GetFieldDescriptor(
    179           pbtest::EveryField::kFieldInt32FieldNumber);
    180   EXPECT_STREQ("field_int32", reflection->name());
    181   EXPECT_EQ(ProtoFieldDescriptor::Type::TYPE_INT32, reflection->type());
    182   EXPECT_EQ(1u, reflection->number());
    183   EXPECT_FALSE(reflection->is_repeated());
    184   EXPECT_TRUE(reflection->is_valid());
    185 
    186   EXPECT_FALSE(pbtest::TransgalacticParcel::GetFieldDescriptor(42)->is_valid());
    187 }
    188 
    189 }  // namespace
    190 }  // namespace protozero
    191