Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / profiler / metadata_recorder_unittest.cc
1 // Copyright 2019 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/profiler/metadata_recorder.h"
6
7 #include "base/ranges/algorithm.h"
8 #include "base/test/gtest_util.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/abseil-cpp/absl/types/optional.h"
12
13 namespace base {
14
15 bool operator==(const MetadataRecorder::Item& lhs,
16                 const MetadataRecorder::Item& rhs) {
17   return lhs.name_hash == rhs.name_hash && lhs.value == rhs.value;
18 }
19
20 bool operator<(const MetadataRecorder::Item& lhs,
21                const MetadataRecorder::Item& rhs) {
22   return lhs.name_hash < rhs.name_hash;
23 }
24
25 TEST(MetadataRecorderTest, GetItems_Empty) {
26   MetadataRecorder recorder;
27   MetadataRecorder::ItemArray items;
28
29   EXPECT_EQ(0u, MetadataRecorder::MetadataProvider(&recorder,
30                                                    PlatformThread::CurrentId())
31                     .GetItems(&items));
32   EXPECT_EQ(0u, MetadataRecorder::MetadataProvider(&recorder,
33                                                    PlatformThread::CurrentId())
34                     .GetItems(&items));
35 }
36
37 TEST(MetadataRecorderTest, Set_NewNameHash) {
38   MetadataRecorder recorder;
39
40   recorder.Set(10, absl::nullopt, absl::nullopt, 20);
41
42   MetadataRecorder::ItemArray items;
43   size_t item_count;
44   {
45     item_count = MetadataRecorder::MetadataProvider(&recorder,
46                                                     PlatformThread::CurrentId())
47                      .GetItems(&items);
48     ASSERT_EQ(1u, item_count);
49     EXPECT_EQ(10u, items[0].name_hash);
50     EXPECT_FALSE(items[0].key.has_value());
51     EXPECT_FALSE(items[0].thread_id.has_value());
52     EXPECT_EQ(20, items[0].value);
53   }
54
55   recorder.Set(20, absl::nullopt, absl::nullopt, 30);
56
57   {
58     item_count = MetadataRecorder::MetadataProvider(&recorder,
59                                                     PlatformThread::CurrentId())
60                      .GetItems(&items);
61     ASSERT_EQ(2u, item_count);
62     EXPECT_EQ(20u, items[1].name_hash);
63     EXPECT_FALSE(items[1].key.has_value());
64     EXPECT_FALSE(items[1].thread_id.has_value());
65     EXPECT_EQ(30, items[1].value);
66   }
67 }
68
69 TEST(MetadataRecorderTest, Set_ExistingNameNash) {
70   MetadataRecorder recorder;
71   recorder.Set(10, absl::nullopt, absl::nullopt, 20);
72   recorder.Set(10, absl::nullopt, absl::nullopt, 30);
73
74   MetadataRecorder::ItemArray items;
75   size_t item_count =
76       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
77           .GetItems(&items);
78   ASSERT_EQ(1u, item_count);
79   EXPECT_EQ(10u, items[0].name_hash);
80   EXPECT_FALSE(items[0].key.has_value());
81   EXPECT_FALSE(items[0].thread_id.has_value());
82   EXPECT_EQ(30, items[0].value);
83 }
84
85 TEST(MetadataRecorderTest, Set_ReAddRemovedNameNash) {
86   MetadataRecorder recorder;
87   MetadataRecorder::ItemArray items;
88   std::vector<MetadataRecorder::Item> expected;
89   for (size_t i = 0; i < items.size(); ++i) {
90     expected.emplace_back(i, absl::nullopt, absl::nullopt, 0);
91     recorder.Set(i, absl::nullopt, absl::nullopt, 0);
92   }
93
94   // By removing an item from a full recorder, re-setting the same item, and
95   // verifying that the item is returned, we can verify that the recorder is
96   // reusing the inactive slot for the same name hash instead of trying (and
97   // failing) to allocate a new slot.
98   recorder.Remove(3, absl::nullopt, absl::nullopt);
99   recorder.Set(3, absl::nullopt, absl::nullopt, 0);
100
101   size_t item_count =
102       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
103           .GetItems(&items);
104   EXPECT_EQ(items.size(), item_count);
105   EXPECT_THAT(expected, ::testing::UnorderedElementsAreArray(items));
106 }
107
108 TEST(MetadataRecorderTest, Set_AddPastMaxCount) {
109   MetadataRecorder recorder;
110   MetadataRecorder::ItemArray items;
111   for (size_t i = 0; i < items.size(); ++i) {
112     recorder.Set(i, absl::nullopt, absl::nullopt, 0);
113   }
114
115   // This should fail silently.
116   recorder.Set(items.size(), absl::nullopt, absl::nullopt, 0);
117 }
118
119 TEST(MetadataRecorderTest, Set_NulloptKeyIsIndependentOfNonNulloptKey) {
120   MetadataRecorder recorder;
121
122   recorder.Set(10, 100, absl::nullopt, 20);
123
124   MetadataRecorder::ItemArray items;
125   size_t item_count;
126   {
127     item_count = MetadataRecorder::MetadataProvider(&recorder,
128                                                     PlatformThread::CurrentId())
129                      .GetItems(&items);
130     ASSERT_EQ(1u, item_count);
131     EXPECT_EQ(10u, items[0].name_hash);
132     ASSERT_TRUE(items[0].key.has_value());
133     EXPECT_EQ(100, *items[0].key);
134     EXPECT_EQ(20, items[0].value);
135   }
136
137   recorder.Set(10, absl::nullopt, absl::nullopt, 30);
138
139   {
140     item_count = MetadataRecorder::MetadataProvider(&recorder,
141                                                     PlatformThread::CurrentId())
142                      .GetItems(&items);
143     ASSERT_EQ(2u, item_count);
144
145     EXPECT_EQ(10u, items[0].name_hash);
146     ASSERT_TRUE(items[0].key.has_value());
147     EXPECT_EQ(100, *items[0].key);
148     EXPECT_EQ(20, items[0].value);
149
150     EXPECT_EQ(10u, items[1].name_hash);
151     EXPECT_FALSE(items[1].key.has_value());
152     EXPECT_EQ(30, items[1].value);
153   }
154 }
155
156 TEST(MetadataRecorderTest, Set_ThreadIdIsScoped) {
157   MetadataRecorder recorder;
158
159   recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
160
161   MetadataRecorder::ItemArray items;
162   size_t item_count;
163   {
164     item_count = MetadataRecorder::MetadataProvider(&recorder,
165                                                     PlatformThread::CurrentId())
166                      .GetItems(&items);
167     ASSERT_EQ(1u, item_count);
168     EXPECT_EQ(10u, items[0].name_hash);
169     EXPECT_FALSE(items[0].key.has_value());
170     ASSERT_TRUE(items[0].thread_id.has_value());
171     EXPECT_EQ(PlatformThread::CurrentId(), *items[0].thread_id);
172     EXPECT_EQ(20, items[0].value);
173   }
174   {
175     item_count = MetadataRecorder::MetadataProvider(&recorder, kInvalidThreadId)
176                      .GetItems(&items);
177     EXPECT_EQ(0U, item_count);
178   }
179 }
180
181 TEST(MetadataRecorderTest, Set_NulloptThreadAndNonNulloptThread) {
182   MetadataRecorder recorder;
183
184   recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
185   recorder.Set(10, absl::nullopt, absl::nullopt, 30);
186
187   MetadataRecorder::ItemArray items;
188   size_t item_count =
189       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
190           .GetItems(&items);
191   ASSERT_EQ(2u, item_count);
192   EXPECT_EQ(10u, items[0].name_hash);
193   EXPECT_FALSE(items[0].key.has_value());
194   ASSERT_TRUE(items[0].thread_id.has_value());
195   EXPECT_EQ(PlatformThread::CurrentId(), *items[0].thread_id);
196   EXPECT_EQ(20, items[0].value);
197
198   EXPECT_EQ(10u, items[1].name_hash);
199   EXPECT_FALSE(items[1].key.has_value());
200   EXPECT_FALSE(items[1].thread_id.has_value());
201   EXPECT_EQ(30, items[1].value);
202 }
203
204 TEST(MetadataRecorderTest, Remove) {
205   MetadataRecorder recorder;
206   recorder.Set(10, absl::nullopt, absl::nullopt, 20);
207   recorder.Set(30, absl::nullopt, absl::nullopt, 40);
208   recorder.Set(50, absl::nullopt, absl::nullopt, 60);
209   recorder.Remove(30, absl::nullopt, absl::nullopt);
210
211   MetadataRecorder::ItemArray items;
212   size_t item_count =
213       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
214           .GetItems(&items);
215   ASSERT_EQ(2u, item_count);
216   EXPECT_EQ(10u, items[0].name_hash);
217   EXPECT_FALSE(items[0].key.has_value());
218   EXPECT_EQ(20, items[0].value);
219   EXPECT_EQ(50u, items[1].name_hash);
220   EXPECT_FALSE(items[1].key.has_value());
221   EXPECT_EQ(60, items[1].value);
222 }
223
224 TEST(MetadataRecorderTest, Remove_DoesntExist) {
225   MetadataRecorder recorder;
226   recorder.Set(10, absl::nullopt, absl::nullopt, 20);
227   recorder.Remove(20, absl::nullopt, absl::nullopt);
228
229   MetadataRecorder::ItemArray items;
230   size_t item_count =
231       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
232           .GetItems(&items);
233   ASSERT_EQ(1u, item_count);
234   EXPECT_EQ(10u, items[0].name_hash);
235   EXPECT_FALSE(items[0].key.has_value());
236   EXPECT_EQ(20, items[0].value);
237 }
238
239 TEST(MetadataRecorderTest, Remove_NulloptKeyIsIndependentOfNonNulloptKey) {
240   MetadataRecorder recorder;
241
242   recorder.Set(10, 100, absl::nullopt, 20);
243   recorder.Set(10, absl::nullopt, absl::nullopt, 30);
244
245   recorder.Remove(10, absl::nullopt, absl::nullopt);
246
247   MetadataRecorder::ItemArray items;
248   size_t item_count =
249       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
250           .GetItems(&items);
251   ASSERT_EQ(1u, item_count);
252   EXPECT_EQ(10u, items[0].name_hash);
253   ASSERT_TRUE(items[0].key.has_value());
254   EXPECT_EQ(100, *items[0].key);
255   EXPECT_EQ(20, items[0].value);
256 }
257
258 TEST(MetadataRecorderTest,
259      Remove_NulloptThreadIsIndependentOfNonNulloptThread) {
260   MetadataRecorder recorder;
261
262   recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
263   recorder.Set(10, absl::nullopt, absl::nullopt, 30);
264
265   recorder.Remove(10, absl::nullopt, absl::nullopt);
266
267   MetadataRecorder::ItemArray items;
268   size_t item_count =
269       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
270           .GetItems(&items);
271   ASSERT_EQ(1u, item_count);
272   EXPECT_EQ(10u, items[0].name_hash);
273   EXPECT_FALSE(items[0].key.has_value());
274   ASSERT_TRUE(items[0].thread_id.has_value());
275   EXPECT_EQ(PlatformThread::CurrentId(), *items[0].thread_id);
276   EXPECT_EQ(20, items[0].value);
277 }
278
279 TEST(MetadataRecorderTest, ReclaimInactiveSlots) {
280   MetadataRecorder recorder;
281
282   std::set<MetadataRecorder::Item> items_set;
283   // Fill up the metadata map.
284   for (size_t i = 0; i < MetadataRecorder::MAX_METADATA_COUNT; ++i) {
285     recorder.Set(i, absl::nullopt, absl::nullopt, i);
286     items_set.insert(MetadataRecorder::Item{i, absl::nullopt, absl::nullopt,
287                                             static_cast<int64_t>(i)});
288   }
289
290   // Remove every fourth entry to fragment the data.
291   size_t entries_removed = 0;
292   for (size_t i = 3; i < MetadataRecorder::MAX_METADATA_COUNT; i += 4) {
293     recorder.Remove(i, absl::nullopt, absl::nullopt);
294     ++entries_removed;
295     items_set.erase(MetadataRecorder::Item{i, absl::nullopt, absl::nullopt,
296                                            static_cast<int64_t>(i)});
297   }
298
299   // Ensure that the inactive slots are reclaimed to make room for more entries.
300   for (size_t i = 1; i <= entries_removed; ++i) {
301     recorder.Set(i * 100, absl::nullopt, absl::nullopt, i * 100);
302     items_set.insert(MetadataRecorder::Item{
303         i * 100, absl::nullopt, absl::nullopt, static_cast<int64_t>(i * 100)});
304   }
305
306   MetadataRecorder::ItemArray items_arr;
307   ranges::copy(items_set, items_arr.begin());
308
309   MetadataRecorder::ItemArray recorder_items;
310   size_t recorder_item_count =
311       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
312           .GetItems(&recorder_items);
313   EXPECT_EQ(recorder_item_count, MetadataRecorder::MAX_METADATA_COUNT);
314   EXPECT_THAT(recorder_items, ::testing::UnorderedElementsAreArray(items_arr));
315 }
316
317 }  // namespace base