xref: /aosp_15_r20/external/cronet/base/allocator/dispatcher/internal/dispatcher_internal_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/allocator/dispatcher/internal/dispatcher_internal.h"
6 
7 #include <iostream>
8 #include <tuple>
9 #include <utility>
10 
11 #include "base/allocator/dispatcher/subsystem.h"
12 #include "base/allocator/dispatcher/testing/dispatcher_test.h"
13 #include "base/allocator/dispatcher/testing/observer_mock.h"
14 #include "base/allocator/dispatcher/testing/tools.h"
15 #include "base/dcheck_is_on.h"
16 #include "partition_alloc/partition_alloc_buildflags.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 #if BUILDFLAG(USE_PARTITION_ALLOC)
20 #include "partition_alloc/partition_alloc_allocation_data.h"
21 #endif
22 
23 using ::base::allocator::dispatcher::AllocationSubsystem;
24 using ::base::allocator::dispatcher::configuration::kMaximumNumberOfObservers;
25 using ::base::allocator::dispatcher::testing::CreateTupleOfPointers;
26 using ::base::allocator::dispatcher::testing::DispatcherTest;
27 using ::testing::_;
28 using ::testing::AllOf;
29 using ::testing::InSequence;
30 using ::testing::Matcher;
31 using ::testing::Property;
32 
33 namespace base::allocator::dispatcher::internal {
34 
35 namespace {
36 
AllocationNotificationMatches(Matcher<void * > address_matcher,Matcher<size_t> size_matcher,Matcher<AllocationSubsystem> subsystem_matcher=_)37 auto AllocationNotificationMatches(
38     Matcher<void*> address_matcher,
39     Matcher<size_t> size_matcher,
40     Matcher<AllocationSubsystem> subsystem_matcher = _) {
41   return AllOf(Property("address", &AllocationNotificationData::address,
42                         std::move(address_matcher)),
43                Property("size", &AllocationNotificationData::size,
44                         std::move(size_matcher)),
45                Property("allocation_subsystem",
46                         &AllocationNotificationData::allocation_subsystem,
47                         std::move(subsystem_matcher)));
48 }
49 
FreeNotificationMatches(Matcher<void * > address_matcher,Matcher<AllocationSubsystem> subsystem_matcher=_)50 auto FreeNotificationMatches(
51     Matcher<void*> address_matcher,
52     Matcher<AllocationSubsystem> subsystem_matcher = _) {
53   return AllOf(Property("address", &FreeNotificationData::address,
54                         std::move(address_matcher)),
55                Property("allocation_subsystem",
56                         &FreeNotificationData::allocation_subsystem,
57                         std::move(subsystem_matcher)));
58 }
59 
60 #if BUILDFLAG(USE_PARTITION_ALLOC)
CreatePAAllocationData(void * address,size_t size,partition_alloc::TagViolationReportingMode mte_mode=partition_alloc::TagViolationReportingMode::kUndefined)61 ::partition_alloc::AllocationNotificationData CreatePAAllocationData(
62     void* address,
63     size_t size,
64     partition_alloc::TagViolationReportingMode mte_mode =
65         partition_alloc::TagViolationReportingMode::kUndefined) {
66   return ::partition_alloc::AllocationNotificationData(address, size, nullptr)
67 #if BUILDFLAG(HAS_MEMORY_TAGGING)
68       .SetMteReportingMode(mte_mode)
69 #endif
70       ;
71 }
72 
CreatePAFreeData(void * address,partition_alloc::TagViolationReportingMode mte_mode=partition_alloc::TagViolationReportingMode::kUndefined)73 ::partition_alloc::FreeNotificationData CreatePAFreeData(
74     void* address,
75     partition_alloc::TagViolationReportingMode mte_mode =
76         partition_alloc::TagViolationReportingMode::kUndefined) {
77   return ::partition_alloc::FreeNotificationData(address)
78 #if BUILDFLAG(HAS_MEMORY_TAGGING)
79       .SetMteReportingMode(mte_mode)
80 #endif
81       ;
82 }
83 #endif  // BUILDFLAG(USE_PARTITION_ALLOC)
84 
85 struct AllocationEventDispatcherInternalTest : public DispatcherTest {
GetAllocatedAddressbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest86   static void* GetAllocatedAddress() {
87     return reinterpret_cast<void*>(0x12345678);
88   }
GetAllocatedSizebase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest89   static unsigned int GetAllocatedSize() { return 35; }
GetEstimatedSizebase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest90   static unsigned int GetEstimatedSize() { return 77; }
GetFreedAddressbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest91   static void* GetFreedAddress() {
92     return reinterpret_cast<void*>(0x876543210);
93   }
94 
95 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
GetNextAllocatorDispatchbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest96   AllocatorDispatch* GetNextAllocatorDispatch() { return &allocator_dispatch_; }
alloc_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest97   static void* alloc_function(const AllocatorDispatch*, size_t, void*) {
98     return GetAllocatedAddress();
99   }
alloc_unchecked_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest100   static void* alloc_unchecked_function(const AllocatorDispatch*,
101                                         size_t,
102                                         void*) {
103     return GetAllocatedAddress();
104   }
alloc_zero_initialized_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest105   static void* alloc_zero_initialized_function(const AllocatorDispatch*,
106                                                size_t,
107                                                size_t,
108                                                void*) {
109     return GetAllocatedAddress();
110   }
alloc_aligned_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest111   static void* alloc_aligned_function(const AllocatorDispatch*,
112                                       size_t,
113                                       size_t,
114                                       void*) {
115     return GetAllocatedAddress();
116   }
realloc_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest117   static void* realloc_function(const AllocatorDispatch*,
118                                 void*,
119                                 size_t,
120                                 void*) {
121     return GetAllocatedAddress();
122   }
get_size_estimate_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest123   static size_t get_size_estimate_function(const AllocatorDispatch*,
124                                            void*,
125                                            void*) {
126     return GetEstimatedSize();
127   }
good_size_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest128   static size_t good_size_function(const AllocatorDispatch*,
129                                    size_t size,
130                                    void*) {
131     return size;
132   }
claimed_address_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest133   static bool claimed_address_function(const AllocatorDispatch*, void*, void*) {
134     return GetEstimatedSize();
135   }
batch_malloc_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest136   static unsigned batch_malloc_function(const AllocatorDispatch*,
137                                         size_t,
138                                         void**,
139                                         unsigned num_requested,
140                                         void*) {
141     return num_requested;
142   }
aligned_malloc_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest143   static void* aligned_malloc_function(const AllocatorDispatch*,
144                                        size_t,
145                                        size_t,
146                                        void*) {
147     return GetAllocatedAddress();
148   }
aligned_realloc_functionbase::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest149   static void* aligned_realloc_function(const AllocatorDispatch*,
150                                         void*,
151                                         size_t,
152                                         size_t,
153                                         void*) {
154     return GetAllocatedAddress();
155   }
156 
157   AllocatorDispatch allocator_dispatch_ = {
158       &alloc_function,
159       &alloc_unchecked_function,
160       &alloc_zero_initialized_function,
161       &alloc_aligned_function,
162       &realloc_function,
__anon8da88cf30202base::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest163       [](const AllocatorDispatch*, void*, void*) {},
164       &get_size_estimate_function,
165       &good_size_function,
166       &claimed_address_function,
167       &batch_malloc_function,
__anon8da88cf30302base::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest168       [](const AllocatorDispatch*, void**, unsigned, void*) {},
__anon8da88cf30402base::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest169       [](const AllocatorDispatch*, void*, size_t, void*) {},
__anon8da88cf30502base::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest170       [](const AllocatorDispatch*, void*, void*) {},
171       &aligned_malloc_function,
172       &aligned_realloc_function,
__anon8da88cf30602base::allocator::dispatcher::internal::__anon8da88cf30111::AllocationEventDispatcherInternalTest173       [](const AllocatorDispatch*, void*, void*) {}};
174 #endif
175 };
176 
177 }  // namespace
178 
179 using ::testing::NaggyMock;
180 using ::testing::StrictMock;
181 
182 using ObserverMock = StrictMock<testing::ObserverMock<>>;
183 
184 #if defined(GTEST_HAS_DEATH_TEST) && GTEST_HAS_DEATH_TEST && DCHECK_IS_ON()
TEST(AllocationEventDispatcherInternalDeathTest,VerifyDeathWhenObserverIsNull)185 TEST(AllocationEventDispatcherInternalDeathTest,
186      VerifyDeathWhenObserverIsNull) {
187   testing::ObserverMock<int> observer_1;
188   testing::ObserverMock<float> observer_2;
189   testing::ObserverMock<size_t>* null_observer = nullptr;
190   testing::ObserverMock<double> observer_3;
191 
192   const auto observer_ptrs =
193       std::make_tuple(&observer_1, &observer_2, null_observer, &observer_3);
194 
195   EXPECT_DEATH({ GetNotificationHooks(observer_ptrs); }, "");
196 }
197 #endif  // defined(GTEST_HAS_DEATH_TEST) && GTEST_HAS_DEATH_TEST &&
198         // DCHECK_IS_ON()
199 
200 #if BUILDFLAG(USE_PARTITION_ALLOC)
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorHooksAreSet)201 TEST_F(AllocationEventDispatcherInternalTest,
202        VerifyPartitionAllocatorHooksAreSet) {
203   std::array<ObserverMock, 1> observers;
204 
205   const auto dispatch_data =
206       GetNotificationHooks(CreateTupleOfPointers(observers));
207 
208   EXPECT_NE(nullptr, dispatch_data.GetAllocationObserverHook());
209   EXPECT_NE(nullptr, dispatch_data.GetFreeObserverHook());
210 }
211 
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorHooksAreNullWhenNoObservers)212 TEST_F(AllocationEventDispatcherInternalTest,
213        VerifyPartitionAllocatorHooksAreNullWhenNoObservers) {
214   const auto dispatch_data = GetNotificationHooks(std::make_tuple());
215 
216   EXPECT_EQ(nullptr, dispatch_data.GetAllocationObserverHook());
217   EXPECT_EQ(nullptr, dispatch_data.GetFreeObserverHook());
218 }
219 
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorAllocationHooksTriggerCorrectly)220 TEST_F(AllocationEventDispatcherInternalTest,
221        VerifyPartitionAllocatorAllocationHooksTriggerCorrectly) {
222   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
223 
224   for (auto& mock : observers) {
225     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
226     EXPECT_CALL(
227         mock, OnAllocation(AllocationNotificationMatches(this, sizeof(*this))))
228         .Times(1);
229     EXPECT_CALL(mock, OnFree(_)).Times(0);
230   }
231 
232   const auto dispatch_data =
233       GetNotificationHooks(CreateTupleOfPointers(observers));
234 
235   ::partition_alloc::AllocationNotificationData notification_data =
236       CreatePAAllocationData(this, sizeof(*this));
237 
238   dispatch_data.GetAllocationObserverHook()(notification_data);
239 }
240 
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorFreeHooksTriggerCorrectly)241 TEST_F(AllocationEventDispatcherInternalTest,
242        VerifyPartitionAllocatorFreeHooksTriggerCorrectly) {
243   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
244 
245   for (auto& mock : observers) {
246     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
247     EXPECT_CALL(mock, OnFree(_)).Times(0);
248     EXPECT_CALL(mock, OnFree(FreeNotificationMatches(this))).Times(1);
249   }
250 
251   const auto dispatch_data =
252       GetNotificationHooks(CreateTupleOfPointers(observers));
253 
254   dispatch_data.GetFreeObserverHook()(CreatePAFreeData(this));
255 }
256 #endif  // BUILDFLAG(USE_PARTITION_ALLOC)
257 
258 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimDataIsSet)259 TEST_F(AllocationEventDispatcherInternalTest, VerifyAllocatorShimDataIsSet) {
260   std::array<ObserverMock, 1> observers;
261 
262   const auto dispatch_data =
263       GetNotificationHooks(CreateTupleOfPointers(observers));
264   const auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
265   EXPECT_NE(nullptr, allocator_dispatch);
266   EXPECT_NE(nullptr, allocator_dispatch->alloc_function);
267   EXPECT_NE(nullptr, allocator_dispatch->alloc_unchecked_function);
268   EXPECT_NE(nullptr, allocator_dispatch->alloc_zero_initialized_function);
269   EXPECT_NE(nullptr, allocator_dispatch->alloc_aligned_function);
270   EXPECT_NE(nullptr, allocator_dispatch->realloc_function);
271   EXPECT_NE(nullptr, allocator_dispatch->free_function);
272   EXPECT_NE(nullptr, allocator_dispatch->get_size_estimate_function);
273   EXPECT_NE(nullptr, allocator_dispatch->claimed_address_function);
274   EXPECT_NE(nullptr, allocator_dispatch->batch_malloc_function);
275   EXPECT_NE(nullptr, allocator_dispatch->batch_free_function);
276   EXPECT_NE(nullptr, allocator_dispatch->free_definite_size_function);
277   EXPECT_NE(nullptr, allocator_dispatch->try_free_default_function);
278   EXPECT_NE(nullptr, allocator_dispatch->aligned_malloc_function);
279   EXPECT_NE(nullptr, allocator_dispatch->aligned_realloc_function);
280   EXPECT_NE(nullptr, allocator_dispatch->aligned_free_function);
281 }
282 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimDataIsNullWhenNoObservers)283 TEST_F(AllocationEventDispatcherInternalTest,
284        VerifyAllocatorShimDataIsNullWhenNoObservers) {
285   const auto dispatch_data = GetNotificationHooks(std::make_tuple());
286 
287   EXPECT_EQ(nullptr, dispatch_data.GetAllocatorDispatch());
288 }
289 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_function)290 TEST_F(AllocationEventDispatcherInternalTest,
291        VerifyAllocatorShimHooksTriggerCorrectly_alloc_function) {
292   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
293 
294   for (auto& mock : observers) {
295     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
296     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
297                           GetAllocatedAddress(), GetAllocatedSize(),
298                           AllocationSubsystem::kAllocatorShim)))
299         .Times(1);
300     EXPECT_CALL(mock, OnFree(_)).Times(0);
301   }
302 
303   auto const dispatch_data =
304       GetNotificationHooks(CreateTupleOfPointers(observers));
305 
306   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
307   allocator_dispatch->next = GetNextAllocatorDispatch();
308 
309   auto* const allocated_address = allocator_dispatch->alloc_function(
310       allocator_dispatch, GetAllocatedSize(), nullptr);
311 
312   EXPECT_EQ(allocated_address, GetAllocatedAddress());
313 }
314 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_unchecked_function)315 TEST_F(AllocationEventDispatcherInternalTest,
316        VerifyAllocatorShimHooksTriggerCorrectly_alloc_unchecked_function) {
317   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
318 
319   for (auto& mock : observers) {
320     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
321     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
322                           GetAllocatedAddress(), GetAllocatedSize(),
323                           AllocationSubsystem::kAllocatorShim)))
324         .Times(1);
325     EXPECT_CALL(mock, OnFree(_)).Times(0);
326   }
327 
328   auto const dispatch_data =
329       GetNotificationHooks(CreateTupleOfPointers(observers));
330 
331   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
332   allocator_dispatch->next = GetNextAllocatorDispatch();
333 
334   auto* const allocated_address = allocator_dispatch->alloc_unchecked_function(
335       allocator_dispatch, GetAllocatedSize(), nullptr);
336 
337   EXPECT_EQ(allocated_address, GetAllocatedAddress());
338 }
339 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_zero_initialized_function)340 TEST_F(
341     AllocationEventDispatcherInternalTest,
342     VerifyAllocatorShimHooksTriggerCorrectly_alloc_zero_initialized_function) {
343   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
344   constexpr int n = 8;
345 
346   for (auto& mock : observers) {
347     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
348     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
349                           GetAllocatedAddress(), n * GetAllocatedSize(),
350                           AllocationSubsystem::kAllocatorShim)))
351         .Times(1);
352     EXPECT_CALL(mock, OnFree(_)).Times(0);
353   }
354 
355   auto const dispatch_data =
356       GetNotificationHooks(CreateTupleOfPointers(observers));
357 
358   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
359   allocator_dispatch->next = GetNextAllocatorDispatch();
360 
361   auto* const allocated_address =
362       allocator_dispatch->alloc_zero_initialized_function(
363           allocator_dispatch, n, GetAllocatedSize(), nullptr);
364 
365   EXPECT_EQ(allocated_address, GetAllocatedAddress());
366 }
367 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_aligned_function)368 TEST_F(AllocationEventDispatcherInternalTest,
369        VerifyAllocatorShimHooksTriggerCorrectly_alloc_aligned_function) {
370   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
371 
372   for (auto& mock : observers) {
373     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
374     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
375                           GetAllocatedAddress(), GetAllocatedSize(),
376                           AllocationSubsystem::kAllocatorShim)))
377         .Times(1);
378     EXPECT_CALL(mock, OnFree(_)).Times(0);
379   }
380 
381   auto const dispatch_data =
382       GetNotificationHooks(CreateTupleOfPointers(observers));
383 
384   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
385   allocator_dispatch->next = GetNextAllocatorDispatch();
386 
387   auto* const allocated_address = allocator_dispatch->alloc_aligned_function(
388       allocator_dispatch, 2048, GetAllocatedSize(), nullptr);
389 
390   EXPECT_EQ(allocated_address, GetAllocatedAddress());
391 }
392 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_realloc_function)393 TEST_F(AllocationEventDispatcherInternalTest,
394        VerifyAllocatorShimHooksTriggerCorrectly_realloc_function) {
395   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
396 
397   for (auto& mock : observers) {
398     InSequence execution_order;
399 
400     EXPECT_CALL(mock,
401                 OnFree(FreeNotificationMatches(
402                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
403         .Times(1);
404     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
405                           GetAllocatedAddress(), GetAllocatedSize(),
406                           AllocationSubsystem::kAllocatorShim)))
407         .Times(1);
408   }
409 
410   auto const dispatch_data =
411       GetNotificationHooks(CreateTupleOfPointers(observers));
412 
413   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
414   allocator_dispatch->next = GetNextAllocatorDispatch();
415 
416   auto* const allocated_address = allocator_dispatch->realloc_function(
417       allocator_dispatch, GetFreedAddress(), GetAllocatedSize(), nullptr);
418 
419   EXPECT_EQ(allocated_address, GetAllocatedAddress());
420 }
421 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_free_function)422 TEST_F(AllocationEventDispatcherInternalTest,
423        VerifyAllocatorShimHooksTriggerCorrectly_free_function) {
424   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
425 
426   for (auto& mock : observers) {
427     EXPECT_CALL(mock,
428                 OnFree(FreeNotificationMatches(
429                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
430         .Times(1);
431     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
432   }
433 
434   auto const dispatch_data =
435       GetNotificationHooks(CreateTupleOfPointers(observers));
436 
437   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
438   allocator_dispatch->next = GetNextAllocatorDispatch();
439 
440   allocator_dispatch->free_function(allocator_dispatch, GetFreedAddress(),
441                                     nullptr);
442 }
443 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_get_size_estimate_function)444 TEST_F(AllocationEventDispatcherInternalTest,
445        VerifyAllocatorShimHooksTriggerCorrectly_get_size_estimate_function) {
446   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
447 
448   for (auto& mock : observers) {
449     EXPECT_CALL(mock, OnFree(_)).Times(0);
450     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
451   }
452 
453   auto const dispatch_data =
454       GetNotificationHooks(CreateTupleOfPointers(observers));
455 
456   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
457   allocator_dispatch->next = GetNextAllocatorDispatch();
458 
459   auto const estimated_size = allocator_dispatch->get_size_estimate_function(
460       allocator_dispatch, GetAllocatedAddress(), nullptr);
461 
462   EXPECT_EQ(estimated_size, GetEstimatedSize());
463 }
464 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_batch_malloc_function)465 TEST_F(AllocationEventDispatcherInternalTest,
466        VerifyAllocatorShimHooksTriggerCorrectly_batch_malloc_function) {
467   constexpr size_t allocation_batch_size = 10;
468   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
469   std::array<void*, allocation_batch_size> allocation_batch = {nullptr};
470 
471   for (auto& mock : observers) {
472     EXPECT_CALL(mock, OnFree(_)).Times(0);
473     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
474                           nullptr, GetAllocatedSize(),
475                           AllocationSubsystem::kAllocatorShim)))
476         .Times(allocation_batch_size);
477   }
478 
479   auto const dispatch_data =
480       GetNotificationHooks(CreateTupleOfPointers(observers));
481 
482   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
483   EXPECT_NE(allocator_dispatch->batch_malloc_function, nullptr);
484 
485   allocator_dispatch->next = GetNextAllocatorDispatch();
486 
487   auto const number_allocated = allocator_dispatch->batch_malloc_function(
488       allocator_dispatch, GetAllocatedSize(), allocation_batch.data(),
489       allocation_batch_size, nullptr);
490 
491   EXPECT_EQ(number_allocated, allocation_batch_size);
492 }
493 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_batch_free_function)494 TEST_F(AllocationEventDispatcherInternalTest,
495        VerifyAllocatorShimHooksTriggerCorrectly_batch_free_function) {
496   constexpr size_t allocation_batch_size = 10;
497   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
498   std::array<void*, allocation_batch_size> allocation_batch;
499   allocation_batch.fill(GetFreedAddress());
500 
501   for (auto& mock : observers) {
502     EXPECT_CALL(mock,
503                 OnFree(FreeNotificationMatches(
504                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
505         .Times(allocation_batch_size);
506     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
507   }
508 
509   auto const dispatch_data =
510       GetNotificationHooks(CreateTupleOfPointers(observers));
511 
512   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
513   EXPECT_NE(allocator_dispatch->batch_free_function, nullptr);
514 
515   allocator_dispatch->next = GetNextAllocatorDispatch();
516 
517   allocator_dispatch->batch_free_function(allocator_dispatch,
518                                           allocation_batch.data(),
519                                           allocation_batch_size, nullptr);
520 }
521 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_free_definite_size_function)522 TEST_F(AllocationEventDispatcherInternalTest,
523        VerifyAllocatorShimHooksTriggerCorrectly_free_definite_size_function) {
524   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
525 
526   for (auto& mock : observers) {
527     EXPECT_CALL(
528         mock, OnFree(FreeNotificationMatches(
529                   GetAllocatedAddress(), AllocationSubsystem::kAllocatorShim)))
530         .Times(1);
531     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
532   }
533 
534   DispatchData const dispatch_data =
535       GetNotificationHooks(CreateTupleOfPointers(observers));
536 
537   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
538   EXPECT_NE(allocator_dispatch->free_definite_size_function, nullptr);
539 
540   allocator_dispatch->next = GetNextAllocatorDispatch();
541 
542   allocator_dispatch->free_definite_size_function(
543       allocator_dispatch, GetAllocatedAddress(), GetAllocatedSize(), nullptr);
544 }
545 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_try_free_default_function)546 TEST_F(AllocationEventDispatcherInternalTest,
547        VerifyAllocatorShimHooksTriggerCorrectly_try_free_default_function) {
548   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
549 
550   for (auto& mock : observers) {
551     EXPECT_CALL(
552         mock, OnFree(FreeNotificationMatches(
553                   GetAllocatedAddress(), AllocationSubsystem::kAllocatorShim)))
554         .Times(1);
555     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
556   }
557 
558   DispatchData const dispatch_data =
559       GetNotificationHooks(CreateTupleOfPointers(observers));
560 
561   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
562   EXPECT_NE(allocator_dispatch->try_free_default_function, nullptr);
563 
564   allocator_dispatch->next = GetNextAllocatorDispatch();
565 
566   allocator_dispatch->try_free_default_function(allocator_dispatch,
567                                                 GetAllocatedAddress(), nullptr);
568 }
569 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_function)570 TEST_F(AllocationEventDispatcherInternalTest,
571        VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_function) {
572   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
573 
574   for (auto& mock : observers) {
575     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
576     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
577                           GetAllocatedAddress(), GetAllocatedSize(),
578                           AllocationSubsystem::kAllocatorShim)))
579         .Times(1);
580     EXPECT_CALL(mock, OnFree(_)).Times(0);
581   }
582 
583   auto const dispatch_data =
584       GetNotificationHooks(CreateTupleOfPointers(observers));
585 
586   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
587   allocator_dispatch->next = GetNextAllocatorDispatch();
588 
589   auto* const allocated_address = allocator_dispatch->aligned_malloc_function(
590       allocator_dispatch, GetAllocatedSize(), 2048, nullptr);
591 
592   EXPECT_EQ(allocated_address, GetAllocatedAddress());
593 }
594 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_function)595 TEST_F(AllocationEventDispatcherInternalTest,
596        VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_function) {
597   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
598 
599   for (auto& mock : observers) {
600     InSequence execution_order;
601 
602     EXPECT_CALL(mock,
603                 OnFree(FreeNotificationMatches(
604                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
605         .Times(1);
606     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
607                           GetAllocatedAddress(), GetAllocatedSize(),
608                           AllocationSubsystem::kAllocatorShim)))
609         .Times(1);
610   }
611 
612   auto const dispatch_data =
613       GetNotificationHooks(CreateTupleOfPointers(observers));
614 
615   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
616   allocator_dispatch->next = GetNextAllocatorDispatch();
617 
618   auto* const allocated_address = allocator_dispatch->aligned_realloc_function(
619       allocator_dispatch, GetFreedAddress(), GetAllocatedSize(), 2048, nullptr);
620 
621   EXPECT_EQ(allocated_address, GetAllocatedAddress());
622 }
623 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_free_function)624 TEST_F(AllocationEventDispatcherInternalTest,
625        VerifyAllocatorShimHooksTriggerCorrectly_aligned_free_function) {
626   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
627 
628   for (auto& mock : observers) {
629     EXPECT_CALL(mock,
630                 OnFree(FreeNotificationMatches(
631                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
632         .Times(1);
633     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
634   }
635 
636   auto const dispatch_data =
637       GetNotificationHooks(CreateTupleOfPointers(observers));
638 
639   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
640   allocator_dispatch->next = GetNextAllocatorDispatch();
641 
642   allocator_dispatch->aligned_free_function(allocator_dispatch,
643                                             GetFreedAddress(), nullptr);
644 }
645 #endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
646 }  // namespace base::allocator::dispatcher::internal
647