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 InternallyRefCountedWithTracing<Baz> {
87 public:
Baz()88 Baz() : Baz(0) {}
Baz(int value)89 explicit Baz(int value)
90 : InternallyRefCountedWithTracing<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_test_init(argc, argv);
118 ::testing::InitGoogleTest(&argc, argv);
119 return RUN_ALL_TESTS();
120 }
121