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 #include "base/metrics/histogram.h" 6 7 #include <limits.h> 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <algorithm> 12 #include <climits> 13 #include <vector> 14 15 #include "base/logging.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/metrics/bucket_ranges.h" 18 #include "base/metrics/histogram_macros.h" 19 #include "base/metrics/sample_vector.h" 20 #include "base/metrics/statistics_recorder.h" 21 #include "base/pickle.h" 22 #include "base/time/time.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 25 namespace base { 26 27 class HistogramTest : public testing::Test { 28 protected: 29 void SetUp() override { 30 // Each test will have a clean state (no Histogram / BucketRanges 31 // registered). 32 InitializeStatisticsRecorder(); 33 } 34 35 void TearDown() override { UninitializeStatisticsRecorder(); } 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 std::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 room. 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 std::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 std::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 std::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 // Test the AddCount function. 239 TEST_F(HistogramTest, AddCountTest) { 240 const size_t kBucketCount = 50; 241 Histogram* histogram = static_cast<Histogram*>( 242 Histogram::FactoryGet("AddCountHistogram", 10, 100, kBucketCount, 243 HistogramBase::kNoFlags)); 244 245 histogram->AddCount(20, 15); 246 histogram->AddCount(30, 14); 247 248 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); 249 EXPECT_EQ(29, samples->TotalCount()); 250 EXPECT_EQ(15, samples->GetCount(20)); 251 EXPECT_EQ(14, samples->GetCount(30)); 252 253 histogram->AddCount(20, 25); 254 histogram->AddCount(30, 24); 255 256 scoped_ptr<SampleVector> samples2 = histogram->SnapshotSampleVector(); 257 EXPECT_EQ(78, samples2->TotalCount()); 258 EXPECT_EQ(40, samples2->GetCount(20)); 259 EXPECT_EQ(38, samples2->GetCount(30)); 260 } 261 262 // Make sure histogram handles out-of-bounds data gracefully. 263 TEST_F(HistogramTest, BoundsTest) { 264 const size_t kBucketCount = 50; 265 Histogram* histogram = static_cast<Histogram*>( 266 Histogram::FactoryGet("Bounded", 10, 100, kBucketCount, 267 HistogramBase::kNoFlags)); 268 269 // Put two samples "out of bounds" above and below. 270 histogram->Add(5); 271 histogram->Add(-50); 272 273 histogram->Add(100); 274 histogram->Add(10000); 275 276 // Verify they landed in the underflow, and overflow buckets. 277 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); 278 EXPECT_EQ(2, samples->GetCountAtIndex(0)); 279 EXPECT_EQ(0, samples->GetCountAtIndex(1)); 280 size_t array_size = histogram->bucket_count(); 281 EXPECT_EQ(kBucketCount, array_size); 282 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2)); 283 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1)); 284 285 std::vector<int> custom_ranges; 286 custom_ranges.push_back(10); 287 custom_ranges.push_back(50); 288 custom_ranges.push_back(100); 289 Histogram* test_custom_histogram = static_cast<Histogram*>( 290 CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram", 291 custom_ranges, HistogramBase::kNoFlags)); 292 293 // Put two samples "out of bounds" above and below. 294 test_custom_histogram->Add(5); 295 test_custom_histogram->Add(-50); 296 test_custom_histogram->Add(100); 297 test_custom_histogram->Add(1000); 298 test_custom_histogram->Add(INT_MAX); 299 300 // Verify they landed in the underflow, and overflow buckets. 301 scoped_ptr<SampleVector> custom_samples = 302 test_custom_histogram->SnapshotSampleVector(); 303 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0)); 304 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1)); 305 size_t bucket_count = test_custom_histogram->bucket_count(); 306 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2)); 307 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1)); 308 } 309 310 // Check to be sure samples land as expected is "correct" buckets. 311 TEST_F(HistogramTest, BucketPlacementTest) { 312 Histogram* histogram = static_cast<Histogram*>( 313 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); 314 315 // Add i+1 samples to the i'th bucket. 316 histogram->Add(0); 317 int power_of_2 = 1; 318 for (int i = 1; i < 8; i++) { 319 for (int j = 0; j <= i; j++) 320 histogram->Add(power_of_2); 321 power_of_2 *= 2; 322 } 323 324 // Check to see that the bucket counts reflect our additions. 325 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); 326 for (int i = 0; i < 8; i++) 327 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i)); 328 } 329 330 TEST_F(HistogramTest, CorruptSampleCounts) { 331 Histogram* histogram = static_cast<Histogram*>( 332 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); 333 334 // Add some samples. 335 histogram->Add(20); 336 histogram->Add(40); 337 338 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); 339 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, 340 histogram->FindCorruption(*snapshot)); 341 EXPECT_EQ(2, snapshot->redundant_count()); 342 EXPECT_EQ(2, snapshot->TotalCount()); 343 344 snapshot->counts_[3] += 100; // Sample count won't match redundant count. 345 EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR, 346 histogram->FindCorruption(*snapshot)); 347 snapshot->counts_[2] -= 200; 348 EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR, 349 histogram->FindCorruption(*snapshot)); 350 351 // But we can't spot a corruption if it is compensated for. 352 snapshot->counts_[1] += 100; 353 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, 354 histogram->FindCorruption(*snapshot)); 355 } 356 357 TEST_F(HistogramTest, CorruptBucketBounds) { 358 Histogram* histogram = static_cast<Histogram*>( 359 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); 360 361 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); 362 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, 363 histogram->FindCorruption(*snapshot)); 364 365 BucketRanges* bucket_ranges = 366 const_cast<BucketRanges*>(histogram->bucket_ranges()); 367 HistogramBase::Sample tmp = bucket_ranges->range(1); 368 bucket_ranges->set_range(1, bucket_ranges->range(2)); 369 bucket_ranges->set_range(2, tmp); 370 EXPECT_EQ( 371 HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR, 372 histogram->FindCorruption(*snapshot)); 373 374 bucket_ranges->set_range(2, bucket_ranges->range(1)); 375 bucket_ranges->set_range(1, tmp); 376 EXPECT_EQ(0, histogram->FindCorruption(*snapshot)); 377 378 // Show that two simple changes don't offset each other 379 bucket_ranges->set_range(3, bucket_ranges->range(3) + 1); 380 EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR, 381 histogram->FindCorruption(*snapshot)); 382 383 bucket_ranges->set_range(4, bucket_ranges->range(4) - 1); 384 EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR, 385 histogram->FindCorruption(*snapshot)); 386 387 // Repair histogram so that destructor won't DCHECK(). 388 bucket_ranges->set_range(3, bucket_ranges->range(3) - 1); 389 bucket_ranges->set_range(4, bucket_ranges->range(4) + 1); 390 } 391 392 TEST_F(HistogramTest, HistogramSerializeInfo) { 393 Histogram* histogram = static_cast<Histogram*>( 394 Histogram::FactoryGet("Histogram", 1, 64, 8, 395 HistogramBase::kIPCSerializationSourceFlag)); 396 Pickle pickle; 397 histogram->SerializeInfo(&pickle); 398 399 PickleIterator iter(pickle); 400 401 int type; 402 EXPECT_TRUE(iter.ReadInt(&type)); 403 EXPECT_EQ(HISTOGRAM, type); 404 405 std::string name; 406 EXPECT_TRUE(iter.ReadString(&name)); 407 EXPECT_EQ("Histogram", name); 408 409 int flag; 410 EXPECT_TRUE(iter.ReadInt(&flag)); 411 EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag, flag); 412 413 int min; 414 EXPECT_TRUE(iter.ReadInt(&min)); 415 EXPECT_EQ(1, min); 416 417 int max; 418 EXPECT_TRUE(iter.ReadInt(&max)); 419 EXPECT_EQ(64, max); 420 421 int64_t bucket_count; 422 EXPECT_TRUE(iter.ReadInt64(&bucket_count)); 423 EXPECT_EQ(8, bucket_count); 424 425 uint32_t checksum; 426 EXPECT_TRUE(iter.ReadUInt32(&checksum)); 427 EXPECT_EQ(histogram->bucket_ranges()->checksum(), checksum); 428 429 // No more data in the pickle. 430 EXPECT_FALSE(iter.SkipBytes(1)); 431 } 432 433 TEST_F(HistogramTest, CustomHistogramSerializeInfo) { 434 std::vector<int> custom_ranges; 435 custom_ranges.push_back(10); 436 custom_ranges.push_back(100); 437 438 HistogramBase* custom_histogram = CustomHistogram::FactoryGet( 439 "TestCustomRangeBoundedHistogram", 440 custom_ranges, 441 HistogramBase::kNoFlags); 442 Pickle pickle; 443 custom_histogram->SerializeInfo(&pickle); 444 445 // Validate the pickle. 446 PickleIterator iter(pickle); 447 448 int i; 449 std::string s; 450 int64_t bucket_count; 451 uint32_t ui32; 452 EXPECT_TRUE(iter.ReadInt(&i) && iter.ReadString(&s) && iter.ReadInt(&i) && 453 iter.ReadInt(&i) && iter.ReadInt(&i) && 454 iter.ReadInt64(&bucket_count) && iter.ReadUInt32(&ui32)); 455 EXPECT_EQ(3, bucket_count); 456 457 int range; 458 EXPECT_TRUE(iter.ReadInt(&range)); 459 EXPECT_EQ(10, range); 460 EXPECT_TRUE(iter.ReadInt(&range)); 461 EXPECT_EQ(100, range); 462 463 // No more data in the pickle. 464 EXPECT_FALSE(iter.SkipBytes(1)); 465 } 466 467 TEST_F(HistogramTest, BadConstruction) { 468 HistogramBase* histogram = Histogram::FactoryGet( 469 "BadConstruction", 0, 100, 8, HistogramBase::kNoFlags); 470 EXPECT_TRUE(histogram->HasConstructionArguments(1, 100, 8)); 471 472 // Try to get the same histogram name with different arguments. 473 HistogramBase* bad_histogram = Histogram::FactoryGet( 474 "BadConstruction", 0, 100, 7, HistogramBase::kNoFlags); 475 EXPECT_EQ(NULL, bad_histogram); 476 bad_histogram = Histogram::FactoryGet( 477 "BadConstruction", 0, 99, 8, HistogramBase::kNoFlags); 478 EXPECT_EQ(NULL, bad_histogram); 479 480 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( 481 "BadConstructionLinear", 0, 100, 8, HistogramBase::kNoFlags); 482 EXPECT_TRUE(linear_histogram->HasConstructionArguments(1, 100, 8)); 483 484 // Try to get the same histogram name with different arguments. 485 bad_histogram = LinearHistogram::FactoryGet( 486 "BadConstructionLinear", 0, 100, 7, HistogramBase::kNoFlags); 487 EXPECT_EQ(NULL, bad_histogram); 488 bad_histogram = LinearHistogram::FactoryGet( 489 "BadConstructionLinear", 10, 100, 8, HistogramBase::kNoFlags); 490 EXPECT_EQ(NULL, bad_histogram); 491 } 492 493 #if GTEST_HAS_DEATH_TEST 494 // For Histogram, LinearHistogram and CustomHistogram, the minimum for a 495 // declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX - 496 // 1). But we accept ranges exceeding those limits, and silently clamped to 497 // those limits. This is for backwards compatibility. 498 TEST(HistogramDeathTest, BadRangesTest) { 499 HistogramBase* histogram = Histogram::FactoryGet( 500 "BadRanges", 0, HistogramBase::kSampleType_MAX, 8, 501 HistogramBase::kNoFlags); 502 EXPECT_TRUE( 503 histogram->HasConstructionArguments( 504 1, HistogramBase::kSampleType_MAX - 1, 8)); 505 506 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( 507 "BadRangesLinear", 0, HistogramBase::kSampleType_MAX, 8, 508 HistogramBase::kNoFlags); 509 EXPECT_TRUE( 510 linear_histogram->HasConstructionArguments( 511 1, HistogramBase::kSampleType_MAX - 1, 8)); 512 513 std::vector<int> custom_ranges; 514 custom_ranges.push_back(0); 515 custom_ranges.push_back(5); 516 Histogram* custom_histogram = static_cast<Histogram*>( 517 CustomHistogram::FactoryGet( 518 "BadRangesCustom", custom_ranges, HistogramBase::kNoFlags)); 519 const BucketRanges* ranges = custom_histogram->bucket_ranges(); 520 ASSERT_EQ(3u, ranges->size()); 521 EXPECT_EQ(0, ranges->range(0)); 522 EXPECT_EQ(5, ranges->range(1)); 523 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2)); 524 525 // CustomHistogram does not accepts kSampleType_MAX as range. 526 custom_ranges.push_back(HistogramBase::kSampleType_MAX); 527 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom2", custom_ranges, 528 HistogramBase::kNoFlags), 529 ""); 530 531 // CustomHistogram needs at least 1 valid range. 532 custom_ranges.clear(); 533 custom_ranges.push_back(0); 534 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, 535 HistogramBase::kNoFlags), 536 ""); 537 } 538 #endif 539 540 } // namespace base 541