memory_quota_test.cc
Go to the documentation of this file.
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
17 #include <algorithm>
18 #include <vector>
19 
20 #include "gtest/gtest.h"
21 
22 #include <grpc/slice.h>
23 
27 
28 namespace grpc_core {
29 namespace testing {
30 
31 //
32 // Helpers
33 //
34 
35 template <size_t kSize>
36 struct Sized {
37  char blah[kSize];
38  virtual ~Sized() {}
39 };
40 
41 //
42 // MemoryRequestTest
43 //
44 
45 TEST(MemoryRequestTest, ConversionFromSize) {
47  EXPECT_EQ(request.min(), 3);
48  EXPECT_EQ(request.max(), 3);
49 }
50 
51 TEST(MemoryRequestTest, MinMax) {
52  MemoryRequest request(3, 7);
53  EXPECT_EQ(request.min(), 3);
54  EXPECT_EQ(request.max(), 7);
55 }
56 
57 //
58 // MemoryQuotaTest
59 //
60 
61 TEST(MemoryQuotaTest, NoOp) { MemoryQuota("foo"); }
62 
63 TEST(MemoryQuotaTest, CreateAllocatorNoOp) {
64  MemoryQuota memory_quota("foo");
65  auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
66 }
67 
68 TEST(MemoryQuotaTest, CreateObjectFromAllocator) {
69  MemoryQuota memory_quota("foo");
70  auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
71  auto object = memory_allocator.MakeUnique<Sized<4096>>();
72 }
73 
74 TEST(MemoryQuotaTest, CreateSomeObjectsAndExpectReclamation) {
76 
77  MemoryQuota memory_quota("foo");
78  memory_quota.SetSize(4096);
79  auto memory_allocator = memory_quota.CreateMemoryOwner("bar");
80  auto object = memory_allocator.MakeUnique<Sized<2048>>();
81 
82  auto checker1 = CallChecker::Make();
83  memory_allocator.PostReclaimer(
85  [&object, checker1](absl::optional<ReclamationSweep> sweep) {
86  checker1->Called();
87  EXPECT_TRUE(sweep.has_value());
88  object.reset();
89  });
90  auto object2 = memory_allocator.MakeUnique<Sized<2048>>();
91  exec_ctx.Flush();
92  EXPECT_EQ(object.get(), nullptr);
93 
94  auto checker2 = CallChecker::Make();
95  memory_allocator.PostReclaimer(
97  [&object2, checker2](absl::optional<ReclamationSweep> sweep) {
98  checker2->Called();
99  EXPECT_TRUE(sweep.has_value());
100  object2.reset();
101  });
102  auto object3 = memory_allocator.MakeUnique<Sized<2048>>();
103  exec_ctx.Flush();
104  EXPECT_EQ(object2.get(), nullptr);
105 }
106 
107 TEST(MemoryQuotaTest, ReserveRangeNoPressure) {
108  MemoryQuota memory_quota("foo");
109  auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
110  size_t total = 0;
111  for (int i = 0; i < 10000; i++) {
112  auto n = memory_allocator.Reserve(MemoryRequest(100, 40000));
113  EXPECT_EQ(n, 40000);
114  total += n;
115  }
116  memory_allocator.Release(total);
117 }
118 
119 TEST(MemoryQuotaTest, MakeSlice) {
120  MemoryQuota memory_quota("foo");
121  auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
122  std::vector<grpc_slice> slices;
123  for (int i = 1; i < 1000; i++) {
124  int min = i;
125  int max = 10 * i - 9;
126  slices.push_back(memory_allocator.MakeSlice(MemoryRequest(min, max)));
127  }
128  for (grpc_slice slice : slices) {
130  }
131 }
132 
133 TEST(MemoryQuotaTest, ContainerAllocator) {
134  MemoryQuota memory_quota("foo");
135  auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
136  Vector<int> vec(&memory_allocator);
137  for (int i = 0; i < 100000; i++) {
138  vec.push_back(i);
139  }
140 }
141 
142 TEST(MemoryQuotaTest, NoBunchingIfIdle) {
143  // Ensure that we don't queue up useless reclamations even if there are no
144  // memory reclamations needed.
145  MemoryQuota memory_quota("foo");
146  std::atomic<size_t> count_reclaimers_called{0};
147 
148  for (size_t i = 0; i < 10000; i++) {
150  auto memory_owner = memory_quota.CreateMemoryOwner("bar");
151  memory_owner.PostReclaimer(
153  [&count_reclaimers_called](absl::optional<ReclamationSweep> sweep) {
154  EXPECT_FALSE(sweep.has_value());
155  count_reclaimers_called.fetch_add(1, std::memory_order_relaxed);
156  });
157  auto object = memory_owner.MakeUnique<Sized<2048>>();
158  }
159 
160  EXPECT_GE(count_reclaimers_called.load(std::memory_order_relaxed), 8000);
161 }
162 
163 } // namespace testing
164 } // namespace grpc_core
165 
166 // Hook needed to run ExecCtx outside of iomgr.
168 
169 int main(int argc, char** argv) {
170  ::testing::InitGoogleTest(&argc, argv);
172  return RUN_ALL_TESTS();
173 }
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
testing
Definition: aws_request_signer_test.cc:25
get
absl::string_view get(const Cont &c)
Definition: abseil-cpp/absl/strings/str_replace_test.cc:185
grpc_core::MemoryQuota::CreateMemoryOwner
MemoryOwner CreateMemoryOwner(absl::string_view name)
Definition: memory_quota.cc:472
grpc_core::testing::Sized::~Sized
virtual ~Sized()
Definition: memory_quota_test.cc:38
gpr_log_verbosity_init
GPRAPI void gpr_log_verbosity_init(void)
Definition: log.cc:115
main
int main(int argc, char **argv)
Definition: memory_quota_test.cc:169
slice.h
NoOp
Definition: bm_call_create.cc:477
grpc_core
Definition: call_metric_recorder.h:31
total
size_t total
Definition: cord_analysis.cc:59
benchmark.request
request
Definition: benchmark.py:77
call_checker.h
grpc_core::testing::Sized
Definition: memory_quota_test.cc:36
grpc_core::testing::Sized::blah
char blah[kSize]
Definition: memory_quota_test.cc:37
grpc_set_default_iomgr_platform
void grpc_set_default_iomgr_platform()
Definition: memory_quota_test.cc:167
grpc_event_engine::experimental::MemoryAllocator::MakeUnique
std::unique_ptr< T > MakeUnique(Args &&... args)
Construct a unique_ptr immediately.
Definition: memory_allocator.h:129
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
grpc_core::MemoryOwner::PostReclaimer
void PostReclaimer(ReclamationPass pass, F fn)
Definition: memory_quota.h:390
absl::optional::has_value
constexpr bool has_value() const noexcept
Definition: abseil-cpp/absl/types/optional.h:461
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
grpc_core::ExecCtx::Flush
bool Flush()
Definition: exec_ctx.cc:69
slice
grpc_slice slice
Definition: src/core/lib/surface/server.cc:467
MakeSlice
Slice MakeSlice(size_t len)
Definition: event_engine/slice_buffer_test.cc:31
absl::optional
Definition: abseil-cpp/absl/types/internal/optional.h:61
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
min
#define min(a, b)
Definition: qsort.h:83
grpc_core::ExecCtx
Definition: exec_ctx.h:97
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
grpc_core::MemoryQuota::SetSize
void SetSize(size_t new_size)
Definition: memory_quota.h:441
grpc_event_engine::experimental::Vector
Definition: memory_allocator.h:189
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
slices
SliceBuffer * slices
Definition: retry_filter.cc:631
exec_ctx.h
slice_refcount.h
EXPECT_GE
#define EXPECT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2034
memory_quota.h
grpc_core::StatusIntProperty::kSize
@ kSize
context sensitive size associated with the error
grpc_core::testing::TEST
TEST(ServiceConfigParserTest, DoubleRegistration)
Definition: service_config_test.cc:448
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
grpc_core::testing::CallChecker::Make
static std::shared_ptr< CallChecker > Make()
Definition: call_checker.h:44
grpc_core::MemoryQuota
Definition: memory_quota.h:421
grpc_event_engine::experimental::MemoryRequest
Reservation request - how much memory do we want to allocate?
Definition: memory_request.h:27
grpc_core::ReclamationPass::kDestructive
@ kDestructive
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_slice_unref_internal
void grpc_slice_unref_internal(const grpc_slice &slice)
Definition: slice_refcount.h:39
grpc_core::MemoryQuota::CreateMemoryAllocator
MemoryAllocator CreateMemoryAllocator(absl::string_view name) override
Definition: memory_quota.cc:466


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:23