1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <limits.h>
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include <climits>
12*6777b538SAndroid Build Coastguard Worker #include <memory>
13*6777b538SAndroid Build Coastguard Worker #include <string>
14*6777b538SAndroid Build Coastguard Worker #include <vector>
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker #include "base/lazy_instance.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/metrics/bucket_ranges.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/metrics/dummy_histogram.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/metrics/metrics_hashes.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/metrics/persistent_histogram_allocator.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/metrics/persistent_memory_allocator.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/metrics/record_histogram_checker.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/metrics/sample_vector.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/metrics/statistics_recorder.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/pickle.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
33*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
34*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Worker namespace base {
37*6777b538SAndroid Build Coastguard Worker namespace {
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker const char kExpiredHistogramName[] = "ExpiredHistogram";
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker // Test implementation of RecordHistogramChecker interface.
42*6777b538SAndroid Build Coastguard Worker class TestRecordHistogramChecker : public RecordHistogramChecker {
43*6777b538SAndroid Build Coastguard Worker public:
44*6777b538SAndroid Build Coastguard Worker ~TestRecordHistogramChecker() override = default;
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker // RecordHistogramChecker:
ShouldRecord(uint32_t histogram_hash) const47*6777b538SAndroid Build Coastguard Worker bool ShouldRecord(uint32_t histogram_hash) const override {
48*6777b538SAndroid Build Coastguard Worker return histogram_hash != HashMetricNameAs32Bits(kExpiredHistogramName);
49*6777b538SAndroid Build Coastguard Worker }
50*6777b538SAndroid Build Coastguard Worker };
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker } // namespace
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker // Test parameter indicates if a persistent memory allocator should be used
55*6777b538SAndroid Build Coastguard Worker // for histogram allocation. False will allocate histograms from the process
56*6777b538SAndroid Build Coastguard Worker // heap.
57*6777b538SAndroid Build Coastguard Worker class HistogramTest : public testing::TestWithParam<bool> {
58*6777b538SAndroid Build Coastguard Worker public:
59*6777b538SAndroid Build Coastguard Worker HistogramTest(const HistogramTest&) = delete;
60*6777b538SAndroid Build Coastguard Worker HistogramTest& operator=(const HistogramTest&) = delete;
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker protected:
63*6777b538SAndroid Build Coastguard Worker using CountAndBucketData = base::Histogram::CountAndBucketData;
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker const int32_t kAllocatorMemorySize = 8 << 20; // 8 MiB
66*6777b538SAndroid Build Coastguard Worker
HistogramTest()67*6777b538SAndroid Build Coastguard Worker HistogramTest() : use_persistent_histogram_allocator_(GetParam()) {}
68*6777b538SAndroid Build Coastguard Worker
SetUp()69*6777b538SAndroid Build Coastguard Worker void SetUp() override {
70*6777b538SAndroid Build Coastguard Worker if (use_persistent_histogram_allocator_)
71*6777b538SAndroid Build Coastguard Worker CreatePersistentHistogramAllocator();
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker // Each test will have a clean state (no Histogram / BucketRanges
74*6777b538SAndroid Build Coastguard Worker // registered).
75*6777b538SAndroid Build Coastguard Worker InitializeStatisticsRecorder();
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker
TearDown()78*6777b538SAndroid Build Coastguard Worker void TearDown() override {
79*6777b538SAndroid Build Coastguard Worker if (allocator_) {
80*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(allocator_->IsFull());
81*6777b538SAndroid Build Coastguard Worker ASSERT_FALSE(allocator_->IsCorrupt());
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker UninitializeStatisticsRecorder();
84*6777b538SAndroid Build Coastguard Worker DestroyPersistentHistogramAllocator();
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker
InitializeStatisticsRecorder()87*6777b538SAndroid Build Coastguard Worker void InitializeStatisticsRecorder() {
88*6777b538SAndroid Build Coastguard Worker DCHECK(!statistics_recorder_);
89*6777b538SAndroid Build Coastguard Worker statistics_recorder_ = StatisticsRecorder::CreateTemporaryForTesting();
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
UninitializeStatisticsRecorder()92*6777b538SAndroid Build Coastguard Worker void UninitializeStatisticsRecorder() { statistics_recorder_.reset(); }
93*6777b538SAndroid Build Coastguard Worker
CreatePersistentHistogramAllocator()94*6777b538SAndroid Build Coastguard Worker void CreatePersistentHistogramAllocator() {
95*6777b538SAndroid Build Coastguard Worker GlobalHistogramAllocator::CreateWithLocalMemory(kAllocatorMemorySize, 0,
96*6777b538SAndroid Build Coastguard Worker "HistogramAllocatorTest");
97*6777b538SAndroid Build Coastguard Worker allocator_ = GlobalHistogramAllocator::Get()->memory_allocator();
98*6777b538SAndroid Build Coastguard Worker }
99*6777b538SAndroid Build Coastguard Worker
DestroyPersistentHistogramAllocator()100*6777b538SAndroid Build Coastguard Worker void DestroyPersistentHistogramAllocator() {
101*6777b538SAndroid Build Coastguard Worker allocator_ = nullptr;
102*6777b538SAndroid Build Coastguard Worker GlobalHistogramAllocator::ReleaseForTesting();
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker
SnapshotAllSamples(Histogram * h)105*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> SnapshotAllSamples(Histogram* h) {
106*6777b538SAndroid Build Coastguard Worker return h->SnapshotAllSamples();
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker
GetCountAndBucketData(Histogram * histogram)109*6777b538SAndroid Build Coastguard Worker CountAndBucketData GetCountAndBucketData(Histogram* histogram) {
110*6777b538SAndroid Build Coastguard Worker // A simple wrapper around |GetCountAndBucketData| to make it visible for
111*6777b538SAndroid Build Coastguard Worker // testing.
112*6777b538SAndroid Build Coastguard Worker return histogram->GetCountAndBucketData();
113*6777b538SAndroid Build Coastguard Worker }
114*6777b538SAndroid Build Coastguard Worker
115*6777b538SAndroid Build Coastguard Worker const bool use_persistent_histogram_allocator_;
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker std::unique_ptr<StatisticsRecorder> statistics_recorder_;
118*6777b538SAndroid Build Coastguard Worker std::unique_ptr<char[]> allocator_memory_;
119*6777b538SAndroid Build Coastguard Worker raw_ptr<PersistentMemoryAllocator> allocator_ = nullptr;
120*6777b538SAndroid Build Coastguard Worker };
121*6777b538SAndroid Build Coastguard Worker
122*6777b538SAndroid Build Coastguard Worker // Run all HistogramTest cases with both heap and persistent memory.
123*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(HeapAndPersistent, HistogramTest, testing::Bool());
124*6777b538SAndroid Build Coastguard Worker
125*6777b538SAndroid Build Coastguard Worker // Check for basic syntax and use.
TEST_P(HistogramTest,BasicTest)126*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, BasicTest) {
127*6777b538SAndroid Build Coastguard Worker // Try basic construction
128*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet("TestHistogram", 1, 1000, 10,
129*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
130*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram);
131*6777b538SAndroid Build Coastguard Worker
132*6777b538SAndroid Build Coastguard Worker HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
133*6777b538SAndroid Build Coastguard Worker "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
134*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(linear_histogram);
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker std::vector<int> custom_ranges;
137*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(1);
138*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(5);
139*6777b538SAndroid Build Coastguard Worker HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
140*6777b538SAndroid Build Coastguard Worker "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
141*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(custom_histogram);
142*6777b538SAndroid Build Coastguard Worker
143*6777b538SAndroid Build Coastguard Worker // Macros that create histograms have an internal static variable which will
144*6777b538SAndroid Build Coastguard Worker // continue to point to those from the very first run of this method even
145*6777b538SAndroid Build Coastguard Worker // during subsequent runs.
146*6777b538SAndroid Build Coastguard Worker static bool already_run = false;
147*6777b538SAndroid Build Coastguard Worker if (already_run)
148*6777b538SAndroid Build Coastguard Worker return;
149*6777b538SAndroid Build Coastguard Worker already_run = true;
150*6777b538SAndroid Build Coastguard Worker
151*6777b538SAndroid Build Coastguard Worker // Use standard macros (but with fixed samples)
152*6777b538SAndroid Build Coastguard Worker LOCAL_HISTOGRAM_TIMES("Test2Histogram", Days(1));
153*6777b538SAndroid Build Coastguard Worker LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30);
154*6777b538SAndroid Build Coastguard Worker
155*6777b538SAndroid Build Coastguard Worker LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
156*6777b538SAndroid Build Coastguard Worker }
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker // Check that the macro correctly matches histograms by name and records their
159*6777b538SAndroid Build Coastguard Worker // data together.
TEST_P(HistogramTest,NameMatchTest)160*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, NameMatchTest) {
161*6777b538SAndroid Build Coastguard Worker // Macros that create histograms have an internal static variable which will
162*6777b538SAndroid Build Coastguard Worker // continue to point to those from the very first run of this method even
163*6777b538SAndroid Build Coastguard Worker // during subsequent runs.
164*6777b538SAndroid Build Coastguard Worker static bool already_run = false;
165*6777b538SAndroid Build Coastguard Worker if (already_run)
166*6777b538SAndroid Build Coastguard Worker return;
167*6777b538SAndroid Build Coastguard Worker already_run = true;
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
170*6777b538SAndroid Build Coastguard Worker LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
171*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = LinearHistogram::FactoryGet(
172*6777b538SAndroid Build Coastguard Worker "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags);
173*6777b538SAndroid Build Coastguard Worker
174*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
175*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->TotalCount());
176*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCount(10));
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker // Check that delta calculations work correctly.
TEST_P(HistogramTest,DeltaTest)180*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, DeltaTest) {
181*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet("DeltaHistogram", 1, 64, 8,
182*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
183*6777b538SAndroid Build Coastguard Worker histogram->Add(1);
184*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
185*6777b538SAndroid Build Coastguard Worker histogram->Add(50);
186*6777b538SAndroid Build Coastguard Worker
187*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
188*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->TotalCount());
189*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(1));
190*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(10));
191*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
192*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
193*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(61, samples->sum());
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotDelta();
196*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
197*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->sum());
198*6777b538SAndroid Build Coastguard Worker
199*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
200*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
201*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotDelta();
202*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->TotalCount());
203*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCount(10));
204*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(20, samples->sum());
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotDelta();
207*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
208*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->sum());
209*6777b538SAndroid Build Coastguard Worker
210*6777b538SAndroid Build Coastguard Worker // Verify that the logged samples contain everything emitted.
211*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotSamples();
212*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5, samples->TotalCount());
213*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
214*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(1));
215*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->GetCount(10));
216*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
217*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(81, samples->sum());
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker
220*6777b538SAndroid Build Coastguard Worker // Check that delta calculations work correctly with SnapshotUnloggedSamples()
221*6777b538SAndroid Build Coastguard Worker // and MarkSamplesAsLogged().
TEST_P(HistogramTest,UnloggedSamplesTest)222*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, UnloggedSamplesTest) {
223*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet("DeltaHistogram", 1, 64, 8,
224*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
225*6777b538SAndroid Build Coastguard Worker histogram->Add(1);
226*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
227*6777b538SAndroid Build Coastguard Worker histogram->Add(50);
228*6777b538SAndroid Build Coastguard Worker
229*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples =
230*6777b538SAndroid Build Coastguard Worker histogram->SnapshotUnloggedSamples();
231*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->TotalCount());
232*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(1));
233*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(10));
234*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
235*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
236*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(61, samples->sum());
237*6777b538SAndroid Build Coastguard Worker
238*6777b538SAndroid Build Coastguard Worker // Snapshot unlogged samples again, which would be the same as above.
239*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotUnloggedSamples();
240*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->TotalCount());
241*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(1));
242*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(10));
243*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
244*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
245*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(61, samples->sum());
246*6777b538SAndroid Build Coastguard Worker
247*6777b538SAndroid Build Coastguard Worker // Verify that marking the samples as logged works correctly, and that
248*6777b538SAndroid Build Coastguard Worker // SnapshotDelta() will not pick up the samples.
249*6777b538SAndroid Build Coastguard Worker histogram->MarkSamplesAsLogged(*samples);
250*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotUnloggedSamples();
251*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
252*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
253*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->sum());
254*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotDelta();
255*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
256*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
257*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->sum());
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker // Similarly, verify that SnapshotDelta() marks the samples as logged.
260*6777b538SAndroid Build Coastguard Worker histogram->Add(1);
261*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
262*6777b538SAndroid Build Coastguard Worker histogram->Add(50);
263*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotDelta();
264*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->TotalCount());
265*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(1));
266*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(10));
267*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
268*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
269*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(61, samples->sum());
270*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotUnloggedSamples();
271*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
272*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
273*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->sum());
274*6777b538SAndroid Build Coastguard Worker
275*6777b538SAndroid Build Coastguard Worker // Verify that the logged samples contain everything emitted.
276*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotSamples();
277*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(6, samples->TotalCount());
278*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
279*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCount(1));
280*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCount(10));
281*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCount(50));
282*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(122, samples->sum());
283*6777b538SAndroid Build Coastguard Worker }
284*6777b538SAndroid Build Coastguard Worker
285*6777b538SAndroid Build Coastguard Worker // Check that final-delta calculations work correctly.
TEST_P(HistogramTest,FinalDeltaTest)286*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, FinalDeltaTest) {
287*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet("FinalDeltaHistogram", 1, 64,
288*6777b538SAndroid Build Coastguard Worker 8, HistogramBase::kNoFlags);
289*6777b538SAndroid Build Coastguard Worker histogram->Add(1);
290*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
291*6777b538SAndroid Build Coastguard Worker histogram->Add(50);
292*6777b538SAndroid Build Coastguard Worker
293*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
294*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->TotalCount());
295*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(1));
296*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(10));
297*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
298*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
299*6777b538SAndroid Build Coastguard Worker
300*6777b538SAndroid Build Coastguard Worker histogram->Add(2);
301*6777b538SAndroid Build Coastguard Worker histogram->Add(50);
302*6777b538SAndroid Build Coastguard Worker
303*6777b538SAndroid Build Coastguard Worker samples = histogram->SnapshotFinalDelta();
304*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->TotalCount());
305*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(2));
306*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCount(50));
307*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
308*6777b538SAndroid Build Coastguard Worker }
309*6777b538SAndroid Build Coastguard Worker
310*6777b538SAndroid Build Coastguard Worker // Check that IsDefinitelyEmpty() works with the results of SnapshotDelta().
TEST_P(HistogramTest,IsDefinitelyEmpty_SnapshotDelta)311*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, IsDefinitelyEmpty_SnapshotDelta) {
312*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet("DeltaHistogram", 1, 64, 8,
313*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
314*6777b538SAndroid Build Coastguard Worker // No samples initially.
315*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
316*6777b538SAndroid Build Coastguard Worker
317*6777b538SAndroid Build Coastguard Worker // Verify when |histogram| is using SingleSample.
318*6777b538SAndroid Build Coastguard Worker histogram->Add(1);
319*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
320*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
321*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
322*6777b538SAndroid Build Coastguard Worker histogram->Add(10);
323*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
324*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
325*6777b538SAndroid Build Coastguard Worker
326*6777b538SAndroid Build Coastguard Worker // Verify when |histogram| uses a counts array instead of SingleSample.
327*6777b538SAndroid Build Coastguard Worker histogram->Add(1);
328*6777b538SAndroid Build Coastguard Worker histogram->Add(50);
329*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
330*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram->SnapshotDelta()->IsDefinitelyEmpty());
331*6777b538SAndroid Build Coastguard Worker }
332*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,ExponentialRangesTest)333*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, ExponentialRangesTest) {
334*6777b538SAndroid Build Coastguard Worker // Check that we got a nice exponential when there was enough room.
335*6777b538SAndroid Build Coastguard Worker BucketRanges ranges(9);
336*6777b538SAndroid Build Coastguard Worker Histogram::InitializeBucketRanges(1, 64, &ranges);
337*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges.range(0));
338*6777b538SAndroid Build Coastguard Worker int power_of_2 = 1;
339*6777b538SAndroid Build Coastguard Worker for (int i = 1; i < 8; i++) {
340*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(power_of_2, ranges.range(i));
341*6777b538SAndroid Build Coastguard Worker power_of_2 *= 2;
342*6777b538SAndroid Build Coastguard Worker }
343*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker // Check the corresponding Histogram will use the correct ranges.
346*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(
347*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
348*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
349*6777b538SAndroid Build Coastguard Worker
350*6777b538SAndroid Build Coastguard Worker // When bucket count is limited, exponential ranges will partially look like
351*6777b538SAndroid Build Coastguard Worker // linear.
352*6777b538SAndroid Build Coastguard Worker BucketRanges ranges2(16);
353*6777b538SAndroid Build Coastguard Worker Histogram::InitializeBucketRanges(1, 32, &ranges2);
354*6777b538SAndroid Build Coastguard Worker
355*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges2.range(0));
356*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, ranges2.range(1));
357*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, ranges2.range(2));
358*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, ranges2.range(3));
359*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, ranges2.range(4));
360*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5, ranges2.range(5));
361*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(6, ranges2.range(6));
362*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(7, ranges2.range(7));
363*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(9, ranges2.range(8));
364*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(11, ranges2.range(9));
365*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(14, ranges2.range(10));
366*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(17, ranges2.range(11));
367*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(21, ranges2.range(12));
368*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(26, ranges2.range(13));
369*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(32, ranges2.range(14));
370*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(15));
371*6777b538SAndroid Build Coastguard Worker
372*6777b538SAndroid Build Coastguard Worker // Check the corresponding Histogram will use the correct ranges.
373*6777b538SAndroid Build Coastguard Worker Histogram* histogram2 = static_cast<Histogram*>(
374*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("Histogram2", 1, 32, 15, HistogramBase::kNoFlags));
375*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
376*6777b538SAndroid Build Coastguard Worker }
377*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,LinearRangesTest)378*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, LinearRangesTest) {
379*6777b538SAndroid Build Coastguard Worker BucketRanges ranges(9);
380*6777b538SAndroid Build Coastguard Worker LinearHistogram::InitializeBucketRanges(1, 7, &ranges);
381*6777b538SAndroid Build Coastguard Worker // Gets a nice linear set of bucket ranges.
382*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < 8; i++)
383*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(i, ranges.range(i));
384*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
385*6777b538SAndroid Build Coastguard Worker
386*6777b538SAndroid Build Coastguard Worker // The correspoding LinearHistogram should use the correct ranges.
387*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(
388*6777b538SAndroid Build Coastguard Worker LinearHistogram::FactoryGet("Linear", 1, 7, 8, HistogramBase::kNoFlags));
389*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
390*6777b538SAndroid Build Coastguard Worker
391*6777b538SAndroid Build Coastguard Worker // Linear ranges are not divisible.
392*6777b538SAndroid Build Coastguard Worker BucketRanges ranges2(6);
393*6777b538SAndroid Build Coastguard Worker LinearHistogram::InitializeBucketRanges(1, 6, &ranges2);
394*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges2.range(0));
395*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, ranges2.range(1));
396*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, ranges2.range(2));
397*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, ranges2.range(3));
398*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(6, ranges2.range(4));
399*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(5));
400*6777b538SAndroid Build Coastguard Worker // The correspoding LinearHistogram should use the correct ranges.
401*6777b538SAndroid Build Coastguard Worker Histogram* histogram2 = static_cast<Histogram*>(
402*6777b538SAndroid Build Coastguard Worker LinearHistogram::FactoryGet("Linear2", 1, 6, 5, HistogramBase::kNoFlags));
403*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
404*6777b538SAndroid Build Coastguard Worker }
405*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,SingleValueEnumerationHistogram)406*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, SingleValueEnumerationHistogram) {
407*6777b538SAndroid Build Coastguard Worker // Make sure its possible to construct a linear histogram with only the two
408*6777b538SAndroid Build Coastguard Worker // required outlier buckets (underflow and overflow).
409*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = LinearHistogram::FactoryGet(
410*6777b538SAndroid Build Coastguard Worker "SingleValueEnum", 1, 1, 2, HistogramBase::kNoFlags);
411*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram);
412*6777b538SAndroid Build Coastguard Worker
413*6777b538SAndroid Build Coastguard Worker // Make sure the macros work properly. This can only be run when
414*6777b538SAndroid Build Coastguard Worker // there is no persistent allocator which can be discarded and leave
415*6777b538SAndroid Build Coastguard Worker // dangling pointers.
416*6777b538SAndroid Build Coastguard Worker if (!use_persistent_histogram_allocator_) {
417*6777b538SAndroid Build Coastguard Worker enum EnumWithMax {
418*6777b538SAndroid Build Coastguard Worker kSomething = 0,
419*6777b538SAndroid Build Coastguard Worker kMaxValue = kSomething,
420*6777b538SAndroid Build Coastguard Worker };
421*6777b538SAndroid Build Coastguard Worker UMA_HISTOGRAM_ENUMERATION("h1", kSomething);
422*6777b538SAndroid Build Coastguard Worker }
423*6777b538SAndroid Build Coastguard Worker }
424*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,ArrayToCustomEnumRangesTest)425*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, ArrayToCustomEnumRangesTest) {
426*6777b538SAndroid Build Coastguard Worker const HistogramBase::Sample ranges[3] = {5, 10, 20};
427*6777b538SAndroid Build Coastguard Worker std::vector<HistogramBase::Sample> ranges_vec =
428*6777b538SAndroid Build Coastguard Worker CustomHistogram::ArrayToCustomEnumRanges(ranges);
429*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(6u, ranges_vec.size());
430*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5, ranges_vec[0]);
431*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(6, ranges_vec[1]);
432*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(10, ranges_vec[2]);
433*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(11, ranges_vec[3]);
434*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(20, ranges_vec[4]);
435*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(21, ranges_vec[5]);
436*6777b538SAndroid Build Coastguard Worker }
437*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,CustomHistogramTest)438*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, CustomHistogramTest) {
439*6777b538SAndroid Build Coastguard Worker // A well prepared custom ranges.
440*6777b538SAndroid Build Coastguard Worker std::vector<HistogramBase::Sample> custom_ranges;
441*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(1);
442*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(2);
443*6777b538SAndroid Build Coastguard Worker
444*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(CustomHistogram::FactoryGet(
445*6777b538SAndroid Build Coastguard Worker "TestCustomHistogram1", custom_ranges, HistogramBase::kNoFlags));
446*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges = histogram->bucket_ranges();
447*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(4u, ranges->size());
448*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges->range(0)); // Auto added.
449*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, ranges->range(1));
450*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, ranges->range(2));
451*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); // Auto added.
452*6777b538SAndroid Build Coastguard Worker
453*6777b538SAndroid Build Coastguard Worker // A unordered custom ranges.
454*6777b538SAndroid Build Coastguard Worker custom_ranges.clear();
455*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(2);
456*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(1);
457*6777b538SAndroid Build Coastguard Worker histogram = static_cast<Histogram*>(CustomHistogram::FactoryGet(
458*6777b538SAndroid Build Coastguard Worker "TestCustomHistogram2", custom_ranges, HistogramBase::kNoFlags));
459*6777b538SAndroid Build Coastguard Worker ranges = histogram->bucket_ranges();
460*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(4u, ranges->size());
461*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges->range(0));
462*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, ranges->range(1));
463*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, ranges->range(2));
464*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
465*6777b538SAndroid Build Coastguard Worker
466*6777b538SAndroid Build Coastguard Worker // A custom ranges with duplicated values.
467*6777b538SAndroid Build Coastguard Worker custom_ranges.clear();
468*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(4);
469*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(1);
470*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(4);
471*6777b538SAndroid Build Coastguard Worker histogram = static_cast<Histogram*>(CustomHistogram::FactoryGet(
472*6777b538SAndroid Build Coastguard Worker "TestCustomHistogram3", custom_ranges, HistogramBase::kNoFlags));
473*6777b538SAndroid Build Coastguard Worker ranges = histogram->bucket_ranges();
474*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(4u, ranges->size());
475*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges->range(0));
476*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, ranges->range(1));
477*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, ranges->range(2));
478*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
479*6777b538SAndroid Build Coastguard Worker }
480*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,CustomHistogramWithOnly2Buckets)481*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, CustomHistogramWithOnly2Buckets) {
482*6777b538SAndroid Build Coastguard Worker // This test exploits the fact that the CustomHistogram can have 2 buckets,
483*6777b538SAndroid Build Coastguard Worker // while the base class Histogram is *supposed* to have at least 3 buckets.
484*6777b538SAndroid Build Coastguard Worker // We should probably change the restriction on the base class (or not inherit
485*6777b538SAndroid Build Coastguard Worker // the base class!).
486*6777b538SAndroid Build Coastguard Worker
487*6777b538SAndroid Build Coastguard Worker std::vector<HistogramBase::Sample> custom_ranges;
488*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(4);
489*6777b538SAndroid Build Coastguard Worker
490*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(CustomHistogram::FactoryGet(
491*6777b538SAndroid Build Coastguard Worker "2BucketsCustomHistogram", custom_ranges, HistogramBase::kNoFlags));
492*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges = histogram->bucket_ranges();
493*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(3u, ranges->size());
494*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges->range(0));
495*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, ranges->range(1));
496*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
497*6777b538SAndroid Build Coastguard Worker }
498*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,AddCountTest)499*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, AddCountTest) {
500*6777b538SAndroid Build Coastguard Worker const size_t kBucketCount = 50;
501*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(Histogram::FactoryGet(
502*6777b538SAndroid Build Coastguard Worker "AddCountHistogram", 10, 100, kBucketCount, HistogramBase::kNoFlags));
503*6777b538SAndroid Build Coastguard Worker
504*6777b538SAndroid Build Coastguard Worker histogram->AddCount(20, 15);
505*6777b538SAndroid Build Coastguard Worker histogram->AddCount(30, 14);
506*6777b538SAndroid Build Coastguard Worker
507*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
508*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(29, samples->TotalCount());
509*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(15, samples->GetCount(20));
510*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(14, samples->GetCount(30));
511*6777b538SAndroid Build Coastguard Worker
512*6777b538SAndroid Build Coastguard Worker histogram->AddCount(20, 25);
513*6777b538SAndroid Build Coastguard Worker histogram->AddCount(30, 24);
514*6777b538SAndroid Build Coastguard Worker
515*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples();
516*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(78, samples2->TotalCount());
517*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(40, samples2->GetCount(20));
518*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(38, samples2->GetCount(30));
519*6777b538SAndroid Build Coastguard Worker }
520*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,AddCount_LargeValuesDontOverflow)521*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, AddCount_LargeValuesDontOverflow) {
522*6777b538SAndroid Build Coastguard Worker const size_t kBucketCount = 50;
523*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(
524*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("AddCountHistogram", 10, 1000000000, kBucketCount,
525*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags));
526*6777b538SAndroid Build Coastguard Worker
527*6777b538SAndroid Build Coastguard Worker histogram->AddCount(200000000, 15);
528*6777b538SAndroid Build Coastguard Worker histogram->AddCount(300000000, 14);
529*6777b538SAndroid Build Coastguard Worker
530*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
531*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(29, samples->TotalCount());
532*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(15, samples->GetCount(200000000));
533*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(14, samples->GetCount(300000000));
534*6777b538SAndroid Build Coastguard Worker
535*6777b538SAndroid Build Coastguard Worker histogram->AddCount(200000000, 25);
536*6777b538SAndroid Build Coastguard Worker histogram->AddCount(300000000, 24);
537*6777b538SAndroid Build Coastguard Worker
538*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples();
539*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(78, samples2->TotalCount());
540*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(40, samples2->GetCount(200000000));
541*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(38, samples2->GetCount(300000000));
542*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(19400000000LL, samples2->sum());
543*6777b538SAndroid Build Coastguard Worker }
544*6777b538SAndroid Build Coastguard Worker
545*6777b538SAndroid Build Coastguard Worker // Some metrics are designed so that they are guaranteed not to overflow between
546*6777b538SAndroid Build Coastguard Worker // snapshots, but could overflow over a long-running session.
547*6777b538SAndroid Build Coastguard Worker // Make sure that counts returned by Histogram::SnapshotDelta do not overflow
548*6777b538SAndroid Build Coastguard Worker // even when a total count (returned by Histogram::SnapshotSample) does.
TEST_P(HistogramTest,AddCount_LargeCountsDontOverflow)549*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, AddCount_LargeCountsDontOverflow) {
550*6777b538SAndroid Build Coastguard Worker const size_t kBucketCount = 10;
551*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(Histogram::FactoryGet(
552*6777b538SAndroid Build Coastguard Worker "AddCountHistogram", 10, 50, kBucketCount, HistogramBase::kNoFlags));
553*6777b538SAndroid Build Coastguard Worker
554*6777b538SAndroid Build Coastguard Worker const int count = (1 << 30) - 1;
555*6777b538SAndroid Build Coastguard Worker
556*6777b538SAndroid Build Coastguard Worker // Repeat N times to make sure that there is no internal value overflow.
557*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < 10; ++i) {
558*6777b538SAndroid Build Coastguard Worker histogram->AddCount(42, count);
559*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
560*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(count, samples->TotalCount());
561*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(count, samples->GetCount(42));
562*6777b538SAndroid Build Coastguard Worker }
563*6777b538SAndroid Build Coastguard Worker }
564*6777b538SAndroid Build Coastguard Worker
565*6777b538SAndroid Build Coastguard Worker // Make sure histogram handles out-of-bounds data gracefully.
TEST_P(HistogramTest,BoundsTest)566*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, BoundsTest) {
567*6777b538SAndroid Build Coastguard Worker const size_t kBucketCount = 50;
568*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(Histogram::FactoryGet(
569*6777b538SAndroid Build Coastguard Worker "Bounded", 10, 100, kBucketCount, HistogramBase::kNoFlags));
570*6777b538SAndroid Build Coastguard Worker
571*6777b538SAndroid Build Coastguard Worker // Put two samples "out of bounds" above and below.
572*6777b538SAndroid Build Coastguard Worker histogram->Add(5);
573*6777b538SAndroid Build Coastguard Worker histogram->Add(-50);
574*6777b538SAndroid Build Coastguard Worker
575*6777b538SAndroid Build Coastguard Worker histogram->Add(100);
576*6777b538SAndroid Build Coastguard Worker histogram->Add(10000);
577*6777b538SAndroid Build Coastguard Worker
578*6777b538SAndroid Build Coastguard Worker // Verify they landed in the underflow, and overflow buckets.
579*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> samples = histogram->SnapshotAllSamples();
580*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCountAtIndex(0));
581*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->GetCountAtIndex(1));
582*6777b538SAndroid Build Coastguard Worker size_t array_size = histogram->bucket_count();
583*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kBucketCount, array_size);
584*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2));
585*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1));
586*6777b538SAndroid Build Coastguard Worker
587*6777b538SAndroid Build Coastguard Worker std::vector<int> custom_ranges;
588*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(10);
589*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(50);
590*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(100);
591*6777b538SAndroid Build Coastguard Worker Histogram* test_custom_histogram = static_cast<Histogram*>(
592*6777b538SAndroid Build Coastguard Worker CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram",
593*6777b538SAndroid Build Coastguard Worker custom_ranges, HistogramBase::kNoFlags));
594*6777b538SAndroid Build Coastguard Worker
595*6777b538SAndroid Build Coastguard Worker // Put two samples "out of bounds" above and below.
596*6777b538SAndroid Build Coastguard Worker test_custom_histogram->Add(5);
597*6777b538SAndroid Build Coastguard Worker test_custom_histogram->Add(-50);
598*6777b538SAndroid Build Coastguard Worker test_custom_histogram->Add(100);
599*6777b538SAndroid Build Coastguard Worker test_custom_histogram->Add(1000);
600*6777b538SAndroid Build Coastguard Worker test_custom_histogram->Add(INT_MAX);
601*6777b538SAndroid Build Coastguard Worker
602*6777b538SAndroid Build Coastguard Worker // Verify they landed in the underflow, and overflow buckets.
603*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> custom_samples =
604*6777b538SAndroid Build Coastguard Worker test_custom_histogram->SnapshotAllSamples();
605*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, custom_samples->GetCountAtIndex(0));
606*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, custom_samples->GetCountAtIndex(1));
607*6777b538SAndroid Build Coastguard Worker size_t bucket_count = test_custom_histogram->bucket_count();
608*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2));
609*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1));
610*6777b538SAndroid Build Coastguard Worker }
611*6777b538SAndroid Build Coastguard Worker
612*6777b538SAndroid Build Coastguard Worker // Check to be sure samples land as expected is "correct" buckets.
TEST_P(HistogramTest,BucketPlacementTest)613*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, BucketPlacementTest) {
614*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(
615*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker // Add i+1 samples to the i'th bucket.
618*6777b538SAndroid Build Coastguard Worker histogram->Add(0);
619*6777b538SAndroid Build Coastguard Worker int power_of_2 = 1;
620*6777b538SAndroid Build Coastguard Worker for (int i = 1; i < 8; i++) {
621*6777b538SAndroid Build Coastguard Worker for (int j = 0; j <= i; j++)
622*6777b538SAndroid Build Coastguard Worker histogram->Add(power_of_2);
623*6777b538SAndroid Build Coastguard Worker power_of_2 *= 2;
624*6777b538SAndroid Build Coastguard Worker }
625*6777b538SAndroid Build Coastguard Worker
626*6777b538SAndroid Build Coastguard Worker // Check to see that the bucket counts reflect our additions.
627*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> samples = histogram->SnapshotAllSamples();
628*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < 8; i++)
629*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(i + 1, samples->GetCountAtIndex(i));
630*6777b538SAndroid Build Coastguard Worker }
631*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,CorruptSampleCounts)632*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, CorruptSampleCounts) {
633*6777b538SAndroid Build Coastguard Worker // The internal code creates histograms via macros and thus keeps static
634*6777b538SAndroid Build Coastguard Worker // pointers to them. If those pointers are to persistent memory which will
635*6777b538SAndroid Build Coastguard Worker // be free'd then any following calls to that code will crash with a
636*6777b538SAndroid Build Coastguard Worker // segmentation violation.
637*6777b538SAndroid Build Coastguard Worker if (use_persistent_histogram_allocator_)
638*6777b538SAndroid Build Coastguard Worker return;
639*6777b538SAndroid Build Coastguard Worker
640*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(
641*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
642*6777b538SAndroid Build Coastguard Worker
643*6777b538SAndroid Build Coastguard Worker // Add some samples.
644*6777b538SAndroid Build Coastguard Worker histogram->Add(20);
645*6777b538SAndroid Build Coastguard Worker histogram->Add(40);
646*6777b538SAndroid Build Coastguard Worker
647*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> snapshot = histogram->SnapshotAllSamples();
648*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
649*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
650*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, snapshot->redundant_count());
651*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, snapshot->TotalCount());
652*6777b538SAndroid Build Coastguard Worker
653*6777b538SAndroid Build Coastguard Worker // Sample count won't match redundant count.
654*6777b538SAndroid Build Coastguard Worker snapshot->counts().value()[3u] += 100;
655*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR,
656*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
657*6777b538SAndroid Build Coastguard Worker snapshot->counts().value()[2u] -= 200;
658*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR,
659*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
660*6777b538SAndroid Build Coastguard Worker
661*6777b538SAndroid Build Coastguard Worker // But we can't spot a corruption if it is compensated for.
662*6777b538SAndroid Build Coastguard Worker snapshot->counts().value()[1u] += 100;
663*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
664*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
665*6777b538SAndroid Build Coastguard Worker }
666*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,CorruptBucketBounds)667*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, CorruptBucketBounds) {
668*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(
669*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
670*6777b538SAndroid Build Coastguard Worker
671*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HistogramSamples> snapshot = histogram->SnapshotSamples();
672*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
673*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
674*6777b538SAndroid Build Coastguard Worker
675*6777b538SAndroid Build Coastguard Worker BucketRanges* bucket_ranges =
676*6777b538SAndroid Build Coastguard Worker const_cast<BucketRanges*>(histogram->bucket_ranges());
677*6777b538SAndroid Build Coastguard Worker HistogramBase::Sample tmp = bucket_ranges->range(1);
678*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(1, bucket_ranges->range(2));
679*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(2, tmp);
680*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
681*6777b538SAndroid Build Coastguard Worker HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR,
682*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
683*6777b538SAndroid Build Coastguard Worker
684*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(2, bucket_ranges->range(1));
685*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(1, tmp);
686*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0U, histogram->FindCorruption(*snapshot));
687*6777b538SAndroid Build Coastguard Worker
688*6777b538SAndroid Build Coastguard Worker // Show that two simple changes don't offset each other
689*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(3, bucket_ranges->range(3) + 1);
690*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
691*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
692*6777b538SAndroid Build Coastguard Worker
693*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(4, bucket_ranges->range(4) - 1);
694*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
695*6777b538SAndroid Build Coastguard Worker histogram->FindCorruption(*snapshot));
696*6777b538SAndroid Build Coastguard Worker
697*6777b538SAndroid Build Coastguard Worker // Repair histogram so that destructor won't DCHECK().
698*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(3, bucket_ranges->range(3) - 1);
699*6777b538SAndroid Build Coastguard Worker bucket_ranges->set_range(4, bucket_ranges->range(4) + 1);
700*6777b538SAndroid Build Coastguard Worker }
701*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,HistogramSerializeInfo)702*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, HistogramSerializeInfo) {
703*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(Histogram::FactoryGet(
704*6777b538SAndroid Build Coastguard Worker "Histogram", 1, 64, 8, HistogramBase::kIPCSerializationSourceFlag));
705*6777b538SAndroid Build Coastguard Worker Pickle pickle;
706*6777b538SAndroid Build Coastguard Worker histogram->SerializeInfo(&pickle);
707*6777b538SAndroid Build Coastguard Worker
708*6777b538SAndroid Build Coastguard Worker PickleIterator iter(pickle);
709*6777b538SAndroid Build Coastguard Worker
710*6777b538SAndroid Build Coastguard Worker int type;
711*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&type));
712*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HISTOGRAM, type);
713*6777b538SAndroid Build Coastguard Worker
714*6777b538SAndroid Build Coastguard Worker std::string name;
715*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadString(&name));
716*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Histogram", name);
717*6777b538SAndroid Build Coastguard Worker
718*6777b538SAndroid Build Coastguard Worker int flag;
719*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&flag));
720*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag,
721*6777b538SAndroid Build Coastguard Worker flag & ~HistogramBase::kIsPersistent);
722*6777b538SAndroid Build Coastguard Worker
723*6777b538SAndroid Build Coastguard Worker int min;
724*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&min));
725*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, min);
726*6777b538SAndroid Build Coastguard Worker
727*6777b538SAndroid Build Coastguard Worker int max;
728*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&max));
729*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(64, max);
730*6777b538SAndroid Build Coastguard Worker
731*6777b538SAndroid Build Coastguard Worker uint32_t bucket_count;
732*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadUInt32(&bucket_count));
733*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(8u, bucket_count);
734*6777b538SAndroid Build Coastguard Worker
735*6777b538SAndroid Build Coastguard Worker uint32_t checksum;
736*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadUInt32(&checksum));
737*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(histogram->bucket_ranges()->checksum(), checksum);
738*6777b538SAndroid Build Coastguard Worker
739*6777b538SAndroid Build Coastguard Worker // No more data in the pickle.
740*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(iter.SkipBytes(1));
741*6777b538SAndroid Build Coastguard Worker }
742*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,CustomHistogramSerializeInfo)743*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, CustomHistogramSerializeInfo) {
744*6777b538SAndroid Build Coastguard Worker std::vector<int> custom_ranges;
745*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(10);
746*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(100);
747*6777b538SAndroid Build Coastguard Worker
748*6777b538SAndroid Build Coastguard Worker HistogramBase* custom_histogram =
749*6777b538SAndroid Build Coastguard Worker CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram",
750*6777b538SAndroid Build Coastguard Worker custom_ranges, HistogramBase::kNoFlags);
751*6777b538SAndroid Build Coastguard Worker Pickle pickle;
752*6777b538SAndroid Build Coastguard Worker custom_histogram->SerializeInfo(&pickle);
753*6777b538SAndroid Build Coastguard Worker
754*6777b538SAndroid Build Coastguard Worker // Validate the pickle.
755*6777b538SAndroid Build Coastguard Worker PickleIterator iter(pickle);
756*6777b538SAndroid Build Coastguard Worker
757*6777b538SAndroid Build Coastguard Worker int i;
758*6777b538SAndroid Build Coastguard Worker std::string s;
759*6777b538SAndroid Build Coastguard Worker uint32_t bucket_count;
760*6777b538SAndroid Build Coastguard Worker uint32_t ui32;
761*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&i) && iter.ReadString(&s) && iter.ReadInt(&i) &&
762*6777b538SAndroid Build Coastguard Worker iter.ReadInt(&i) && iter.ReadInt(&i) &&
763*6777b538SAndroid Build Coastguard Worker iter.ReadUInt32(&bucket_count) && iter.ReadUInt32(&ui32));
764*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, bucket_count);
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker int range;
767*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&range));
768*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(10, range);
769*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&range));
770*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(100, range);
771*6777b538SAndroid Build Coastguard Worker
772*6777b538SAndroid Build Coastguard Worker // No more data in the pickle.
773*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(iter.SkipBytes(1));
774*6777b538SAndroid Build Coastguard Worker }
775*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,BadConstruction)776*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, BadConstruction) {
777*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet("BadConstruction", 0, 100, 8,
778*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
779*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram->HasConstructionArguments(1, 100, 8));
780*6777b538SAndroid Build Coastguard Worker
781*6777b538SAndroid Build Coastguard Worker // Try to get the same histogram name with different arguments.
782*6777b538SAndroid Build Coastguard Worker HistogramBase* bad_histogram = Histogram::FactoryGet(
783*6777b538SAndroid Build Coastguard Worker "BadConstruction", 0, 100, 7, HistogramBase::kNoFlags);
784*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DummyHistogram::GetInstance(), bad_histogram);
785*6777b538SAndroid Build Coastguard Worker bad_histogram = Histogram::FactoryGet("BadConstruction", 0, 99, 8,
786*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
787*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DummyHistogram::GetInstance(), bad_histogram);
788*6777b538SAndroid Build Coastguard Worker
789*6777b538SAndroid Build Coastguard Worker HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
790*6777b538SAndroid Build Coastguard Worker "BadConstructionLinear", 0, 100, 8, HistogramBase::kNoFlags);
791*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(linear_histogram->HasConstructionArguments(1, 100, 8));
792*6777b538SAndroid Build Coastguard Worker
793*6777b538SAndroid Build Coastguard Worker // Try to get the same histogram name with different arguments.
794*6777b538SAndroid Build Coastguard Worker bad_histogram = LinearHistogram::FactoryGet("BadConstructionLinear", 0, 100,
795*6777b538SAndroid Build Coastguard Worker 7, HistogramBase::kNoFlags);
796*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DummyHistogram::GetInstance(), bad_histogram);
797*6777b538SAndroid Build Coastguard Worker bad_histogram = LinearHistogram::FactoryGet("BadConstructionLinear", 10, 100,
798*6777b538SAndroid Build Coastguard Worker 8, HistogramBase::kNoFlags);
799*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DummyHistogram::GetInstance(), bad_histogram);
800*6777b538SAndroid Build Coastguard Worker }
801*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,FactoryTime)802*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, FactoryTime) {
803*6777b538SAndroid Build Coastguard Worker const int kTestCreateCount = 1 << 14; // Must be power-of-2.
804*6777b538SAndroid Build Coastguard Worker const int kTestLookupCount = 100000;
805*6777b538SAndroid Build Coastguard Worker const int kTestAddCount = 1000000;
806*6777b538SAndroid Build Coastguard Worker
807*6777b538SAndroid Build Coastguard Worker // Create all histogram names in advance for accurate timing below.
808*6777b538SAndroid Build Coastguard Worker std::vector<std::string> histogram_names;
809*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kTestCreateCount; ++i) {
810*6777b538SAndroid Build Coastguard Worker histogram_names.push_back(
811*6777b538SAndroid Build Coastguard Worker StringPrintf("TestHistogram.%d", i % kTestCreateCount));
812*6777b538SAndroid Build Coastguard Worker }
813*6777b538SAndroid Build Coastguard Worker
814*6777b538SAndroid Build Coastguard Worker // Calculate cost of creating histograms.
815*6777b538SAndroid Build Coastguard Worker TimeTicks create_start = TimeTicks::Now();
816*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kTestCreateCount; ++i) {
817*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet(histogram_names[i], 1, 100, 10,
818*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
819*6777b538SAndroid Build Coastguard Worker }
820*6777b538SAndroid Build Coastguard Worker TimeDelta create_ticks = TimeTicks::Now() - create_start;
821*6777b538SAndroid Build Coastguard Worker int64_t create_ms = create_ticks.InMilliseconds();
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker VLOG(1) << kTestCreateCount << " histogram creations took " << create_ms
824*6777b538SAndroid Build Coastguard Worker << "ms or about " << (create_ms * 1000000) / kTestCreateCount
825*6777b538SAndroid Build Coastguard Worker << "ns each.";
826*6777b538SAndroid Build Coastguard Worker
827*6777b538SAndroid Build Coastguard Worker // Calculate cost of looking up existing histograms.
828*6777b538SAndroid Build Coastguard Worker TimeTicks lookup_start = TimeTicks::Now();
829*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kTestLookupCount; ++i) {
830*6777b538SAndroid Build Coastguard Worker // 6007 is co-prime with kTestCreateCount and so will do lookups in an
831*6777b538SAndroid Build Coastguard Worker // order less likely to be cacheable (but still hit them all) should the
832*6777b538SAndroid Build Coastguard Worker // underlying storage use the exact histogram name as the key.
833*6777b538SAndroid Build Coastguard Worker const int i_mult = 6007;
834*6777b538SAndroid Build Coastguard Worker static_assert(i_mult < INT_MAX / kTestCreateCount, "Multiplier too big");
835*6777b538SAndroid Build Coastguard Worker int index = (i * i_mult) & (kTestCreateCount - 1);
836*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet(histogram_names[index], 1, 100, 10,
837*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
838*6777b538SAndroid Build Coastguard Worker }
839*6777b538SAndroid Build Coastguard Worker TimeDelta lookup_ticks = TimeTicks::Now() - lookup_start;
840*6777b538SAndroid Build Coastguard Worker int64_t lookup_ms = lookup_ticks.InMilliseconds();
841*6777b538SAndroid Build Coastguard Worker
842*6777b538SAndroid Build Coastguard Worker VLOG(1) << kTestLookupCount << " histogram lookups took " << lookup_ms
843*6777b538SAndroid Build Coastguard Worker << "ms or about " << (lookup_ms * 1000000) / kTestLookupCount
844*6777b538SAndroid Build Coastguard Worker << "ns each.";
845*6777b538SAndroid Build Coastguard Worker
846*6777b538SAndroid Build Coastguard Worker // Calculate cost of accessing histograms.
847*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram = Histogram::FactoryGet(histogram_names[0], 1, 100,
848*6777b538SAndroid Build Coastguard Worker 10, HistogramBase::kNoFlags);
849*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(histogram);
850*6777b538SAndroid Build Coastguard Worker TimeTicks add_start = TimeTicks::Now();
851*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kTestAddCount; ++i)
852*6777b538SAndroid Build Coastguard Worker histogram->Add(i & 127);
853*6777b538SAndroid Build Coastguard Worker TimeDelta add_ticks = TimeTicks::Now() - add_start;
854*6777b538SAndroid Build Coastguard Worker int64_t add_ms = add_ticks.InMilliseconds();
855*6777b538SAndroid Build Coastguard Worker
856*6777b538SAndroid Build Coastguard Worker VLOG(1) << kTestAddCount << " histogram adds took " << add_ms
857*6777b538SAndroid Build Coastguard Worker << "ms or about " << (add_ms * 1000000) / kTestAddCount << "ns each.";
858*6777b538SAndroid Build Coastguard Worker }
859*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,ScaledLinearHistogram)860*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, ScaledLinearHistogram) {
861*6777b538SAndroid Build Coastguard Worker ScaledLinearHistogram scaled("SLH", 1, 5, 6, 100, HistogramBase::kNoFlags);
862*6777b538SAndroid Build Coastguard Worker
863*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(0, 1);
864*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(1, 49);
865*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(2, 50);
866*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(3, 101);
867*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(4, 160);
868*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(5, 130);
869*6777b538SAndroid Build Coastguard Worker scaled.AddScaledCount(6, 140);
870*6777b538SAndroid Build Coastguard Worker
871*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SampleVector> samples =
872*6777b538SAndroid Build Coastguard Worker SnapshotAllSamples(static_cast<Histogram*>(scaled.histogram()));
873*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->GetCountAtIndex(0));
874*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->GetCountAtIndex(1));
875*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCountAtIndex(2));
876*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, samples->GetCountAtIndex(3));
877*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->GetCountAtIndex(4));
878*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, samples->GetCountAtIndex(5));
879*6777b538SAndroid Build Coastguard Worker
880*6777b538SAndroid Build Coastguard Worker // Make sure the macros compile properly. This can only be run when
881*6777b538SAndroid Build Coastguard Worker // there is no persistent allocator which can be discarded and leave
882*6777b538SAndroid Build Coastguard Worker // dangling pointers.
883*6777b538SAndroid Build Coastguard Worker if (!use_persistent_histogram_allocator_) {
884*6777b538SAndroid Build Coastguard Worker enum EnumWithMax {
885*6777b538SAndroid Build Coastguard Worker kA = 0,
886*6777b538SAndroid Build Coastguard Worker kB = 1,
887*6777b538SAndroid Build Coastguard Worker kC = 2,
888*6777b538SAndroid Build Coastguard Worker kMaxValue = kC,
889*6777b538SAndroid Build Coastguard Worker };
890*6777b538SAndroid Build Coastguard Worker UMA_HISTOGRAM_SCALED_EXACT_LINEAR("h1", 1, 5000, 5, 100);
891*6777b538SAndroid Build Coastguard Worker UMA_HISTOGRAM_SCALED_ENUMERATION("h2", kB, 5000, 100);
892*6777b538SAndroid Build Coastguard Worker }
893*6777b538SAndroid Build Coastguard Worker }
894*6777b538SAndroid Build Coastguard Worker
895*6777b538SAndroid Build Coastguard Worker // For Histogram, LinearHistogram and CustomHistogram, the minimum for a
896*6777b538SAndroid Build Coastguard Worker // declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX -
897*6777b538SAndroid Build Coastguard Worker // 1). But we accept ranges exceeding those limits, and silently clamped to
898*6777b538SAndroid Build Coastguard Worker // those limits. This is for backwards compatibility.
TEST(HistogramDeathTest,BadRangesTest)899*6777b538SAndroid Build Coastguard Worker TEST(HistogramDeathTest, BadRangesTest) {
900*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram =
901*6777b538SAndroid Build Coastguard Worker Histogram::FactoryGet("BadRanges", 0, HistogramBase::kSampleType_MAX, 8,
902*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
903*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(histogram->HasConstructionArguments(
904*6777b538SAndroid Build Coastguard Worker 1, HistogramBase::kSampleType_MAX - 1, 8));
905*6777b538SAndroid Build Coastguard Worker
906*6777b538SAndroid Build Coastguard Worker HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
907*6777b538SAndroid Build Coastguard Worker "BadRangesLinear", 0, HistogramBase::kSampleType_MAX, 8,
908*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
909*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(linear_histogram->HasConstructionArguments(
910*6777b538SAndroid Build Coastguard Worker 1, HistogramBase::kSampleType_MAX - 1, 8));
911*6777b538SAndroid Build Coastguard Worker
912*6777b538SAndroid Build Coastguard Worker std::vector<int> custom_ranges;
913*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(0);
914*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(5);
915*6777b538SAndroid Build Coastguard Worker Histogram* custom_histogram =
916*6777b538SAndroid Build Coastguard Worker static_cast<Histogram*>(CustomHistogram::FactoryGet(
917*6777b538SAndroid Build Coastguard Worker "BadRangesCustom", custom_ranges, HistogramBase::kNoFlags));
918*6777b538SAndroid Build Coastguard Worker const BucketRanges* ranges = custom_histogram->bucket_ranges();
919*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(3u, ranges->size());
920*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ranges->range(0));
921*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5, ranges->range(1));
922*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
923*6777b538SAndroid Build Coastguard Worker
924*6777b538SAndroid Build Coastguard Worker // CustomHistogram does not accepts kSampleType_MAX as range.
925*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(HistogramBase::kSampleType_MAX);
926*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH_IF_SUPPORTED(
927*6777b538SAndroid Build Coastguard Worker CustomHistogram::FactoryGet("BadRangesCustom2", custom_ranges,
928*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags),
929*6777b538SAndroid Build Coastguard Worker "");
930*6777b538SAndroid Build Coastguard Worker
931*6777b538SAndroid Build Coastguard Worker // CustomHistogram needs at least 1 valid range.
932*6777b538SAndroid Build Coastguard Worker custom_ranges.clear();
933*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(0);
934*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH_IF_SUPPORTED(
935*6777b538SAndroid Build Coastguard Worker CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges,
936*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags),
937*6777b538SAndroid Build Coastguard Worker "");
938*6777b538SAndroid Build Coastguard Worker }
939*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,ExpiredHistogramTest)940*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, ExpiredHistogramTest) {
941*6777b538SAndroid Build Coastguard Worker auto record_checker = std::make_unique<TestRecordHistogramChecker>();
942*6777b538SAndroid Build Coastguard Worker StatisticsRecorder::SetRecordChecker(std::move(record_checker));
943*6777b538SAndroid Build Coastguard Worker
944*6777b538SAndroid Build Coastguard Worker HistogramBase* expired = Histogram::FactoryGet(kExpiredHistogramName, 1, 1000,
945*6777b538SAndroid Build Coastguard Worker 10, HistogramBase::kNoFlags);
946*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(expired);
947*6777b538SAndroid Build Coastguard Worker expired->Add(5);
948*6777b538SAndroid Build Coastguard Worker expired->Add(500);
949*6777b538SAndroid Build Coastguard Worker auto samples = expired->SnapshotDelta();
950*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
951*6777b538SAndroid Build Coastguard Worker
952*6777b538SAndroid Build Coastguard Worker HistogramBase* linear_expired = LinearHistogram::FactoryGet(
953*6777b538SAndroid Build Coastguard Worker kExpiredHistogramName, 1, 1000, 10, HistogramBase::kNoFlags);
954*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(linear_expired);
955*6777b538SAndroid Build Coastguard Worker linear_expired->Add(5);
956*6777b538SAndroid Build Coastguard Worker linear_expired->Add(500);
957*6777b538SAndroid Build Coastguard Worker samples = linear_expired->SnapshotDelta();
958*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
959*6777b538SAndroid Build Coastguard Worker
960*6777b538SAndroid Build Coastguard Worker ScaledLinearHistogram scaled_linear_expired(kExpiredHistogramName, 1, 5, 6,
961*6777b538SAndroid Build Coastguard Worker 100, HistogramBase::kNoFlags);
962*6777b538SAndroid Build Coastguard Worker scaled_linear_expired.AddScaledCount(0, 1);
963*6777b538SAndroid Build Coastguard Worker scaled_linear_expired.AddScaledCount(1, 49);
964*6777b538SAndroid Build Coastguard Worker samples = scaled_linear_expired.histogram()->SnapshotDelta();
965*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
966*6777b538SAndroid Build Coastguard Worker
967*6777b538SAndroid Build Coastguard Worker std::vector<int> custom_ranges;
968*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(1);
969*6777b538SAndroid Build Coastguard Worker custom_ranges.push_back(5);
970*6777b538SAndroid Build Coastguard Worker HistogramBase* custom_expired = CustomHistogram::FactoryGet(
971*6777b538SAndroid Build Coastguard Worker kExpiredHistogramName, custom_ranges, HistogramBase::kNoFlags);
972*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(custom_expired);
973*6777b538SAndroid Build Coastguard Worker custom_expired->Add(2);
974*6777b538SAndroid Build Coastguard Worker custom_expired->Add(4);
975*6777b538SAndroid Build Coastguard Worker samples = custom_expired->SnapshotDelta();
976*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, samples->TotalCount());
977*6777b538SAndroid Build Coastguard Worker
978*6777b538SAndroid Build Coastguard Worker HistogramBase* valid = Histogram::FactoryGet("ValidHistogram", 1, 1000, 10,
979*6777b538SAndroid Build Coastguard Worker HistogramBase::kNoFlags);
980*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(valid);
981*6777b538SAndroid Build Coastguard Worker valid->Add(5);
982*6777b538SAndroid Build Coastguard Worker valid->Add(500);
983*6777b538SAndroid Build Coastguard Worker samples = valid->SnapshotDelta();
984*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->TotalCount());
985*6777b538SAndroid Build Coastguard Worker
986*6777b538SAndroid Build Coastguard Worker HistogramBase* linear_valid = LinearHistogram::FactoryGet(
987*6777b538SAndroid Build Coastguard Worker "LinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
988*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(linear_valid);
989*6777b538SAndroid Build Coastguard Worker linear_valid->Add(5);
990*6777b538SAndroid Build Coastguard Worker linear_valid->Add(500);
991*6777b538SAndroid Build Coastguard Worker samples = linear_valid->SnapshotDelta();
992*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->TotalCount());
993*6777b538SAndroid Build Coastguard Worker
994*6777b538SAndroid Build Coastguard Worker HistogramBase* custom_valid = CustomHistogram::FactoryGet(
995*6777b538SAndroid Build Coastguard Worker "CustomHistogram", custom_ranges, HistogramBase::kNoFlags);
996*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(custom_valid);
997*6777b538SAndroid Build Coastguard Worker custom_valid->Add(2);
998*6777b538SAndroid Build Coastguard Worker custom_valid->Add(4);
999*6777b538SAndroid Build Coastguard Worker samples = custom_valid->SnapshotDelta();
1000*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, samples->TotalCount());
1001*6777b538SAndroid Build Coastguard Worker }
1002*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,CheckGetCountAndBucketData)1003*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, CheckGetCountAndBucketData) {
1004*6777b538SAndroid Build Coastguard Worker const size_t kBucketCount = 50;
1005*6777b538SAndroid Build Coastguard Worker Histogram* histogram = static_cast<Histogram*>(Histogram::FactoryGet(
1006*6777b538SAndroid Build Coastguard Worker "AddCountHistogram", 10, 100, kBucketCount, HistogramBase::kNoFlags));
1007*6777b538SAndroid Build Coastguard Worker // Add samples in reverse order and make sure the output is in correct order.
1008*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*sample=*/30, /*value=*/14);
1009*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*sample=*/20, /*value=*/15);
1010*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*sample=*/20, /*value=*/15);
1011*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*sample=*/30, /*value=*/14);
1012*6777b538SAndroid Build Coastguard Worker
1013*6777b538SAndroid Build Coastguard Worker const CountAndBucketData count_and_data_bucket =
1014*6777b538SAndroid Build Coastguard Worker GetCountAndBucketData(histogram);
1015*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(58, count_and_data_bucket.count);
1016*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1440, count_and_data_bucket.sum);
1017*6777b538SAndroid Build Coastguard Worker
1018*6777b538SAndroid Build Coastguard Worker const base::Value::List& buckets_list = count_and_data_bucket.buckets;
1019*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(2u, buckets_list.size());
1020*6777b538SAndroid Build Coastguard Worker
1021*6777b538SAndroid Build Coastguard Worker // Check the first bucket.
1022*6777b538SAndroid Build Coastguard Worker const base::Value::Dict* bucket1 = buckets_list[0].GetIfDict();
1023*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(bucket1 != nullptr);
1024*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(bucket1->FindInt("low"), std::optional<int>(20));
1025*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(bucket1->FindInt("high"), std::optional<int>(21));
1026*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(bucket1->FindInt("count"), std::optional<int>(30));
1027*6777b538SAndroid Build Coastguard Worker
1028*6777b538SAndroid Build Coastguard Worker // Check the second bucket.
1029*6777b538SAndroid Build Coastguard Worker const base::Value::Dict* bucket2 = buckets_list[1].GetIfDict();
1030*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(bucket2 != nullptr);
1031*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(bucket2->FindInt("low"), std::optional<int>(30));
1032*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(bucket2->FindInt("high"), std::optional<int>(31));
1033*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(bucket2->FindInt("count"), std::optional<int>(28));
1034*6777b538SAndroid Build Coastguard Worker }
1035*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,WriteAscii)1036*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, WriteAscii) {
1037*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram =
1038*6777b538SAndroid Build Coastguard Worker LinearHistogram::FactoryGet("AsciiOut", /*minimum=*/1, /*maximum=*/10,
1039*6777b538SAndroid Build Coastguard Worker /*bucket_count=*/5, HistogramBase::kNoFlags);
1040*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*sample=*/4, /*value=*/5);
1041*6777b538SAndroid Build Coastguard Worker
1042*6777b538SAndroid Build Coastguard Worker std::string output;
1043*6777b538SAndroid Build Coastguard Worker histogram->WriteAscii(&output);
1044*6777b538SAndroid Build Coastguard Worker
1045*6777b538SAndroid Build Coastguard Worker const char kOutputFormatRe[] =
1046*6777b538SAndroid Build Coastguard Worker R"(Histogram: AsciiOut recorded 5 samples, mean = 4\.0.*\n)"
1047*6777b538SAndroid Build Coastguard Worker R"(0 \.\.\. \n)"
1048*6777b538SAndroid Build Coastguard Worker R"(4 -+O \s* \(5 = 100\.0%\) \{0\.0%\}\n)"
1049*6777b538SAndroid Build Coastguard Worker R"(7 \.\.\. \n)";
1050*6777b538SAndroid Build Coastguard Worker
1051*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(output, testing::MatchesRegex(kOutputFormatRe));
1052*6777b538SAndroid Build Coastguard Worker }
1053*6777b538SAndroid Build Coastguard Worker
TEST_P(HistogramTest,ToGraphDict)1054*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, ToGraphDict) {
1055*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram =
1056*6777b538SAndroid Build Coastguard Worker LinearHistogram::FactoryGet("HTMLOut", /*minimum=*/1, /*maximum=*/10,
1057*6777b538SAndroid Build Coastguard Worker /*bucket_count=*/5, HistogramBase::kNoFlags);
1058*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*sample=*/4, /*value=*/5);
1059*6777b538SAndroid Build Coastguard Worker
1060*6777b538SAndroid Build Coastguard Worker base::Value::Dict output = histogram->ToGraphDict();
1061*6777b538SAndroid Build Coastguard Worker const std::string* header = output.FindString("header");
1062*6777b538SAndroid Build Coastguard Worker const std::string* body = output.FindString("body");
1063*6777b538SAndroid Build Coastguard Worker
1064*6777b538SAndroid Build Coastguard Worker const char kOutputHeaderFormatRe[] =
1065*6777b538SAndroid Build Coastguard Worker R"(Histogram: HTMLOut recorded 5 samples, mean = 4\.0.*)";
1066*6777b538SAndroid Build Coastguard Worker const char kOutputBodyFormatRe[] =
1067*6777b538SAndroid Build Coastguard Worker R"(0 \.\.\. \n)"
1068*6777b538SAndroid Build Coastguard Worker R"(4 -+O \s* \(5 = 100\.0%\) \{0\.0%\}\n)"
1069*6777b538SAndroid Build Coastguard Worker R"(7 \.\.\. \n)";
1070*6777b538SAndroid Build Coastguard Worker
1071*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(*header, testing::MatchesRegex(kOutputHeaderFormatRe));
1072*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(*body, testing::MatchesRegex(kOutputBodyFormatRe));
1073*6777b538SAndroid Build Coastguard Worker }
1074*6777b538SAndroid Build Coastguard Worker
1075*6777b538SAndroid Build Coastguard Worker // Tests ToGraphDict() returns deterministic length size and normalizes to
1076*6777b538SAndroid Build Coastguard Worker // scale.
TEST_P(HistogramTest,ToGraphDictNormalize)1077*6777b538SAndroid Build Coastguard Worker TEST_P(HistogramTest, ToGraphDictNormalize) {
1078*6777b538SAndroid Build Coastguard Worker int count_bucket_1 = 80;
1079*6777b538SAndroid Build Coastguard Worker int value_bucket_1 = 4;
1080*6777b538SAndroid Build Coastguard Worker int count_bucket_2 = 40;
1081*6777b538SAndroid Build Coastguard Worker int value_bucket_2 = 5;
1082*6777b538SAndroid Build Coastguard Worker HistogramBase* histogram =
1083*6777b538SAndroid Build Coastguard Worker LinearHistogram::FactoryGet("AsciiOut", /*minimum=*/1, /*maximum=*/100,
1084*6777b538SAndroid Build Coastguard Worker /*bucket_count=*/80, HistogramBase::kNoFlags);
1085*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*value=*/value_bucket_1, /*count=*/count_bucket_1);
1086*6777b538SAndroid Build Coastguard Worker histogram->AddCount(/*value=*/value_bucket_2, /*count=*/count_bucket_2);
1087*6777b538SAndroid Build Coastguard Worker
1088*6777b538SAndroid Build Coastguard Worker base::Value::Dict output = histogram->ToGraphDict();
1089*6777b538SAndroid Build Coastguard Worker std::string* header = output.FindString("header");
1090*6777b538SAndroid Build Coastguard Worker std::string* body = output.FindString("body");
1091*6777b538SAndroid Build Coastguard Worker
1092*6777b538SAndroid Build Coastguard Worker const char kOutputHeaderFormatRe[] =
1093*6777b538SAndroid Build Coastguard Worker R"(Histogram: AsciiOut recorded 120 samples, mean = 4\.3.*)";
1094*6777b538SAndroid Build Coastguard Worker const char kOutputBodyFormatRe[] =
1095*6777b538SAndroid Build Coastguard Worker R"(0 \.\.\. \n)"
1096*6777b538SAndroid Build Coastguard Worker R"(4 ---------------------------------------------------)"
1097*6777b538SAndroid Build Coastguard Worker R"(---------------------O \(80 = 66\.7%\) \{0\.0%\}\n)"
1098*6777b538SAndroid Build Coastguard Worker R"(5 ----------------)"
1099*6777b538SAndroid Build Coastguard Worker R"(--------------------O \s* \(40 = 33\.3%\) \{66\.7%\}\n)"
1100*6777b538SAndroid Build Coastguard Worker R"(6 \.\.\. \n)";
1101*6777b538SAndroid Build Coastguard Worker
1102*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(*header, testing::MatchesRegex(kOutputHeaderFormatRe));
1103*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(*body, testing::MatchesRegex(kOutputBodyFormatRe));
1104*6777b538SAndroid Build Coastguard Worker }
1105*6777b538SAndroid Build Coastguard Worker
1106*6777b538SAndroid Build Coastguard Worker } // namespace base
1107