ref_counted_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 <set>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 
28 
29 namespace grpc_core {
30 namespace testing {
31 namespace {
32 
33 class Foo : public RefCounted<Foo> {
34  public:
35  Foo() {
37  "PolymorphicRefCount doesn't have a virtual dtor");
38  }
39 };
40 
41 TEST(RefCounted, Basic) {
42  Foo* foo = new Foo();
43  foo->Unref();
44 }
45 
46 TEST(RefCounted, ExtraRef) {
47  Foo* foo = new Foo();
48  RefCountedPtr<Foo> foop = foo->Ref();
49  foop.release();
50  foo->Unref();
51  foo->Unref();
52 }
53 
54 class Value : public RefCounted<Value, PolymorphicRefCount, kUnrefNoDelete> {
55  public:
56  Value(int value, std::set<std::unique_ptr<Value>>* registry) : value_(value) {
57  registry->emplace(this);
58  }
59 
60  int value() const { return value_; }
61 
62  private:
63  int value_;
64 };
65 
66 void GarbageCollectRegistry(std::set<std::unique_ptr<Value>>* registry) {
67  for (auto it = registry->begin(); it != registry->end();) {
68  RefCountedPtr<Value> v = (*it)->RefIfNonZero();
69  // Check if the object has any refs remaining.
70  if (v != nullptr) {
71  // It has refs remaining, so we do not delete it.
72  ++it;
73  } else {
74  // No refs remaining, so remove it from the registry.
75  it = registry->erase(it);
76  }
77  }
78 }
79 
80 TEST(RefCounted, NoDeleteUponUnref) {
81  std::set<std::unique_ptr<Value>> registry;
82  // Add two objects to the registry.
83  auto v1 = MakeRefCounted<Value>(1, &registry);
84  auto v2 = MakeRefCounted<Value>(2, &registry);
85  EXPECT_THAT(registry,
89  // Running garbage collection should not delete anything, since both
90  // entries still have refs.
91  GarbageCollectRegistry(&registry);
92  EXPECT_THAT(registry,
96  // Unref v2 and run GC to remove it.
97  v2.reset();
98  GarbageCollectRegistry(&registry);
101  // Now unref v1 and run GC again.
102  v1.reset();
103  GarbageCollectRegistry(&registry);
105 }
106 
107 class ValueInExternalAllocation
108  : public RefCounted<ValueInExternalAllocation, PolymorphicRefCount,
109  kUnrefCallDtor> {
110  public:
111  explicit ValueInExternalAllocation(int value) : value_(value) {}
112 
113  int value() const { return value_; }
114 
115  private:
116  int value_;
117 };
118 
119 TEST(RefCounted, CallDtorUponUnref) {
120  std::aligned_storage<sizeof(ValueInExternalAllocation),
121  alignof(ValueInExternalAllocation)>::type storage;
122  RefCountedPtr<ValueInExternalAllocation> value(
123  new (&storage) ValueInExternalAllocation(5));
124  EXPECT_EQ(value->value(), 5);
125 }
126 
127 class FooNonPolymorphic
128  : public RefCounted<FooNonPolymorphic, NonPolymorphicRefCount> {
129  public:
130  FooNonPolymorphic() {
132  "NonPolymorphicRefCount has a virtual dtor");
133  }
134 };
135 
136 TEST(RefCountedNonPolymorphic, Basic) {
137  FooNonPolymorphic* foo = new FooNonPolymorphic();
138  foo->Unref();
139 }
140 
141 TEST(RefCountedNonPolymorphic, ExtraRef) {
142  FooNonPolymorphic* foo = new FooNonPolymorphic();
143  RefCountedPtr<FooNonPolymorphic> foop = foo->Ref();
144  foop.release();
145  foo->Unref();
146  foo->Unref();
147 }
148 
149 class FooWithTracing : public RefCounted<FooWithTracing> {
150  public:
151  FooWithTracing() : RefCounted("Foo") {}
152 };
153 
154 TEST(RefCountedWithTracing, Basic) {
155  FooWithTracing* foo = new FooWithTracing();
156  RefCountedPtr<FooWithTracing> foop = foo->Ref(DEBUG_LOCATION, "extra_ref");
157  foop.release();
158  foo->Unref(DEBUG_LOCATION, "extra_ref");
159  // Can use the no-argument methods, too.
160  foop = foo->Ref();
161  foop.release();
162  foo->Unref();
163  foo->Unref(DEBUG_LOCATION, "original_ref");
164 }
165 
166 class FooNonPolymorphicWithTracing
167  : public RefCounted<FooNonPolymorphicWithTracing, NonPolymorphicRefCount> {
168  public:
169  FooNonPolymorphicWithTracing() : RefCounted("FooNonPolymorphicWithTracing") {}
170 };
171 
172 TEST(RefCountedNonPolymorphicWithTracing, Basic) {
173  FooNonPolymorphicWithTracing* foo = new FooNonPolymorphicWithTracing();
174  RefCountedPtr<FooNonPolymorphicWithTracing> foop =
175  foo->Ref(DEBUG_LOCATION, "extra_ref");
176  foop.release();
177  foo->Unref(DEBUG_LOCATION, "extra_ref");
178  // Can use the no-argument methods, too.
179  foop = foo->Ref();
180  foop.release();
181  foo->Unref();
182  foo->Unref(DEBUG_LOCATION, "original_ref");
183 }
184 
185 } // namespace
186 } // namespace testing
187 } // namespace grpc_core
188 
189 int main(int argc, char** argv) {
190  grpc::testing::TestEnvironment env(&argc, argv);
191  ::testing::InitGoogleTest(&argc, argv);
192  return RUN_ALL_TESTS();
193 }
testing
Definition: aws_request_signer_test.cc:25
regen-readme.it
it
Definition: regen-readme.py:15
testing::Pointee
internal::PointeeMatcher< InnerMatcher > Pointee(const InnerMatcher &inner_matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8691
generate.env
env
Definition: generate.py:37
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
grpc_core
Definition: call_metric_recorder.h:31
foo
Definition: bloaty/third_party/googletest/googletest/test/googletest-output-test_.cc:546
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
memory.h
testing::Property
PolymorphicMatcher< internal::PropertyMatcher< Class, PropertyType > > Property(PropertyType(Class::*property)() const, const PropertyMatcher &matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8732
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
Foo
Definition: abseil-cpp/absl/debugging/symbolize_test.cc:65
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
test_config.h
value
const char * value
Definition: hpack_parser_table.cc:165
value_
int value_
Definition: ref_counted_test.cc:63
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
ref_counted.h
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
main
int main(int argc, char **argv)
Definition: ref_counted_test.cc:189
cpp.gmock_class.set
set
Definition: bloaty/third_party/googletest/googlemock/scripts/generator/cpp/gmock_class.py:44
testing::UnorderedElementsAre
internal::UnorderedElementsAreMatcher< ::testing::tuple<> > UnorderedElementsAre()
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13255
grpc_core::testing::TEST
TEST(ServiceConfigParserTest, DoubleRegistration)
Definition: service_config_test.cc:448
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
Value
struct Value Value
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:676
absl::status_internal::storage
static ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook< StatusPayloadPrinter > storage
Definition: abseil-cpp/absl/status/status_payload_printer.cc:26


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