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