• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Test of Histogram class
6 
7 #include <climits>
8 #include <algorithm>
9 #include <vector>
10 
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/metrics/bucket_ranges.h"
14 #include "base/metrics/histogram.h"
15 #include "base/metrics/sample_vector.h"
16 #include "base/metrics/statistics_recorder.h"
17 #include "base/pickle.h"
18 #include "base/time/time.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 using std::vector;
22 
23 namespace base {
24 
25 class HistogramTest : public testing::Test {
26  protected:
SetUp()27   virtual void SetUp() {
28     // Each test will have a clean state (no Histogram / BucketRanges
29     // registered).
30     InitializeStatisticsRecorder();
31   }
32 
TearDown()33   virtual void TearDown() {
34     UninitializeStatisticsRecorder();
35   }
36 
InitializeStatisticsRecorder()37   void InitializeStatisticsRecorder() {
38     statistics_recorder_ = new StatisticsRecorder();
39   }
40 
UninitializeStatisticsRecorder()41   void UninitializeStatisticsRecorder() {
42     delete statistics_recorder_;
43     statistics_recorder_ = NULL;
44   }
45 
46   StatisticsRecorder* statistics_recorder_;
47 };
48 
49 // Check for basic syntax and use.
TEST_F(HistogramTest,BasicTest)50 TEST_F(HistogramTest, BasicTest) {
51   // Try basic construction
52   HistogramBase* histogram = Histogram::FactoryGet(
53       "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
54   EXPECT_TRUE(histogram);
55 
56   HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
57       "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
58   EXPECT_TRUE(linear_histogram);
59 
60   vector<int> custom_ranges;
61   custom_ranges.push_back(1);
62   custom_ranges.push_back(5);
63   HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
64       "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
65   EXPECT_TRUE(custom_histogram);
66 
67   // Use standard macros (but with fixed samples)
68   LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1));
69   LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30);
70 
71   LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
72 }
73 
74 // Check that the macro correctly matches histograms by name and records their
75 // data together.
TEST_F(HistogramTest,NameMatchTest)76 TEST_F(HistogramTest, NameMatchTest) {
77   LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
78   LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
79   HistogramBase* histogram = LinearHistogram::FactoryGet(
80       "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags);
81 
82   scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
83   EXPECT_EQ(2, samples->TotalCount());
84   EXPECT_EQ(2, samples->GetCount(10));
85 }
86 
TEST_F(HistogramTest,ExponentialRangesTest)87 TEST_F(HistogramTest, ExponentialRangesTest) {
88   // Check that we got a nice exponential when there was enough rooom.
89   BucketRanges ranges(9);
90   Histogram::InitializeBucketRanges(1, 64, &ranges);
91   EXPECT_EQ(0, ranges.range(0));
92   int power_of_2 = 1;
93   for (int i = 1; i < 8; i++) {
94     EXPECT_EQ(power_of_2, ranges.range(i));
95     power_of_2 *= 2;
96   }
97   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
98 
99   // Check the corresponding Histogram will use the correct ranges.
100   Histogram* histogram = static_cast<Histogram*>(
101       Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
102   EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
103 
104   // When bucket count is limited, exponential ranges will partially look like
105   // linear.
106   BucketRanges ranges2(16);
107   Histogram::InitializeBucketRanges(1, 32, &ranges2);
108 
109   EXPECT_EQ(0, ranges2.range(0));
110   EXPECT_EQ(1, ranges2.range(1));
111   EXPECT_EQ(2, ranges2.range(2));
112   EXPECT_EQ(3, ranges2.range(3));
113   EXPECT_EQ(4, ranges2.range(4));
114   EXPECT_EQ(5, ranges2.range(5));
115   EXPECT_EQ(6, ranges2.range(6));
116   EXPECT_EQ(7, ranges2.range(7));
117   EXPECT_EQ(9, ranges2.range(8));
118   EXPECT_EQ(11, ranges2.range(9));
119   EXPECT_EQ(14, ranges2.range(10));
120   EXPECT_EQ(17, ranges2.range(11));
121   EXPECT_EQ(21, ranges2.range(12));
122   EXPECT_EQ(26, ranges2.range(13));
123   EXPECT_EQ(32, ranges2.range(14));
124   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(15));
125 
126   // Check the corresponding Histogram will use the correct ranges.
127   Histogram* histogram2 = static_cast<Histogram*>(
128       Histogram::FactoryGet("Histogram2", 1, 32, 15, HistogramBase::kNoFlags));
129   EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
130 }
131 
TEST_F(HistogramTest,LinearRangesTest)132 TEST_F(HistogramTest, LinearRangesTest) {
133   BucketRanges ranges(9);
134   LinearHistogram::InitializeBucketRanges(1, 7, &ranges);
135   // Gets a nice linear set of bucket ranges.
136   for (int i = 0; i < 8; i++)
137     EXPECT_EQ(i, ranges.range(i));
138   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
139 
140   // The correspoding LinearHistogram should use the correct ranges.
141   Histogram* histogram = static_cast<Histogram*>(
142       LinearHistogram::FactoryGet("Linear", 1, 7, 8, HistogramBase::kNoFlags));
143   EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
144 
145   // Linear ranges are not divisible.
146   BucketRanges ranges2(6);
147   LinearHistogram::InitializeBucketRanges(1, 6, &ranges2);
148   EXPECT_EQ(0, ranges2.range(0));
149   EXPECT_EQ(1, ranges2.range(1));
150   EXPECT_EQ(3, ranges2.range(2));
151   EXPECT_EQ(4, ranges2.range(3));
152   EXPECT_EQ(6, ranges2.range(4));
153   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(5));
154   // The correspoding LinearHistogram should use the correct ranges.
155   Histogram* histogram2 = static_cast<Histogram*>(
156       LinearHistogram::FactoryGet("Linear2", 1, 6, 5, HistogramBase::kNoFlags));
157   EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
158 }
159 
TEST_F(HistogramTest,ArrayToCustomRangesTest)160 TEST_F(HistogramTest, ArrayToCustomRangesTest) {
161   const HistogramBase::Sample ranges[3] = {5, 10, 20};
162   vector<HistogramBase::Sample> ranges_vec =
163       CustomHistogram::ArrayToCustomRanges(ranges, 3);
164   ASSERT_EQ(6u, ranges_vec.size());
165   EXPECT_EQ(5, ranges_vec[0]);
166   EXPECT_EQ(6, ranges_vec[1]);
167   EXPECT_EQ(10, ranges_vec[2]);
168   EXPECT_EQ(11, ranges_vec[3]);
169   EXPECT_EQ(20, ranges_vec[4]);
170   EXPECT_EQ(21, ranges_vec[5]);
171 }
172 
TEST_F(HistogramTest,CustomHistogramTest)173 TEST_F(HistogramTest, CustomHistogramTest) {
174   // A well prepared custom ranges.
175   vector<HistogramBase::Sample> custom_ranges;
176   custom_ranges.push_back(1);
177   custom_ranges.push_back(2);
178 
179   Histogram* histogram = static_cast<Histogram*>(
180       CustomHistogram::FactoryGet("TestCustomHistogram1", custom_ranges,
181                                   HistogramBase::kNoFlags));
182   const BucketRanges* ranges = histogram->bucket_ranges();
183   ASSERT_EQ(4u, ranges->size());
184   EXPECT_EQ(0, ranges->range(0));  // Auto added.
185   EXPECT_EQ(1, ranges->range(1));
186   EXPECT_EQ(2, ranges->range(2));
187   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));  // Auto added.
188 
189   // A unordered custom ranges.
190   custom_ranges.clear();
191   custom_ranges.push_back(2);
192   custom_ranges.push_back(1);
193   histogram = static_cast<Histogram*>(
194       CustomHistogram::FactoryGet("TestCustomHistogram2", custom_ranges,
195                                   HistogramBase::kNoFlags));
196   ranges = histogram->bucket_ranges();
197   ASSERT_EQ(4u, ranges->size());
198   EXPECT_EQ(0, ranges->range(0));
199   EXPECT_EQ(1, ranges->range(1));
200   EXPECT_EQ(2, ranges->range(2));
201   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
202 
203   // A custom ranges with duplicated values.
204   custom_ranges.clear();
205   custom_ranges.push_back(4);
206   custom_ranges.push_back(1);
207   custom_ranges.push_back(4);
208   histogram = static_cast<Histogram*>(
209       CustomHistogram::FactoryGet("TestCustomHistogram3", custom_ranges,
210                                   HistogramBase::kNoFlags));
211   ranges = histogram->bucket_ranges();
212   ASSERT_EQ(4u, ranges->size());
213   EXPECT_EQ(0, ranges->range(0));
214   EXPECT_EQ(1, ranges->range(1));
215   EXPECT_EQ(4, ranges->range(2));
216   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
217 }
218 
TEST_F(HistogramTest,CustomHistogramWithOnly2Buckets)219 TEST_F(HistogramTest, CustomHistogramWithOnly2Buckets) {
220   // This test exploits the fact that the CustomHistogram can have 2 buckets,
221   // while the base class Histogram is *supposed* to have at least 3 buckets.
222   // We should probably change the restriction on the base class (or not inherit
223   // the base class!).
224 
225   vector<HistogramBase::Sample> custom_ranges;
226   custom_ranges.push_back(4);
227 
228   Histogram* histogram = static_cast<Histogram*>(
229       CustomHistogram::FactoryGet("2BucketsCustomHistogram", custom_ranges,
230                                   HistogramBase::kNoFlags));
231   const BucketRanges* ranges = histogram->bucket_ranges();
232   ASSERT_EQ(3u, ranges->size());
233   EXPECT_EQ(0, ranges->range(0));
234   EXPECT_EQ(4, ranges->range(1));
235   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
236 }
237 
238 // Make sure histogram handles out-of-bounds data gracefully.
TEST_F(HistogramTest,BoundsTest)239 TEST_F(HistogramTest, BoundsTest) {
240   const size_t kBucketCount = 50;
241   Histogram* histogram = static_cast<Histogram*>(
242       Histogram::FactoryGet("Bounded", 10, 100, kBucketCount,
243                             HistogramBase::kNoFlags));
244 
245   // Put two samples "out of bounds" above and below.
246   histogram->Add(5);
247   histogram->Add(-50);
248 
249   histogram->Add(100);
250   histogram->Add(10000);
251 
252   // Verify they landed in the underflow, and overflow buckets.
253   scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector();
254   EXPECT_EQ(2, samples->GetCountAtIndex(0));
255   EXPECT_EQ(0, samples->GetCountAtIndex(1));
256   size_t array_size = histogram->bucket_count();
257   EXPECT_EQ(kBucketCount, array_size);
258   EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2));
259   EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1));
260 
261   vector<int> custom_ranges;
262   custom_ranges.push_back(10);
263   custom_ranges.push_back(50);
264   custom_ranges.push_back(100);
265   Histogram* test_custom_histogram = static_cast<Histogram*>(
266       CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram",
267                                   custom_ranges, HistogramBase::kNoFlags));
268 
269   // Put two samples "out of bounds" above and below.
270   test_custom_histogram->Add(5);
271   test_custom_histogram->Add(-50);
272   test_custom_histogram->Add(100);
273   test_custom_histogram->Add(1000);
274   test_custom_histogram->Add(INT_MAX);
275 
276   // Verify they landed in the underflow, and overflow buckets.
277   scoped_ptr<SampleVector> custom_samples =
278       test_custom_histogram->SnapshotSampleVector();
279   EXPECT_EQ(2, custom_samples->GetCountAtIndex(0));
280   EXPECT_EQ(0, custom_samples->GetCountAtIndex(1));
281   size_t bucket_count = test_custom_histogram->bucket_count();
282   EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2));
283   EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1));
284 }
285 
286 // Check to be sure samples land as expected is "correct" buckets.
TEST_F(HistogramTest,BucketPlacementTest)287 TEST_F(HistogramTest, BucketPlacementTest) {
288   Histogram* histogram = static_cast<Histogram*>(
289       Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
290 
291   // Add i+1 samples to the i'th bucket.
292   histogram->Add(0);
293   int power_of_2 = 1;
294   for (int i = 1; i < 8; i++) {
295     for (int j = 0; j <= i; j++)
296       histogram->Add(power_of_2);
297     power_of_2 *= 2;
298   }
299 
300   // Check to see that the bucket counts reflect our additions.
301   scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector();
302   for (int i = 0; i < 8; i++)
303     EXPECT_EQ(i + 1, samples->GetCountAtIndex(i));
304 }
305 
TEST_F(HistogramTest,CorruptSampleCounts)306 TEST_F(HistogramTest, CorruptSampleCounts) {
307   Histogram* histogram = static_cast<Histogram*>(
308       Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
309 
310   // Add some samples.
311   histogram->Add(20);
312   histogram->Add(40);
313 
314   scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector();
315   EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
316             histogram->FindCorruption(*snapshot));
317   EXPECT_EQ(2, snapshot->redundant_count());
318   EXPECT_EQ(2, snapshot->TotalCount());
319 
320   snapshot->counts_[3] += 100;  // Sample count won't match redundant count.
321   EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR,
322             histogram->FindCorruption(*snapshot));
323   snapshot->counts_[2] -= 200;
324   EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR,
325             histogram->FindCorruption(*snapshot));
326 
327   // But we can't spot a corruption if it is compensated for.
328   snapshot->counts_[1] += 100;
329   EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
330             histogram->FindCorruption(*snapshot));
331 }
332 
TEST_F(HistogramTest,CorruptBucketBounds)333 TEST_F(HistogramTest, CorruptBucketBounds) {
334   Histogram* histogram = static_cast<Histogram*>(
335       Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
336 
337   scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector();
338   EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
339             histogram->FindCorruption(*snapshot));
340 
341   BucketRanges* bucket_ranges =
342       const_cast<BucketRanges*>(histogram->bucket_ranges());
343   HistogramBase::Sample tmp = bucket_ranges->range(1);
344   bucket_ranges->set_range(1, bucket_ranges->range(2));
345   bucket_ranges->set_range(2, tmp);
346   EXPECT_EQ(
347       HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR,
348       histogram->FindCorruption(*snapshot));
349 
350   bucket_ranges->set_range(2, bucket_ranges->range(1));
351   bucket_ranges->set_range(1, tmp);
352   EXPECT_EQ(0, histogram->FindCorruption(*snapshot));
353 
354   // Show that two simple changes don't offset each other
355   bucket_ranges->set_range(3, bucket_ranges->range(3) + 1);
356   EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
357             histogram->FindCorruption(*snapshot));
358 
359   bucket_ranges->set_range(4, bucket_ranges->range(4) - 1);
360   EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
361             histogram->FindCorruption(*snapshot));
362 
363   // Repair histogram so that destructor won't DCHECK().
364   bucket_ranges->set_range(3, bucket_ranges->range(3) - 1);
365   bucket_ranges->set_range(4, bucket_ranges->range(4) + 1);
366 }
367 
TEST_F(HistogramTest,HistogramSerializeInfo)368 TEST_F(HistogramTest, HistogramSerializeInfo) {
369   Histogram* histogram = static_cast<Histogram*>(
370       Histogram::FactoryGet("Histogram", 1, 64, 8,
371                             HistogramBase::kIPCSerializationSourceFlag));
372   Pickle pickle;
373   histogram->SerializeInfo(&pickle);
374 
375   PickleIterator iter(pickle);
376 
377   int type;
378   EXPECT_TRUE(iter.ReadInt(&type));
379   EXPECT_EQ(HISTOGRAM, type);
380 
381   std::string name;
382   EXPECT_TRUE(iter.ReadString(&name));
383   EXPECT_EQ("Histogram", name);
384 
385   int flag;
386   EXPECT_TRUE(iter.ReadInt(&flag));
387   EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag, flag);
388 
389   int min;
390   EXPECT_TRUE(iter.ReadInt(&min));
391   EXPECT_EQ(1, min);
392 
393   int max;
394   EXPECT_TRUE(iter.ReadInt(&max));
395   EXPECT_EQ(64, max);
396 
397   int64 bucket_count;
398   EXPECT_TRUE(iter.ReadInt64(&bucket_count));
399   EXPECT_EQ(8, bucket_count);
400 
401   uint32 checksum;
402   EXPECT_TRUE(iter.ReadUInt32(&checksum));
403   EXPECT_EQ(histogram->bucket_ranges()->checksum(), checksum);
404 
405   // No more data in the pickle.
406   EXPECT_FALSE(iter.SkipBytes(1));
407 }
408 
TEST_F(HistogramTest,CustomHistogramSerializeInfo)409 TEST_F(HistogramTest, CustomHistogramSerializeInfo) {
410   vector<int> custom_ranges;
411   custom_ranges.push_back(10);
412   custom_ranges.push_back(100);
413 
414   HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
415       "TestCustomRangeBoundedHistogram",
416       custom_ranges,
417       HistogramBase::kNoFlags);
418   Pickle pickle;
419   custom_histogram->SerializeInfo(&pickle);
420 
421   // Validate the pickle.
422   PickleIterator iter(pickle);
423 
424   int i;
425   std::string s;
426   int64 bucket_count;
427   uint32 ui32;
428   EXPECT_TRUE(iter.ReadInt(&i) && iter.ReadString(&s) && iter.ReadInt(&i) &&
429               iter.ReadInt(&i) && iter.ReadInt(&i) &&
430               iter.ReadInt64(&bucket_count) && iter.ReadUInt32(&ui32));
431   EXPECT_EQ(3, bucket_count);
432 
433   int range;
434   EXPECT_TRUE(iter.ReadInt(&range));
435   EXPECT_EQ(10, range);
436   EXPECT_TRUE(iter.ReadInt(&range));
437   EXPECT_EQ(100, range);
438 
439   // No more data in the pickle.
440   EXPECT_FALSE(iter.SkipBytes(1));
441 }
442 
TEST_F(HistogramTest,BadConstruction)443 TEST_F(HistogramTest, BadConstruction) {
444   HistogramBase* histogram = Histogram::FactoryGet(
445       "BadConstruction", 0, 100, 8, HistogramBase::kNoFlags);
446   EXPECT_TRUE(histogram->HasConstructionArguments(1, 100, 8));
447 
448   // Try to get the same histogram name with different arguments.
449   HistogramBase* bad_histogram = Histogram::FactoryGet(
450       "BadConstruction", 0, 100, 7, HistogramBase::kNoFlags);
451   EXPECT_EQ(NULL, bad_histogram);
452   bad_histogram = Histogram::FactoryGet(
453       "BadConstruction", 0, 99, 8, HistogramBase::kNoFlags);
454   EXPECT_EQ(NULL, bad_histogram);
455 
456   HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
457       "BadConstructionLinear", 0, 100, 8, HistogramBase::kNoFlags);
458   EXPECT_TRUE(linear_histogram->HasConstructionArguments(1, 100, 8));
459 
460   // Try to get the same histogram name with different arguments.
461   bad_histogram = LinearHistogram::FactoryGet(
462       "BadConstructionLinear", 0, 100, 7, HistogramBase::kNoFlags);
463   EXPECT_EQ(NULL, bad_histogram);
464   bad_histogram = LinearHistogram::FactoryGet(
465       "BadConstructionLinear", 10, 100, 8, HistogramBase::kNoFlags);
466   EXPECT_EQ(NULL, bad_histogram);
467 }
468 
469 #if GTEST_HAS_DEATH_TEST
470 // For Histogram, LinearHistogram and CustomHistogram, the minimum for a
471 // declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX -
472 // 1). But we accept ranges exceeding those limits, and silently clamped to
473 // those limits. This is for backwards compatibility.
TEST(HistogramDeathTest,BadRangesTest)474 TEST(HistogramDeathTest, BadRangesTest) {
475   HistogramBase* histogram = Histogram::FactoryGet(
476       "BadRanges", 0, HistogramBase::kSampleType_MAX, 8,
477       HistogramBase::kNoFlags);
478   EXPECT_TRUE(
479       histogram->HasConstructionArguments(
480           1, HistogramBase::kSampleType_MAX - 1, 8));
481 
482   HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
483       "BadRangesLinear", 0, HistogramBase::kSampleType_MAX, 8,
484       HistogramBase::kNoFlags);
485   EXPECT_TRUE(
486       linear_histogram->HasConstructionArguments(
487           1, HistogramBase::kSampleType_MAX - 1, 8));
488 
489   vector<int> custom_ranges;
490   custom_ranges.push_back(0);
491   custom_ranges.push_back(5);
492   Histogram* custom_histogram = static_cast<Histogram*>(
493       CustomHistogram::FactoryGet(
494           "BadRangesCustom", custom_ranges, HistogramBase::kNoFlags));
495   const BucketRanges* ranges = custom_histogram->bucket_ranges();
496   ASSERT_EQ(3u, ranges->size());
497   EXPECT_EQ(0, ranges->range(0));
498   EXPECT_EQ(5, ranges->range(1));
499   EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
500 
501   // CustomHistogram does not accepts kSampleType_MAX as range.
502   custom_ranges.push_back(HistogramBase::kSampleType_MAX);
503   EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom2", custom_ranges,
504                                            HistogramBase::kNoFlags),
505                "");
506 
507   // CustomHistogram needs at least 1 valid range.
508   custom_ranges.clear();
509   custom_ranges.push_back(0);
510   EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges,
511                                            HistogramBase::kNoFlags),
512                "");
513 }
514 #endif
515 
516 }  // namespace base
517