Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: base/metrics/histogram_unittest.cc

Issue 2867303004: [histogram] Make histograms more resistant to overflows. (Closed)
Patch Set: final final fix Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/metrics/histogram_base.h ('k') | base/metrics/sparse_histogram.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/metrics/histogram.h" 5 #include "base/metrics/histogram.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 histogram->AddCount(200000000, 25); 394 histogram->AddCount(200000000, 25);
395 histogram->AddCount(300000000, 24); 395 histogram->AddCount(300000000, 24);
396 396
397 std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples(); 397 std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples();
398 EXPECT_EQ(78, samples2->TotalCount()); 398 EXPECT_EQ(78, samples2->TotalCount());
399 EXPECT_EQ(40, samples2->GetCount(200000000)); 399 EXPECT_EQ(40, samples2->GetCount(200000000));
400 EXPECT_EQ(38, samples2->GetCount(300000000)); 400 EXPECT_EQ(38, samples2->GetCount(300000000));
401 EXPECT_EQ(19400000000LL, samples2->sum()); 401 EXPECT_EQ(19400000000LL, samples2->sum());
402 } 402 }
403 403
404 // Some metrics are designed so that they are guaranteed not to overflow between
405 // snapshots, but could overflow over a long-running session.
406 // Make sure that counts returned by Histogram::SnapshotDelta do not overflow
407 // even when a total count (returned by Histogram::SnapshotSample) does.
408 TEST_P(HistogramTest, AddCount_LargeCountsDontOverflow) {
409 const size_t kBucketCount = 10;
410 Histogram* histogram = static_cast<Histogram*>(Histogram::FactoryGet(
411 "AddCountHistogram", 10, 50, kBucketCount, HistogramBase::kNoFlags));
412
413 const int count = (1 << 30) - 1;
414
415 // Repeat N times to make sure that there is no internal value overflow.
416 for (int i = 0; i < 10; ++i) {
417 histogram->AddCount(42, count);
418 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
419 EXPECT_EQ(count, samples->TotalCount());
420 EXPECT_EQ(count, samples->GetCount(42));
421 }
422 }
423
404 // Make sure histogram handles out-of-bounds data gracefully. 424 // Make sure histogram handles out-of-bounds data gracefully.
405 TEST_P(HistogramTest, BoundsTest) { 425 TEST_P(HistogramTest, BoundsTest) {
406 const size_t kBucketCount = 50; 426 const size_t kBucketCount = 50;
407 Histogram* histogram = static_cast<Histogram*>( 427 Histogram* histogram = static_cast<Histogram*>(
408 Histogram::FactoryGet("Bounded", 10, 100, kBucketCount, 428 Histogram::FactoryGet("Bounded", 10, 100, kBucketCount,
409 HistogramBase::kNoFlags)); 429 HistogramBase::kNoFlags));
410 430
411 // Put two samples "out of bounds" above and below. 431 // Put two samples "out of bounds" above and below.
412 histogram->Add(5); 432 histogram->Add(5);
413 histogram->Add(-50); 433 histogram->Add(-50);
414 434
415 histogram->Add(100); 435 histogram->Add(100);
416 histogram->Add(10000); 436 histogram->Add(10000);
417 437
418 // Verify they landed in the underflow, and overflow buckets. 438 // Verify they landed in the underflow, and overflow buckets.
419 std::unique_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); 439 std::unique_ptr<SampleVector> samples = histogram->SnapshotAllSamples();
420 EXPECT_EQ(2, samples->GetCountAtIndex(0)); 440 EXPECT_EQ(2, samples->GetCountAtIndex(0));
421 EXPECT_EQ(0, samples->GetCountAtIndex(1)); 441 EXPECT_EQ(0, samples->GetCountAtIndex(1));
422 size_t array_size = histogram->bucket_count(); 442 size_t array_size = histogram->bucket_count();
423 EXPECT_EQ(kBucketCount, array_size); 443 EXPECT_EQ(kBucketCount, array_size);
424 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2)); 444 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2));
425 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1)); 445 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1));
426 446
427 std::vector<int> custom_ranges; 447 std::vector<int> custom_ranges;
428 custom_ranges.push_back(10); 448 custom_ranges.push_back(10);
429 custom_ranges.push_back(50); 449 custom_ranges.push_back(50);
430 custom_ranges.push_back(100); 450 custom_ranges.push_back(100);
431 Histogram* test_custom_histogram = static_cast<Histogram*>( 451 Histogram* test_custom_histogram = static_cast<Histogram*>(
432 CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram", 452 CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram",
433 custom_ranges, HistogramBase::kNoFlags)); 453 custom_ranges, HistogramBase::kNoFlags));
434 454
435 // Put two samples "out of bounds" above and below. 455 // Put two samples "out of bounds" above and below.
436 test_custom_histogram->Add(5); 456 test_custom_histogram->Add(5);
437 test_custom_histogram->Add(-50); 457 test_custom_histogram->Add(-50);
438 test_custom_histogram->Add(100); 458 test_custom_histogram->Add(100);
439 test_custom_histogram->Add(1000); 459 test_custom_histogram->Add(1000);
440 test_custom_histogram->Add(INT_MAX); 460 test_custom_histogram->Add(INT_MAX);
441 461
442 // Verify they landed in the underflow, and overflow buckets. 462 // Verify they landed in the underflow, and overflow buckets.
443 std::unique_ptr<SampleVector> custom_samples = 463 std::unique_ptr<SampleVector> custom_samples =
444 test_custom_histogram->SnapshotSampleVector(); 464 test_custom_histogram->SnapshotAllSamples();
445 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0)); 465 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0));
446 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1)); 466 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1));
447 size_t bucket_count = test_custom_histogram->bucket_count(); 467 size_t bucket_count = test_custom_histogram->bucket_count();
448 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2)); 468 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2));
449 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1)); 469 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1));
450 } 470 }
451 471
452 // Check to be sure samples land as expected is "correct" buckets. 472 // Check to be sure samples land as expected is "correct" buckets.
453 TEST_P(HistogramTest, BucketPlacementTest) { 473 TEST_P(HistogramTest, BucketPlacementTest) {
454 Histogram* histogram = static_cast<Histogram*>( 474 Histogram* histogram = static_cast<Histogram*>(
455 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); 475 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
456 476
457 // Add i+1 samples to the i'th bucket. 477 // Add i+1 samples to the i'th bucket.
458 histogram->Add(0); 478 histogram->Add(0);
459 int power_of_2 = 1; 479 int power_of_2 = 1;
460 for (int i = 1; i < 8; i++) { 480 for (int i = 1; i < 8; i++) {
461 for (int j = 0; j <= i; j++) 481 for (int j = 0; j <= i; j++)
462 histogram->Add(power_of_2); 482 histogram->Add(power_of_2);
463 power_of_2 *= 2; 483 power_of_2 *= 2;
464 } 484 }
465 485
466 // Check to see that the bucket counts reflect our additions. 486 // Check to see that the bucket counts reflect our additions.
467 std::unique_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); 487 std::unique_ptr<SampleVector> samples = histogram->SnapshotAllSamples();
468 for (int i = 0; i < 8; i++) 488 for (int i = 0; i < 8; i++)
469 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i)); 489 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i));
470 } 490 }
471 491
472 TEST_P(HistogramTest, CorruptSampleCounts) { 492 TEST_P(HistogramTest, CorruptSampleCounts) {
473 // The internal code creates histograms via macros and thus keeps static 493 // The internal code creates histograms via macros and thus keeps static
474 // pointers to them. If those pointers are to persistent memory which will 494 // pointers to them. If those pointers are to persistent memory which will
475 // be free'd then any following calls to that code will crash with a 495 // be free'd then any following calls to that code will crash with a
476 // segmentation violation. 496 // segmentation violation.
477 if (use_persistent_histogram_allocator_) 497 if (use_persistent_histogram_allocator_)
478 return; 498 return;
479 499
480 Histogram* histogram = static_cast<Histogram*>( 500 Histogram* histogram = static_cast<Histogram*>(
481 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); 501 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
482 502
483 // Add some samples. 503 // Add some samples.
484 histogram->Add(20); 504 histogram->Add(20);
485 histogram->Add(40); 505 histogram->Add(40);
486 506
487 std::unique_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); 507 std::unique_ptr<SampleVector> snapshot = histogram->SnapshotAllSamples();
488 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, 508 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
489 histogram->FindCorruption(*snapshot)); 509 histogram->FindCorruption(*snapshot));
490 EXPECT_EQ(2, snapshot->redundant_count()); 510 EXPECT_EQ(2, snapshot->redundant_count());
491 EXPECT_EQ(2, snapshot->TotalCount()); 511 EXPECT_EQ(2, snapshot->TotalCount());
492 512
493 snapshot->counts()[3] += 100; // Sample count won't match redundant count. 513 snapshot->counts()[3] += 100; // Sample count won't match redundant count.
494 EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR, 514 EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR,
495 histogram->FindCorruption(*snapshot)); 515 histogram->FindCorruption(*snapshot));
496 snapshot->counts()[2] -= 200; 516 snapshot->counts()[2] -= 200;
497 EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR, 517 EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR,
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 // CustomHistogram needs at least 1 valid range. 763 // CustomHistogram needs at least 1 valid range.
744 custom_ranges.clear(); 764 custom_ranges.clear();
745 custom_ranges.push_back(0); 765 custom_ranges.push_back(0);
746 EXPECT_DEATH_IF_SUPPORTED( 766 EXPECT_DEATH_IF_SUPPORTED(
747 CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, 767 CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges,
748 HistogramBase::kNoFlags), 768 HistogramBase::kNoFlags),
749 ""); 769 "");
750 } 770 }
751 771
752 } // namespace base 772 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/histogram_base.h ('k') | base/metrics/sparse_histogram.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698