ref_counted_ptr_test.cc
Go to the documentation of this file.
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 
20 
21 #include <gtest/gtest.h>
22 
23 #include <grpc/support/log.h>
24 
29 
30 namespace grpc_core {
31 namespace testing {
32 namespace {
33 
34 //
35 // RefCountedPtr<> tests
36 //
37 
38 class Foo : public RefCounted<Foo> {
39  public:
40  Foo() : value_(0) {}
41 
42  explicit Foo(int value) : value_(value) {}
43 
44  int value() const { return value_; }
45 
46  private:
47  int value_;
48 };
49 
50 TEST(RefCountedPtr, DefaultConstructor) { RefCountedPtr<Foo> foo; }
51 
52 TEST(RefCountedPtr, ExplicitConstructorEmpty) {
53  RefCountedPtr<Foo> foo(nullptr);
54 }
55 
56 TEST(RefCountedPtr, ExplicitConstructor) { RefCountedPtr<Foo> foo(new Foo()); }
57 
58 TEST(RefCountedPtr, MoveConstructor) {
59  RefCountedPtr<Foo> foo(new Foo());
60  RefCountedPtr<Foo> foo2(std::move(foo));
61  // NOLINTNEXTLINE(bugprone-use-after-move)
62  EXPECT_EQ(nullptr, foo.get());
63  EXPECT_NE(nullptr, foo2.get());
64 }
65 
66 TEST(RefCountedPtr, MoveAssignment) {
67  RefCountedPtr<Foo> foo(new Foo());
68  RefCountedPtr<Foo> foo2 = std::move(foo);
69  // NOLINTNEXTLINE(bugprone-use-after-move)
70  EXPECT_EQ(nullptr, foo.get());
71  EXPECT_NE(nullptr, foo2.get());
72 }
73 
74 TEST(RefCountedPtr, CopyConstructor) {
75  RefCountedPtr<Foo> foo(new Foo());
76  RefCountedPtr<Foo> foo2(foo);
77  EXPECT_NE(nullptr, foo.get());
78  EXPECT_EQ(foo.get(), foo2.get());
79 }
80 
81 TEST(RefCountedPtr, CopyAssignment) {
82  RefCountedPtr<Foo> foo(new Foo());
83  RefCountedPtr<Foo> foo2 = foo;
84  EXPECT_NE(nullptr, foo.get());
85  EXPECT_EQ(foo.get(), foo2.get());
86 }
87 
88 TEST(RefCountedPtr, CopyAssignmentWhenEmpty) {
89  RefCountedPtr<Foo> foo;
90  RefCountedPtr<Foo> foo2;
91  foo2 = foo;
92  EXPECT_EQ(nullptr, foo.get());
93  EXPECT_EQ(nullptr, foo2.get());
94 }
95 
96 TEST(RefCountedPtr, CopyAssignmentToSelf) {
97  RefCountedPtr<Foo> foo(new Foo());
98  foo = *&foo; // The "*&" avoids warnings from LLVM -Wself-assign.
99 }
100 
101 TEST(RefCountedPtr, EnclosedScope) {
102  RefCountedPtr<Foo> foo(new Foo());
103  {
104  RefCountedPtr<Foo> foo2(std::move(foo));
105  // NOLINTNEXTLINE(bugprone-use-after-move)
106  EXPECT_EQ(nullptr, foo.get());
107  EXPECT_NE(nullptr, foo2.get());
108  }
109  EXPECT_EQ(nullptr, foo.get());
110 }
111 
112 TEST(RefCountedPtr, ResetFromNullToNonNull) {
113  RefCountedPtr<Foo> foo;
114  EXPECT_EQ(nullptr, foo.get());
115  foo.reset(new Foo());
116  EXPECT_NE(nullptr, foo.get());
117 }
118 
119 TEST(RefCountedPtr, ResetFromNonNullToNonNull) {
120  RefCountedPtr<Foo> foo(new Foo());
121  EXPECT_NE(nullptr, foo.get());
122  Foo* original = foo.get();
123  foo.reset(new Foo());
124  EXPECT_NE(nullptr, foo.get());
125  EXPECT_NE(original, foo.get());
126 }
127 
128 TEST(RefCountedPtr, ResetFromNonNullToNull) {
129  RefCountedPtr<Foo> foo(new Foo());
130  EXPECT_NE(nullptr, foo.get());
131  foo.reset();
132  EXPECT_EQ(nullptr, foo.get());
133 }
134 
135 TEST(RefCountedPtr, ResetFromNullToNull) {
136  RefCountedPtr<Foo> foo;
137  EXPECT_EQ(nullptr, foo.get());
138  foo.reset();
139  EXPECT_EQ(nullptr, foo.get());
140 }
141 
142 TEST(RefCountedPtr, DerefernceOperators) {
143  RefCountedPtr<Foo> foo(new Foo());
144  foo->value();
145  Foo& foo_ref = *foo;
146  foo_ref.value();
147 }
148 
149 TEST(RefCountedPtr, EqualityOperators) {
150  RefCountedPtr<Foo> foo(new Foo());
151  RefCountedPtr<Foo> bar = foo;
152  RefCountedPtr<Foo> empty;
153  // Test equality between RefCountedPtrs.
154  EXPECT_EQ(foo, bar);
155  EXPECT_NE(foo, empty);
156  // Test equality with bare pointers.
157  EXPECT_EQ(foo, foo.get());
158  EXPECT_EQ(empty, nullptr);
159  EXPECT_NE(foo, nullptr);
160 }
161 
162 TEST(RefCountedPtr, Swap) {
163  Foo* foo = new Foo();
164  Foo* bar = new Foo();
165  RefCountedPtr<Foo> ptr1(foo);
166  RefCountedPtr<Foo> ptr2(bar);
167  ptr1.swap(ptr2);
168  EXPECT_EQ(foo, ptr2.get());
169  EXPECT_EQ(bar, ptr1.get());
170  RefCountedPtr<Foo> ptr3;
171  ptr3.swap(ptr2);
172  EXPECT_EQ(nullptr, ptr2.get());
173  EXPECT_EQ(foo, ptr3.get());
174 }
175 
176 TEST(MakeRefCounted, NoArgs) {
177  RefCountedPtr<Foo> foo = MakeRefCounted<Foo>();
178  EXPECT_EQ(0, foo->value());
179 }
180 
182  RefCountedPtr<Foo> foo = MakeRefCounted<Foo>(3);
183  EXPECT_EQ(3, foo->value());
184 }
185 
186 class FooWithTracing : public RefCounted<FooWithTracing> {
187  public:
188  FooWithTracing() : RefCounted("FooWithTracing") {}
189 };
190 
191 TEST(RefCountedPtr, RefCountedWithTracing) {
192  RefCountedPtr<FooWithTracing> foo(new FooWithTracing());
193  RefCountedPtr<FooWithTracing> foo2 = foo->Ref(DEBUG_LOCATION, "foo");
194  foo2.release();
195  foo->Unref(DEBUG_LOCATION, "foo");
196 }
197 
198 class BaseClass : public RefCounted<BaseClass> {
199  public:
200  BaseClass() {}
201 };
202 
203 class Subclass : public BaseClass {
204  public:
205  Subclass() {}
206 };
207 
208 TEST(RefCountedPtr, ConstructFromSubclass) {
209  RefCountedPtr<BaseClass> p(new Subclass());
210 }
211 
212 TEST(RefCountedPtr, CopyAssignFromSubclass) {
213  RefCountedPtr<BaseClass> b;
214  EXPECT_EQ(nullptr, b.get());
215  RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
216  b = s;
217  EXPECT_NE(nullptr, b.get());
218 }
219 
220 TEST(RefCountedPtr, MoveAssignFromSubclass) {
221  RefCountedPtr<BaseClass> b;
222  EXPECT_EQ(nullptr, b.get());
223  RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
224  b = std::move(s);
225  EXPECT_NE(nullptr, b.get());
226 }
227 
228 TEST(RefCountedPtr, ResetFromSubclass) {
229  RefCountedPtr<BaseClass> b;
230  EXPECT_EQ(nullptr, b.get());
231  b.reset(new Subclass());
232  EXPECT_NE(nullptr, b.get());
233 }
234 
235 TEST(RefCountedPtr, EqualityWithSubclass) {
236  Subclass* s = new Subclass();
237  RefCountedPtr<BaseClass> b(s);
238  EXPECT_EQ(b, s);
239 }
240 
241 void FunctionTakingBaseClass(RefCountedPtr<BaseClass> p) {
242  p.reset(); // To appease clang-tidy.
243 }
244 
245 TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingBaseClass) {
246  RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
247  FunctionTakingBaseClass(p);
248 }
249 
250 void FunctionTakingSubclass(RefCountedPtr<Subclass> p) {
251  p.reset(); // To appease clang-tidy.
252 }
253 
254 TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) {
255  RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
256  FunctionTakingSubclass(p);
257 }
258 
259 //
260 // WeakRefCountedPtr<> tests
261 //
262 
263 class Bar : public DualRefCounted<Bar> {
264  public:
265  Bar() : value_(0) {}
266 
267  explicit Bar(int value) : value_(value) {}
268 
269  ~Bar() override { GPR_ASSERT(shutting_down_); }
270 
271  void Orphan() override { shutting_down_ = true; }
272 
273  int value() const { return value_; }
274 
275  private:
276  int value_;
277  bool shutting_down_ = false;
278 };
279 
280 TEST(WeakRefCountedPtr, DefaultConstructor) { WeakRefCountedPtr<Bar> bar; }
281 
282 TEST(WeakRefCountedPtr, ExplicitConstructorEmpty) {
283  WeakRefCountedPtr<Bar> bar(nullptr);
284 }
285 
286 TEST(WeakRefCountedPtr, ExplicitConstructor) {
287  RefCountedPtr<Bar> bar_strong(new Bar());
288  bar_strong->WeakRef().release();
289  WeakRefCountedPtr<Bar> bar(bar_strong.get());
290 }
291 
292 TEST(WeakRefCountedPtr, MoveConstructor) {
293  RefCountedPtr<Bar> bar_strong(new Bar());
294  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
295  WeakRefCountedPtr<Bar> bar2(std::move(bar));
296  EXPECT_EQ(nullptr, bar.get()); // NOLINT
297  EXPECT_NE(nullptr, bar2.get());
298 }
299 
300 TEST(WeakRefCountedPtr, MoveAssignment) {
301  RefCountedPtr<Bar> bar_strong(new Bar());
302  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
303  WeakRefCountedPtr<Bar> bar2 = std::move(bar);
304  EXPECT_EQ(nullptr, bar.get()); // NOLINT
305  EXPECT_NE(nullptr, bar2.get());
306 }
307 
308 TEST(WeakRefCountedPtr, CopyConstructor) {
309  RefCountedPtr<Bar> bar_strong(new Bar());
310  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
311  WeakRefCountedPtr<Bar> bar2(bar);
312  EXPECT_NE(nullptr, bar.get());
313  EXPECT_EQ(bar.get(), bar2.get());
314 }
315 
316 TEST(WeakRefCountedPtr, CopyAssignment) {
317  RefCountedPtr<Bar> bar_strong(new Bar());
318  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
319  WeakRefCountedPtr<Bar> bar2 = bar;
320  EXPECT_NE(nullptr, bar.get());
321  EXPECT_EQ(bar.get(), bar2.get());
322 }
323 
324 TEST(WeakRefCountedPtr, CopyAssignmentWhenEmpty) {
325  WeakRefCountedPtr<Bar> bar;
326  WeakRefCountedPtr<Bar> bar2;
327  bar2 = bar;
328  EXPECT_EQ(nullptr, bar.get());
329  EXPECT_EQ(nullptr, bar2.get());
330 }
331 
332 TEST(WeakRefCountedPtr, CopyAssignmentToSelf) {
333  RefCountedPtr<Bar> bar_strong(new Bar());
334  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
335  bar = *&bar; // The "*&" avoids warnings from LLVM -Wself-assign.
336 }
337 
338 TEST(WeakRefCountedPtr, EnclosedScope) {
339  RefCountedPtr<Bar> bar_strong(new Bar());
340  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
341  {
342  WeakRefCountedPtr<Bar> bar2(std::move(bar));
343  // NOLINTNEXTLINE(bugprone-use-after-move)
344  EXPECT_EQ(nullptr, bar.get());
345  EXPECT_NE(nullptr, bar2.get());
346  }
347  EXPECT_EQ(nullptr, bar.get());
348 }
349 
350 TEST(WeakRefCountedPtr, ResetFromNullToNonNull) {
351  RefCountedPtr<Bar> bar_strong(new Bar());
352  WeakRefCountedPtr<Bar> bar;
353  EXPECT_EQ(nullptr, bar.get());
354  bar_strong->WeakRef().release();
355  bar.reset(bar_strong.get());
356  EXPECT_NE(nullptr, bar.get());
357 }
358 
359 TEST(WeakRefCountedPtr, ResetFromNonNullToNonNull) {
360  RefCountedPtr<Bar> bar_strong(new Bar());
361  RefCountedPtr<Bar> bar2_strong(new Bar());
362  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
363  EXPECT_NE(nullptr, bar.get());
364  bar2_strong->WeakRef().release();
365  bar.reset(bar2_strong.get());
366  EXPECT_NE(nullptr, bar.get());
367  EXPECT_NE(bar_strong.get(), bar.get());
368 }
369 
370 TEST(WeakRefCountedPtr, ResetFromNonNullToNull) {
371  RefCountedPtr<Bar> bar_strong(new Bar());
372  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
373  EXPECT_NE(nullptr, bar.get());
374  bar.reset();
375  EXPECT_EQ(nullptr, bar.get());
376 }
377 
378 TEST(WeakRefCountedPtr, ResetFromNullToNull) {
379  WeakRefCountedPtr<Bar> bar;
380  EXPECT_EQ(nullptr, bar.get());
381  bar.reset();
382  EXPECT_EQ(nullptr, bar.get());
383 }
384 
385 TEST(WeakRefCountedPtr, DerefernceOperators) {
386  RefCountedPtr<Bar> bar_strong(new Bar());
387  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
388  bar->value();
389  Bar& bar_ref = *bar;
390  bar_ref.value();
391 }
392 
393 TEST(WeakRefCountedPtr, EqualityOperators) {
394  RefCountedPtr<Bar> bar_strong(new Bar());
395  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
396  WeakRefCountedPtr<Bar> bar2 = bar;
397  WeakRefCountedPtr<Bar> empty;
398  // Test equality between RefCountedPtrs.
399  EXPECT_EQ(bar, bar2);
400  EXPECT_NE(bar, empty);
401  // Test equality with bare pointers.
402  EXPECT_EQ(bar, bar.get());
403  EXPECT_EQ(empty, nullptr);
404  EXPECT_NE(bar, nullptr);
405 }
406 
407 TEST(WeakRefCountedPtr, Swap) {
408  RefCountedPtr<Bar> bar_strong(new Bar());
409  RefCountedPtr<Bar> bar2_strong(new Bar());
410  WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
411  WeakRefCountedPtr<Bar> bar2 = bar2_strong->WeakRef();
412  bar.swap(bar2);
413  EXPECT_EQ(bar_strong.get(), bar2.get());
414  EXPECT_EQ(bar2_strong.get(), bar.get());
415  WeakRefCountedPtr<Bar> bar3;
416  bar3.swap(bar2);
417  EXPECT_EQ(nullptr, bar2.get());
418  EXPECT_EQ(bar_strong.get(), bar3.get());
419 }
420 
421 class BarWithTracing : public DualRefCounted<BarWithTracing> {
422  public:
423  BarWithTracing() : DualRefCounted("BarWithTracing") {}
424 
425  ~BarWithTracing() override { GPR_ASSERT(shutting_down_); }
426 
427  void Orphan() override { shutting_down_ = true; }
428 
429  private:
430  bool shutting_down_ = false;
431 };
432 
433 TEST(WeakRefCountedPtr, RefCountedWithTracing) {
434  RefCountedPtr<BarWithTracing> bar_strong(new BarWithTracing());
435  WeakRefCountedPtr<BarWithTracing> bar = bar_strong->WeakRef();
436  WeakRefCountedPtr<BarWithTracing> bar2 = bar->WeakRef(DEBUG_LOCATION, "bar");
437  bar2.release();
438  bar->WeakUnref(DEBUG_LOCATION, "bar");
439 }
440 
441 class WeakBaseClass : public DualRefCounted<WeakBaseClass> {
442  public:
443  WeakBaseClass() {}
444 
445  ~WeakBaseClass() override { GPR_ASSERT(shutting_down_); }
446 
447  void Orphan() override { shutting_down_ = true; }
448 
449  private:
450  bool shutting_down_ = false;
451 };
452 
453 class WeakSubclass : public WeakBaseClass {
454  public:
455  WeakSubclass() {}
456 };
457 
458 TEST(WeakRefCountedPtr, ConstructFromWeakSubclass) {
459  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
460  WeakRefCountedPtr<WeakBaseClass> p(strong->WeakRef().release());
461 }
462 
463 TEST(WeakRefCountedPtr, CopyAssignFromWeakSubclass) {
464  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
465  WeakRefCountedPtr<WeakBaseClass> b;
466  EXPECT_EQ(nullptr, b.get());
467  WeakRefCountedPtr<WeakSubclass> s = strong->WeakRef();
468  b = s;
469  EXPECT_NE(nullptr, b.get());
470 }
471 
472 TEST(WeakRefCountedPtr, MoveAssignFromWeakSubclass) {
473  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
474  WeakRefCountedPtr<WeakBaseClass> b;
475  EXPECT_EQ(nullptr, b.get());
476  WeakRefCountedPtr<WeakSubclass> s = strong->WeakRef();
477  b = std::move(s);
478  EXPECT_NE(nullptr, b.get());
479 }
480 
481 TEST(WeakRefCountedPtr, ResetFromWeakSubclass) {
482  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
483  WeakRefCountedPtr<WeakBaseClass> b;
484  EXPECT_EQ(nullptr, b.get());
485  b.reset(strong->WeakRef().release());
486  EXPECT_NE(nullptr, b.get());
487 }
488 
489 TEST(WeakRefCountedPtr, EqualityWithWeakSubclass) {
490  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
491  WeakRefCountedPtr<WeakBaseClass> b = strong->WeakRef();
492  EXPECT_EQ(b, strong.get());
493 }
494 
495 void FunctionTakingWeakBaseClass(WeakRefCountedPtr<WeakBaseClass> p) {
496  p.reset(); // To appease clang-tidy.
497 }
498 
499 TEST(WeakRefCountedPtr, CanPassWeakSubclassToFunctionExpectingWeakBaseClass) {
500  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
501  WeakRefCountedPtr<WeakSubclass> p = strong->WeakRef();
502  FunctionTakingWeakBaseClass(p);
503 }
504 
505 void FunctionTakingWeakSubclass(WeakRefCountedPtr<WeakSubclass> p) {
506  p.reset(); // To appease clang-tidy.
507 }
508 
509 TEST(WeakRefCountedPtr, CanPassWeakSubclassToFunctionExpectingWeakSubclass) {
510  RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
511  WeakRefCountedPtr<WeakSubclass> p = strong->WeakRef();
512  FunctionTakingWeakSubclass(p);
513 }
514 
515 } // namespace
516 } // namespace testing
517 } // namespace grpc_core
518 
519 int main(int argc, char** argv) {
520  grpc::testing::TestEnvironment env(&argc, argv);
521  ::testing::InitGoogleTest(&argc, argv);
522  return RUN_ALL_TESTS();
523 }
testing
Definition: aws_request_signer_test.cc:25
grpc_core::MakeRefCounted
RefCountedPtr< T > MakeRefCounted(Args &&... args)
Definition: ref_counted_ptr.h:335
absl::swap_internal::Swap
void Swap(T &lhs, T &rhs) noexcept(IsNothrowSwappable< T >::value)
Definition: abseil-cpp/absl/meta/type_traits.h:772
log.h
generate.env
env
Definition: generate.py:37
grpc_core
Definition: call_metric_recorder.h:31
bar
Definition: bloaty/third_party/googletest/googletest/test/googletest-output-test_.cc:562
foo
Definition: bloaty/third_party/googletest/googletest/test/googletest-output-test_.cc:546
absl::FormatConversionChar::s
@ s
shutting_down_
bool shutting_down_
Definition: ref_counted_ptr_test.cc:277
xds_manager.p
p
Definition: xds_manager.py:60
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
memory.h
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
hpack_encoder_fixtures::Args
Args({0, 16384})
Foo
Definition: abseil-cpp/absl/debugging/symbolize_test.cc:65
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
test_config.h
value
const char * value
Definition: hpack_parser_table.cc:165
foo
int foo
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/statusor_test.cc:66
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
ref_counted.h
value_
int value_
Definition: ref_counted_ptr_test.cc:47
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
ref_counted_ptr.h
dual_ref_counted.h
grpc_core::testing::TEST
TEST(ServiceConfigParserTest, DoubleRegistration)
Definition: service_config_test.cc:448
bar
void bar()
Definition: bar.cc:3
main
int main(int argc, char **argv)
Definition: ref_counted_ptr_test.cc:519


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:00