xref: /aosp_15_r20/external/grpc-grpc/test/core/gprpp/ref_counted_ptr_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 <memory>
22 
23 #include "absl/container/flat_hash_set.h"
24 #include "gtest/gtest.h"
25 
26 #include <grpc/support/log.h>
27 
28 #include "src/core/lib/gprpp/dual_ref_counted.h"
29 #include "src/core/lib/gprpp/ref_counted.h"
30 #include "test/core/util/test_config.h"
31 
32 namespace grpc_core {
33 namespace testing {
34 namespace {
35 
36 //
37 // RefCountedPtr<> tests
38 //
39 
40 class Foo : public RefCounted<Foo> {
41  public:
Foo()42   Foo() : value_(0) {}
43 
Foo(int value)44   explicit Foo(int value) : value_(value) {}
45 
value() const46   int value() const { return value_; }
47 
48  private:
49   int value_;
50 };
51 
TEST(RefCountedPtr,DefaultConstructor)52 TEST(RefCountedPtr, DefaultConstructor) { RefCountedPtr<Foo> foo; }
53 
TEST(RefCountedPtr,ExplicitConstructorEmpty)54 TEST(RefCountedPtr, ExplicitConstructorEmpty) {
55   RefCountedPtr<Foo> foo(nullptr);
56 }
57 
TEST(RefCountedPtr,ExplicitConstructor)58 TEST(RefCountedPtr, ExplicitConstructor) { RefCountedPtr<Foo> foo(new Foo()); }
59 
TEST(RefCountedPtr,MoveConstructor)60 TEST(RefCountedPtr, MoveConstructor) {
61   RefCountedPtr<Foo> foo(new Foo());
62   RefCountedPtr<Foo> foo2(std::move(foo));
63   // NOLINTNEXTLINE(bugprone-use-after-move)
64   EXPECT_EQ(nullptr, foo.get());
65   EXPECT_NE(nullptr, foo2.get());
66 }
67 
TEST(RefCountedPtr,MoveAssignment)68 TEST(RefCountedPtr, MoveAssignment) {
69   RefCountedPtr<Foo> foo(new Foo());
70   RefCountedPtr<Foo> foo2 = std::move(foo);
71   // NOLINTNEXTLINE(bugprone-use-after-move)
72   EXPECT_EQ(nullptr, foo.get());
73   EXPECT_NE(nullptr, foo2.get());
74 }
75 
TEST(RefCountedPtr,CopyConstructor)76 TEST(RefCountedPtr, CopyConstructor) {
77   RefCountedPtr<Foo> foo(new Foo());
78   RefCountedPtr<Foo> foo2(foo);
79   EXPECT_NE(nullptr, foo.get());
80   EXPECT_EQ(foo.get(), foo2.get());
81 }
82 
TEST(RefCountedPtr,CopyAssignment)83 TEST(RefCountedPtr, CopyAssignment) {
84   RefCountedPtr<Foo> foo(new Foo());
85   RefCountedPtr<Foo> foo2 = foo;
86   EXPECT_NE(nullptr, foo.get());
87   EXPECT_EQ(foo.get(), foo2.get());
88 }
89 
TEST(RefCountedPtr,CopyAssignmentWhenEmpty)90 TEST(RefCountedPtr, CopyAssignmentWhenEmpty) {
91   RefCountedPtr<Foo> foo;
92   RefCountedPtr<Foo> foo2;
93   foo2 = foo;
94   EXPECT_EQ(nullptr, foo.get());
95   EXPECT_EQ(nullptr, foo2.get());
96 }
97 
TEST(RefCountedPtr,CopyAssignmentToSelf)98 TEST(RefCountedPtr, CopyAssignmentToSelf) {
99   RefCountedPtr<Foo> foo(new Foo());
100   foo = *&foo;  // The "*&" avoids warnings from LLVM -Wself-assign.
101 }
102 
TEST(RefCountedPtr,EnclosedScope)103 TEST(RefCountedPtr, EnclosedScope) {
104   RefCountedPtr<Foo> foo(new Foo());
105   {
106     RefCountedPtr<Foo> foo2(std::move(foo));
107     // NOLINTNEXTLINE(bugprone-use-after-move)
108     EXPECT_EQ(nullptr, foo.get());
109     EXPECT_NE(nullptr, foo2.get());
110   }
111   EXPECT_EQ(nullptr, foo.get());
112 }
113 
TEST(RefCountedPtr,ResetFromNullToNonNull)114 TEST(RefCountedPtr, ResetFromNullToNonNull) {
115   RefCountedPtr<Foo> foo;
116   EXPECT_EQ(nullptr, foo.get());
117   foo.reset(new Foo());
118   EXPECT_NE(nullptr, foo.get());
119 }
120 
TEST(RefCountedPtr,ResetFromNonNullToNonNull)121 TEST(RefCountedPtr, ResetFromNonNullToNonNull) {
122   RefCountedPtr<Foo> foo(new Foo());
123   EXPECT_NE(nullptr, foo.get());
124   Foo* original = foo.get();
125   foo.reset(new Foo());
126   EXPECT_NE(nullptr, foo.get());
127   EXPECT_NE(original, foo.get());
128 }
129 
TEST(RefCountedPtr,ResetFromNonNullToNull)130 TEST(RefCountedPtr, ResetFromNonNullToNull) {
131   RefCountedPtr<Foo> foo(new Foo());
132   EXPECT_NE(nullptr, foo.get());
133   foo.reset();
134   EXPECT_EQ(nullptr, foo.get());
135 }
136 
TEST(RefCountedPtr,ResetFromNullToNull)137 TEST(RefCountedPtr, ResetFromNullToNull) {
138   RefCountedPtr<Foo> foo;
139   EXPECT_EQ(nullptr, foo.get());
140   foo.reset();
141   EXPECT_EQ(nullptr, foo.get());
142 }
143 
TEST(RefCountedPtr,DerefernceOperators)144 TEST(RefCountedPtr, DerefernceOperators) {
145   RefCountedPtr<Foo> foo(new Foo());
146   foo->value();
147   Foo& foo_ref = *foo;
148   foo_ref.value();
149 }
150 
TEST(RefCountedPtr,EqualityOperators)151 TEST(RefCountedPtr, EqualityOperators) {
152   RefCountedPtr<Foo> foo(new Foo());
153   RefCountedPtr<Foo> bar = foo;
154   RefCountedPtr<Foo> empty;
155   // Test equality between RefCountedPtrs.
156   EXPECT_EQ(foo, bar);
157   EXPECT_NE(foo, empty);
158   // Test equality with bare pointers.
159   EXPECT_EQ(foo, foo.get());
160   EXPECT_EQ(empty, nullptr);
161   EXPECT_NE(foo, nullptr);
162 }
163 
TEST(RefCountedPtr,Swap)164 TEST(RefCountedPtr, Swap) {
165   Foo* foo = new Foo();
166   Foo* bar = new Foo();
167   RefCountedPtr<Foo> ptr1(foo);
168   RefCountedPtr<Foo> ptr2(bar);
169   ptr1.swap(ptr2);
170   EXPECT_EQ(foo, ptr2.get());
171   EXPECT_EQ(bar, ptr1.get());
172   RefCountedPtr<Foo> ptr3;
173   ptr3.swap(ptr2);
174   EXPECT_EQ(nullptr, ptr2.get());
175   EXPECT_EQ(foo, ptr3.get());
176 }
177 
TEST(MakeRefCounted,NoArgs)178 TEST(MakeRefCounted, NoArgs) {
179   RefCountedPtr<Foo> foo = MakeRefCounted<Foo>();
180   EXPECT_EQ(0, foo->value());
181 }
182 
TEST(MakeRefCounted,Args)183 TEST(MakeRefCounted, Args) {
184   RefCountedPtr<Foo> foo = MakeRefCounted<Foo>(3);
185   EXPECT_EQ(3, foo->value());
186 }
187 
188 class FooWithTracing : public RefCounted<FooWithTracing> {
189  public:
FooWithTracing()190   FooWithTracing() : RefCounted("FooWithTracing") {}
191 };
192 
TEST(RefCountedPtr,RefCountedWithTracing)193 TEST(RefCountedPtr, RefCountedWithTracing) {
194   RefCountedPtr<FooWithTracing> foo(new FooWithTracing());
195   RefCountedPtr<FooWithTracing> foo2 = foo->Ref(DEBUG_LOCATION, "foo");
196   foo2.release();
197   RefCountedPtr<FooWithTracing> foo3 = foo.Ref(DEBUG_LOCATION, "foo");
198   foo3.release();
199   foo->Unref(DEBUG_LOCATION, "foo");
200   foo->Unref(DEBUG_LOCATION, "foo");
201 }
202 
203 class BaseClass : public RefCounted<BaseClass> {
204  public:
BaseClass()205   BaseClass() {}
206 };
207 
208 class Subclass : public BaseClass {
209  public:
Subclass()210   Subclass() {}
211 };
212 
TEST(RefCountedPtr,ConstructFromSubclass)213 TEST(RefCountedPtr, ConstructFromSubclass) {
214   RefCountedPtr<BaseClass> p(new Subclass());
215 }
216 
TEST(RefCountedPtr,CopyAssignFromSubclass)217 TEST(RefCountedPtr, CopyAssignFromSubclass) {
218   RefCountedPtr<BaseClass> b;
219   EXPECT_EQ(nullptr, b.get());
220   RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
221   b = s;
222   EXPECT_NE(nullptr, b.get());
223 }
224 
TEST(RefCountedPtr,MoveAssignFromSubclass)225 TEST(RefCountedPtr, MoveAssignFromSubclass) {
226   RefCountedPtr<BaseClass> b;
227   EXPECT_EQ(nullptr, b.get());
228   RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
229   b = std::move(s);
230   EXPECT_NE(nullptr, b.get());
231 }
232 
TEST(RefCountedPtr,ResetFromSubclass)233 TEST(RefCountedPtr, ResetFromSubclass) {
234   RefCountedPtr<BaseClass> b;
235   EXPECT_EQ(nullptr, b.get());
236   b.reset(new Subclass());
237   EXPECT_NE(nullptr, b.get());
238 }
239 
TEST(RefCountedPtr,EqualityWithSubclass)240 TEST(RefCountedPtr, EqualityWithSubclass) {
241   Subclass* s = new Subclass();
242   RefCountedPtr<BaseClass> b(s);
243   EXPECT_EQ(b, s);
244 }
245 
FunctionTakingBaseClass(RefCountedPtr<BaseClass>)246 void FunctionTakingBaseClass(RefCountedPtr<BaseClass>) {}
247 
TEST(RefCountedPtr,CanPassSubclassToFunctionExpectingBaseClass)248 TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingBaseClass) {
249   RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
250   FunctionTakingBaseClass(p);
251 }
252 
FunctionTakingSubclass(RefCountedPtr<Subclass>)253 void FunctionTakingSubclass(RefCountedPtr<Subclass>) {}
254 
TEST(RefCountedPtr,CanPassSubclassToFunctionExpectingSubclass)255 TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) {
256   RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
257   FunctionTakingSubclass(p);
258 }
259 
TEST(RefCountedPtr,TakeAsSubclass)260 TEST(RefCountedPtr, TakeAsSubclass) {
261   RefCountedPtr<BaseClass> p = MakeRefCounted<Subclass>();
262   auto s = p.TakeAsSubclass<Subclass>();
263   EXPECT_EQ(p.get(), nullptr);
264   EXPECT_NE(s.get(), nullptr);
265 }
266 
267 //
268 // WeakRefCountedPtr<> tests
269 //
270 
271 class Bar : public DualRefCounted<Bar> {
272  public:
Bar()273   Bar() : value_(0) {}
274 
Bar(int value)275   explicit Bar(int value) : value_(value) {}
276 
~Bar()277   ~Bar() override { GPR_ASSERT(shutting_down_); }
278 
Orphaned()279   void Orphaned() override { shutting_down_ = true; }
280 
value() const281   int value() const { return value_; }
282 
283  private:
284   int value_;
285   bool shutting_down_ = false;
286 };
287 
TEST(WeakRefCountedPtr,DefaultConstructor)288 TEST(WeakRefCountedPtr, DefaultConstructor) { WeakRefCountedPtr<Bar> bar; }
289 
TEST(WeakRefCountedPtr,ExplicitConstructorEmpty)290 TEST(WeakRefCountedPtr, ExplicitConstructorEmpty) {
291   WeakRefCountedPtr<Bar> bar(nullptr);
292 }
293 
TEST(WeakRefCountedPtr,ExplicitConstructor)294 TEST(WeakRefCountedPtr, ExplicitConstructor) {
295   RefCountedPtr<Bar> bar_strong(new Bar());
296   bar_strong->WeakRef().release();
297   WeakRefCountedPtr<Bar> bar(bar_strong.get());
298 }
299 
TEST(WeakRefCountedPtr,MoveConstructor)300 TEST(WeakRefCountedPtr, MoveConstructor) {
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 
TEST(WeakRefCountedPtr,MoveAssignment)308 TEST(WeakRefCountedPtr, MoveAssignment) {
309   RefCountedPtr<Bar> bar_strong(new Bar());
310   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
311   WeakRefCountedPtr<Bar> bar2 = std::move(bar);
312   EXPECT_EQ(nullptr, bar.get());  // NOLINT
313   EXPECT_NE(nullptr, bar2.get());
314 }
315 
TEST(WeakRefCountedPtr,CopyConstructor)316 TEST(WeakRefCountedPtr, CopyConstructor) {
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 
TEST(WeakRefCountedPtr,CopyAssignment)324 TEST(WeakRefCountedPtr, CopyAssignment) {
325   RefCountedPtr<Bar> bar_strong(new Bar());
326   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
327   WeakRefCountedPtr<Bar> bar2 = bar;
328   EXPECT_NE(nullptr, bar.get());
329   EXPECT_EQ(bar.get(), bar2.get());
330 }
331 
TEST(WeakRefCountedPtr,CopyAssignmentWhenEmpty)332 TEST(WeakRefCountedPtr, CopyAssignmentWhenEmpty) {
333   WeakRefCountedPtr<Bar> bar;
334   WeakRefCountedPtr<Bar> bar2;
335   bar2 = bar;
336   EXPECT_EQ(nullptr, bar.get());
337   EXPECT_EQ(nullptr, bar2.get());
338 }
339 
TEST(WeakRefCountedPtr,CopyAssignmentToSelf)340 TEST(WeakRefCountedPtr, CopyAssignmentToSelf) {
341   RefCountedPtr<Bar> bar_strong(new Bar());
342   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
343   bar = *&bar;  // The "*&" avoids warnings from LLVM -Wself-assign.
344 }
345 
TEST(WeakRefCountedPtr,EnclosedScope)346 TEST(WeakRefCountedPtr, EnclosedScope) {
347   RefCountedPtr<Bar> bar_strong(new Bar());
348   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
349   {
350     WeakRefCountedPtr<Bar> bar2(std::move(bar));
351     // NOLINTNEXTLINE(bugprone-use-after-move)
352     EXPECT_EQ(nullptr, bar.get());
353     EXPECT_NE(nullptr, bar2.get());
354   }
355   EXPECT_EQ(nullptr, bar.get());
356 }
357 
TEST(WeakRefCountedPtr,ResetFromNullToNonNull)358 TEST(WeakRefCountedPtr, ResetFromNullToNonNull) {
359   RefCountedPtr<Bar> bar_strong(new Bar());
360   WeakRefCountedPtr<Bar> bar;
361   EXPECT_EQ(nullptr, bar.get());
362   bar_strong->WeakRef().release();
363   bar.reset(bar_strong.get());
364   EXPECT_NE(nullptr, bar.get());
365 }
366 
TEST(WeakRefCountedPtr,ResetFromNonNullToNonNull)367 TEST(WeakRefCountedPtr, ResetFromNonNullToNonNull) {
368   RefCountedPtr<Bar> bar_strong(new Bar());
369   RefCountedPtr<Bar> bar2_strong(new Bar());
370   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
371   EXPECT_NE(nullptr, bar.get());
372   bar2_strong->WeakRef().release();
373   bar.reset(bar2_strong.get());
374   EXPECT_NE(nullptr, bar.get());
375   EXPECT_NE(bar_strong.get(), bar.get());
376 }
377 
TEST(WeakRefCountedPtr,ResetFromNonNullToNull)378 TEST(WeakRefCountedPtr, ResetFromNonNullToNull) {
379   RefCountedPtr<Bar> bar_strong(new Bar());
380   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
381   EXPECT_NE(nullptr, bar.get());
382   bar.reset();
383   EXPECT_EQ(nullptr, bar.get());
384 }
385 
TEST(WeakRefCountedPtr,ResetFromNullToNull)386 TEST(WeakRefCountedPtr, ResetFromNullToNull) {
387   WeakRefCountedPtr<Bar> bar;
388   EXPECT_EQ(nullptr, bar.get());
389   bar.reset();
390   EXPECT_EQ(nullptr, bar.get());
391 }
392 
TEST(WeakRefCountedPtr,DerefernceOperators)393 TEST(WeakRefCountedPtr, DerefernceOperators) {
394   RefCountedPtr<Bar> bar_strong(new Bar());
395   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
396   bar->value();
397   Bar& bar_ref = *bar;
398   bar_ref.value();
399 }
400 
TEST(WeakRefCountedPtr,EqualityOperators)401 TEST(WeakRefCountedPtr, EqualityOperators) {
402   RefCountedPtr<Bar> bar_strong(new Bar());
403   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
404   WeakRefCountedPtr<Bar> bar2 = bar;
405   WeakRefCountedPtr<Bar> empty;
406   // Test equality between RefCountedPtrs.
407   EXPECT_EQ(bar, bar2);
408   EXPECT_NE(bar, empty);
409   // Test equality with bare pointers.
410   EXPECT_EQ(bar, bar.get());
411   EXPECT_EQ(empty, nullptr);
412   EXPECT_NE(bar, nullptr);
413 }
414 
TEST(WeakRefCountedPtr,Swap)415 TEST(WeakRefCountedPtr, Swap) {
416   RefCountedPtr<Bar> bar_strong(new Bar());
417   RefCountedPtr<Bar> bar2_strong(new Bar());
418   WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
419   WeakRefCountedPtr<Bar> bar2 = bar2_strong->WeakRef();
420   bar.swap(bar2);
421   EXPECT_EQ(bar_strong.get(), bar2.get());
422   EXPECT_EQ(bar2_strong.get(), bar.get());
423   WeakRefCountedPtr<Bar> bar3;
424   bar3.swap(bar2);
425   EXPECT_EQ(nullptr, bar2.get());
426   EXPECT_EQ(bar_strong.get(), bar3.get());
427 }
428 
429 class BarWithTracing : public DualRefCounted<BarWithTracing> {
430  public:
BarWithTracing()431   BarWithTracing() : DualRefCounted("BarWithTracing") {}
432 
~BarWithTracing()433   ~BarWithTracing() override { GPR_ASSERT(shutting_down_); }
434 
Orphaned()435   void Orphaned() override { shutting_down_ = true; }
436 
437  private:
438   bool shutting_down_ = false;
439 };
440 
TEST(WeakRefCountedPtr,RefCountedWithTracing)441 TEST(WeakRefCountedPtr, RefCountedWithTracing) {
442   RefCountedPtr<BarWithTracing> bar_strong(new BarWithTracing());
443   WeakRefCountedPtr<BarWithTracing> bar = bar_strong->WeakRef();
444   WeakRefCountedPtr<BarWithTracing> bar2 = bar->WeakRef(DEBUG_LOCATION, "bar");
445   bar2.release();
446   WeakRefCountedPtr<BarWithTracing> bar3 = bar.WeakRef(DEBUG_LOCATION, "bar");
447   bar3.release();
448   bar->WeakUnref(DEBUG_LOCATION, "bar");
449   bar->WeakUnref(DEBUG_LOCATION, "bar");
450 }
451 
452 class WeakBaseClass : public DualRefCounted<WeakBaseClass> {
453  public:
WeakBaseClass()454   WeakBaseClass() {}
455 
~WeakBaseClass()456   ~WeakBaseClass() override { GPR_ASSERT(shutting_down_); }
457 
Orphaned()458   void Orphaned() override { shutting_down_ = true; }
459 
460  private:
461   bool shutting_down_ = false;
462 };
463 
464 class WeakSubclass : public WeakBaseClass {
465  public:
WeakSubclass()466   WeakSubclass() {}
467 };
468 
TEST(WeakRefCountedPtr,ConstructFromWeakSubclass)469 TEST(WeakRefCountedPtr, ConstructFromWeakSubclass) {
470   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
471   WeakRefCountedPtr<WeakBaseClass> p(strong->WeakRef().release());
472 }
473 
TEST(WeakRefCountedPtr,CopyAssignFromWeakSubclass)474 TEST(WeakRefCountedPtr, CopyAssignFromWeakSubclass) {
475   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
476   WeakRefCountedPtr<WeakBaseClass> b;
477   EXPECT_EQ(nullptr, b.get());
478   WeakRefCountedPtr<WeakSubclass> s = strong->WeakRefAsSubclass<WeakSubclass>();
479   b = s;
480   EXPECT_NE(nullptr, b.get());
481 }
482 
TEST(WeakRefCountedPtr,MoveAssignFromWeakSubclass)483 TEST(WeakRefCountedPtr, MoveAssignFromWeakSubclass) {
484   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
485   WeakRefCountedPtr<WeakBaseClass> b;
486   EXPECT_EQ(nullptr, b.get());
487   WeakRefCountedPtr<WeakSubclass> s = strong->WeakRefAsSubclass<WeakSubclass>();
488   b = std::move(s);
489   EXPECT_NE(nullptr, b.get());
490 }
491 
TEST(WeakRefCountedPtr,ResetFromWeakSubclass)492 TEST(WeakRefCountedPtr, ResetFromWeakSubclass) {
493   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
494   WeakRefCountedPtr<WeakBaseClass> b;
495   EXPECT_EQ(nullptr, b.get());
496   b.reset(strong->WeakRefAsSubclass<WeakSubclass>().release());
497   EXPECT_NE(nullptr, b.get());
498 }
499 
TEST(WeakRefCountedPtr,EqualityWithWeakSubclass)500 TEST(WeakRefCountedPtr, EqualityWithWeakSubclass) {
501   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
502   WeakRefCountedPtr<WeakBaseClass> b = strong->WeakRef();
503   EXPECT_EQ(b, strong.get());
504 }
505 
FunctionTakingWeakBaseClass(WeakRefCountedPtr<WeakBaseClass>)506 void FunctionTakingWeakBaseClass(WeakRefCountedPtr<WeakBaseClass>) {}
507 
TEST(WeakRefCountedPtr,CanPassWeakSubclassToFunctionExpectingWeakBaseClass)508 TEST(WeakRefCountedPtr, CanPassWeakSubclassToFunctionExpectingWeakBaseClass) {
509   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
510   WeakRefCountedPtr<WeakSubclass> p = strong->WeakRefAsSubclass<WeakSubclass>();
511   FunctionTakingWeakBaseClass(p);
512 }
513 
FunctionTakingWeakSubclass(WeakRefCountedPtr<WeakSubclass>)514 void FunctionTakingWeakSubclass(WeakRefCountedPtr<WeakSubclass>) {}
515 
TEST(WeakRefCountedPtr,CanPassWeakSubclassToFunctionExpectingWeakSubclass)516 TEST(WeakRefCountedPtr, CanPassWeakSubclassToFunctionExpectingWeakSubclass) {
517   RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
518   WeakRefCountedPtr<WeakSubclass> p = strong->WeakRefAsSubclass<WeakSubclass>();
519   FunctionTakingWeakSubclass(p);
520 }
521 
TEST(WeakRefCountedPtr,TakeAsSubclass)522 TEST(WeakRefCountedPtr, TakeAsSubclass) {
523   RefCountedPtr<WeakBaseClass> strong = MakeRefCounted<WeakSubclass>();
524   WeakRefCountedPtr<WeakBaseClass> p = strong->WeakRef();
525   WeakRefCountedPtr<WeakSubclass> s = p.TakeAsSubclass<WeakSubclass>();
526   EXPECT_EQ(p.get(), nullptr);
527   EXPECT_NE(s.get(), nullptr);
528 }
529 
530 //
531 // tests for absl hash integration
532 //
533 
TEST(AbslHashIntegration,RefCountedPtr)534 TEST(AbslHashIntegration, RefCountedPtr) {
535   absl::flat_hash_set<RefCountedPtr<Foo>> set;
536   auto p = MakeRefCounted<Foo>(5);
537   set.insert(p);
538   auto it = set.find(p);
539   ASSERT_NE(it, set.end());
540   EXPECT_EQ(*it, p);
541 }
542 
TEST(AbslHashIntegration,WeakRefCountedPtr)543 TEST(AbslHashIntegration, WeakRefCountedPtr) {
544   absl::flat_hash_set<WeakRefCountedPtr<Bar>> set;
545   auto p = MakeRefCounted<Bar>(5);
546   auto q = p->WeakRef();
547   set.insert(q);
548   auto it = set.find(q);
549   ASSERT_NE(it, set.end());
550   EXPECT_EQ(*it, q);
551 }
552 
TEST(AbslHashIntegration,RefCountedPtrHeterogenousLookup)553 TEST(AbslHashIntegration, RefCountedPtrHeterogenousLookup) {
554   absl::flat_hash_set<RefCountedPtr<Bar>, RefCountedPtrHash<Bar>,
555                       RefCountedPtrEq<Bar>>
556       set;
557   auto p = MakeRefCounted<Bar>(5);
558   set.insert(p);
559   auto it = set.find(p);
560   ASSERT_NE(it, set.end());
561   EXPECT_EQ(*it, p);
562   auto q = p->WeakRef();
563   it = set.find(q);
564   ASSERT_NE(it, set.end());
565   EXPECT_EQ(*it, p);
566   it = set.find(p.get());
567   ASSERT_NE(it, set.end());
568   EXPECT_EQ(*it, p);
569 }
570 
TEST(AbslHashIntegration,WeakRefCountedPtrHeterogenousLookup)571 TEST(AbslHashIntegration, WeakRefCountedPtrHeterogenousLookup) {
572   absl::flat_hash_set<WeakRefCountedPtr<Bar>, RefCountedPtrHash<Bar>,
573                       RefCountedPtrEq<Bar>>
574       set;
575   auto p = MakeRefCounted<Bar>(5);
576   auto q = p->WeakRef();
577   set.insert(q);
578   auto it = set.find(q);
579   ASSERT_NE(it, set.end());
580   EXPECT_EQ(*it, q);
581   it = set.find(p);
582   ASSERT_NE(it, set.end());
583   EXPECT_EQ(*it, q);
584   it = set.find(p.get());
585   ASSERT_NE(it, set.end());
586   EXPECT_EQ(*it, q);
587 }
588 
589 }  // namespace
590 }  // namespace testing
591 }  // namespace grpc_core
592 
main(int argc,char ** argv)593 int main(int argc, char** argv) {
594   grpc::testing::TestEnvironment env(&argc, argv);
595   ::testing::InitGoogleTest(&argc, argv);
596   return RUN_ALL_TESTS();
597 }
598