• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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/metrics/persistent_sample_map.h"
6 
7 #include <memory>
8 
9 #include "base/memory/ptr_util.h"
10 #include "base/metrics/persistent_histogram_allocator.h"
11 #include "base/test/gtest_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace base {
15 namespace {
16 
CreateHistogramAllocator(size_t bytes)17 std::unique_ptr<PersistentHistogramAllocator> CreateHistogramAllocator(
18     size_t bytes) {
19   return std::make_unique<PersistentHistogramAllocator>(
20       std::make_unique<LocalPersistentMemoryAllocator>(bytes, 0, ""));
21 }
22 
DuplicateHistogramAllocator(PersistentHistogramAllocator * original)23 std::unique_ptr<PersistentHistogramAllocator> DuplicateHistogramAllocator(
24     PersistentHistogramAllocator* original) {
25   return std::make_unique<PersistentHistogramAllocator>(
26       std::make_unique<PersistentMemoryAllocator>(
27           const_cast<void*>(original->data()), original->length(), 0,
28           original->Id(), original->Name(),
29           PersistentMemoryAllocator::kReadWrite));
30 }
31 
TEST(PersistentSampleMapTest,AccumulateTest)32 TEST(PersistentSampleMapTest, AccumulateTest) {
33   std::unique_ptr<PersistentHistogramAllocator> allocator =
34       CreateHistogramAllocator(64 << 10);  // 64 KiB
35   HistogramSamples::LocalMetadata meta;
36   PersistentSampleMap samples(1, allocator.get(), &meta);
37 
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 
TEST(PersistentSampleMapTest,Accumulate_LargeValuesDontOverflow)49 TEST(PersistentSampleMapTest, Accumulate_LargeValuesDontOverflow) {
50   std::unique_ptr<PersistentHistogramAllocator> allocator =
51       CreateHistogramAllocator(64 << 10);  // 64 KiB
52   HistogramSamples::LocalMetadata meta;
53   PersistentSampleMap samples(1, allocator.get(), &meta);
54 
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 
TEST(PersistentSampleMapTest,AddSubtractTest)66 TEST(PersistentSampleMapTest, AddSubtractTest) {
67   std::unique_ptr<PersistentHistogramAllocator> allocator1 =
68       CreateHistogramAllocator(64 << 10);  // 64 KiB
69   HistogramSamples::LocalMetadata meta1;
70   PersistentSampleMap samples1(1, allocator1.get(), &meta1);
71   samples1.Accumulate(1, 100);
72   samples1.Accumulate(2, 100);
73   samples1.Accumulate(3, 100);
74 
75   std::unique_ptr<PersistentHistogramAllocator> allocator2 =
76       DuplicateHistogramAllocator(allocator1.get());
77   HistogramSamples::LocalMetadata meta2;
78   PersistentSampleMap samples2(2, allocator2.get(), &meta2);
79   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 
TEST(PersistentSampleMapTest,PersistenceTest)102 TEST(PersistentSampleMapTest, PersistenceTest) {
103   std::unique_ptr<PersistentHistogramAllocator> allocator1 =
104       CreateHistogramAllocator(64 << 10);  // 64 KiB
105   HistogramSamples::LocalMetadata meta12;
106   PersistentSampleMap samples1(12, allocator1.get(), &meta12);
107   samples1.Accumulate(1, 100);
108   samples1.Accumulate(2, 200);
109   samples1.Accumulate(1, -200);
110   samples1.Accumulate(-1, 1);
111   EXPECT_EQ(-100, samples1.GetCount(1));
112   EXPECT_EQ(200, samples1.GetCount(2));
113   EXPECT_EQ(1, samples1.GetCount(-1));
114   EXPECT_EQ(299, samples1.sum());
115   EXPECT_EQ(101, samples1.TotalCount());
116   EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
117 
118   std::unique_ptr<PersistentHistogramAllocator> allocator2 =
119       DuplicateHistogramAllocator(allocator1.get());
120   PersistentSampleMap samples2(12, allocator2.get(), &meta12);
121   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));
127   EXPECT_EQ(1, samples2.GetCount(-1));
128   EXPECT_EQ(299, samples2.sum());
129   EXPECT_EQ(101, samples2.TotalCount());
130   EXPECT_EQ(samples2.redundant_count(), samples2.TotalCount());
131 
132   samples1.Accumulate(-1, -1);
133   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());
141 
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());
153 }
154 
TEST(PersistentSampleMapIteratorTest,IterateTest)155 TEST(PersistentSampleMapIteratorTest, IterateTest) {
156   std::unique_ptr<PersistentHistogramAllocator> allocator =
157       CreateHistogramAllocator(64 << 10);  // 64 KiB
158   HistogramSamples::LocalMetadata meta;
159   PersistentSampleMap samples(1, allocator.get(), &meta);
160   samples.Accumulate(1, 100);
161   samples.Accumulate(2, 200);
162   samples.Accumulate(4, -300);
163   samples.Accumulate(5, 0);
164 
165   std::unique_ptr<SampleCountIterator> it = samples.Iterator();
166 
167   HistogramBase::Sample min;
168   int64_t max;
169   HistogramBase::Count count;
170 
171   it->Get(&min, &max, &count);
172   EXPECT_EQ(1, min);
173   EXPECT_EQ(2, max);
174   EXPECT_EQ(100, count);
175   EXPECT_FALSE(it->GetBucketIndex(nullptr));
176 
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 
TEST(PersistentSampleMapIteratorTest,SkipEmptyRanges)193 TEST(PersistentSampleMapIteratorTest, SkipEmptyRanges) {
194   std::unique_ptr<PersistentHistogramAllocator> allocator1 =
195       CreateHistogramAllocator(64 << 10);  // 64 KiB
196   HistogramSamples::LocalMetadata meta1;
197   PersistentSampleMap samples1(1, allocator1.get(), &meta1);
198   samples1.Accumulate(5, 1);
199   samples1.Accumulate(10, 2);
200   samples1.Accumulate(15, 3);
201   samples1.Accumulate(20, 4);
202   samples1.Accumulate(25, 5);
203 
204   std::unique_ptr<PersistentHistogramAllocator> allocator2 =
205       DuplicateHistogramAllocator(allocator1.get());
206   HistogramSamples::LocalMetadata meta2;
207   PersistentSampleMap samples2(2, allocator2.get(), &meta2);
208   samples2.Accumulate(5, 1);
209   samples2.Accumulate(20, 4);
210   samples2.Accumulate(25, 5);
211 
212   samples1.Subtract(samples2);
213 
214   std::unique_ptr<SampleCountIterator> it = samples1.Iterator();
215   EXPECT_FALSE(it->Done());
216 
217   HistogramBase::Sample min;
218   int64_t max;
219   HistogramBase::Count count;
220 
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 
TEST(PersistentSampleMapIteratorDeathTest,IterateDoneTest)238 TEST(PersistentSampleMapIteratorDeathTest, IterateDoneTest) {
239   std::unique_ptr<PersistentHistogramAllocator> allocator =
240       CreateHistogramAllocator(64 << 10);  // 64 KiB
241   HistogramSamples::LocalMetadata meta;
242   PersistentSampleMap samples(1, allocator.get(), &meta);
243 
244   std::unique_ptr<SampleCountIterator> it = samples.Iterator();
245 
246   EXPECT_TRUE(it->Done());
247 
248   HistogramBase::Sample min;
249   int64_t max;
250   HistogramBase::Count count;
251   EXPECT_DCHECK_DEATH(it->Get(&min, &max, &count));
252 
253   EXPECT_DCHECK_DEATH(it->Next());
254 
255   samples.Accumulate(1, 100);
256   it = samples.Iterator();
257   EXPECT_FALSE(it->Done());
258 }
259 
260 }  // namespace
261 }  // namespace base
262