| 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 <string> | 12 #include <string> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/memory/scoped_ptr.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/histogram_persistence.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" |
| 27 | 27 |
| 28 namespace base { | 28 namespace base { |
| 29 | 29 |
| 30 // Test parameter indicates if a persistent memory allocator should be used | 30 // Test parameter indicates if a persistent memory allocator should be used |
| 31 // for histogram allocation. False will allocate histograms from the process | 31 // for histogram allocation. False will allocate histograms from the process |
| 32 // heap. | 32 // heap. |
| 33 class HistogramTest : public testing::TestWithParam<bool> { | 33 class HistogramTest : public testing::TestWithParam<bool> { |
| 34 protected: | 34 protected: |
| 35 const int32_t kAllocatorMemorySize = 8 << 20; // 8 MiB | 35 const int32_t kAllocatorMemorySize = 8 << 20; // 8 MiB |
| 36 | 36 |
| 37 HistogramTest() : use_persistent_histogram_allocator_(GetParam()) {} | 37 HistogramTest() : use_persistent_histogram_allocator_(GetParam()) {} |
| 38 | 38 |
| 39 void SetUp() override { | 39 void SetUp() override { |
| 40 // Each test will have a clean state (no Histogram / BucketRanges | 40 // Each test will have a clean state (no Histogram / BucketRanges |
| 41 // registered). | 41 // registered). |
| 42 InitializeStatisticsRecorder(); | 42 InitializeStatisticsRecorder(); |
| 43 if (use_persistent_histogram_allocator_) | 43 if (use_persistent_histogram_allocator_) |
| 44 CreatePersistentMemoryAllocator(); | 44 CreatePersistentHistogramAllocator(); |
| 45 } | 45 } |
| 46 | 46 |
| 47 void TearDown() override { | 47 void TearDown() override { |
| 48 if (allocator_) { | 48 if (allocator_) { |
| 49 ASSERT_FALSE(allocator_->IsFull()); | 49 ASSERT_FALSE(allocator_->IsFull()); |
| 50 ASSERT_FALSE(allocator_->IsCorrupt()); | 50 ASSERT_FALSE(allocator_->IsCorrupt()); |
| 51 } | 51 } |
| 52 UninitializeStatisticsRecorder(); | 52 UninitializeStatisticsRecorder(); |
| 53 DestroyPersistentMemoryAllocator(); | 53 DestroyPersistentHistogramAllocator(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 void InitializeStatisticsRecorder() { | 56 void InitializeStatisticsRecorder() { |
| 57 StatisticsRecorder::ResetForTesting(); | 57 StatisticsRecorder::ResetForTesting(); |
| 58 statistics_recorder_ = new StatisticsRecorder(); | 58 statistics_recorder_ = new StatisticsRecorder(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 void UninitializeStatisticsRecorder() { | 61 void UninitializeStatisticsRecorder() { |
| 62 delete statistics_recorder_; | 62 delete statistics_recorder_; |
| 63 statistics_recorder_ = NULL; | 63 statistics_recorder_ = NULL; |
| 64 } | 64 } |
| 65 | 65 |
| 66 void CreatePersistentMemoryAllocator() { | 66 void CreatePersistentHistogramAllocator() { |
| 67 // By getting the results-histogram before any persistent allocator | 67 // By getting the results-histogram before any persistent allocator |
| 68 // is attached, that histogram is guaranteed not to be stored in | 68 // is attached, that histogram is guaranteed not to be stored in |
| 69 // any persistent memory segment (which simplifies some tests). | 69 // any persistent memory segment (which simplifies some tests). |
| 70 GetCreateHistogramResultHistogram(); | 70 PersistentHistogramAllocator::GetCreateHistogramResultHistogram(); |
| 71 | 71 |
| 72 if (!allocator_memory_) | 72 if (!allocator_memory_) |
| 73 allocator_memory_.reset(new char[kAllocatorMemorySize]); | 73 allocator_memory_.reset(new char[kAllocatorMemorySize]); |
| 74 | 74 |
| 75 delete ReleasePersistentHistogramMemoryAllocatorForTesting(); | 75 PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting(); |
| 76 memset(allocator_memory_.get(), 0, kAllocatorMemorySize); | 76 memset(allocator_memory_.get(), 0, kAllocatorMemorySize); |
| 77 SetPersistentHistogramMemoryAllocator( | 77 PersistentHistogramAllocator::CreateGlobalAllocatorOnPersistentMemory( |
| 78 new PersistentMemoryAllocator( | 78 allocator_memory_.get(), kAllocatorMemorySize, 0, 0, |
| 79 allocator_memory_.get(), kAllocatorMemorySize, 0, | 79 "HistogramAllocatorTest"); |
| 80 0, "HistogramAllocatorTest", false)); | 80 allocator_ = |
| 81 allocator_ = GetPersistentHistogramMemoryAllocator(); | 81 PersistentHistogramAllocator::GetGlobalAllocator()->memory_allocator(); |
| 82 } | 82 } |
| 83 | 83 |
| 84 void DestroyPersistentMemoryAllocator() { | 84 void DestroyPersistentHistogramAllocator() { |
| 85 allocator_ = nullptr; | 85 allocator_ = nullptr; |
| 86 delete ReleasePersistentHistogramMemoryAllocatorForTesting(); | 86 PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting(); |
| 87 } | 87 } |
| 88 | 88 |
| 89 const bool use_persistent_histogram_allocator_; | 89 const bool use_persistent_histogram_allocator_; |
| 90 | 90 |
| 91 StatisticsRecorder* statistics_recorder_ = nullptr; | 91 StatisticsRecorder* statistics_recorder_ = nullptr; |
| 92 scoped_ptr<char[]> allocator_memory_; | 92 scoped_ptr<char[]> allocator_memory_; |
| 93 PersistentMemoryAllocator* allocator_ = nullptr; | 93 PersistentMemoryAllocator* allocator_ = nullptr; |
| 94 | 94 |
| 95 private: | 95 private: |
| 96 DISALLOW_COPY_AND_ASSIGN(HistogramTest); | 96 DISALLOW_COPY_AND_ASSIGN(HistogramTest); |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 // Run all HistogramTest cases with both heap and persistent memory. | 99 // Run all HistogramTest cases with both heap and persistent memory. |
| 100 INSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest, | 100 INSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest, testing::Bool()); |
| 101 testing::Bool()); | |
| 102 | 101 |
| 103 | 102 |
| 104 // Check for basic syntax and use. | 103 // Check for basic syntax and use. |
| 105 TEST_P(HistogramTest, BasicTest) { | 104 TEST_P(HistogramTest, BasicTest) { |
| 106 // Try basic construction | 105 // Try basic construction |
| 107 HistogramBase* histogram = Histogram::FactoryGet( | 106 HistogramBase* histogram = Histogram::FactoryGet( |
| 108 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags); | 107 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags); |
| 109 EXPECT_TRUE(histogram); | 108 EXPECT_TRUE(histogram); |
| 110 | 109 |
| 111 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( | 110 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( |
| 112 "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags); | 111 "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags); |
| 113 EXPECT_TRUE(linear_histogram); | 112 EXPECT_TRUE(linear_histogram); |
| 114 | 113 |
| 115 std::vector<int> custom_ranges; | 114 std::vector<int> custom_ranges; |
| 116 custom_ranges.push_back(1); | 115 custom_ranges.push_back(1); |
| 117 custom_ranges.push_back(5); | 116 custom_ranges.push_back(5); |
| 118 HistogramBase* custom_histogram = CustomHistogram::FactoryGet( | 117 HistogramBase* custom_histogram = CustomHistogram::FactoryGet( |
| 119 "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags); | 118 "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags); |
| 120 EXPECT_TRUE(custom_histogram); | 119 EXPECT_TRUE(custom_histogram); |
| 121 | 120 |
| 122 // Use standard macros (but with fixed samples) | 121 // Use standard macros (but with fixed samples) |
| 123 LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); | 122 LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); |
| 124 LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30); | 123 LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30); |
| 125 | 124 |
| 126 LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); | 125 LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); |
| 127 } | 126 } |
| 128 | 127 |
| 129 // Check for basic syntax and use with persistent allocator. | |
| 130 TEST_P(HistogramTest, PersistentTest) { | |
| 131 if (!use_persistent_histogram_allocator_) | |
| 132 return; | |
| 133 | |
| 134 PersistentMemoryAllocator::MemoryInfo meminfo0; | |
| 135 allocator_->GetMemoryInfo(&meminfo0); | |
| 136 | |
| 137 // Try basic construction | |
| 138 HistogramBase* histogram = Histogram::FactoryGet( | |
| 139 "TestHistogram", 1, 1000, 10, | |
| 140 HistogramBase::kIsPersistent); | |
| 141 EXPECT_TRUE(histogram); | |
| 142 histogram->CheckName("TestHistogram"); | |
| 143 PersistentMemoryAllocator::MemoryInfo meminfo1; | |
| 144 allocator_->GetMemoryInfo(&meminfo1); | |
| 145 EXPECT_GT(meminfo0.free, meminfo1.free); | |
| 146 | |
| 147 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( | |
| 148 "TestLinearHistogram", 1, 1000, 10, | |
| 149 HistogramBase::kIsPersistent); | |
| 150 EXPECT_TRUE(linear_histogram); | |
| 151 linear_histogram->CheckName("TestLinearHistogram"); | |
| 152 PersistentMemoryAllocator::MemoryInfo meminfo2; | |
| 153 allocator_->GetMemoryInfo(&meminfo2); | |
| 154 EXPECT_GT(meminfo1.free, meminfo2.free); | |
| 155 | |
| 156 HistogramBase* boolean_histogram = BooleanHistogram::FactoryGet( | |
| 157 "TestBooleanHistogram", HistogramBase::kIsPersistent); | |
| 158 EXPECT_TRUE(boolean_histogram); | |
| 159 boolean_histogram->CheckName("TestBooleanHistogram"); | |
| 160 PersistentMemoryAllocator::MemoryInfo meminfo3; | |
| 161 allocator_->GetMemoryInfo(&meminfo3); | |
| 162 EXPECT_GT(meminfo2.free, meminfo3.free); | |
| 163 | |
| 164 std::vector<int> custom_ranges; | |
| 165 custom_ranges.push_back(1); | |
| 166 custom_ranges.push_back(5); | |
| 167 HistogramBase* custom_histogram = CustomHistogram::FactoryGet( | |
| 168 "TestCustomHistogram", custom_ranges, | |
| 169 HistogramBase::kIsPersistent); | |
| 170 EXPECT_TRUE(custom_histogram); | |
| 171 custom_histogram->CheckName("TestCustomHistogram"); | |
| 172 PersistentMemoryAllocator::MemoryInfo meminfo4; | |
| 173 allocator_->GetMemoryInfo(&meminfo4); | |
| 174 EXPECT_GT(meminfo3.free, meminfo4.free); | |
| 175 | |
| 176 PersistentMemoryAllocator::Iterator iter; | |
| 177 uint32_t type; | |
| 178 allocator_->CreateIterator(&iter); | |
| 179 EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type)); // Histogram | |
| 180 EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type)); // LinearHistogram | |
| 181 EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type)); // BooleanHistogram | |
| 182 EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type)); // CustomHistogram | |
| 183 EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type)); | |
| 184 | |
| 185 // Create a second allocator and have it access the memory of the first. | |
| 186 scoped_ptr<HistogramBase> recovered; | |
| 187 PersistentMemoryAllocator recovery( | |
| 188 allocator_memory_.get(), kAllocatorMemorySize, 0, | |
| 189 0, std::string(), false); | |
| 190 recovery.CreateIterator(&iter); | |
| 191 | |
| 192 recovered.reset(GetNextPersistentHistogram(&recovery, &iter)); | |
| 193 ASSERT_TRUE(recovered); | |
| 194 recovered->CheckName("TestHistogram"); | |
| 195 | |
| 196 recovered.reset(GetNextPersistentHistogram(&recovery, &iter)); | |
| 197 ASSERT_TRUE(recovered); | |
| 198 recovered->CheckName("TestLinearHistogram"); | |
| 199 | |
| 200 recovered.reset(GetNextPersistentHistogram(&recovery, &iter)); | |
| 201 ASSERT_TRUE(recovered); | |
| 202 recovered->CheckName("TestBooleanHistogram"); | |
| 203 | |
| 204 recovered.reset(GetNextPersistentHistogram(&recovery, &iter)); | |
| 205 ASSERT_TRUE(recovered); | |
| 206 recovered->CheckName("TestCustomHistogram"); | |
| 207 | |
| 208 recovered.reset(GetNextPersistentHistogram(&recovery, &iter)); | |
| 209 EXPECT_FALSE(recovered); | |
| 210 | |
| 211 // Use standard macros (but with fixed samples) | |
| 212 LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); | |
| 213 LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30); | |
| 214 LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); | |
| 215 } | |
| 216 | |
| 217 // Check that the macro correctly matches histograms by name and records their | 128 // Check that the macro correctly matches histograms by name and records their |
| 218 // data together. | 129 // data together. |
| 219 TEST_P(HistogramTest, NameMatchTest) { | 130 TEST_P(HistogramTest, NameMatchTest) { |
| 220 // Macros that create hitograms have an internal static variable which will | 131 // Macros that create hitograms have an internal static variable which will |
| 221 // continue to point to those from the very first run of this method even | 132 // continue to point to those from the very first run of this method even |
| 222 // during subsequent runs. | 133 // during subsequent runs. |
| 223 static bool already_run = false; | 134 static bool already_run = false; |
| 224 if (already_run) | 135 if (already_run) |
| 225 return; | 136 return; |
| 226 already_run = true; | 137 already_run = true; |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 // CustomHistogram needs at least 1 valid range. | 708 // CustomHistogram needs at least 1 valid range. |
| 798 custom_ranges.clear(); | 709 custom_ranges.clear(); |
| 799 custom_ranges.push_back(0); | 710 custom_ranges.push_back(0); |
| 800 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, | 711 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, |
| 801 HistogramBase::kNoFlags), | 712 HistogramBase::kNoFlags), |
| 802 ""); | 713 ""); |
| 803 } | 714 } |
| 804 #endif | 715 #endif |
| 805 | 716 |
| 806 } // namespace base | 717 } // namespace base |
| OLD | NEW |