blob: 728413f7c21b7c94ffe2cefc40f191ab481da06d [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2016 The Chromium Authors
bcwhite3dd85c4f2016-03-17 13:21:562// 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/metrics/persistent_sample_map.h"
6
dcheng093de9b2016-04-04 21:25:517#include <memory>
8
bcwhite1d02f432016-04-28 18:59:539#include "base/memory/ptr_util.h"
bcwhiteb0bb9192016-04-18 01:33:1010#include "base/metrics/persistent_histogram_allocator.h"
gabc964a852016-08-01 16:39:5611#include "base/test/gtest_util.h"
bcwhite3dd85c4f2016-03-17 13:21:5612#include "testing/gtest/include/gtest/gtest.h"
13
14namespace base {
15namespace {
16
bcwhite1d02f432016-04-28 18:59:5317std::unique_ptr<PersistentHistogramAllocator> CreateHistogramAllocator(
18 size_t bytes) {
Jeremy Roman9532f252017-08-16 23:27:2419 return std::make_unique<PersistentHistogramAllocator>(
20 std::make_unique<LocalPersistentMemoryAllocator>(bytes, 0, ""));
bcwhite1d02f432016-04-28 18:59:5321}
bcwhite3dd85c4f2016-03-17 13:21:5622
bcwhite1d02f432016-04-28 18:59:5323std::unique_ptr<PersistentHistogramAllocator> DuplicateHistogramAllocator(
24 PersistentHistogramAllocator* original) {
Jeremy Roman9532f252017-08-16 23:27:2425 return std::make_unique<PersistentHistogramAllocator>(
26 std::make_unique<PersistentMemoryAllocator>(
bcwhite1d02f432016-04-28 18:59:5327 const_cast<void*>(original->data()), original->length(), 0,
Alexei Svitkine50fa8122023-08-29 21:01:5828 original->Id(), original->Name(),
29 PersistentMemoryAllocator::kReadWrite));
bcwhite1d02f432016-04-28 18:59:5330}
31
32TEST(PersistentSampleMapTest, AccumulateTest) {
33 std::unique_ptr<PersistentHistogramAllocator> allocator =
34 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:2935 HistogramSamples::LocalMetadata meta;
bcwhite1d02f432016-04-28 18:59:5336 PersistentSampleMap samples(1, allocator.get(), &meta);
bcwhite3dd85c4f2016-03-17 13:21:5637
38 samples.Accumulate(1, 100);
39 samples.Accumulate(2, 200);
40 samples.Accumulate(1, -200);
41 EXPECT_EQ(-100, samples.GetCount(1));
42 EXPECT_EQ(200, samples.GetCount(2));
43
44 EXPECT_EQ(300, samples.sum());
45 EXPECT_EQ(100, samples.TotalCount());
46 EXPECT_EQ(samples.redundant_count(), samples.TotalCount());
47}
48
49TEST(PersistentSampleMapTest, Accumulate_LargeValuesDontOverflow) {
bcwhite1d02f432016-04-28 18:59:5350 std::unique_ptr<PersistentHistogramAllocator> allocator =
51 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:2952 HistogramSamples::LocalMetadata meta;
bcwhite1d02f432016-04-28 18:59:5353 PersistentSampleMap samples(1, allocator.get(), &meta);
bcwhite3dd85c4f2016-03-17 13:21:5654
55 samples.Accumulate(250000000, 100);
56 samples.Accumulate(500000000, 200);
57 samples.Accumulate(250000000, -200);
58 EXPECT_EQ(-100, samples.GetCount(250000000));
59 EXPECT_EQ(200, samples.GetCount(500000000));
60
61 EXPECT_EQ(75000000000LL, samples.sum());
62 EXPECT_EQ(100, samples.TotalCount());
63 EXPECT_EQ(samples.redundant_count(), samples.TotalCount());
64}
65
66TEST(PersistentSampleMapTest, AddSubtractTest) {
bcwhite1d02f432016-04-28 18:59:5367 std::unique_ptr<PersistentHistogramAllocator> allocator1 =
68 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:2969 HistogramSamples::LocalMetadata meta1;
bcwhite1d02f432016-04-28 18:59:5370 PersistentSampleMap samples1(1, allocator1.get(), &meta1);
bcwhite3dd85c4f2016-03-17 13:21:5671 samples1.Accumulate(1, 100);
72 samples1.Accumulate(2, 100);
73 samples1.Accumulate(3, 100);
74
bcwhite1d02f432016-04-28 18:59:5375 std::unique_ptr<PersistentHistogramAllocator> allocator2 =
76 DuplicateHistogramAllocator(allocator1.get());
piman03cd21b2016-11-22 21:03:2977 HistogramSamples::LocalMetadata meta2;
bcwhite1d02f432016-04-28 18:59:5378 PersistentSampleMap samples2(2, allocator2.get(), &meta2);
bcwhite3dd85c4f2016-03-17 13:21:5679 samples2.Accumulate(1, 200);
80 samples2.Accumulate(2, 200);
81 samples2.Accumulate(4, 200);
82
83 samples1.Add(samples2);
84 EXPECT_EQ(300, samples1.GetCount(1));
85 EXPECT_EQ(300, samples1.GetCount(2));
86 EXPECT_EQ(100, samples1.GetCount(3));
87 EXPECT_EQ(200, samples1.GetCount(4));
88 EXPECT_EQ(2000, samples1.sum());
89 EXPECT_EQ(900, samples1.TotalCount());
90 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
91
92 samples1.Subtract(samples2);
93 EXPECT_EQ(100, samples1.GetCount(1));
94 EXPECT_EQ(100, samples1.GetCount(2));
95 EXPECT_EQ(100, samples1.GetCount(3));
96 EXPECT_EQ(0, samples1.GetCount(4));
97 EXPECT_EQ(600, samples1.sum());
98 EXPECT_EQ(300, samples1.TotalCount());
99 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
100}
101
102TEST(PersistentSampleMapTest, PersistenceTest) {
bcwhite1d02f432016-04-28 18:59:53103 std::unique_ptr<PersistentHistogramAllocator> allocator1 =
104 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:29105 HistogramSamples::LocalMetadata meta12;
bcwhite1d02f432016-04-28 18:59:53106 PersistentSampleMap samples1(12, allocator1.get(), &meta12);
bcwhite3dd85c4f2016-03-17 13:21:56107 samples1.Accumulate(1, 100);
108 samples1.Accumulate(2, 200);
109 samples1.Accumulate(1, -200);
bcwhite82b10a43c2016-04-21 13:39:07110 samples1.Accumulate(-1, 1);
bcwhite3dd85c4f2016-03-17 13:21:56111 EXPECT_EQ(-100, samples1.GetCount(1));
112 EXPECT_EQ(200, samples1.GetCount(2));
bcwhite82b10a43c2016-04-21 13:39:07113 EXPECT_EQ(1, samples1.GetCount(-1));
114 EXPECT_EQ(299, samples1.sum());
115 EXPECT_EQ(101, samples1.TotalCount());
bcwhite3dd85c4f2016-03-17 13:21:56116 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
117
bcwhite1d02f432016-04-28 18:59:53118 std::unique_ptr<PersistentHistogramAllocator> allocator2 =
119 DuplicateHistogramAllocator(allocator1.get());
120 PersistentSampleMap samples2(12, allocator2.get(), &meta12);
bcwhite3dd85c4f2016-03-17 13:21:56121 EXPECT_EQ(samples1.id(), samples2.id());
122 EXPECT_EQ(samples1.sum(), samples2.sum());
123 EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count());
124 EXPECT_EQ(samples1.TotalCount(), samples2.TotalCount());
125 EXPECT_EQ(-100, samples2.GetCount(1));
126 EXPECT_EQ(200, samples2.GetCount(2));
bcwhite82b10a43c2016-04-21 13:39:07127 EXPECT_EQ(1, samples2.GetCount(-1));
128 EXPECT_EQ(299, samples2.sum());
129 EXPECT_EQ(101, samples2.TotalCount());
bcwhite3dd85c4f2016-03-17 13:21:56130 EXPECT_EQ(samples2.redundant_count(), samples2.TotalCount());
131
bcwhite82b10a43c2016-04-21 13:39:07132 samples1.Accumulate(-1, -1);
bcwhite3dd85c4f2016-03-17 13:21:56133 EXPECT_EQ(0, samples2.GetCount(3));
134 EXPECT_EQ(0, samples1.GetCount(3));
135 samples2.Accumulate(3, 300);
136 EXPECT_EQ(300, samples2.GetCount(3));
137 EXPECT_EQ(300, samples1.GetCount(3));
138 EXPECT_EQ(samples1.sum(), samples2.sum());
139 EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count());
140 EXPECT_EQ(samples1.TotalCount(), samples2.TotalCount());
bcwhiteb0bb9192016-04-18 01:33:10141
142 EXPECT_EQ(0, samples2.GetCount(4));
143 EXPECT_EQ(0, samples1.GetCount(4));
144 samples1.Accumulate(4, 400);
145 EXPECT_EQ(400, samples2.GetCount(4));
146 EXPECT_EQ(400, samples1.GetCount(4));
147 samples2.Accumulate(4, 4000);
148 EXPECT_EQ(4400, samples2.GetCount(4));
149 EXPECT_EQ(4400, samples1.GetCount(4));
150 EXPECT_EQ(samples1.sum(), samples2.sum());
151 EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count());
152 EXPECT_EQ(samples1.TotalCount(), samples2.TotalCount());
bcwhite3dd85c4f2016-03-17 13:21:56153}
154
155TEST(PersistentSampleMapIteratorTest, IterateTest) {
bcwhite1d02f432016-04-28 18:59:53156 std::unique_ptr<PersistentHistogramAllocator> allocator =
157 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:29158 HistogramSamples::LocalMetadata meta;
bcwhite1d02f432016-04-28 18:59:53159 PersistentSampleMap samples(1, allocator.get(), &meta);
bcwhite3dd85c4f2016-03-17 13:21:56160 samples.Accumulate(1, 100);
161 samples.Accumulate(2, 200);
162 samples.Accumulate(4, -300);
163 samples.Accumulate(5, 0);
164
dcheng093de9b2016-04-04 21:25:51165 std::unique_ptr<SampleCountIterator> it = samples.Iterator();
bcwhite3dd85c4f2016-03-17 13:21:56166
Ramon Cano Aparicio79e06642025-01-09 19:10:22167 HistogramBase::Sample32 min;
asvitkine3f17b1462017-05-03 21:37:37168 int64_t max;
Ramon Cano Aparicio1a549ea2025-01-24 13:45:06169 HistogramBase::Count32 count;
bcwhite3dd85c4f2016-03-17 13:21:56170
171 it->Get(&min, &max, &count);
172 EXPECT_EQ(1, min);
173 EXPECT_EQ(2, max);
174 EXPECT_EQ(100, count);
Ivan Kotenkova16212a52017-11-08 12:37:33175 EXPECT_FALSE(it->GetBucketIndex(nullptr));
bcwhite3dd85c4f2016-03-17 13:21:56176
177 it->Next();
178 it->Get(&min, &max, &count);
179 EXPECT_EQ(2, min);
180 EXPECT_EQ(3, max);
181 EXPECT_EQ(200, count);
182
183 it->Next();
184 it->Get(&min, &max, &count);
185 EXPECT_EQ(4, min);
186 EXPECT_EQ(5, max);
187 EXPECT_EQ(-300, count);
188
189 it->Next();
190 EXPECT_TRUE(it->Done());
191}
192
193TEST(PersistentSampleMapIteratorTest, SkipEmptyRanges) {
bcwhite1d02f432016-04-28 18:59:53194 std::unique_ptr<PersistentHistogramAllocator> allocator1 =
195 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:29196 HistogramSamples::LocalMetadata meta1;
bcwhite1d02f432016-04-28 18:59:53197 PersistentSampleMap samples1(1, allocator1.get(), &meta1);
bcwhiteb0bb9192016-04-18 01:33:10198 samples1.Accumulate(5, 1);
199 samples1.Accumulate(10, 2);
200 samples1.Accumulate(15, 3);
201 samples1.Accumulate(20, 4);
202 samples1.Accumulate(25, 5);
bcwhite3dd85c4f2016-03-17 13:21:56203
bcwhite1d02f432016-04-28 18:59:53204 std::unique_ptr<PersistentHistogramAllocator> allocator2 =
205 DuplicateHistogramAllocator(allocator1.get());
piman03cd21b2016-11-22 21:03:29206 HistogramSamples::LocalMetadata meta2;
bcwhite1d02f432016-04-28 18:59:53207 PersistentSampleMap samples2(2, allocator2.get(), &meta2);
bcwhite3dd85c4f2016-03-17 13:21:56208 samples2.Accumulate(5, 1);
209 samples2.Accumulate(20, 4);
210 samples2.Accumulate(25, 5);
211
bcwhiteb0bb9192016-04-18 01:33:10212 samples1.Subtract(samples2);
bcwhite3dd85c4f2016-03-17 13:21:56213
bcwhiteb0bb9192016-04-18 01:33:10214 std::unique_ptr<SampleCountIterator> it = samples1.Iterator();
bcwhite3dd85c4f2016-03-17 13:21:56215 EXPECT_FALSE(it->Done());
216
Ramon Cano Aparicio79e06642025-01-09 19:10:22217 HistogramBase::Sample32 min;
asvitkine3f17b1462017-05-03 21:37:37218 int64_t max;
Ramon Cano Aparicio1a549ea2025-01-24 13:45:06219 HistogramBase::Count32 count;
bcwhite3dd85c4f2016-03-17 13:21:56220
221 it->Get(&min, &max, &count);
222 EXPECT_EQ(10, min);
223 EXPECT_EQ(11, max);
224 EXPECT_EQ(2, count);
225
226 it->Next();
227 EXPECT_FALSE(it->Done());
228
229 it->Get(&min, &max, &count);
230 EXPECT_EQ(15, min);
231 EXPECT_EQ(16, max);
232 EXPECT_EQ(3, count);
233
234 it->Next();
235 EXPECT_TRUE(it->Done());
236}
237
bcwhite3dd85c4f2016-03-17 13:21:56238TEST(PersistentSampleMapIteratorDeathTest, IterateDoneTest) {
bcwhite1d02f432016-04-28 18:59:53239 std::unique_ptr<PersistentHistogramAllocator> allocator =
240 CreateHistogramAllocator(64 << 10); // 64 KiB
piman03cd21b2016-11-22 21:03:29241 HistogramSamples::LocalMetadata meta;
bcwhite1d02f432016-04-28 18:59:53242 PersistentSampleMap samples(1, allocator.get(), &meta);
bcwhite3dd85c4f2016-03-17 13:21:56243
dcheng093de9b2016-04-04 21:25:51244 std::unique_ptr<SampleCountIterator> it = samples.Iterator();
bcwhite3dd85c4f2016-03-17 13:21:56245
246 EXPECT_TRUE(it->Done());
247
Ramon Cano Aparicio79e06642025-01-09 19:10:22248 HistogramBase::Sample32 min;
asvitkine3f17b1462017-05-03 21:37:37249 int64_t max;
Ramon Cano Aparicio1a549ea2025-01-24 13:45:06250 HistogramBase::Count32 count;
gab5e69cff2016-08-05 03:25:40251 EXPECT_DCHECK_DEATH(it->Get(&min, &max, &count));
bcwhite3dd85c4f2016-03-17 13:21:56252
gab5e69cff2016-08-05 03:25:40253 EXPECT_DCHECK_DEATH(it->Next());
bcwhite3dd85c4f2016-03-17 13:21:56254
255 samples.Accumulate(1, 100);
256 it = samples.Iterator();
257 EXPECT_FALSE(it->Done());
258}
bcwhite3dd85c4f2016-03-17 13:21:56259
260} // namespace
261} // namespace base