Home | History | Annotate | Download | only in metrics
      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:
     27   virtual void SetUp() {
     28     // Each test will have a clean state (no Histogram / BucketRanges
     29     // registered).
     30     InitializeStatisticsRecorder();
     31   }
     32 
     33   virtual void TearDown() {
     34     UninitializeStatisticsRecorder();
     35   }
     36 
     37   void InitializeStatisticsRecorder() {
     38     statistics_recorder_ = new StatisticsRecorder();
     39   }
     40 
     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.
     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.
     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 
     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 
    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 
    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 
    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 
    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.
    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.
    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 
    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 
    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 
    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 
    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 
    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.
    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