| 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 // Test of Histogram class | 5 // Test of Histogram class |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/metrics/bucket_ranges.h" | 12 #include "base/metrics/bucket_ranges.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/metrics/statistics_recorder.h" | 14 #include "base/metrics/statistics_recorder.h" |
| 15 #include "base/time.h" | 15 #include "base/time.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using std::vector; |
| 19 |
| 18 namespace base { | 20 namespace base { |
| 19 | 21 |
| 20 class HistogramTest : public testing::Test { | |
| 21 }; | |
| 22 | |
| 23 // Check for basic syntax and use. | 22 // Check for basic syntax and use. |
| 24 TEST(HistogramTest, StartupShutdownTest) { | 23 TEST(HistogramTest, BasicTest) { |
| 25 // Try basic construction | 24 // Try basic construction |
| 26 Histogram* histogram(Histogram::FactoryGet( | 25 Histogram* histogram(Histogram::FactoryGet( |
| 27 "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); | 26 "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); |
| 28 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); | 27 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); |
| 29 Histogram* histogram1(Histogram::FactoryGet( | |
| 30 "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags)); | |
| 31 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1); | |
| 32 EXPECT_NE(histogram, histogram1); | |
| 33 | |
| 34 | 28 |
| 35 Histogram* linear_histogram(LinearHistogram::FactoryGet( | 29 Histogram* linear_histogram(LinearHistogram::FactoryGet( |
| 36 "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); | 30 "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); |
| 37 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); | 31 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); |
| 38 Histogram* linear_histogram1(LinearHistogram::FactoryGet( | |
| 39 "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); | |
| 40 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1); | |
| 41 EXPECT_NE(linear_histogram, linear_histogram1); | |
| 42 | 32 |
| 43 std::vector<int> custom_ranges; | 33 vector<int> custom_ranges; |
| 44 custom_ranges.push_back(1); | 34 custom_ranges.push_back(1); |
| 45 custom_ranges.push_back(5); | 35 custom_ranges.push_back(5); |
| 46 custom_ranges.push_back(10); | |
| 47 custom_ranges.push_back(20); | |
| 48 custom_ranges.push_back(30); | |
| 49 Histogram* custom_histogram(CustomHistogram::FactoryGet( | 36 Histogram* custom_histogram(CustomHistogram::FactoryGet( |
| 50 "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); | 37 "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); |
| 51 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); | 38 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); |
| 52 Histogram* custom_histogram1(CustomHistogram::FactoryGet( | |
| 53 "Test1CustomHistogram", custom_ranges, Histogram::kNoFlags)); | |
| 54 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1); | |
| 55 | 39 |
| 56 // Use standard macros (but with fixed samples) | 40 // Use standard macros (but with fixed samples) |
| 57 HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); | 41 HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); |
| 58 HISTOGRAM_COUNTS("Test3Histogram", 30); | 42 HISTOGRAM_COUNTS("Test3Histogram", 30); |
| 59 | 43 |
| 60 DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1)); | 44 DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1)); |
| 61 DHISTOGRAM_COUNTS("Test5Histogram", 30); | 45 DHISTOGRAM_COUNTS("Test5Histogram", 30); |
| 62 | 46 |
| 63 HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); | 47 HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); |
| 64 | |
| 65 // Try to construct samples. | |
| 66 Histogram::SampleSet sample1; | |
| 67 Histogram::SampleSet sample2; | |
| 68 | |
| 69 // Use copy constructor of SampleSet | |
| 70 sample1 = sample2; | |
| 71 Histogram::SampleSet sample3(sample1); | |
| 72 | |
| 73 // Finally test a statistics recorder, without really using it. | |
| 74 StatisticsRecorder recorder; | |
| 75 } | 48 } |
| 76 | 49 |
| 77 // Repeat with a recorder present to register with. | 50 TEST(HistogramTest, ExponentialRangesTest) { |
| 78 TEST(HistogramTest, RecordedStartupTest) { | 51 // Check that we got a nice exponential when there was enough rooom. |
| 79 // Test a statistics recorder, by letting histograms register. | 52 BucketRanges ranges(9); |
| 80 StatisticsRecorder recorder; // This initializes the global state. | 53 Histogram::InitializeBucketRanges(1, 64, 8, &ranges); |
| 54 EXPECT_EQ(0, ranges.range(0)); |
| 55 int power_of_2 = 1; |
| 56 for (int i = 1; i < 8; i++) { |
| 57 EXPECT_EQ(power_of_2, ranges.range(i)); |
| 58 power_of_2 *= 2; |
| 59 } |
| 60 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8)); |
| 81 | 61 |
| 82 StatisticsRecorder::Histograms histograms; | 62 // Check the corresponding Histogram will use the correct ranges. |
| 83 EXPECT_EQ(0U, histograms.size()); | 63 Histogram* histogram(Histogram::FactoryGet( |
| 84 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | 64 "Histogram", 1, 64, 8, Histogram::kNoFlags)); |
| 85 EXPECT_EQ(0U, histograms.size()); | 65 EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges())); |
| 86 | 66 |
| 87 // Try basic construction | 67 // When bucket count is limited, exponential ranges will partially look like |
| 88 Histogram* histogram(Histogram::FactoryGet( | 68 // linear. |
| 89 "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); | 69 BucketRanges ranges2(16); |
| 90 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); | 70 Histogram::InitializeBucketRanges(1, 32, 15, &ranges2); |
| 91 histograms.clear(); | |
| 92 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 93 EXPECT_EQ(1U, histograms.size()); | |
| 94 Histogram* histogram1(Histogram::FactoryGet( | |
| 95 "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags)); | |
| 96 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1); | |
| 97 histograms.clear(); | |
| 98 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 99 EXPECT_EQ(2U, histograms.size()); | |
| 100 | 71 |
| 101 Histogram* linear_histogram(LinearHistogram::FactoryGet( | 72 EXPECT_EQ(0, ranges2.range(0)); |
| 102 "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); | 73 EXPECT_EQ(1, ranges2.range(1)); |
| 103 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); | 74 EXPECT_EQ(2, ranges2.range(2)); |
| 104 histograms.clear(); | 75 EXPECT_EQ(3, ranges2.range(3)); |
| 105 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | 76 EXPECT_EQ(4, ranges2.range(4)); |
| 106 EXPECT_EQ(3U, histograms.size()); | 77 EXPECT_EQ(5, ranges2.range(5)); |
| 78 EXPECT_EQ(6, ranges2.range(6)); |
| 79 EXPECT_EQ(7, ranges2.range(7)); |
| 80 EXPECT_EQ(9, ranges2.range(8)); |
| 81 EXPECT_EQ(11, ranges2.range(9)); |
| 82 EXPECT_EQ(14, ranges2.range(10)); |
| 83 EXPECT_EQ(17, ranges2.range(11)); |
| 84 EXPECT_EQ(21, ranges2.range(12)); |
| 85 EXPECT_EQ(26, ranges2.range(13)); |
| 86 EXPECT_EQ(32, ranges2.range(14)); |
| 87 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(15)); |
| 107 | 88 |
| 108 Histogram* linear_histogram1(LinearHistogram::FactoryGet( | 89 // Check the corresponding Histogram will use the correct ranges. |
| 109 "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); | 90 Histogram* histogram2(Histogram::FactoryGet( |
| 110 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1); | 91 "Histogram2", 1, 32, 15, Histogram::kNoFlags)); |
| 111 histograms.clear(); | 92 EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges())); |
| 112 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 113 EXPECT_EQ(4U, histograms.size()); | |
| 114 | |
| 115 std::vector<int> custom_ranges; | |
| 116 custom_ranges.push_back(1); | |
| 117 custom_ranges.push_back(5); | |
| 118 custom_ranges.push_back(10); | |
| 119 custom_ranges.push_back(20); | |
| 120 custom_ranges.push_back(30); | |
| 121 Histogram* custom_histogram(CustomHistogram::FactoryGet( | |
| 122 "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); | |
| 123 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); | |
| 124 Histogram* custom_histogram1(CustomHistogram::FactoryGet( | |
| 125 "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); | |
| 126 EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1); | |
| 127 | |
| 128 histograms.clear(); | |
| 129 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 130 EXPECT_EQ(5U, histograms.size()); | |
| 131 | |
| 132 // Use standard macros (but with fixed samples) | |
| 133 HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); | |
| 134 HISTOGRAM_COUNTS("Test3Histogram", 30); | |
| 135 histograms.clear(); | |
| 136 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 137 EXPECT_EQ(7U, histograms.size()); | |
| 138 | |
| 139 HISTOGRAM_ENUMERATION("TestEnumerationHistogram", 20, 200); | |
| 140 histograms.clear(); | |
| 141 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 142 EXPECT_EQ(8U, histograms.size()); | |
| 143 | |
| 144 DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1)); | |
| 145 DHISTOGRAM_COUNTS("Test5Histogram", 30); | |
| 146 histograms.clear(); | |
| 147 StatisticsRecorder::GetHistograms(&histograms); // Load up lists | |
| 148 #ifndef NDEBUG | |
| 149 EXPECT_EQ(10U, histograms.size()); | |
| 150 #else | |
| 151 EXPECT_EQ(8U, histograms.size()); | |
| 152 #endif | |
| 153 } | 93 } |
| 154 | 94 |
| 155 TEST(HistogramTest, RangeTest) { | 95 TEST(HistogramTest, LinearRangesTest) { |
| 156 StatisticsRecorder recorder; | 96 BucketRanges ranges(9); |
| 157 StatisticsRecorder::Histograms histograms; | 97 LinearHistogram::InitializeBucketRanges(1, 7, 8, &ranges); |
| 98 // Gets a nice linear set of bucket ranges. |
| 99 for (int i = 0; i < 8; i++) |
| 100 EXPECT_EQ(i, ranges.range(i)); |
| 101 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8)); |
| 102 // The correspoding LinearHistogram should use the correct ranges. |
| 103 Histogram* histogram( |
| 104 LinearHistogram::FactoryGet("Linear", 1, 7, 8, Histogram::kNoFlags)); |
| 105 EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges())); |
| 158 | 106 |
| 159 recorder.GetHistograms(&histograms); | 107 // Linear ranges are not divisible. |
| 160 EXPECT_EQ(0U, histograms.size()); | 108 BucketRanges ranges2(6); |
| 161 | 109 LinearHistogram::InitializeBucketRanges(1, 6, 5, &ranges2); |
| 162 Histogram* histogram(Histogram::FactoryGet( | 110 EXPECT_EQ(0, ranges2.range(0)); |
| 163 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. | 111 EXPECT_EQ(1, ranges2.range(1)); |
| 164 // Check that we got a nice exponential when there was enough rooom. | 112 EXPECT_EQ(3, ranges2.range(2)); |
| 165 EXPECT_EQ(0, histogram->ranges(0)); | 113 EXPECT_EQ(4, ranges2.range(3)); |
| 166 int power_of_2 = 1; | 114 EXPECT_EQ(6, ranges2.range(4)); |
| 167 for (int i = 1; i < 8; i++) { | 115 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(5)); |
| 168 EXPECT_EQ(power_of_2, histogram->ranges(i)); | 116 // The correspoding LinearHistogram should use the correct ranges. |
| 169 power_of_2 *= 2; | 117 Histogram* histogram2( |
| 170 } | 118 LinearHistogram::FactoryGet("Linear2", 1, 6, 5, Histogram::kNoFlags)); |
| 171 EXPECT_EQ(INT_MAX, histogram->ranges(8)); | 119 EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges())); |
| 172 | |
| 173 Histogram* short_histogram(Histogram::FactoryGet( | |
| 174 "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags)); | |
| 175 // Check that when the number of buckets is short, we get a linear histogram | |
| 176 // for lack of space to do otherwise. | |
| 177 for (int i = 0; i < 8; i++) | |
| 178 EXPECT_EQ(i, short_histogram->ranges(i)); | |
| 179 EXPECT_EQ(INT_MAX, short_histogram->ranges(8)); | |
| 180 | |
| 181 Histogram* linear_histogram(LinearHistogram::FactoryGet( | |
| 182 "Linear", 1, 7, 8, Histogram::kNoFlags)); | |
| 183 // We also get a nice linear set of bucket ranges when we ask for it | |
| 184 for (int i = 0; i < 8; i++) | |
| 185 EXPECT_EQ(i, linear_histogram->ranges(i)); | |
| 186 EXPECT_EQ(INT_MAX, linear_histogram->ranges(8)); | |
| 187 | |
| 188 Histogram* linear_broad_histogram(LinearHistogram::FactoryGet( | |
| 189 "Linear widened", 2, 14, 8, Histogram::kNoFlags)); | |
| 190 // ...but when the list has more space, then the ranges naturally spread out. | |
| 191 for (int i = 0; i < 8; i++) | |
| 192 EXPECT_EQ(2 * i, linear_broad_histogram->ranges(i)); | |
| 193 EXPECT_EQ(INT_MAX, linear_broad_histogram->ranges(8)); | |
| 194 | |
| 195 Histogram* transitioning_histogram(Histogram::FactoryGet( | |
| 196 "LinearAndExponential", 1, 32, 15, Histogram::kNoFlags)); | |
| 197 // When space is a little tight, we transition from linear to exponential. | |
| 198 EXPECT_EQ(0, transitioning_histogram->ranges(0)); | |
| 199 EXPECT_EQ(1, transitioning_histogram->ranges(1)); | |
| 200 EXPECT_EQ(2, transitioning_histogram->ranges(2)); | |
| 201 EXPECT_EQ(3, transitioning_histogram->ranges(3)); | |
| 202 EXPECT_EQ(4, transitioning_histogram->ranges(4)); | |
| 203 EXPECT_EQ(5, transitioning_histogram->ranges(5)); | |
| 204 EXPECT_EQ(6, transitioning_histogram->ranges(6)); | |
| 205 EXPECT_EQ(7, transitioning_histogram->ranges(7)); | |
| 206 EXPECT_EQ(9, transitioning_histogram->ranges(8)); | |
| 207 EXPECT_EQ(11, transitioning_histogram->ranges(9)); | |
| 208 EXPECT_EQ(14, transitioning_histogram->ranges(10)); | |
| 209 EXPECT_EQ(17, transitioning_histogram->ranges(11)); | |
| 210 EXPECT_EQ(21, transitioning_histogram->ranges(12)); | |
| 211 EXPECT_EQ(26, transitioning_histogram->ranges(13)); | |
| 212 EXPECT_EQ(32, transitioning_histogram->ranges(14)); | |
| 213 EXPECT_EQ(INT_MAX, transitioning_histogram->ranges(15)); | |
| 214 | |
| 215 std::vector<int> custom_ranges; | |
| 216 custom_ranges.push_back(0); | |
| 217 custom_ranges.push_back(9); | |
| 218 custom_ranges.push_back(10); | |
| 219 custom_ranges.push_back(11); | |
| 220 custom_ranges.push_back(300); | |
| 221 Histogram* test_custom_histogram(CustomHistogram::FactoryGet( | |
| 222 "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags)); | |
| 223 | |
| 224 EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(0)); | |
| 225 EXPECT_EQ(custom_ranges[1], test_custom_histogram->ranges(1)); | |
| 226 EXPECT_EQ(custom_ranges[2], test_custom_histogram->ranges(2)); | |
| 227 EXPECT_EQ(custom_ranges[3], test_custom_histogram->ranges(3)); | |
| 228 EXPECT_EQ(custom_ranges[4], test_custom_histogram->ranges(4)); | |
| 229 | |
| 230 recorder.GetHistograms(&histograms); | |
| 231 EXPECT_EQ(6U, histograms.size()); | |
| 232 } | 120 } |
| 233 | 121 |
| 234 TEST(HistogramTest, CustomRangeTest) { | 122 TEST(HistogramTest, ArrayToCustomRangesTest) { |
| 235 StatisticsRecorder recorder; | 123 const HistogramBase::Sample ranges[3] = {5, 10 ,20}; |
| 236 StatisticsRecorder::Histograms histograms; | 124 vector<HistogramBase::Sample> ranges_vec = |
| 237 | 125 CustomHistogram::ArrayToCustomRanges(ranges, 3); |
| 238 // Check that missing leading zero is handled by an auto-insertion. | 126 ASSERT_EQ(6u, ranges_vec.size()); |
| 239 std::vector<int> custom_ranges; | 127 EXPECT_EQ(5, ranges_vec[0]); |
| 240 // Don't include a zero. | 128 EXPECT_EQ(6, ranges_vec[1]); |
| 241 custom_ranges.push_back(9); | 129 EXPECT_EQ(10, ranges_vec[2]); |
| 242 custom_ranges.push_back(10); | 130 EXPECT_EQ(11, ranges_vec[3]); |
| 243 custom_ranges.push_back(11); | 131 EXPECT_EQ(20, ranges_vec[4]); |
| 244 Histogram* test_custom_histogram(CustomHistogram::FactoryGet( | 132 EXPECT_EQ(21, ranges_vec[5]); |
| 245 "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags)); | |
| 246 | |
| 247 EXPECT_EQ(0, test_custom_histogram->ranges(0)); // Auto added | |
| 248 EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(1)); | |
| 249 EXPECT_EQ(custom_ranges[1], test_custom_histogram->ranges(2)); | |
| 250 EXPECT_EQ(custom_ranges[2], test_custom_histogram->ranges(3)); | |
| 251 | |
| 252 // Check that unsorted data with dups is handled gracefully. | |
| 253 const int kSmall = 7; | |
| 254 const int kMid = 8; | |
| 255 const int kBig = 9; | |
| 256 custom_ranges.clear(); | |
| 257 custom_ranges.push_back(kBig); | |
| 258 custom_ranges.push_back(kMid); | |
| 259 custom_ranges.push_back(kSmall); | |
| 260 custom_ranges.push_back(kSmall); | |
| 261 custom_ranges.push_back(kMid); | |
| 262 custom_ranges.push_back(0); // Push an explicit zero. | |
| 263 custom_ranges.push_back(kBig); | |
| 264 | |
| 265 Histogram* unsorted_histogram(CustomHistogram::FactoryGet( | |
| 266 "TestCustomUnsortedDupedHistogram", custom_ranges, Histogram::kNoFlags)); | |
| 267 EXPECT_EQ(0, unsorted_histogram->ranges(0)); | |
| 268 EXPECT_EQ(kSmall, unsorted_histogram->ranges(1)); | |
| 269 EXPECT_EQ(kMid, unsorted_histogram->ranges(2)); | |
| 270 EXPECT_EQ(kBig, unsorted_histogram->ranges(3)); | |
| 271 } | 133 } |
| 272 | 134 |
| 135 TEST(HistogramTest, CustomHistogramTest) { |
| 136 // A well prepared custom ranges. |
| 137 vector<HistogramBase::Sample> custom_ranges; |
| 138 custom_ranges.push_back(1); |
| 139 custom_ranges.push_back(2); |
| 140 Histogram* histogram = CustomHistogram::FactoryGet( |
| 141 "TestCustomHistogram1", custom_ranges, Histogram::kNoFlags); |
| 142 const BucketRanges* ranges = histogram->bucket_ranges(); |
| 143 ASSERT_EQ(4u, ranges->size()); |
| 144 EXPECT_EQ(0, ranges->range(0)); // Auto added. |
| 145 EXPECT_EQ(1, ranges->range(1)); |
| 146 EXPECT_EQ(2, ranges->range(2)); |
| 147 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); // Auto added. |
| 148 |
| 149 // A unordered custom ranges. |
| 150 custom_ranges.clear(); |
| 151 custom_ranges.push_back(2); |
| 152 custom_ranges.push_back(1); |
| 153 histogram = CustomHistogram::FactoryGet( |
| 154 "TestCustomHistogram2", custom_ranges, Histogram::kNoFlags); |
| 155 ranges = histogram->bucket_ranges(); |
| 156 ASSERT_EQ(4u, ranges->size()); |
| 157 EXPECT_EQ(0, ranges->range(0)); |
| 158 EXPECT_EQ(1, ranges->range(1)); |
| 159 EXPECT_EQ(2, ranges->range(2)); |
| 160 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); |
| 161 |
| 162 // A custom ranges with duplicated values. |
| 163 custom_ranges.clear(); |
| 164 custom_ranges.push_back(4); |
| 165 custom_ranges.push_back(1); |
| 166 custom_ranges.push_back(4); |
| 167 histogram = CustomHistogram::FactoryGet( |
| 168 "TestCustomHistogram3", custom_ranges, Histogram::kNoFlags); |
| 169 ranges = histogram->bucket_ranges(); |
| 170 ASSERT_EQ(4u, ranges->size()); |
| 171 EXPECT_EQ(0, ranges->range(0)); |
| 172 EXPECT_EQ(1, ranges->range(1)); |
| 173 EXPECT_EQ(4, ranges->range(2)); |
| 174 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); |
| 175 } |
| 176 |
| 177 TEST(HistogramTest, CustomHistogramWithOnly2Buckets) { |
| 178 // This test exploits the fact that the CustomHistogram can have 2 buckets, |
| 179 // while the base class Histogram is *supposed* to have at least 3 buckets. |
| 180 // We should probably change the restriction on the base class (or not inherit |
| 181 // the base class!). |
| 182 |
| 183 vector<HistogramBase::Sample> custom_ranges; |
| 184 custom_ranges.push_back(4); |
| 185 |
| 186 Histogram* histogram = CustomHistogram::FactoryGet( |
| 187 "2BucketsCustomHistogram", custom_ranges, Histogram::kNoFlags); |
| 188 const BucketRanges* ranges = histogram->bucket_ranges(); |
| 189 ASSERT_EQ(3u, ranges->size()); |
| 190 EXPECT_EQ(0, ranges->range(0)); |
| 191 EXPECT_EQ(4, ranges->range(1)); |
| 192 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2)); |
| 193 } |
| 273 | 194 |
| 274 // Make sure histogram handles out-of-bounds data gracefully. | 195 // Make sure histogram handles out-of-bounds data gracefully. |
| 275 TEST(HistogramTest, BoundsTest) { | 196 TEST(HistogramTest, BoundsTest) { |
| 276 const size_t kBucketCount = 50; | 197 const size_t kBucketCount = 50; |
| 277 Histogram* histogram(Histogram::FactoryGet( | 198 Histogram* histogram(Histogram::FactoryGet( |
| 278 "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags)); | 199 "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags)); |
| 279 | 200 |
| 280 // Put two samples "out of bounds" above and below. | 201 // Put two samples "out of bounds" above and below. |
| 281 histogram->Add(5); | 202 histogram->Add(5); |
| 282 histogram->Add(-50); | 203 histogram->Add(-50); |
| 283 | 204 |
| 284 histogram->Add(100); | 205 histogram->Add(100); |
| 285 histogram->Add(10000); | 206 histogram->Add(10000); |
| 286 | 207 |
| 287 // Verify they landed in the underflow, and overflow buckets. | 208 // Verify they landed in the underflow, and overflow buckets. |
| 288 Histogram::SampleSet sample; | 209 Histogram::SampleSet sample; |
| 289 histogram->SnapshotSample(&sample); | 210 histogram->SnapshotSample(&sample); |
| 290 EXPECT_EQ(2, sample.counts(0)); | 211 EXPECT_EQ(2, sample.counts(0)); |
| 291 EXPECT_EQ(0, sample.counts(1)); | 212 EXPECT_EQ(0, sample.counts(1)); |
| 292 size_t array_size = histogram->bucket_count(); | 213 size_t array_size = histogram->bucket_count(); |
| 293 EXPECT_EQ(kBucketCount, array_size); | 214 EXPECT_EQ(kBucketCount, array_size); |
| 294 EXPECT_EQ(0, sample.counts(array_size - 2)); | 215 EXPECT_EQ(0, sample.counts(array_size - 2)); |
| 295 EXPECT_EQ(2, sample.counts(array_size - 1)); | 216 EXPECT_EQ(2, sample.counts(array_size - 1)); |
| 296 | 217 |
| 297 std::vector<int> custom_ranges; | 218 vector<int> custom_ranges; |
| 298 custom_ranges.push_back(10); | 219 custom_ranges.push_back(10); |
| 299 custom_ranges.push_back(50); | 220 custom_ranges.push_back(50); |
| 300 custom_ranges.push_back(100); | 221 custom_ranges.push_back(100); |
| 301 Histogram* test_custom_histogram(CustomHistogram::FactoryGet( | 222 Histogram* test_custom_histogram(CustomHistogram::FactoryGet( |
| 302 "TestCustomRangeBoundedHistogram", custom_ranges, Histogram::kNoFlags)); | 223 "TestCustomRangeBoundedHistogram", custom_ranges, Histogram::kNoFlags)); |
| 303 | 224 |
| 304 // Put two samples "out of bounds" above and below. | 225 // Put two samples "out of bounds" above and below. |
| 305 test_custom_histogram->Add(5); | 226 test_custom_histogram->Add(5); |
| 306 test_custom_histogram->Add(-50); | 227 test_custom_histogram->Add(-50); |
| 307 test_custom_histogram->Add(100); | 228 test_custom_histogram->Add(100); |
| 308 test_custom_histogram->Add(1000); | 229 test_custom_histogram->Add(1000); |
| 309 | 230 |
| 310 // Verify they landed in the underflow, and overflow buckets. | 231 // Verify they landed in the underflow, and overflow buckets. |
| 311 Histogram::SampleSet custom_sample; | 232 Histogram::SampleSet custom_sample; |
| 312 test_custom_histogram->SnapshotSample(&custom_sample); | 233 test_custom_histogram->SnapshotSample(&custom_sample); |
| 313 EXPECT_EQ(2, custom_sample.counts(0)); | 234 EXPECT_EQ(2, custom_sample.counts(0)); |
| 314 EXPECT_EQ(0, custom_sample.counts(1)); | 235 EXPECT_EQ(0, custom_sample.counts(1)); |
| 315 size_t custom_array_size = test_custom_histogram->bucket_count(); | 236 size_t custom_array_size = test_custom_histogram->bucket_count(); |
| 316 EXPECT_EQ(0, custom_sample.counts(custom_array_size - 2)); | 237 EXPECT_EQ(0, custom_sample.counts(custom_array_size - 2)); |
| 317 EXPECT_EQ(2, custom_sample.counts(custom_array_size - 1)); | 238 EXPECT_EQ(2, custom_sample.counts(custom_array_size - 1)); |
| 318 } | 239 } |
| 319 | 240 |
| 320 // Check to be sure samples land as expected is "correct" buckets. | 241 // Check to be sure samples land as expected is "correct" buckets. |
| 321 TEST(HistogramTest, BucketPlacementTest) { | 242 TEST(HistogramTest, BucketPlacementTest) { |
| 322 Histogram* histogram(Histogram::FactoryGet( | 243 Histogram* histogram(Histogram::FactoryGet( |
| 323 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. | 244 "Histogram", 1, 64, 8, Histogram::kNoFlags)); |
| 324 | |
| 325 // Check that we got a nice exponential since there was enough rooom. | |
| 326 EXPECT_EQ(0, histogram->ranges(0)); | |
| 327 int power_of_2 = 1; | |
| 328 for (int i = 1; i < 8; i++) { | |
| 329 EXPECT_EQ(power_of_2, histogram->ranges(i)); | |
| 330 power_of_2 *= 2; | |
| 331 } | |
| 332 EXPECT_EQ(INT_MAX, histogram->ranges(8)); | |
| 333 | 245 |
| 334 // Add i+1 samples to the i'th bucket. | 246 // Add i+1 samples to the i'th bucket. |
| 335 histogram->Add(0); | 247 histogram->Add(0); |
| 336 power_of_2 = 1; | 248 int power_of_2 = 1; |
| 337 for (int i = 1; i < 8; i++) { | 249 for (int i = 1; i < 8; i++) { |
| 338 for (int j = 0; j <= i; j++) | 250 for (int j = 0; j <= i; j++) |
| 339 histogram->Add(power_of_2); | 251 histogram->Add(power_of_2); |
| 340 power_of_2 *= 2; | 252 power_of_2 *= 2; |
| 341 } | 253 } |
| 342 // Leave overflow bucket empty. | |
| 343 | 254 |
| 344 // Check to see that the bucket counts reflect our additions. | 255 // Check to see that the bucket counts reflect our additions. |
| 345 Histogram::SampleSet sample; | 256 Histogram::SampleSet sample; |
| 346 histogram->SnapshotSample(&sample); | 257 histogram->SnapshotSample(&sample); |
| 347 EXPECT_EQ(INT_MAX, histogram->ranges(8)); | |
| 348 for (int i = 0; i < 8; i++) | 258 for (int i = 0; i < 8; i++) |
| 349 EXPECT_EQ(i + 1, sample.counts(i)); | 259 EXPECT_EQ(i + 1, sample.counts(i)); |
| 350 } | 260 } |
| 351 | 261 |
| 352 TEST(HistogramTest, CorruptSampleCounts) { | 262 TEST(HistogramTest, CorruptSampleCounts) { |
| 353 Histogram* histogram(Histogram::FactoryGet( | 263 Histogram* histogram(Histogram::FactoryGet( |
| 354 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. | 264 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. |
| 355 | 265 |
| 356 EXPECT_EQ(0, histogram->sample_.redundant_count()); | 266 EXPECT_EQ(0, histogram->sample_.redundant_count()); |
| 357 histogram->Add(20); // Add some samples. | 267 histogram->Add(20); // Add some samples. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 376 | 286 |
| 377 TEST(HistogramTest, CorruptBucketBounds) { | 287 TEST(HistogramTest, CorruptBucketBounds) { |
| 378 Histogram* histogram(Histogram::FactoryGet( | 288 Histogram* histogram(Histogram::FactoryGet( |
| 379 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. | 289 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. |
| 380 | 290 |
| 381 Histogram::SampleSet snapshot; | 291 Histogram::SampleSet snapshot; |
| 382 histogram->SnapshotSample(&snapshot); | 292 histogram->SnapshotSample(&snapshot); |
| 383 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, 0); | 293 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, 0); |
| 384 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); // No default corruption. | 294 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); // No default corruption. |
| 385 | 295 |
| 386 BucketRanges* bucket_ranges = histogram->bucket_ranges(); | 296 BucketRanges* bucket_ranges = |
| 297 const_cast<BucketRanges*>(histogram->bucket_ranges()); |
| 387 HistogramBase::Sample tmp = bucket_ranges->range(1); | 298 HistogramBase::Sample tmp = bucket_ranges->range(1); |
| 388 bucket_ranges->set_range(1, bucket_ranges->range(2)); | 299 bucket_ranges->set_range(1, bucket_ranges->range(2)); |
| 389 bucket_ranges->set_range(2, tmp); | 300 bucket_ranges->set_range(2, tmp); |
| 390 EXPECT_EQ(Histogram::BUCKET_ORDER_ERROR | Histogram::RANGE_CHECKSUM_ERROR, | 301 EXPECT_EQ(Histogram::BUCKET_ORDER_ERROR | Histogram::RANGE_CHECKSUM_ERROR, |
| 391 histogram->FindCorruption(snapshot)); | 302 histogram->FindCorruption(snapshot)); |
| 392 | 303 |
| 393 bucket_ranges->set_range(2, bucket_ranges->range(1)); | 304 bucket_ranges->set_range(2, bucket_ranges->range(1)); |
| 394 bucket_ranges->set_range(1, tmp); | 305 bucket_ranges->set_range(1, tmp); |
| 395 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); | 306 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); |
| 396 | 307 |
| 397 bucket_ranges->set_range(3, bucket_ranges->range(3) + 1); | 308 bucket_ranges->set_range(3, bucket_ranges->range(3) + 1); |
| 398 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, | 309 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, |
| 399 histogram->FindCorruption(snapshot)); | 310 histogram->FindCorruption(snapshot)); |
| 400 | 311 |
| 401 // Show that two simple changes don't offset each other | 312 // Show that two simple changes don't offset each other |
| 402 bucket_ranges->set_range(4, bucket_ranges->range(4) - 1); | 313 bucket_ranges->set_range(4, bucket_ranges->range(4) - 1); |
| 403 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, | 314 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, |
| 404 histogram->FindCorruption(snapshot)); | 315 histogram->FindCorruption(snapshot)); |
| 405 | 316 |
| 406 // Repair histogram so that destructor won't DCHECK(). | 317 // Repair histogram so that destructor won't DCHECK(). |
| 407 bucket_ranges->set_range(3, bucket_ranges->range(3) - 1); | 318 bucket_ranges->set_range(3, bucket_ranges->range(3) - 1); |
| 408 bucket_ranges->set_range(4, bucket_ranges->range(4) + 1); | 319 bucket_ranges->set_range(4, bucket_ranges->range(4) + 1); |
| 409 } | 320 } |
| 410 | 321 |
| 411 // Table was generated similarly to sample code for CRC-32 given on: | |
| 412 // http://www.w3.org/TR/PNG/#D-CRCAppendix. | |
| 413 TEST(HistogramTest, Crc32TableTest) { | |
| 414 for (int i = 0; i < 256; ++i) { | |
| 415 uint32 checksum = i; | |
| 416 for (int j = 0; j < 8; ++j) { | |
| 417 const uint32 kReversedPolynomial = 0xedb88320L; | |
| 418 if (checksum & 1) | |
| 419 checksum = kReversedPolynomial ^ (checksum >> 1); | |
| 420 else | |
| 421 checksum >>= 1; | |
| 422 } | |
| 423 EXPECT_EQ(Histogram::kCrcTable[i], checksum); | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 // RangeTest, CustomRangeTest and CorruptBucketBounds test BucketRanges class. | |
| 428 // The following tests sharing of BucketRanges object. | |
| 429 TEST(HistogramTest, BucketRangesTest) { | |
| 430 StatisticsRecorder recorder; | |
| 431 StatisticsRecorder::Histograms histograms; | |
| 432 | |
| 433 recorder.GetHistograms(&histograms); | |
| 434 EXPECT_EQ(0U, histograms.size()); | |
| 435 | |
| 436 Histogram* histogram1(Histogram::FactoryGet( | |
| 437 "Histogram", 1, 64, 8, Histogram::kNoFlags)); | |
| 438 | |
| 439 Histogram* histogram2(Histogram::FactoryGet( | |
| 440 "Histogram2", 1, 64, 8, Histogram::kNoFlags)); | |
| 441 | |
| 442 Histogram* histogram3(Histogram::FactoryGet( | |
| 443 "Histogram3", 1, 64, 16, Histogram::kNoFlags)); | |
| 444 | |
| 445 BucketRanges* bucket_ranges1 = histogram1->bucket_ranges(); | |
| 446 BucketRanges* bucket_ranges2 = histogram2->bucket_ranges(); | |
| 447 BucketRanges* bucket_ranges3 = histogram3->bucket_ranges(); | |
| 448 EXPECT_TRUE(bucket_ranges1->Equals(bucket_ranges2)); | |
| 449 EXPECT_FALSE(bucket_ranges1->Equals(bucket_ranges3)); | |
| 450 } | |
| 451 | |
| 452 } // namespace base | 322 } // namespace base |
| OLD | NEW |