ref_counted_ptr_test.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  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. #include "src/core/lib/gprpp/ref_counted_ptr.h"
  19. #include <gtest/gtest.h>
  20. #include <grpc/support/log.h>
  21. #include "src/core/lib/gprpp/dual_ref_counted.h"
  22. #include "src/core/lib/gprpp/memory.h"
  23. #include "src/core/lib/gprpp/ref_counted.h"
  24. #include "test/core/util/test_config.h"
  25. namespace grpc_core {
  26. namespace testing {
  27. namespace {
  28. //
  29. // RefCountedPtr<> tests
  30. //
  31. class Foo : public RefCounted<Foo> {
  32. public:
  33. Foo() : value_(0) {}
  34. explicit Foo(int value) : value_(value) {}
  35. int value() const { return value_; }
  36. private:
  37. int value_;
  38. };
  39. TEST(RefCountedPtr, DefaultConstructor) { RefCountedPtr<Foo> foo; }
  40. TEST(RefCountedPtr, ExplicitConstructorEmpty) {
  41. RefCountedPtr<Foo> foo(nullptr);
  42. }
  43. TEST(RefCountedPtr, ExplicitConstructor) { RefCountedPtr<Foo> foo(new Foo()); }
  44. TEST(RefCountedPtr, MoveConstructor) {
  45. RefCountedPtr<Foo> foo(new Foo());
  46. RefCountedPtr<Foo> foo2(std::move(foo));
  47. // NOLINTNEXTLINE(bugprone-use-after-move)
  48. EXPECT_EQ(nullptr, foo.get());
  49. EXPECT_NE(nullptr, foo2.get());
  50. }
  51. TEST(RefCountedPtr, MoveAssignment) {
  52. RefCountedPtr<Foo> foo(new Foo());
  53. RefCountedPtr<Foo> foo2 = std::move(foo);
  54. // NOLINTNEXTLINE(bugprone-use-after-move)
  55. EXPECT_EQ(nullptr, foo.get());
  56. EXPECT_NE(nullptr, foo2.get());
  57. }
  58. TEST(RefCountedPtr, CopyConstructor) {
  59. RefCountedPtr<Foo> foo(new Foo());
  60. RefCountedPtr<Foo> foo2(foo);
  61. EXPECT_NE(nullptr, foo.get());
  62. EXPECT_EQ(foo.get(), foo2.get());
  63. }
  64. TEST(RefCountedPtr, CopyAssignment) {
  65. RefCountedPtr<Foo> foo(new Foo());
  66. RefCountedPtr<Foo> foo2 = foo;
  67. EXPECT_NE(nullptr, foo.get());
  68. EXPECT_EQ(foo.get(), foo2.get());
  69. }
  70. TEST(RefCountedPtr, CopyAssignmentWhenEmpty) {
  71. RefCountedPtr<Foo> foo;
  72. RefCountedPtr<Foo> foo2;
  73. foo2 = foo;
  74. EXPECT_EQ(nullptr, foo.get());
  75. EXPECT_EQ(nullptr, foo2.get());
  76. }
  77. TEST(RefCountedPtr, CopyAssignmentToSelf) {
  78. RefCountedPtr<Foo> foo(new Foo());
  79. foo = *&foo; // The "*&" avoids warnings from LLVM -Wself-assign.
  80. }
  81. TEST(RefCountedPtr, EnclosedScope) {
  82. RefCountedPtr<Foo> foo(new Foo());
  83. {
  84. RefCountedPtr<Foo> foo2(std::move(foo));
  85. // NOLINTNEXTLINE(bugprone-use-after-move)
  86. EXPECT_EQ(nullptr, foo.get());
  87. EXPECT_NE(nullptr, foo2.get());
  88. }
  89. EXPECT_EQ(nullptr, foo.get());
  90. }
  91. TEST(RefCountedPtr, ResetFromNullToNonNull) {
  92. RefCountedPtr<Foo> foo;
  93. EXPECT_EQ(nullptr, foo.get());
  94. foo.reset(new Foo());
  95. EXPECT_NE(nullptr, foo.get());
  96. }
  97. TEST(RefCountedPtr, ResetFromNonNullToNonNull) {
  98. RefCountedPtr<Foo> foo(new Foo());
  99. EXPECT_NE(nullptr, foo.get());
  100. Foo* original = foo.get();
  101. foo.reset(new Foo());
  102. EXPECT_NE(nullptr, foo.get());
  103. EXPECT_NE(original, foo.get());
  104. }
  105. TEST(RefCountedPtr, ResetFromNonNullToNull) {
  106. RefCountedPtr<Foo> foo(new Foo());
  107. EXPECT_NE(nullptr, foo.get());
  108. foo.reset();
  109. EXPECT_EQ(nullptr, foo.get());
  110. }
  111. TEST(RefCountedPtr, ResetFromNullToNull) {
  112. RefCountedPtr<Foo> foo;
  113. EXPECT_EQ(nullptr, foo.get());
  114. foo.reset();
  115. EXPECT_EQ(nullptr, foo.get());
  116. }
  117. TEST(RefCountedPtr, DerefernceOperators) {
  118. RefCountedPtr<Foo> foo(new Foo());
  119. foo->value();
  120. Foo& foo_ref = *foo;
  121. foo_ref.value();
  122. }
  123. TEST(RefCountedPtr, EqualityOperators) {
  124. RefCountedPtr<Foo> foo(new Foo());
  125. RefCountedPtr<Foo> bar = foo;
  126. RefCountedPtr<Foo> empty;
  127. // Test equality between RefCountedPtrs.
  128. EXPECT_EQ(foo, bar);
  129. EXPECT_NE(foo, empty);
  130. // Test equality with bare pointers.
  131. EXPECT_EQ(foo, foo.get());
  132. EXPECT_EQ(empty, nullptr);
  133. EXPECT_NE(foo, nullptr);
  134. }
  135. TEST(RefCountedPtr, Swap) {
  136. Foo* foo = new Foo();
  137. Foo* bar = new Foo();
  138. RefCountedPtr<Foo> ptr1(foo);
  139. RefCountedPtr<Foo> ptr2(bar);
  140. ptr1.swap(ptr2);
  141. EXPECT_EQ(foo, ptr2.get());
  142. EXPECT_EQ(bar, ptr1.get());
  143. RefCountedPtr<Foo> ptr3;
  144. ptr3.swap(ptr2);
  145. EXPECT_EQ(nullptr, ptr2.get());
  146. EXPECT_EQ(foo, ptr3.get());
  147. }
  148. TEST(MakeRefCounted, NoArgs) {
  149. RefCountedPtr<Foo> foo = MakeRefCounted<Foo>();
  150. EXPECT_EQ(0, foo->value());
  151. }
  152. TEST(MakeRefCounted, Args) {
  153. RefCountedPtr<Foo> foo = MakeRefCounted<Foo>(3);
  154. EXPECT_EQ(3, foo->value());
  155. }
  156. class FooWithTracing : public RefCounted<FooWithTracing> {
  157. public:
  158. FooWithTracing() : RefCounted("FooWithTracing") {}
  159. };
  160. TEST(RefCountedPtr, RefCountedWithTracing) {
  161. RefCountedPtr<FooWithTracing> foo(new FooWithTracing());
  162. RefCountedPtr<FooWithTracing> foo2 = foo->Ref(DEBUG_LOCATION, "foo");
  163. foo2.release();
  164. foo->Unref(DEBUG_LOCATION, "foo");
  165. }
  166. class BaseClass : public RefCounted<BaseClass> {
  167. public:
  168. BaseClass() {}
  169. };
  170. class Subclass : public BaseClass {
  171. public:
  172. Subclass() {}
  173. };
  174. TEST(RefCountedPtr, ConstructFromSubclass) {
  175. RefCountedPtr<BaseClass> p(new Subclass());
  176. }
  177. TEST(RefCountedPtr, CopyAssignFromSubclass) {
  178. RefCountedPtr<BaseClass> b;
  179. EXPECT_EQ(nullptr, b.get());
  180. RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
  181. b = s;
  182. EXPECT_NE(nullptr, b.get());
  183. }
  184. TEST(RefCountedPtr, MoveAssignFromSubclass) {
  185. RefCountedPtr<BaseClass> b;
  186. EXPECT_EQ(nullptr, b.get());
  187. RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
  188. b = std::move(s);
  189. EXPECT_NE(nullptr, b.get());
  190. }
  191. TEST(RefCountedPtr, ResetFromSubclass) {
  192. RefCountedPtr<BaseClass> b;
  193. EXPECT_EQ(nullptr, b.get());
  194. b.reset(new Subclass());
  195. EXPECT_NE(nullptr, b.get());
  196. }
  197. TEST(RefCountedPtr, EqualityWithSubclass) {
  198. Subclass* s = new Subclass();
  199. RefCountedPtr<BaseClass> b(s);
  200. EXPECT_EQ(b, s);
  201. }
  202. void FunctionTakingBaseClass(RefCountedPtr<BaseClass> p) {
  203. p.reset(); // To appease clang-tidy.
  204. }
  205. TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingBaseClass) {
  206. RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
  207. FunctionTakingBaseClass(p);
  208. }
  209. void FunctionTakingSubclass(RefCountedPtr<Subclass> p) {
  210. p.reset(); // To appease clang-tidy.
  211. }
  212. TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) {
  213. RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
  214. FunctionTakingSubclass(p);
  215. }
  216. //
  217. // WeakRefCountedPtr<> tests
  218. //
  219. class Bar : public DualRefCounted<Bar> {
  220. public:
  221. Bar() : value_(0) {}
  222. explicit Bar(int value) : value_(value) {}
  223. ~Bar() override { GPR_ASSERT(shutting_down_); }
  224. void Orphan() override { shutting_down_ = true; }
  225. int value() const { return value_; }
  226. private:
  227. int value_;
  228. bool shutting_down_ = false;
  229. };
  230. TEST(WeakRefCountedPtr, DefaultConstructor) { WeakRefCountedPtr<Bar> bar; }
  231. TEST(WeakRefCountedPtr, ExplicitConstructorEmpty) {
  232. WeakRefCountedPtr<Bar> bar(nullptr);
  233. }
  234. TEST(WeakRefCountedPtr, ExplicitConstructor) {
  235. RefCountedPtr<Bar> bar_strong(new Bar());
  236. bar_strong->WeakRef().release();
  237. WeakRefCountedPtr<Bar> bar(bar_strong.get());
  238. }
  239. TEST(WeakRefCountedPtr, MoveConstructor) {
  240. RefCountedPtr<Bar> bar_strong(new Bar());
  241. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  242. WeakRefCountedPtr<Bar> bar2(std::move(bar));
  243. EXPECT_EQ(nullptr, bar.get()); // NOLINT
  244. EXPECT_NE(nullptr, bar2.get());
  245. }
  246. TEST(WeakRefCountedPtr, MoveAssignment) {
  247. RefCountedPtr<Bar> bar_strong(new Bar());
  248. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  249. WeakRefCountedPtr<Bar> bar2 = std::move(bar);
  250. EXPECT_EQ(nullptr, bar.get()); // NOLINT
  251. EXPECT_NE(nullptr, bar2.get());
  252. }
  253. TEST(WeakRefCountedPtr, CopyConstructor) {
  254. RefCountedPtr<Bar> bar_strong(new Bar());
  255. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  256. WeakRefCountedPtr<Bar> bar2(bar);
  257. EXPECT_NE(nullptr, bar.get());
  258. EXPECT_EQ(bar.get(), bar2.get());
  259. }
  260. TEST(WeakRefCountedPtr, CopyAssignment) {
  261. RefCountedPtr<Bar> bar_strong(new Bar());
  262. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  263. WeakRefCountedPtr<Bar> bar2 = bar;
  264. EXPECT_NE(nullptr, bar.get());
  265. EXPECT_EQ(bar.get(), bar2.get());
  266. }
  267. TEST(WeakRefCountedPtr, CopyAssignmentWhenEmpty) {
  268. WeakRefCountedPtr<Bar> bar;
  269. WeakRefCountedPtr<Bar> bar2;
  270. bar2 = bar;
  271. EXPECT_EQ(nullptr, bar.get());
  272. EXPECT_EQ(nullptr, bar2.get());
  273. }
  274. TEST(WeakRefCountedPtr, CopyAssignmentToSelf) {
  275. RefCountedPtr<Bar> bar_strong(new Bar());
  276. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  277. bar = *&bar; // The "*&" avoids warnings from LLVM -Wself-assign.
  278. }
  279. TEST(WeakRefCountedPtr, EnclosedScope) {
  280. RefCountedPtr<Bar> bar_strong(new Bar());
  281. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  282. {
  283. WeakRefCountedPtr<Bar> bar2(std::move(bar));
  284. // NOLINTNEXTLINE(bugprone-use-after-move)
  285. EXPECT_EQ(nullptr, bar.get());
  286. EXPECT_NE(nullptr, bar2.get());
  287. }
  288. EXPECT_EQ(nullptr, bar.get());
  289. }
  290. TEST(WeakRefCountedPtr, ResetFromNullToNonNull) {
  291. RefCountedPtr<Bar> bar_strong(new Bar());
  292. WeakRefCountedPtr<Bar> bar;
  293. EXPECT_EQ(nullptr, bar.get());
  294. bar_strong->WeakRef().release();
  295. bar.reset(bar_strong.get());
  296. EXPECT_NE(nullptr, bar.get());
  297. }
  298. TEST(WeakRefCountedPtr, ResetFromNonNullToNonNull) {
  299. RefCountedPtr<Bar> bar_strong(new Bar());
  300. RefCountedPtr<Bar> bar2_strong(new Bar());
  301. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  302. EXPECT_NE(nullptr, bar.get());
  303. bar2_strong->WeakRef().release();
  304. bar.reset(bar2_strong.get());
  305. EXPECT_NE(nullptr, bar.get());
  306. EXPECT_NE(bar_strong.get(), bar.get());
  307. }
  308. TEST(WeakRefCountedPtr, ResetFromNonNullToNull) {
  309. RefCountedPtr<Bar> bar_strong(new Bar());
  310. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  311. EXPECT_NE(nullptr, bar.get());
  312. bar.reset();
  313. EXPECT_EQ(nullptr, bar.get());
  314. }
  315. TEST(WeakRefCountedPtr, ResetFromNullToNull) {
  316. WeakRefCountedPtr<Bar> bar;
  317. EXPECT_EQ(nullptr, bar.get());
  318. bar.reset();
  319. EXPECT_EQ(nullptr, bar.get());
  320. }
  321. TEST(WeakRefCountedPtr, DerefernceOperators) {
  322. RefCountedPtr<Bar> bar_strong(new Bar());
  323. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  324. bar->value();
  325. Bar& bar_ref = *bar;
  326. bar_ref.value();
  327. }
  328. TEST(WeakRefCountedPtr, EqualityOperators) {
  329. RefCountedPtr<Bar> bar_strong(new Bar());
  330. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  331. WeakRefCountedPtr<Bar> bar2 = bar;
  332. WeakRefCountedPtr<Bar> empty;
  333. // Test equality between RefCountedPtrs.
  334. EXPECT_EQ(bar, bar2);
  335. EXPECT_NE(bar, empty);
  336. // Test equality with bare pointers.
  337. EXPECT_EQ(bar, bar.get());
  338. EXPECT_EQ(empty, nullptr);
  339. EXPECT_NE(bar, nullptr);
  340. }
  341. TEST(WeakRefCountedPtr, Swap) {
  342. RefCountedPtr<Bar> bar_strong(new Bar());
  343. RefCountedPtr<Bar> bar2_strong(new Bar());
  344. WeakRefCountedPtr<Bar> bar = bar_strong->WeakRef();
  345. WeakRefCountedPtr<Bar> bar2 = bar2_strong->WeakRef();
  346. bar.swap(bar2);
  347. EXPECT_EQ(bar_strong.get(), bar2.get());
  348. EXPECT_EQ(bar2_strong.get(), bar.get());
  349. WeakRefCountedPtr<Bar> bar3;
  350. bar3.swap(bar2);
  351. EXPECT_EQ(nullptr, bar2.get());
  352. EXPECT_EQ(bar_strong.get(), bar3.get());
  353. }
  354. class BarWithTracing : public DualRefCounted<BarWithTracing> {
  355. public:
  356. BarWithTracing() : DualRefCounted("BarWithTracing") {}
  357. ~BarWithTracing() override { GPR_ASSERT(shutting_down_); }
  358. void Orphan() override { shutting_down_ = true; }
  359. private:
  360. bool shutting_down_ = false;
  361. };
  362. TEST(WeakRefCountedPtr, RefCountedWithTracing) {
  363. RefCountedPtr<BarWithTracing> bar_strong(new BarWithTracing());
  364. WeakRefCountedPtr<BarWithTracing> bar = bar_strong->WeakRef();
  365. WeakRefCountedPtr<BarWithTracing> bar2 = bar->WeakRef(DEBUG_LOCATION, "bar");
  366. bar2.release();
  367. bar->WeakUnref(DEBUG_LOCATION, "bar");
  368. }
  369. class WeakBaseClass : public DualRefCounted<WeakBaseClass> {
  370. public:
  371. WeakBaseClass() {}
  372. ~WeakBaseClass() override { GPR_ASSERT(shutting_down_); }
  373. void Orphan() override { shutting_down_ = true; }
  374. private:
  375. bool shutting_down_ = false;
  376. };
  377. class WeakSubclass : public WeakBaseClass {
  378. public:
  379. WeakSubclass() {}
  380. };
  381. TEST(WeakRefCountedPtr, ConstructFromWeakSubclass) {
  382. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  383. WeakRefCountedPtr<WeakBaseClass> p(strong->WeakRef().release());
  384. }
  385. TEST(WeakRefCountedPtr, CopyAssignFromWeakSubclass) {
  386. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  387. WeakRefCountedPtr<WeakBaseClass> b;
  388. EXPECT_EQ(nullptr, b.get());
  389. WeakRefCountedPtr<WeakSubclass> s = strong->WeakRef();
  390. b = s;
  391. EXPECT_NE(nullptr, b.get());
  392. }
  393. TEST(WeakRefCountedPtr, MoveAssignFromWeakSubclass) {
  394. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  395. WeakRefCountedPtr<WeakBaseClass> b;
  396. EXPECT_EQ(nullptr, b.get());
  397. WeakRefCountedPtr<WeakSubclass> s = strong->WeakRef();
  398. b = std::move(s);
  399. EXPECT_NE(nullptr, b.get());
  400. }
  401. TEST(WeakRefCountedPtr, ResetFromWeakSubclass) {
  402. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  403. WeakRefCountedPtr<WeakBaseClass> b;
  404. EXPECT_EQ(nullptr, b.get());
  405. b.reset(strong->WeakRef().release());
  406. EXPECT_NE(nullptr, b.get());
  407. }
  408. TEST(WeakRefCountedPtr, EqualityWithWeakSubclass) {
  409. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  410. WeakRefCountedPtr<WeakBaseClass> b = strong->WeakRef();
  411. EXPECT_EQ(b, strong.get());
  412. }
  413. void FunctionTakingWeakBaseClass(WeakRefCountedPtr<WeakBaseClass> p) {
  414. p.reset(); // To appease clang-tidy.
  415. }
  416. TEST(WeakRefCountedPtr, CanPassWeakSubclassToFunctionExpectingWeakBaseClass) {
  417. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  418. WeakRefCountedPtr<WeakSubclass> p = strong->WeakRef();
  419. FunctionTakingWeakBaseClass(p);
  420. }
  421. void FunctionTakingWeakSubclass(WeakRefCountedPtr<WeakSubclass> p) {
  422. p.reset(); // To appease clang-tidy.
  423. }
  424. TEST(WeakRefCountedPtr, CanPassWeakSubclassToFunctionExpectingWeakSubclass) {
  425. RefCountedPtr<WeakSubclass> strong(new WeakSubclass());
  426. WeakRefCountedPtr<WeakSubclass> p = strong->WeakRef();
  427. FunctionTakingWeakSubclass(p);
  428. }
  429. } // namespace
  430. } // namespace testing
  431. } // namespace grpc_core
  432. int main(int argc, char** argv) {
  433. grpc::testing::TestEnvironment env(argc, argv);
  434. ::testing::InitGoogleTest(&argc, argv);
  435. return RUN_ALL_TESTS();
  436. }