OLD | NEW |
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 |
11 #include <climits> | 11 #include <climits> |
| 12 #include <memory> |
12 #include <string> | 13 #include <string> |
13 #include <vector> | 14 #include <vector> |
14 | 15 |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/memory/scoped_ptr.h" | |
17 #include "base/metrics/bucket_ranges.h" | 17 #include "base/metrics/bucket_ranges.h" |
18 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
19 #include "base/metrics/persistent_histogram_allocator.h" | 19 #include "base/metrics/persistent_histogram_allocator.h" |
20 #include "base/metrics/persistent_memory_allocator.h" | 20 #include "base/metrics/persistent_memory_allocator.h" |
21 #include "base/metrics/sample_vector.h" | 21 #include "base/metrics/sample_vector.h" |
22 #include "base/metrics/statistics_recorder.h" | 22 #include "base/metrics/statistics_recorder.h" |
23 #include "base/pickle.h" | 23 #include "base/pickle.h" |
24 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
25 #include "base/time/time.h" | 25 #include "base/time/time.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 } | 77 } |
78 | 78 |
79 void DestroyPersistentHistogramAllocator() { | 79 void DestroyPersistentHistogramAllocator() { |
80 allocator_ = nullptr; | 80 allocator_ = nullptr; |
81 PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting(); | 81 PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting(); |
82 } | 82 } |
83 | 83 |
84 const bool use_persistent_histogram_allocator_; | 84 const bool use_persistent_histogram_allocator_; |
85 | 85 |
86 StatisticsRecorder* statistics_recorder_ = nullptr; | 86 StatisticsRecorder* statistics_recorder_ = nullptr; |
87 scoped_ptr<char[]> allocator_memory_; | 87 std::unique_ptr<char[]> allocator_memory_; |
88 PersistentMemoryAllocator* allocator_ = nullptr; | 88 PersistentMemoryAllocator* allocator_ = nullptr; |
89 | 89 |
90 private: | 90 private: |
91 DISALLOW_COPY_AND_ASSIGN(HistogramTest); | 91 DISALLOW_COPY_AND_ASSIGN(HistogramTest); |
92 }; | 92 }; |
93 | 93 |
94 // Run all HistogramTest cases with both heap and persistent memory. | 94 // Run all HistogramTest cases with both heap and persistent memory. |
95 INSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest, testing::Bool()); | 95 INSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest, testing::Bool()); |
96 | 96 |
97 | 97 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 static bool already_run = false; | 129 static bool already_run = false; |
130 if (already_run) | 130 if (already_run) |
131 return; | 131 return; |
132 already_run = true; | 132 already_run = true; |
133 | 133 |
134 LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10); | 134 LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10); |
135 LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10); | 135 LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10); |
136 HistogramBase* histogram = LinearHistogram::FactoryGet( | 136 HistogramBase* histogram = LinearHistogram::FactoryGet( |
137 "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags); | 137 "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags); |
138 | 138 |
139 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); | 139 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); |
140 EXPECT_EQ(2, samples->TotalCount()); | 140 EXPECT_EQ(2, samples->TotalCount()); |
141 EXPECT_EQ(2, samples->GetCount(10)); | 141 EXPECT_EQ(2, samples->GetCount(10)); |
142 } | 142 } |
143 | 143 |
144 // Check that delta calculations work correct. | 144 // Check that delta calculations work correct. |
145 TEST_P(HistogramTest, DeltaTest) { | 145 TEST_P(HistogramTest, DeltaTest) { |
146 HistogramBase* histogram = | 146 HistogramBase* histogram = |
147 Histogram::FactoryGet("DeltaHistogram", 1, 64, 8, | 147 Histogram::FactoryGet("DeltaHistogram", 1, 64, 8, |
148 HistogramBase::kNoFlags); | 148 HistogramBase::kNoFlags); |
149 histogram->Add(1); | 149 histogram->Add(1); |
150 histogram->Add(10); | 150 histogram->Add(10); |
151 histogram->Add(50); | 151 histogram->Add(50); |
152 | 152 |
153 scoped_ptr<HistogramSamples> samples = histogram->SnapshotDelta(); | 153 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta(); |
154 EXPECT_EQ(3, samples->TotalCount()); | 154 EXPECT_EQ(3, samples->TotalCount()); |
155 EXPECT_EQ(1, samples->GetCount(1)); | 155 EXPECT_EQ(1, samples->GetCount(1)); |
156 EXPECT_EQ(1, samples->GetCount(10)); | 156 EXPECT_EQ(1, samples->GetCount(10)); |
157 EXPECT_EQ(1, samples->GetCount(50)); | 157 EXPECT_EQ(1, samples->GetCount(50)); |
158 EXPECT_EQ(samples->TotalCount(), samples->redundant_count()); | 158 EXPECT_EQ(samples->TotalCount(), samples->redundant_count()); |
159 | 159 |
160 samples = histogram->SnapshotDelta(); | 160 samples = histogram->SnapshotDelta(); |
161 EXPECT_EQ(0, samples->TotalCount()); | 161 EXPECT_EQ(0, samples->TotalCount()); |
162 | 162 |
163 histogram->Add(10); | 163 histogram->Add(10); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 323 |
324 TEST_P(HistogramTest, AddCountTest) { | 324 TEST_P(HistogramTest, AddCountTest) { |
325 const size_t kBucketCount = 50; | 325 const size_t kBucketCount = 50; |
326 Histogram* histogram = static_cast<Histogram*>( | 326 Histogram* histogram = static_cast<Histogram*>( |
327 Histogram::FactoryGet("AddCountHistogram", 10, 100, kBucketCount, | 327 Histogram::FactoryGet("AddCountHistogram", 10, 100, kBucketCount, |
328 HistogramBase::kNoFlags)); | 328 HistogramBase::kNoFlags)); |
329 | 329 |
330 histogram->AddCount(20, 15); | 330 histogram->AddCount(20, 15); |
331 histogram->AddCount(30, 14); | 331 histogram->AddCount(30, 14); |
332 | 332 |
333 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); | 333 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); |
334 EXPECT_EQ(29, samples->TotalCount()); | 334 EXPECT_EQ(29, samples->TotalCount()); |
335 EXPECT_EQ(15, samples->GetCount(20)); | 335 EXPECT_EQ(15, samples->GetCount(20)); |
336 EXPECT_EQ(14, samples->GetCount(30)); | 336 EXPECT_EQ(14, samples->GetCount(30)); |
337 | 337 |
338 histogram->AddCount(20, 25); | 338 histogram->AddCount(20, 25); |
339 histogram->AddCount(30, 24); | 339 histogram->AddCount(30, 24); |
340 | 340 |
341 scoped_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples(); | 341 std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples(); |
342 EXPECT_EQ(78, samples2->TotalCount()); | 342 EXPECT_EQ(78, samples2->TotalCount()); |
343 EXPECT_EQ(40, samples2->GetCount(20)); | 343 EXPECT_EQ(40, samples2->GetCount(20)); |
344 EXPECT_EQ(38, samples2->GetCount(30)); | 344 EXPECT_EQ(38, samples2->GetCount(30)); |
345 } | 345 } |
346 | 346 |
347 TEST_P(HistogramTest, AddCount_LargeValuesDontOverflow) { | 347 TEST_P(HistogramTest, AddCount_LargeValuesDontOverflow) { |
348 const size_t kBucketCount = 50; | 348 const size_t kBucketCount = 50; |
349 Histogram* histogram = static_cast<Histogram*>( | 349 Histogram* histogram = static_cast<Histogram*>( |
350 Histogram::FactoryGet("AddCountHistogram", 10, 1000000000, kBucketCount, | 350 Histogram::FactoryGet("AddCountHistogram", 10, 1000000000, kBucketCount, |
351 HistogramBase::kNoFlags)); | 351 HistogramBase::kNoFlags)); |
352 | 352 |
353 histogram->AddCount(200000000, 15); | 353 histogram->AddCount(200000000, 15); |
354 histogram->AddCount(300000000, 14); | 354 histogram->AddCount(300000000, 14); |
355 | 355 |
356 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); | 356 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); |
357 EXPECT_EQ(29, samples->TotalCount()); | 357 EXPECT_EQ(29, samples->TotalCount()); |
358 EXPECT_EQ(15, samples->GetCount(200000000)); | 358 EXPECT_EQ(15, samples->GetCount(200000000)); |
359 EXPECT_EQ(14, samples->GetCount(300000000)); | 359 EXPECT_EQ(14, samples->GetCount(300000000)); |
360 | 360 |
361 histogram->AddCount(200000000, 25); | 361 histogram->AddCount(200000000, 25); |
362 histogram->AddCount(300000000, 24); | 362 histogram->AddCount(300000000, 24); |
363 | 363 |
364 scoped_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples(); | 364 std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples(); |
365 EXPECT_EQ(78, samples2->TotalCount()); | 365 EXPECT_EQ(78, samples2->TotalCount()); |
366 EXPECT_EQ(40, samples2->GetCount(200000000)); | 366 EXPECT_EQ(40, samples2->GetCount(200000000)); |
367 EXPECT_EQ(38, samples2->GetCount(300000000)); | 367 EXPECT_EQ(38, samples2->GetCount(300000000)); |
368 EXPECT_EQ(19400000000LL, samples2->sum()); | 368 EXPECT_EQ(19400000000LL, samples2->sum()); |
369 } | 369 } |
370 | 370 |
371 // Make sure histogram handles out-of-bounds data gracefully. | 371 // Make sure histogram handles out-of-bounds data gracefully. |
372 TEST_P(HistogramTest, BoundsTest) { | 372 TEST_P(HistogramTest, BoundsTest) { |
373 const size_t kBucketCount = 50; | 373 const size_t kBucketCount = 50; |
374 Histogram* histogram = static_cast<Histogram*>( | 374 Histogram* histogram = static_cast<Histogram*>( |
375 Histogram::FactoryGet("Bounded", 10, 100, kBucketCount, | 375 Histogram::FactoryGet("Bounded", 10, 100, kBucketCount, |
376 HistogramBase::kNoFlags)); | 376 HistogramBase::kNoFlags)); |
377 | 377 |
378 // Put two samples "out of bounds" above and below. | 378 // Put two samples "out of bounds" above and below. |
379 histogram->Add(5); | 379 histogram->Add(5); |
380 histogram->Add(-50); | 380 histogram->Add(-50); |
381 | 381 |
382 histogram->Add(100); | 382 histogram->Add(100); |
383 histogram->Add(10000); | 383 histogram->Add(10000); |
384 | 384 |
385 // Verify they landed in the underflow, and overflow buckets. | 385 // Verify they landed in the underflow, and overflow buckets. |
386 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); | 386 std::unique_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); |
387 EXPECT_EQ(2, samples->GetCountAtIndex(0)); | 387 EXPECT_EQ(2, samples->GetCountAtIndex(0)); |
388 EXPECT_EQ(0, samples->GetCountAtIndex(1)); | 388 EXPECT_EQ(0, samples->GetCountAtIndex(1)); |
389 size_t array_size = histogram->bucket_count(); | 389 size_t array_size = histogram->bucket_count(); |
390 EXPECT_EQ(kBucketCount, array_size); | 390 EXPECT_EQ(kBucketCount, array_size); |
391 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2)); | 391 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2)); |
392 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1)); | 392 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1)); |
393 | 393 |
394 std::vector<int> custom_ranges; | 394 std::vector<int> custom_ranges; |
395 custom_ranges.push_back(10); | 395 custom_ranges.push_back(10); |
396 custom_ranges.push_back(50); | 396 custom_ranges.push_back(50); |
397 custom_ranges.push_back(100); | 397 custom_ranges.push_back(100); |
398 Histogram* test_custom_histogram = static_cast<Histogram*>( | 398 Histogram* test_custom_histogram = static_cast<Histogram*>( |
399 CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram", | 399 CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram", |
400 custom_ranges, HistogramBase::kNoFlags)); | 400 custom_ranges, HistogramBase::kNoFlags)); |
401 | 401 |
402 // Put two samples "out of bounds" above and below. | 402 // Put two samples "out of bounds" above and below. |
403 test_custom_histogram->Add(5); | 403 test_custom_histogram->Add(5); |
404 test_custom_histogram->Add(-50); | 404 test_custom_histogram->Add(-50); |
405 test_custom_histogram->Add(100); | 405 test_custom_histogram->Add(100); |
406 test_custom_histogram->Add(1000); | 406 test_custom_histogram->Add(1000); |
407 test_custom_histogram->Add(INT_MAX); | 407 test_custom_histogram->Add(INT_MAX); |
408 | 408 |
409 // Verify they landed in the underflow, and overflow buckets. | 409 // Verify they landed in the underflow, and overflow buckets. |
410 scoped_ptr<SampleVector> custom_samples = | 410 std::unique_ptr<SampleVector> custom_samples = |
411 test_custom_histogram->SnapshotSampleVector(); | 411 test_custom_histogram->SnapshotSampleVector(); |
412 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0)); | 412 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0)); |
413 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1)); | 413 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1)); |
414 size_t bucket_count = test_custom_histogram->bucket_count(); | 414 size_t bucket_count = test_custom_histogram->bucket_count(); |
415 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2)); | 415 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2)); |
416 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1)); | 416 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1)); |
417 } | 417 } |
418 | 418 |
419 // Check to be sure samples land as expected is "correct" buckets. | 419 // Check to be sure samples land as expected is "correct" buckets. |
420 TEST_P(HistogramTest, BucketPlacementTest) { | 420 TEST_P(HistogramTest, BucketPlacementTest) { |
421 Histogram* histogram = static_cast<Histogram*>( | 421 Histogram* histogram = static_cast<Histogram*>( |
422 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | 422 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); |
423 | 423 |
424 // Add i+1 samples to the i'th bucket. | 424 // Add i+1 samples to the i'th bucket. |
425 histogram->Add(0); | 425 histogram->Add(0); |
426 int power_of_2 = 1; | 426 int power_of_2 = 1; |
427 for (int i = 1; i < 8; i++) { | 427 for (int i = 1; i < 8; i++) { |
428 for (int j = 0; j <= i; j++) | 428 for (int j = 0; j <= i; j++) |
429 histogram->Add(power_of_2); | 429 histogram->Add(power_of_2); |
430 power_of_2 *= 2; | 430 power_of_2 *= 2; |
431 } | 431 } |
432 | 432 |
433 // Check to see that the bucket counts reflect our additions. | 433 // Check to see that the bucket counts reflect our additions. |
434 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); | 434 std::unique_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); |
435 for (int i = 0; i < 8; i++) | 435 for (int i = 0; i < 8; i++) |
436 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i)); | 436 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i)); |
437 } | 437 } |
438 | 438 |
439 TEST_P(HistogramTest, CorruptSampleCounts) { | 439 TEST_P(HistogramTest, CorruptSampleCounts) { |
440 Histogram* histogram = static_cast<Histogram*>( | 440 Histogram* histogram = static_cast<Histogram*>( |
441 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | 441 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); |
442 | 442 |
443 // Add some samples. | 443 // Add some samples. |
444 histogram->Add(20); | 444 histogram->Add(20); |
445 histogram->Add(40); | 445 histogram->Add(40); |
446 | 446 |
447 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); | 447 std::unique_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); |
448 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, | 448 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, |
449 histogram->FindCorruption(*snapshot)); | 449 histogram->FindCorruption(*snapshot)); |
450 EXPECT_EQ(2, snapshot->redundant_count()); | 450 EXPECT_EQ(2, snapshot->redundant_count()); |
451 EXPECT_EQ(2, snapshot->TotalCount()); | 451 EXPECT_EQ(2, snapshot->TotalCount()); |
452 | 452 |
453 snapshot->counts_[3] += 100; // Sample count won't match redundant count. | 453 snapshot->counts_[3] += 100; // Sample count won't match redundant count. |
454 EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR, | 454 EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR, |
455 histogram->FindCorruption(*snapshot)); | 455 histogram->FindCorruption(*snapshot)); |
456 snapshot->counts_[2] -= 200; | 456 snapshot->counts_[2] -= 200; |
457 EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR, | 457 EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR, |
458 histogram->FindCorruption(*snapshot)); | 458 histogram->FindCorruption(*snapshot)); |
459 | 459 |
460 // But we can't spot a corruption if it is compensated for. | 460 // But we can't spot a corruption if it is compensated for. |
461 snapshot->counts_[1] += 100; | 461 snapshot->counts_[1] += 100; |
462 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, | 462 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, |
463 histogram->FindCorruption(*snapshot)); | 463 histogram->FindCorruption(*snapshot)); |
464 } | 464 } |
465 | 465 |
466 TEST_P(HistogramTest, CorruptBucketBounds) { | 466 TEST_P(HistogramTest, CorruptBucketBounds) { |
467 Histogram* histogram = static_cast<Histogram*>( | 467 Histogram* histogram = static_cast<Histogram*>( |
468 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | 468 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); |
469 | 469 |
470 scoped_ptr<HistogramSamples> snapshot = histogram->SnapshotSamples(); | 470 std::unique_ptr<HistogramSamples> snapshot = histogram->SnapshotSamples(); |
471 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, | 471 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, |
472 histogram->FindCorruption(*snapshot)); | 472 histogram->FindCorruption(*snapshot)); |
473 | 473 |
474 BucketRanges* bucket_ranges = | 474 BucketRanges* bucket_ranges = |
475 const_cast<BucketRanges*>(histogram->bucket_ranges()); | 475 const_cast<BucketRanges*>(histogram->bucket_ranges()); |
476 HistogramBase::Sample tmp = bucket_ranges->range(1); | 476 HistogramBase::Sample tmp = bucket_ranges->range(1); |
477 bucket_ranges->set_range(1, bucket_ranges->range(2)); | 477 bucket_ranges->set_range(1, bucket_ranges->range(2)); |
478 bucket_ranges->set_range(2, tmp); | 478 bucket_ranges->set_range(2, tmp); |
479 EXPECT_EQ( | 479 EXPECT_EQ( |
480 HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR, | 480 HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR, |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 // CustomHistogram needs at least 1 valid range. | 703 // CustomHistogram needs at least 1 valid range. |
704 custom_ranges.clear(); | 704 custom_ranges.clear(); |
705 custom_ranges.push_back(0); | 705 custom_ranges.push_back(0); |
706 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, | 706 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, |
707 HistogramBase::kNoFlags), | 707 HistogramBase::kNoFlags), |
708 ""); | 708 ""); |
709 } | 709 } |
710 #endif | 710 #endif |
711 | 711 |
712 } // namespace base | 712 } // namespace base |
OLD | NEW |