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 "testing/gtest/include/gtest/gtest.h"
6
7 #include "base/allocator/dispatcher/configuration.h"
8 #include "base/allocator/dispatcher/initializer.h"
9 #include "base/allocator/dispatcher/testing/observer_mock.h"
10 #include "base/allocator/dispatcher/testing/tools.h"
11
12 #include <functional>
13 #include <map>
14 #include <tuple>
15
16 namespace base::allocator::dispatcher {
17 namespace testing {
18
19 // A mock Dispatcher for testing. Since Initializer and Dispatcher rely on
20 // templating, we can't employ GoogleMocks for mocking. The mock dispatcher
21 // records the number of invocations of Initialize for a given tuple of
22 // observers.
23 struct Dispatcher {
24 Dispatcher() = default;
25
~Dispatcherbase::allocator::dispatcher::testing::Dispatcher26 ~Dispatcher() {
27 for (const auto& reset_data : reseter_) {
28 reset_data.second();
29 }
30 }
31
32 template <typename... Observers>
Initializebase::allocator::dispatcher::testing::Dispatcher33 void Initialize(const std::tuple<Observers*...>& observers) {
34 ++total_number_of_inits_;
35 ++(GetInitCounterForObservers(observers));
36 }
37
GetTotalInitCounterbase::allocator::dispatcher::testing::Dispatcher38 size_t GetTotalInitCounter() const { return total_number_of_inits_; }
39
40 template <typename... Observers>
GetInitCounterForObserversbase::allocator::dispatcher::testing::Dispatcher41 size_t& GetInitCounterForObservers(
42 const std::tuple<Observers*...>& observers) {
43 static std::map<std::tuple<Observers*...>, size_t>
44 observer_init_counter_map;
45 reseter_[&observer_init_counter_map] = []() {
46 observer_init_counter_map.clear();
47 };
48 return observer_init_counter_map[observers];
49 }
50
51 size_t total_number_of_inits_ = 0;
52 std::map<void*, std::function<void()>> reseter_;
53 };
54 } // namespace testing
55
56 using testing::ObserverMock;
57
58 struct BaseAllocatorDispatcherInitializerTest : public ::testing::Test {};
59
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifyEmptyInitializer)60 TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyEmptyInitializer) {
61 const auto initializer = CreateInitializer();
62
63 EXPECT_EQ(initializer.GetOptionalObservers(), std::make_tuple());
64 EXPECT_EQ(initializer.GetMandatoryObservers(), std::make_tuple());
65 }
66
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifySettingOptionalObservers)67 TEST_F(BaseAllocatorDispatcherInitializerTest, VerifySettingOptionalObservers) {
68 ObserverMock<int> optional_observer_1;
69 ObserverMock<float> optional_observer_2;
70 ObserverMock<size_t> optional_observer_3;
71
72 auto initializer_1 = CreateInitializer().SetOptionalObservers(
73 &optional_observer_1, &optional_observer_2);
74 EXPECT_EQ(initializer_1.GetOptionalObservers(),
75 std::make_tuple(&optional_observer_1, &optional_observer_2));
76 EXPECT_EQ(initializer_1.GetMandatoryObservers(), std::make_tuple());
77
78 auto initializer_2 = initializer_1.SetOptionalObservers(&optional_observer_3);
79 EXPECT_EQ(initializer_2.GetOptionalObservers(),
80 std::make_tuple(&optional_observer_3));
81 EXPECT_EQ(initializer_2.GetMandatoryObservers(), std::make_tuple());
82
83 auto initializer_3 = initializer_2.SetOptionalObservers();
84 EXPECT_EQ(initializer_3.GetOptionalObservers(), std::make_tuple());
85 EXPECT_EQ(initializer_3.GetMandatoryObservers(), std::make_tuple());
86 }
87
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifyAddingOptionalObservers)88 TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyAddingOptionalObservers) {
89 ObserverMock<int> optional_observer_1;
90 ObserverMock<float> optional_observer_2;
91 ObserverMock<size_t> optional_observer_3;
92
93 auto initializer_1 = CreateInitializer().AddOptionalObservers(
94 &optional_observer_1, &optional_observer_2);
95 EXPECT_EQ(initializer_1.GetOptionalObservers(),
96 std::make_tuple(&optional_observer_1, &optional_observer_2));
97 EXPECT_EQ(initializer_1.GetMandatoryObservers(), std::make_tuple());
98
99 auto initializer_2 = initializer_1.AddOptionalObservers(&optional_observer_3);
100 EXPECT_EQ(initializer_2.GetOptionalObservers(),
101 std::make_tuple(&optional_observer_1, &optional_observer_2,
102 &optional_observer_3));
103 EXPECT_EQ(initializer_2.GetMandatoryObservers(), std::make_tuple());
104
105 auto initializer_3 = initializer_2.AddOptionalObservers();
106 EXPECT_EQ(initializer_3.GetOptionalObservers(),
107 std::make_tuple(&optional_observer_1, &optional_observer_2,
108 &optional_observer_3));
109 EXPECT_EQ(initializer_3.GetMandatoryObservers(), std::make_tuple());
110
111 auto initializer_4 = initializer_3.SetOptionalObservers();
112 EXPECT_EQ(initializer_4.GetOptionalObservers(), std::make_tuple());
113 EXPECT_EQ(initializer_4.GetMandatoryObservers(), std::make_tuple());
114 }
115
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifySettingMandatoryObservers)116 TEST_F(BaseAllocatorDispatcherInitializerTest,
117 VerifySettingMandatoryObservers) {
118 ObserverMock<int> mandatory_observer_1;
119 ObserverMock<float> mandatory_observer_2;
120 ObserverMock<size_t> mandatory_observer_3;
121
122 auto initializer_1 = CreateInitializer().SetMandatoryObservers(
123 &mandatory_observer_1, &mandatory_observer_2);
124 EXPECT_EQ(initializer_1.GetMandatoryObservers(),
125 std::make_tuple(&mandatory_observer_1, &mandatory_observer_2));
126 EXPECT_EQ(initializer_1.GetOptionalObservers(), std::make_tuple());
127
128 auto initializer_2 =
129 initializer_1.SetMandatoryObservers(&mandatory_observer_3);
130 EXPECT_EQ(initializer_2.GetMandatoryObservers(),
131 std::make_tuple(&mandatory_observer_3));
132 EXPECT_EQ(initializer_2.GetOptionalObservers(), std::make_tuple());
133
134 auto initializer_3 = initializer_2.SetMandatoryObservers();
135 EXPECT_EQ(initializer_3.GetMandatoryObservers(), std::make_tuple());
136 EXPECT_EQ(initializer_3.GetOptionalObservers(), std::make_tuple());
137 }
138
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifyAddingMandatoryObservers)139 TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyAddingMandatoryObservers) {
140 ObserverMock<int> mandatory_observer_1;
141 ObserverMock<float> mandatory_observer_2;
142 ObserverMock<size_t> mandatory_observer_3;
143
144 auto initializer_1 = CreateInitializer().AddMandatoryObservers(
145 &mandatory_observer_1, &mandatory_observer_2);
146 EXPECT_EQ(initializer_1.GetMandatoryObservers(),
147 std::make_tuple(&mandatory_observer_1, &mandatory_observer_2));
148 EXPECT_EQ(initializer_1.GetOptionalObservers(), std::make_tuple());
149
150 auto initializer_2 =
151 initializer_1.AddMandatoryObservers(&mandatory_observer_3);
152 EXPECT_EQ(initializer_2.GetMandatoryObservers(),
153 std::make_tuple(&mandatory_observer_1, &mandatory_observer_2,
154 &mandatory_observer_3));
155 EXPECT_EQ(initializer_2.GetOptionalObservers(), std::make_tuple());
156
157 auto initializer_3 = initializer_2.AddMandatoryObservers();
158 EXPECT_EQ(initializer_3.GetMandatoryObservers(),
159 std::make_tuple(&mandatory_observer_1, &mandatory_observer_2,
160 &mandatory_observer_3));
161 EXPECT_EQ(initializer_3.GetOptionalObservers(), std::make_tuple());
162
163 auto initializer_4 = initializer_3.SetMandatoryObservers();
164 EXPECT_EQ(initializer_4.GetMandatoryObservers(), std::make_tuple());
165 EXPECT_EQ(initializer_4.GetOptionalObservers(), std::make_tuple());
166 }
167
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifyBasicInitialization)168 TEST_F(BaseAllocatorDispatcherInitializerTest, VerifyBasicInitialization) {
169 ObserverMock<int> optional_observer_1;
170 ObserverMock<float> optional_observer_2;
171 ObserverMock<size_t> mandatory_observer_1;
172 ObserverMock<double> mandatory_observer_2;
173
174 testing::Dispatcher test_dispatcher;
175
176 CreateInitializer()
177 .SetMandatoryObservers(&mandatory_observer_1, &mandatory_observer_2)
178 .SetOptionalObservers(&optional_observer_1, &optional_observer_2)
179 .DoInitialize(test_dispatcher);
180
181 const auto observer_ptrs =
182 std::make_tuple(&mandatory_observer_1, &mandatory_observer_2,
183 &optional_observer_1, &optional_observer_2);
184
185 EXPECT_EQ(1ul, test_dispatcher.GetInitCounterForObservers(observer_ptrs));
186 }
187
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifyInitializationWithMandatoryNullObservers)188 TEST_F(BaseAllocatorDispatcherInitializerTest,
189 VerifyInitializationWithMandatoryNullObservers) {
190 ObserverMock<int> optional_observer_1;
191 ObserverMock<float> optional_observer_2;
192 ObserverMock<size_t> mandatory_observer;
193 ObserverMock<double>* mandatory_null_observer = nullptr;
194
195 testing::Dispatcher test_dispatcher;
196
197 CreateInitializer()
198 .SetMandatoryObservers(&mandatory_observer, mandatory_null_observer)
199 .SetOptionalObservers(&optional_observer_1, &optional_observer_2)
200 .DoInitialize(test_dispatcher);
201
202 // For mandatory observers being null we expect them to be passed straight
203 // down to the dispatcher, which will then perform a check of ALL observers.
204 const auto valid_observer_ptrs =
205 std::make_tuple(&mandatory_observer, mandatory_null_observer,
206 &optional_observer_1, &optional_observer_2);
207
208 EXPECT_EQ(1ul, test_dispatcher.GetTotalInitCounter());
209 EXPECT_EQ(1ul,
210 test_dispatcher.GetInitCounterForObservers(valid_observer_ptrs));
211 }
212
TEST_F(BaseAllocatorDispatcherInitializerTest,VerifyInitializationWithOptionalNullObservers)213 TEST_F(BaseAllocatorDispatcherInitializerTest,
214 VerifyInitializationWithOptionalNullObservers) {
215 ObserverMock<int> optional_observer;
216 ObserverMock<float>* optional_null_observer = nullptr;
217 ObserverMock<size_t> mandatory_observer_1;
218 ObserverMock<double> mandatory_observer_2;
219
220 testing::Dispatcher test_dispatcher;
221
222 CreateInitializer()
223 .SetMandatoryObservers(&mandatory_observer_1, &mandatory_observer_2)
224 .SetOptionalObservers(&optional_observer, optional_null_observer)
225 .DoInitialize(test_dispatcher);
226
227 const auto valid_observer_ptrs = std::make_tuple(
228 &mandatory_observer_1, &mandatory_observer_2, &optional_observer);
229
230 EXPECT_EQ(1ul, test_dispatcher.GetTotalInitCounter());
231 EXPECT_EQ(1ul,
232 test_dispatcher.GetInitCounterForObservers(valid_observer_ptrs));
233 }
234
235 } // namespace base::allocator::dispatcher