| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/metrics/histogram.h" | |
| 6 | |
| 7 #include <climits> | |
| 8 #include <algorithm> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/logging.h" | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/metrics/bucket_ranges.h" | |
| 14 #include "base/metrics/histogram_macros.h" | |
| 15 #include "base/metrics/sample_vector.h" | |
| 16 #include "base/metrics/statistics_recorder.h" | |
| 17 #include "base/pickle.h" | |
| 18 #include "base/time/time.h" | |
| 19 #include "testing/gtest/include/gtest/gtest.h" | |
| 20 | |
| 21 namespace base { | |
| 22 | |
| 23 class HistogramTest : public testing::Test { | |
| 24 protected: | |
| 25 void SetUp() override { | |
| 26 // Each test will have a clean state (no Histogram / BucketRanges | |
| 27 // registered). | |
| 28 InitializeStatisticsRecorder(); | |
| 29 } | |
| 30 | |
| 31 void TearDown() override { UninitializeStatisticsRecorder(); } | |
| 32 | |
| 33 void InitializeStatisticsRecorder() { | |
| 34 statistics_recorder_ = new StatisticsRecorder(); | |
| 35 } | |
| 36 | |
| 37 void UninitializeStatisticsRecorder() { | |
| 38 delete statistics_recorder_; | |
| 39 statistics_recorder_ = NULL; | |
| 40 } | |
| 41 | |
| 42 StatisticsRecorder* statistics_recorder_; | |
| 43 }; | |
| 44 | |
| 45 // Check for basic syntax and use. | |
| 46 TEST_F(HistogramTest, BasicTest) { | |
| 47 // Try basic construction | |
| 48 HistogramBase* histogram = Histogram::FactoryGet( | |
| 49 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags); | |
| 50 EXPECT_TRUE(histogram); | |
| 51 | |
| 52 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( | |
| 53 "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags); | |
| 54 EXPECT_TRUE(linear_histogram); | |
| 55 | |
| 56 std::vector<int> custom_ranges; | |
| 57 custom_ranges.push_back(1); | |
| 58 custom_ranges.push_back(5); | |
| 59 HistogramBase* custom_histogram = CustomHistogram::FactoryGet( | |
| 60 "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags); | |
| 61 EXPECT_TRUE(custom_histogram); | |
| 62 | |
| 63 // Use standard macros (but with fixed samples) | |
| 64 LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); | |
| 65 LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30); | |
| 66 | |
| 67 LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130); | |
| 68 } | |
| 69 | |
| 70 // Check that the macro correctly matches histograms by name and records their | |
| 71 // data together. | |
| 72 TEST_F(HistogramTest, NameMatchTest) { | |
| 73 LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10); | |
| 74 LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10); | |
| 75 HistogramBase* histogram = LinearHistogram::FactoryGet( | |
| 76 "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags); | |
| 77 | |
| 78 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples(); | |
| 79 EXPECT_EQ(2, samples->TotalCount()); | |
| 80 EXPECT_EQ(2, samples->GetCount(10)); | |
| 81 } | |
| 82 | |
| 83 TEST_F(HistogramTest, ExponentialRangesTest) { | |
| 84 // Check that we got a nice exponential when there was enough rooom. | |
| 85 BucketRanges ranges(9); | |
| 86 Histogram::InitializeBucketRanges(1, 64, &ranges); | |
| 87 EXPECT_EQ(0, ranges.range(0)); | |
| 88 int power_of_2 = 1; | |
| 89 for (int i = 1; i < 8; i++) { | |
| 90 EXPECT_EQ(power_of_2, ranges.range(i)); | |
| 91 power_of_2 *= 2; | |
| 92 } | |
| 93 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8)); | |
| 94 | |
| 95 // Check the corresponding Histogram will use the correct ranges. | |
| 96 Histogram* histogram = static_cast<Histogram*>( | |
| 97 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | |
| 98 EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges())); | |
| 99 | |
| 100 // When bucket count is limited, exponential ranges will partially look like | |
| 101 // linear. | |
| 102 BucketRanges ranges2(16); | |
| 103 Histogram::InitializeBucketRanges(1, 32, &ranges2); | |
| 104 | |
| 105 EXPECT_EQ(0, ranges2.range(0)); | |
| 106 EXPECT_EQ(1, ranges2.range(1)); | |
| 107 EXPECT_EQ(2, ranges2.range(2)); | |
| 108 EXPECT_EQ(3, ranges2.range(3)); | |
| 109 EXPECT_EQ(4, ranges2.range(4)); | |
| 110 EXPECT_EQ(5, ranges2.range(5)); | |
| 111 EXPECT_EQ(6, ranges2.range(6)); | |
| 112 EXPECT_EQ(7, ranges2.range(7)); | |
| 113 EXPECT_EQ(9, ranges2.range(8)); | |
| 114 EXPECT_EQ(11, ranges2.range(9)); | |
| 115 EXPECT_EQ(14, ranges2.range(10)); | |
| 116 EXPECT_EQ(17, ranges2.range(11)); | |
| 117 EXPECT_EQ(21, ranges2.range(12)); | |
| 118 EXPECT_EQ(26, ranges2.range(13)); | |
| 119 EXPECT_EQ(32, ranges2.range(14)); | |
| 120 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(15)); | |
| 121 | |
| 122 // Check the corresponding Histogram will use the correct ranges. | |
| 123 Histogram* histogram2 = static_cast<Histogram*>( | |
| 124 Histogram::FactoryGet("Histogram2", 1, 32, 15, HistogramBase::kNoFlags)); | |
| 125 EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges())); | |
| 126 } | |
| 127 | |
| 128 TEST_F(HistogramTest, LinearRangesTest) { | |
| 129 BucketRanges ranges(9); | |
| 130 LinearHistogram::InitializeBucketRanges(1, 7, &ranges); | |
| 131 // Gets a nice linear set of bucket ranges. | |
| 132 for (int i = 0; i < 8; i++) | |
| 133 EXPECT_EQ(i, ranges.range(i)); | |
| 134 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8)); | |
| 135 | |
| 136 // The correspoding LinearHistogram should use the correct ranges. | |
| 137 Histogram* histogram = static_cast<Histogram*>( | |
| 138 LinearHistogram::FactoryGet("Linear", 1, 7, 8, HistogramBase::kNoFlags)); | |
| 139 EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges())); | |
| 140 | |
| 141 // Linear ranges are not divisible. | |
| 142 BucketRanges ranges2(6); | |
| 143 LinearHistogram::InitializeBucketRanges(1, 6, &ranges2); | |
| 144 EXPECT_EQ(0, ranges2.range(0)); | |
| 145 EXPECT_EQ(1, ranges2.range(1)); | |
| 146 EXPECT_EQ(3, ranges2.range(2)); | |
| 147 EXPECT_EQ(4, ranges2.range(3)); | |
| 148 EXPECT_EQ(6, ranges2.range(4)); | |
| 149 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(5)); | |
| 150 // The correspoding LinearHistogram should use the correct ranges. | |
| 151 Histogram* histogram2 = static_cast<Histogram*>( | |
| 152 LinearHistogram::FactoryGet("Linear2", 1, 6, 5, HistogramBase::kNoFlags)); | |
| 153 EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges())); | |
| 154 } | |
| 155 | |
| 156 TEST_F(HistogramTest, ArrayToCustomRangesTest) { | |
| 157 const HistogramBase::Sample ranges[3] = {5, 10, 20}; | |
| 158 std::vector<HistogramBase::Sample> ranges_vec = | |
| 159 CustomHistogram::ArrayToCustomRanges(ranges, 3); | |
| 160 ASSERT_EQ(6u, ranges_vec.size()); | |
| 161 EXPECT_EQ(5, ranges_vec[0]); | |
| 162 EXPECT_EQ(6, ranges_vec[1]); | |
| 163 EXPECT_EQ(10, ranges_vec[2]); | |
| 164 EXPECT_EQ(11, ranges_vec[3]); | |
| 165 EXPECT_EQ(20, ranges_vec[4]); | |
| 166 EXPECT_EQ(21, ranges_vec[5]); | |
| 167 } | |
| 168 | |
| 169 TEST_F(HistogramTest, CustomHistogramTest) { | |
| 170 // A well prepared custom ranges. | |
| 171 std::vector<HistogramBase::Sample> custom_ranges; | |
| 172 custom_ranges.push_back(1); | |
| 173 custom_ranges.push_back(2); | |
| 174 | |
| 175 Histogram* histogram = static_cast<Histogram*>( | |
| 176 CustomHistogram::FactoryGet("TestCustomHistogram1", custom_ranges, | |
| 177 HistogramBase::kNoFlags)); | |
| 178 const BucketRanges* ranges = histogram->bucket_ranges(); | |
| 179 ASSERT_EQ(4u, ranges->size()); | |
| 180 EXPECT_EQ(0, ranges->range(0)); // Auto added. | |
| 181 EXPECT_EQ(1, ranges->range(1)); | |
| 182 EXPECT_EQ(2, ranges->range(2)); | |
| 183 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); // Auto added. | |
| 184 | |
| 185 // A unordered custom ranges. | |
| 186 custom_ranges.clear(); | |
| 187 custom_ranges.push_back(2); | |
| 188 custom_ranges.push_back(1); | |
| 189 histogram = static_cast<Histogram*>( | |
| 190 CustomHistogram::FactoryGet("TestCustomHistogram2", custom_ranges, | |
| 191 HistogramBase::kNoFlags)); | |
| 192 ranges = histogram->bucket_ranges(); | |
| 193 ASSERT_EQ(4u, ranges->size()); | |
| 194 EXPECT_EQ(0, ranges->range(0)); | |
| 195 EXPECT_EQ(1, ranges->range(1)); | |
| 196 EXPECT_EQ(2, ranges->range(2)); | |
| 197 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); | |
| 198 | |
| 199 // A custom ranges with duplicated values. | |
| 200 custom_ranges.clear(); | |
| 201 custom_ranges.push_back(4); | |
| 202 custom_ranges.push_back(1); | |
| 203 custom_ranges.push_back(4); | |
| 204 histogram = static_cast<Histogram*>( | |
| 205 CustomHistogram::FactoryGet("TestCustomHistogram3", custom_ranges, | |
| 206 HistogramBase::kNoFlags)); | |
| 207 ranges = histogram->bucket_ranges(); | |
| 208 ASSERT_EQ(4u, ranges->size()); | |
| 209 EXPECT_EQ(0, ranges->range(0)); | |
| 210 EXPECT_EQ(1, ranges->range(1)); | |
| 211 EXPECT_EQ(4, ranges->range(2)); | |
| 212 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3)); | |
| 213 } | |
| 214 | |
| 215 TEST_F(HistogramTest, CustomHistogramWithOnly2Buckets) { | |
| 216 // This test exploits the fact that the CustomHistogram can have 2 buckets, | |
| 217 // while the base class Histogram is *supposed* to have at least 3 buckets. | |
| 218 // We should probably change the restriction on the base class (or not inherit | |
| 219 // the base class!). | |
| 220 | |
| 221 std::vector<HistogramBase::Sample> custom_ranges; | |
| 222 custom_ranges.push_back(4); | |
| 223 | |
| 224 Histogram* histogram = static_cast<Histogram*>( | |
| 225 CustomHistogram::FactoryGet("2BucketsCustomHistogram", custom_ranges, | |
| 226 HistogramBase::kNoFlags)); | |
| 227 const BucketRanges* ranges = histogram->bucket_ranges(); | |
| 228 ASSERT_EQ(3u, ranges->size()); | |
| 229 EXPECT_EQ(0, ranges->range(0)); | |
| 230 EXPECT_EQ(4, ranges->range(1)); | |
| 231 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2)); | |
| 232 } | |
| 233 | |
| 234 // Make sure histogram handles out-of-bounds data gracefully. | |
| 235 TEST_F(HistogramTest, BoundsTest) { | |
| 236 const size_t kBucketCount = 50; | |
| 237 Histogram* histogram = static_cast<Histogram*>( | |
| 238 Histogram::FactoryGet("Bounded", 10, 100, kBucketCount, | |
| 239 HistogramBase::kNoFlags)); | |
| 240 | |
| 241 // Put two samples "out of bounds" above and below. | |
| 242 histogram->Add(5); | |
| 243 histogram->Add(-50); | |
| 244 | |
| 245 histogram->Add(100); | |
| 246 histogram->Add(10000); | |
| 247 | |
| 248 // Verify they landed in the underflow, and overflow buckets. | |
| 249 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); | |
| 250 EXPECT_EQ(2, samples->GetCountAtIndex(0)); | |
| 251 EXPECT_EQ(0, samples->GetCountAtIndex(1)); | |
| 252 size_t array_size = histogram->bucket_count(); | |
| 253 EXPECT_EQ(kBucketCount, array_size); | |
| 254 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2)); | |
| 255 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1)); | |
| 256 | |
| 257 std::vector<int> custom_ranges; | |
| 258 custom_ranges.push_back(10); | |
| 259 custom_ranges.push_back(50); | |
| 260 custom_ranges.push_back(100); | |
| 261 Histogram* test_custom_histogram = static_cast<Histogram*>( | |
| 262 CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram", | |
| 263 custom_ranges, HistogramBase::kNoFlags)); | |
| 264 | |
| 265 // Put two samples "out of bounds" above and below. | |
| 266 test_custom_histogram->Add(5); | |
| 267 test_custom_histogram->Add(-50); | |
| 268 test_custom_histogram->Add(100); | |
| 269 test_custom_histogram->Add(1000); | |
| 270 test_custom_histogram->Add(INT_MAX); | |
| 271 | |
| 272 // Verify they landed in the underflow, and overflow buckets. | |
| 273 scoped_ptr<SampleVector> custom_samples = | |
| 274 test_custom_histogram->SnapshotSampleVector(); | |
| 275 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0)); | |
| 276 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1)); | |
| 277 size_t bucket_count = test_custom_histogram->bucket_count(); | |
| 278 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2)); | |
| 279 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1)); | |
| 280 } | |
| 281 | |
| 282 // Check to be sure samples land as expected is "correct" buckets. | |
| 283 TEST_F(HistogramTest, BucketPlacementTest) { | |
| 284 Histogram* histogram = static_cast<Histogram*>( | |
| 285 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | |
| 286 | |
| 287 // Add i+1 samples to the i'th bucket. | |
| 288 histogram->Add(0); | |
| 289 int power_of_2 = 1; | |
| 290 for (int i = 1; i < 8; i++) { | |
| 291 for (int j = 0; j <= i; j++) | |
| 292 histogram->Add(power_of_2); | |
| 293 power_of_2 *= 2; | |
| 294 } | |
| 295 | |
| 296 // Check to see that the bucket counts reflect our additions. | |
| 297 scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector(); | |
| 298 for (int i = 0; i < 8; i++) | |
| 299 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i)); | |
| 300 } | |
| 301 | |
| 302 TEST_F(HistogramTest, CorruptSampleCounts) { | |
| 303 Histogram* histogram = static_cast<Histogram*>( | |
| 304 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | |
| 305 | |
| 306 // Add some samples. | |
| 307 histogram->Add(20); | |
| 308 histogram->Add(40); | |
| 309 | |
| 310 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); | |
| 311 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, | |
| 312 histogram->FindCorruption(*snapshot)); | |
| 313 EXPECT_EQ(2, snapshot->redundant_count()); | |
| 314 EXPECT_EQ(2, snapshot->TotalCount()); | |
| 315 | |
| 316 snapshot->counts_[3] += 100; // Sample count won't match redundant count. | |
| 317 EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR, | |
| 318 histogram->FindCorruption(*snapshot)); | |
| 319 snapshot->counts_[2] -= 200; | |
| 320 EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR, | |
| 321 histogram->FindCorruption(*snapshot)); | |
| 322 | |
| 323 // But we can't spot a corruption if it is compensated for. | |
| 324 snapshot->counts_[1] += 100; | |
| 325 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, | |
| 326 histogram->FindCorruption(*snapshot)); | |
| 327 } | |
| 328 | |
| 329 TEST_F(HistogramTest, CorruptBucketBounds) { | |
| 330 Histogram* histogram = static_cast<Histogram*>( | |
| 331 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags)); | |
| 332 | |
| 333 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector(); | |
| 334 EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES, | |
| 335 histogram->FindCorruption(*snapshot)); | |
| 336 | |
| 337 BucketRanges* bucket_ranges = | |
| 338 const_cast<BucketRanges*>(histogram->bucket_ranges()); | |
| 339 HistogramBase::Sample tmp = bucket_ranges->range(1); | |
| 340 bucket_ranges->set_range(1, bucket_ranges->range(2)); | |
| 341 bucket_ranges->set_range(2, tmp); | |
| 342 EXPECT_EQ( | |
| 343 HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR, | |
| 344 histogram->FindCorruption(*snapshot)); | |
| 345 | |
| 346 bucket_ranges->set_range(2, bucket_ranges->range(1)); | |
| 347 bucket_ranges->set_range(1, tmp); | |
| 348 EXPECT_EQ(0, histogram->FindCorruption(*snapshot)); | |
| 349 | |
| 350 // Show that two simple changes don't offset each other | |
| 351 bucket_ranges->set_range(3, bucket_ranges->range(3) + 1); | |
| 352 EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR, | |
| 353 histogram->FindCorruption(*snapshot)); | |
| 354 | |
| 355 bucket_ranges->set_range(4, bucket_ranges->range(4) - 1); | |
| 356 EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR, | |
| 357 histogram->FindCorruption(*snapshot)); | |
| 358 | |
| 359 // Repair histogram so that destructor won't DCHECK(). | |
| 360 bucket_ranges->set_range(3, bucket_ranges->range(3) - 1); | |
| 361 bucket_ranges->set_range(4, bucket_ranges->range(4) + 1); | |
| 362 } | |
| 363 | |
| 364 TEST_F(HistogramTest, HistogramSerializeInfo) { | |
| 365 Histogram* histogram = static_cast<Histogram*>( | |
| 366 Histogram::FactoryGet("Histogram", 1, 64, 8, | |
| 367 HistogramBase::kIPCSerializationSourceFlag)); | |
| 368 Pickle pickle; | |
| 369 histogram->SerializeInfo(&pickle); | |
| 370 | |
| 371 PickleIterator iter(pickle); | |
| 372 | |
| 373 int type; | |
| 374 EXPECT_TRUE(iter.ReadInt(&type)); | |
| 375 EXPECT_EQ(HISTOGRAM, type); | |
| 376 | |
| 377 std::string name; | |
| 378 EXPECT_TRUE(iter.ReadString(&name)); | |
| 379 EXPECT_EQ("Histogram", name); | |
| 380 | |
| 381 int flag; | |
| 382 EXPECT_TRUE(iter.ReadInt(&flag)); | |
| 383 EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag, flag); | |
| 384 | |
| 385 int min; | |
| 386 EXPECT_TRUE(iter.ReadInt(&min)); | |
| 387 EXPECT_EQ(1, min); | |
| 388 | |
| 389 int max; | |
| 390 EXPECT_TRUE(iter.ReadInt(&max)); | |
| 391 EXPECT_EQ(64, max); | |
| 392 | |
| 393 int64 bucket_count; | |
| 394 EXPECT_TRUE(iter.ReadInt64(&bucket_count)); | |
| 395 EXPECT_EQ(8, bucket_count); | |
| 396 | |
| 397 uint32 checksum; | |
| 398 EXPECT_TRUE(iter.ReadUInt32(&checksum)); | |
| 399 EXPECT_EQ(histogram->bucket_ranges()->checksum(), checksum); | |
| 400 | |
| 401 // No more data in the pickle. | |
| 402 EXPECT_FALSE(iter.SkipBytes(1)); | |
| 403 } | |
| 404 | |
| 405 TEST_F(HistogramTest, CustomHistogramSerializeInfo) { | |
| 406 std::vector<int> custom_ranges; | |
| 407 custom_ranges.push_back(10); | |
| 408 custom_ranges.push_back(100); | |
| 409 | |
| 410 HistogramBase* custom_histogram = CustomHistogram::FactoryGet( | |
| 411 "TestCustomRangeBoundedHistogram", | |
| 412 custom_ranges, | |
| 413 HistogramBase::kNoFlags); | |
| 414 Pickle pickle; | |
| 415 custom_histogram->SerializeInfo(&pickle); | |
| 416 | |
| 417 // Validate the pickle. | |
| 418 PickleIterator iter(pickle); | |
| 419 | |
| 420 int i; | |
| 421 std::string s; | |
| 422 int64 bucket_count; | |
| 423 uint32 ui32; | |
| 424 EXPECT_TRUE(iter.ReadInt(&i) && iter.ReadString(&s) && iter.ReadInt(&i) && | |
| 425 iter.ReadInt(&i) && iter.ReadInt(&i) && | |
| 426 iter.ReadInt64(&bucket_count) && iter.ReadUInt32(&ui32)); | |
| 427 EXPECT_EQ(3, bucket_count); | |
| 428 | |
| 429 int range; | |
| 430 EXPECT_TRUE(iter.ReadInt(&range)); | |
| 431 EXPECT_EQ(10, range); | |
| 432 EXPECT_TRUE(iter.ReadInt(&range)); | |
| 433 EXPECT_EQ(100, range); | |
| 434 | |
| 435 // No more data in the pickle. | |
| 436 EXPECT_FALSE(iter.SkipBytes(1)); | |
| 437 } | |
| 438 | |
| 439 TEST_F(HistogramTest, BadConstruction) { | |
| 440 HistogramBase* histogram = Histogram::FactoryGet( | |
| 441 "BadConstruction", 0, 100, 8, HistogramBase::kNoFlags); | |
| 442 EXPECT_TRUE(histogram->HasConstructionArguments(1, 100, 8)); | |
| 443 | |
| 444 // Try to get the same histogram name with different arguments. | |
| 445 HistogramBase* bad_histogram = Histogram::FactoryGet( | |
| 446 "BadConstruction", 0, 100, 7, HistogramBase::kNoFlags); | |
| 447 EXPECT_EQ(NULL, bad_histogram); | |
| 448 bad_histogram = Histogram::FactoryGet( | |
| 449 "BadConstruction", 0, 99, 8, HistogramBase::kNoFlags); | |
| 450 EXPECT_EQ(NULL, bad_histogram); | |
| 451 | |
| 452 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( | |
| 453 "BadConstructionLinear", 0, 100, 8, HistogramBase::kNoFlags); | |
| 454 EXPECT_TRUE(linear_histogram->HasConstructionArguments(1, 100, 8)); | |
| 455 | |
| 456 // Try to get the same histogram name with different arguments. | |
| 457 bad_histogram = LinearHistogram::FactoryGet( | |
| 458 "BadConstructionLinear", 0, 100, 7, HistogramBase::kNoFlags); | |
| 459 EXPECT_EQ(NULL, bad_histogram); | |
| 460 bad_histogram = LinearHistogram::FactoryGet( | |
| 461 "BadConstructionLinear", 10, 100, 8, HistogramBase::kNoFlags); | |
| 462 EXPECT_EQ(NULL, bad_histogram); | |
| 463 } | |
| 464 | |
| 465 #if GTEST_HAS_DEATH_TEST | |
| 466 // For Histogram, LinearHistogram and CustomHistogram, the minimum for a | |
| 467 // declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX - | |
| 468 // 1). But we accept ranges exceeding those limits, and silently clamped to | |
| 469 // those limits. This is for backwards compatibility. | |
| 470 TEST(HistogramDeathTest, BadRangesTest) { | |
| 471 HistogramBase* histogram = Histogram::FactoryGet( | |
| 472 "BadRanges", 0, HistogramBase::kSampleType_MAX, 8, | |
| 473 HistogramBase::kNoFlags); | |
| 474 EXPECT_TRUE( | |
| 475 histogram->HasConstructionArguments( | |
| 476 1, HistogramBase::kSampleType_MAX - 1, 8)); | |
| 477 | |
| 478 HistogramBase* linear_histogram = LinearHistogram::FactoryGet( | |
| 479 "BadRangesLinear", 0, HistogramBase::kSampleType_MAX, 8, | |
| 480 HistogramBase::kNoFlags); | |
| 481 EXPECT_TRUE( | |
| 482 linear_histogram->HasConstructionArguments( | |
| 483 1, HistogramBase::kSampleType_MAX - 1, 8)); | |
| 484 | |
| 485 std::vector<int> custom_ranges; | |
| 486 custom_ranges.push_back(0); | |
| 487 custom_ranges.push_back(5); | |
| 488 Histogram* custom_histogram = static_cast<Histogram*>( | |
| 489 CustomHistogram::FactoryGet( | |
| 490 "BadRangesCustom", custom_ranges, HistogramBase::kNoFlags)); | |
| 491 const BucketRanges* ranges = custom_histogram->bucket_ranges(); | |
| 492 ASSERT_EQ(3u, ranges->size()); | |
| 493 EXPECT_EQ(0, ranges->range(0)); | |
| 494 EXPECT_EQ(5, ranges->range(1)); | |
| 495 EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2)); | |
| 496 | |
| 497 // CustomHistogram does not accepts kSampleType_MAX as range. | |
| 498 custom_ranges.push_back(HistogramBase::kSampleType_MAX); | |
| 499 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom2", custom_ranges, | |
| 500 HistogramBase::kNoFlags), | |
| 501 ""); | |
| 502 | |
| 503 // CustomHistogram needs at least 1 valid range. | |
| 504 custom_ranges.clear(); | |
| 505 custom_ranges.push_back(0); | |
| 506 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, | |
| 507 HistogramBase::kNoFlags), | |
| 508 ""); | |
| 509 } | |
| 510 #endif | |
| 511 | |
| 512 } // namespace base | |
| OLD | NEW |