• 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/ref_counted_ptr.h"
20 
21 #include <gtest/gtest.h>
22 
23 #include <grpc/support/log.h>
24 
25 #include "src/core/lib/gprpp/memory.h"
26 #include "src/core/lib/gprpp/ref_counted.h"
27 #include "test/core/util/test_config.h"
28 
29 namespace grpc_core {
30 namespace testing {
31 namespace {
32 
33 class Foo : public RefCounted<Foo> {
34  public:
Foo()35   Foo() : value_(0) {}
36 
Foo(int value)37   explicit Foo(int value) : value_(value) {}
38 
value() const39   int value() const { return value_; }
40 
41  private:
42   int value_;
43 };
44 
TEST(RefCountedPtr,DefaultConstructor)45 TEST(RefCountedPtr, DefaultConstructor) { RefCountedPtr<Foo> foo; }
46 
TEST(RefCountedPtr,ExplicitConstructorEmpty)47 TEST(RefCountedPtr, ExplicitConstructorEmpty) {
48   RefCountedPtr<Foo> foo(nullptr);
49 }
50 
TEST(RefCountedPtr,ExplicitConstructor)51 TEST(RefCountedPtr, ExplicitConstructor) { RefCountedPtr<Foo> foo(New<Foo>()); }
52 
TEST(RefCountedPtr,MoveConstructor)53 TEST(RefCountedPtr, MoveConstructor) {
54   RefCountedPtr<Foo> foo(New<Foo>());
55   RefCountedPtr<Foo> foo2(std::move(foo));
56   EXPECT_EQ(nullptr, foo.get());
57   EXPECT_NE(nullptr, foo2.get());
58 }
59 
TEST(RefCountedPtr,MoveAssignment)60 TEST(RefCountedPtr, MoveAssignment) {
61   RefCountedPtr<Foo> foo(New<Foo>());
62   RefCountedPtr<Foo> foo2 = std::move(foo);
63   EXPECT_EQ(nullptr, foo.get());
64   EXPECT_NE(nullptr, foo2.get());
65 }
66 
TEST(RefCountedPtr,CopyConstructor)67 TEST(RefCountedPtr, CopyConstructor) {
68   RefCountedPtr<Foo> foo(New<Foo>());
69   const RefCountedPtr<Foo>& foo2(foo);
70   EXPECT_NE(nullptr, foo.get());
71   EXPECT_EQ(foo.get(), foo2.get());
72 }
73 
TEST(RefCountedPtr,CopyAssignment)74 TEST(RefCountedPtr, CopyAssignment) {
75   RefCountedPtr<Foo> foo(New<Foo>());
76   const RefCountedPtr<Foo>& foo2 = foo;
77   EXPECT_NE(nullptr, foo.get());
78   EXPECT_EQ(foo.get(), foo2.get());
79 }
80 
TEST(RefCountedPtr,CopyAssignmentWhenEmpty)81 TEST(RefCountedPtr, CopyAssignmentWhenEmpty) {
82   RefCountedPtr<Foo> foo;
83   RefCountedPtr<Foo> foo2;
84   foo2 = foo;
85   EXPECT_EQ(nullptr, foo.get());
86   EXPECT_EQ(nullptr, foo2.get());
87 }
88 
TEST(RefCountedPtr,CopyAssignmentToSelf)89 TEST(RefCountedPtr, CopyAssignmentToSelf) {
90   RefCountedPtr<Foo> foo(New<Foo>());
91   foo = *&foo;  // The "*&" avoids warnings from LLVM -Wself-assign.
92 }
93 
TEST(RefCountedPtr,EnclosedScope)94 TEST(RefCountedPtr, EnclosedScope) {
95   RefCountedPtr<Foo> foo(New<Foo>());
96   {
97     RefCountedPtr<Foo> foo2(std::move(foo));
98     EXPECT_EQ(nullptr, foo.get());
99     EXPECT_NE(nullptr, foo2.get());
100   }
101   EXPECT_EQ(nullptr, foo.get());
102 }
103 
TEST(RefCountedPtr,ResetFromNullToNonNull)104 TEST(RefCountedPtr, ResetFromNullToNonNull) {
105   RefCountedPtr<Foo> foo;
106   EXPECT_EQ(nullptr, foo.get());
107   foo.reset(New<Foo>());
108   EXPECT_NE(nullptr, foo.get());
109 }
110 
TEST(RefCountedPtr,ResetFromNonNullToNonNull)111 TEST(RefCountedPtr, ResetFromNonNullToNonNull) {
112   RefCountedPtr<Foo> foo(New<Foo>());
113   EXPECT_NE(nullptr, foo.get());
114   Foo* original = foo.get();
115   foo.reset(New<Foo>());
116   EXPECT_NE(nullptr, foo.get());
117   EXPECT_NE(original, foo.get());
118 }
119 
TEST(RefCountedPtr,ResetFromNonNullToNull)120 TEST(RefCountedPtr, ResetFromNonNullToNull) {
121   RefCountedPtr<Foo> foo(New<Foo>());
122   EXPECT_NE(nullptr, foo.get());
123   foo.reset();
124   EXPECT_EQ(nullptr, foo.get());
125 }
126 
TEST(RefCountedPtr,ResetFromNullToNull)127 TEST(RefCountedPtr, ResetFromNullToNull) {
128   RefCountedPtr<Foo> foo;
129   EXPECT_EQ(nullptr, foo.get());
130   foo.reset();
131   EXPECT_EQ(nullptr, foo.get());
132 }
133 
TEST(RefCountedPtr,DerefernceOperators)134 TEST(RefCountedPtr, DerefernceOperators) {
135   RefCountedPtr<Foo> foo(New<Foo>());
136   foo->value();
137   Foo& foo_ref = *foo;
138   foo_ref.value();
139 }
140 
TEST(RefCountedPtr,EqualityOperators)141 TEST(RefCountedPtr, EqualityOperators) {
142   RefCountedPtr<Foo> foo(New<Foo>());
143   RefCountedPtr<Foo> bar = foo;
144   RefCountedPtr<Foo> empty;
145   // Test equality between RefCountedPtrs.
146   EXPECT_EQ(foo, bar);
147   EXPECT_NE(foo, empty);
148   // Test equality with bare pointers.
149   EXPECT_EQ(foo, foo.get());
150   EXPECT_EQ(empty, nullptr);
151   EXPECT_NE(foo, nullptr);
152 }
153 
TEST(MakeRefCounted,NoArgs)154 TEST(MakeRefCounted, NoArgs) {
155   RefCountedPtr<Foo> foo = MakeRefCounted<Foo>();
156   EXPECT_EQ(0, foo->value());
157 }
158 
TEST(MakeRefCounted,Args)159 TEST(MakeRefCounted, Args) {
160   RefCountedPtr<Foo> foo = MakeRefCounted<Foo>(3);
161   EXPECT_EQ(3, foo->value());
162 }
163 
164 TraceFlag foo_tracer(true, "foo");
165 
166 class FooWithTracing : public RefCountedWithTracing<FooWithTracing> {
167  public:
FooWithTracing()168   FooWithTracing() : RefCountedWithTracing(&foo_tracer) {}
169 };
170 
TEST(RefCountedPtr,RefCountedWithTracing)171 TEST(RefCountedPtr, RefCountedWithTracing) {
172   RefCountedPtr<FooWithTracing> foo(New<FooWithTracing>());
173   RefCountedPtr<FooWithTracing> foo2 = foo->Ref(DEBUG_LOCATION, "foo");
174   foo2.release();
175   foo->Unref(DEBUG_LOCATION, "foo");
176 }
177 
178 class BaseClass : public RefCounted<BaseClass> {
179  public:
BaseClass()180   BaseClass() {}
181 };
182 
183 class Subclass : public BaseClass {
184  public:
Subclass()185   Subclass() {}
186 };
187 
TEST(RefCountedPtr,ConstructFromSubclass)188 TEST(RefCountedPtr, ConstructFromSubclass) {
189   RefCountedPtr<BaseClass> p(New<Subclass>());
190 }
191 
TEST(RefCountedPtr,CopyAssignFromSubclass)192 TEST(RefCountedPtr, CopyAssignFromSubclass) {
193   RefCountedPtr<BaseClass> b;
194   EXPECT_EQ(nullptr, b.get());
195   RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
196   b = s;
197   EXPECT_NE(nullptr, b.get());
198 }
199 
TEST(RefCountedPtr,MoveAssignFromSubclass)200 TEST(RefCountedPtr, MoveAssignFromSubclass) {
201   RefCountedPtr<BaseClass> b;
202   EXPECT_EQ(nullptr, b.get());
203   RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
204   b = std::move(s);
205   EXPECT_NE(nullptr, b.get());
206 }
207 
TEST(RefCountedPtr,ResetFromSubclass)208 TEST(RefCountedPtr, ResetFromSubclass) {
209   RefCountedPtr<BaseClass> b;
210   EXPECT_EQ(nullptr, b.get());
211   b.reset(New<Subclass>());
212   EXPECT_NE(nullptr, b.get());
213 }
214 
TEST(RefCountedPtr,EqualityWithSubclass)215 TEST(RefCountedPtr, EqualityWithSubclass) {
216   Subclass* s = New<Subclass>();
217   RefCountedPtr<BaseClass> b(s);
218   EXPECT_EQ(b, s);
219 }
220 
FunctionTakingBaseClass(RefCountedPtr<BaseClass> p)221 void FunctionTakingBaseClass(RefCountedPtr<BaseClass> p) {
222   p.reset();  // To appease clang-tidy.
223 }
224 
TEST(RefCountedPtr,CanPassSubclassToFunctionExpectingBaseClass)225 TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingBaseClass) {
226   RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
227   FunctionTakingBaseClass(p);
228 }
229 
FunctionTakingSubclass(RefCountedPtr<Subclass> p)230 void FunctionTakingSubclass(RefCountedPtr<Subclass> p) {
231   p.reset();  // To appease clang-tidy.
232 }
233 
TEST(RefCountedPtr,CanPassSubclassToFunctionExpectingSubclass)234 TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) {
235   RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
236   FunctionTakingSubclass(p);
237 }
238 
239 }  // namespace
240 }  // namespace testing
241 }  // namespace grpc_core
242 
main(int argc,char ** argv)243 int main(int argc, char** argv) {
244   grpc_test_init(argc, argv);
245   ::testing::InitGoogleTest(&argc, argv);
246   return RUN_ALL_TESTS();
247 }
248