• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Foo()32   Foo() : Foo(0) {}
Foo(int value)33   explicit Foo(int value) : value_(value) {}
Orphan()34   void Orphan() override { delete this; }
value() const35   int value() const { return value_; }
36 
37  private:
38   int value_;
39 };
40 
TEST(Orphanable,Basic)41 TEST(Orphanable, Basic) {
42   Foo* foo = new Foo();
43   foo->Orphan();
44 }
45 
TEST(OrphanablePtr,Basic)46 TEST(OrphanablePtr, Basic) {
47   OrphanablePtr<Foo> foo(new Foo());
48   EXPECT_EQ(0, foo->value());
49 }
50 
TEST(MakeOrphanable,DefaultConstructor)51 TEST(MakeOrphanable, DefaultConstructor) {
52   auto foo = MakeOrphanable<Foo>();
53   EXPECT_EQ(0, foo->value());
54 }
55 
TEST(MakeOrphanable,WithParameters)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:
Bar()63   Bar() : Bar(0) {}
Bar(int value)64   explicit Bar(int value) : value_(value) {}
Orphan()65   void Orphan() override { Unref(); }
value() const66   int value() const { return value_; }
67 
StartWork()68   void StartWork() { self_ref_ = Ref(); }
FinishWork()69   void FinishWork() { self_ref_.reset(); }
70 
71  private:
72   int value_;
73   RefCountedPtr<Bar> self_ref_;
74 };
75 
TEST(OrphanablePtr,InternallyRefCounted)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 InternallyRefCounted<Baz> {
87  public:
Baz()88   Baz() : Baz(0) {}
Baz(int value)89   explicit Baz(int value)
90       : InternallyRefCounted<Baz>(&baz_tracer), value_(value) {}
Orphan()91   void Orphan() override { Unref(); }
value() const92   int value() const { return value_; }
93 
StartWork()94   void StartWork() { self_ref_ = Ref(DEBUG_LOCATION, "work"); }
FinishWork()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 
TEST(OrphanablePtr,InternallyRefCountedWithTracing)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 
main(int argc,char ** argv)116 int main(int argc, char** argv) {
117   grpc::testing::TestEnvironment env(argc, argv);
118   ::testing::InitGoogleTest(&argc, argv);
119   return RUN_ALL_TESTS();
120 }
121