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 |