Home | History | Annotate | Download | only in gprpp
      1 /*
      2  *
      3  * Copyright 2017 gRPC authors.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  */
     18 
     19 #include "src/core/lib/gprpp/orphanable.h"
     20 
     21 #include <gtest/gtest.h>
     22 
     23 #include "src/core/lib/gprpp/memory.h"
     24 #include "test/core/util/test_config.h"
     25 
     26 namespace grpc_core {
     27 namespace testing {
     28 namespace {
     29 
     30 class Foo : public Orphanable {
     31  public:
     32   Foo() : Foo(0) {}
     33   explicit Foo(int value) : value_(value) {}
     34   void Orphan() override { Delete(this); }
     35   int value() const { return value_; }
     36 
     37  private:
     38   int value_;
     39 };
     40 
     41 TEST(Orphanable, Basic) {
     42   Foo* foo = New<Foo>();
     43   foo->Orphan();
     44 }
     45 
     46 TEST(OrphanablePtr, Basic) {
     47   OrphanablePtr<Foo> foo(New<Foo>());
     48   EXPECT_EQ(0, foo->value());
     49 }
     50 
     51 TEST(MakeOrphanable, DefaultConstructor) {
     52   auto foo = MakeOrphanable<Foo>();
     53   EXPECT_EQ(0, foo->value());
     54 }
     55 
     56 TEST(MakeOrphanable, WithParameters) {
     57   auto foo = MakeOrphanable<Foo>(5);
     58   EXPECT_EQ(5, foo->value());
     59 }
     60 
     61 class Bar : public InternallyRefCounted<Bar> {
     62  public:
     63   Bar() : Bar(0) {}
     64   explicit Bar(int value) : value_(value) {}
     65   void Orphan() override { Unref(); }
     66   int value() const { return value_; }
     67 
     68   void StartWork() { self_ref_ = Ref(); }
     69   void FinishWork() { self_ref_.reset(); }
     70 
     71  private:
     72   int value_;
     73   RefCountedPtr<Bar> self_ref_;
     74 };
     75 
     76 TEST(OrphanablePtr, InternallyRefCounted) {
     77   auto bar = MakeOrphanable<Bar>();
     78   bar->StartWork();
     79   bar->FinishWork();
     80 }
     81 
     82 // Note: We use DebugOnlyTraceFlag instead of TraceFlag to ensure that
     83 // things build properly in both debug and non-debug cases.
     84 DebugOnlyTraceFlag baz_tracer(true, "baz");
     85 
     86 class Baz : public InternallyRefCountedWithTracing<Baz> {
     87  public:
     88   Baz() : Baz(0) {}
     89   explicit Baz(int value)
     90       : InternallyRefCountedWithTracing<Baz>(&baz_tracer), value_(value) {}
     91   void Orphan() override { Unref(); }
     92   int value() const { return value_; }
     93 
     94   void StartWork() { self_ref_ = Ref(DEBUG_LOCATION, "work"); }
     95   void FinishWork() {
     96     // This is a little ugly, but it makes the logged ref and unref match up.
     97     self_ref_.release();
     98     Unref(DEBUG_LOCATION, "work");
     99   }
    100 
    101  private:
    102   int value_;
    103   RefCountedPtr<Baz> self_ref_;
    104 };
    105 
    106 TEST(OrphanablePtr, InternallyRefCountedWithTracing) {
    107   auto baz = MakeOrphanable<Baz>();
    108   baz->StartWork();
    109   baz->FinishWork();
    110 }
    111 
    112 }  // namespace
    113 }  // namespace testing
    114 }  // namespace grpc_core
    115 
    116 int main(int argc, char** argv) {
    117   grpc_test_init(argc, argv);
    118   ::testing::InitGoogleTest(&argc, argv);
    119   return RUN_ALL_TESTS();
    120 }
    121