| 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 <climits> |
| 7 #include <algorithm> | 8 #include <algorithm> |
| 8 #include <vector> | 9 #include <vector> |
| 9 | 10 |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/metrics/bucket_ranges.h" | 13 #include "base/metrics/bucket_ranges.h" |
| 13 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "base/metrics/sample_vector.h" |
| 14 #include "base/metrics/statistics_recorder.h" | 16 #include "base/metrics/statistics_recorder.h" |
| 15 #include "base/time.h" | 17 #include "base/time.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 19 |
| 18 using std::vector; | 20 using std::vector; |
| 19 | 21 |
| 20 namespace base { | 22 namespace base { |
| 21 | 23 |
| 22 // Check for basic syntax and use. | 24 // Check for basic syntax and use. |
| 23 TEST(HistogramTest, BasicTest) { | 25 TEST(HistogramTest, BasicTest) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags)); | 201 "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags)); |
| 200 | 202 |
| 201 // Put two samples "out of bounds" above and below. | 203 // Put two samples "out of bounds" above and below. |
| 202 histogram->Add(5); | 204 histogram->Add(5); |
| 203 histogram->Add(-50); | 205 histogram->Add(-50); |
| 204 | 206 |
| 205 histogram->Add(100); | 207 histogram->Add(100); |
| 206 histogram->Add(10000); | 208 histogram->Add(10000); |
| 207 | 209 |
| 208 // Verify they landed in the underflow, and overflow buckets. | 210 // Verify they landed in the underflow, and overflow buckets. |
| 209 Histogram::SampleSet sample; | 211 scoped_ptr<SampleVector> samples = histogram->SnapshotSamples(); |
| 210 histogram->SnapshotSample(&sample); | 212 EXPECT_EQ(2, samples->GetCountAtIndex(0)); |
| 211 EXPECT_EQ(2, sample.counts(0)); | 213 EXPECT_EQ(0, samples->GetCountAtIndex(1)); |
| 212 EXPECT_EQ(0, sample.counts(1)); | |
| 213 size_t array_size = histogram->bucket_count(); | 214 size_t array_size = histogram->bucket_count(); |
| 214 EXPECT_EQ(kBucketCount, array_size); | 215 EXPECT_EQ(kBucketCount, array_size); |
| 215 EXPECT_EQ(0, sample.counts(array_size - 2)); | 216 EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2)); |
| 216 EXPECT_EQ(2, sample.counts(array_size - 1)); | 217 EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1)); |
| 217 | 218 |
| 218 vector<int> custom_ranges; | 219 vector<int> custom_ranges; |
| 219 custom_ranges.push_back(10); | 220 custom_ranges.push_back(10); |
| 220 custom_ranges.push_back(50); | 221 custom_ranges.push_back(50); |
| 221 custom_ranges.push_back(100); | 222 custom_ranges.push_back(100); |
| 222 Histogram* test_custom_histogram(CustomHistogram::FactoryGet( | 223 Histogram* test_custom_histogram(CustomHistogram::FactoryGet( |
| 223 "TestCustomRangeBoundedHistogram", custom_ranges, Histogram::kNoFlags)); | 224 "TestCustomRangeBoundedHistogram", custom_ranges, Histogram::kNoFlags)); |
| 224 | 225 |
| 225 // Put two samples "out of bounds" above and below. | 226 // Put two samples "out of bounds" above and below. |
| 226 test_custom_histogram->Add(5); | 227 test_custom_histogram->Add(5); |
| 227 test_custom_histogram->Add(-50); | 228 test_custom_histogram->Add(-50); |
| 228 test_custom_histogram->Add(100); | 229 test_custom_histogram->Add(100); |
| 229 test_custom_histogram->Add(1000); | 230 test_custom_histogram->Add(1000); |
| 231 test_custom_histogram->Add(INT_MAX); |
| 230 | 232 |
| 231 // Verify they landed in the underflow, and overflow buckets. | 233 // Verify they landed in the underflow, and overflow buckets. |
| 232 Histogram::SampleSet custom_sample; | 234 scoped_ptr<SampleVector> custom_samples = |
| 233 test_custom_histogram->SnapshotSample(&custom_sample); | 235 test_custom_histogram->SnapshotSamples(); |
| 234 EXPECT_EQ(2, custom_sample.counts(0)); | 236 EXPECT_EQ(2, custom_samples->GetCountAtIndex(0)); |
| 235 EXPECT_EQ(0, custom_sample.counts(1)); | 237 EXPECT_EQ(0, custom_samples->GetCountAtIndex(1)); |
| 236 size_t custom_array_size = test_custom_histogram->bucket_count(); | 238 size_t bucket_count = test_custom_histogram->bucket_count(); |
| 237 EXPECT_EQ(0, custom_sample.counts(custom_array_size - 2)); | 239 EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2)); |
| 238 EXPECT_EQ(2, custom_sample.counts(custom_array_size - 1)); | 240 EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1)); |
| 239 } | 241 } |
| 240 | 242 |
| 241 // Check to be sure samples land as expected is "correct" buckets. | 243 // Check to be sure samples land as expected is "correct" buckets. |
| 242 TEST(HistogramTest, BucketPlacementTest) { | 244 TEST(HistogramTest, BucketPlacementTest) { |
| 243 Histogram* histogram(Histogram::FactoryGet( | 245 Histogram* histogram(Histogram::FactoryGet( |
| 244 "Histogram", 1, 64, 8, Histogram::kNoFlags)); | 246 "Histogram", 1, 64, 8, Histogram::kNoFlags)); |
| 245 | 247 |
| 246 // Add i+1 samples to the i'th bucket. | 248 // Add i+1 samples to the i'th bucket. |
| 247 histogram->Add(0); | 249 histogram->Add(0); |
| 248 int power_of_2 = 1; | 250 int power_of_2 = 1; |
| 249 for (int i = 1; i < 8; i++) { | 251 for (int i = 1; i < 8; i++) { |
| 250 for (int j = 0; j <= i; j++) | 252 for (int j = 0; j <= i; j++) |
| 251 histogram->Add(power_of_2); | 253 histogram->Add(power_of_2); |
| 252 power_of_2 *= 2; | 254 power_of_2 *= 2; |
| 253 } | 255 } |
| 254 | 256 |
| 255 // Check to see that the bucket counts reflect our additions. | 257 // Check to see that the bucket counts reflect our additions. |
| 256 Histogram::SampleSet sample; | 258 scoped_ptr<SampleVector> samples = histogram->SnapshotSamples(); |
| 257 histogram->SnapshotSample(&sample); | |
| 258 for (int i = 0; i < 8; i++) | 259 for (int i = 0; i < 8; i++) |
| 259 EXPECT_EQ(i + 1, sample.counts(i)); | 260 EXPECT_EQ(i + 1, samples->GetCountAtIndex(i)); |
| 260 } | 261 } |
| 261 | 262 |
| 262 TEST(HistogramTest, CorruptSampleCounts) { | 263 TEST(HistogramTest, CorruptSampleCounts) { |
| 263 Histogram* histogram(Histogram::FactoryGet( | 264 Histogram* histogram(Histogram::FactoryGet( |
| 264 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. | 265 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. |
| 265 | 266 |
| 266 EXPECT_EQ(0, histogram->sample_.redundant_count()); | 267 // Add some samples. |
| 267 histogram->Add(20); // Add some samples. | 268 histogram->Add(20); |
| 268 histogram->Add(40); | 269 histogram->Add(40); |
| 269 EXPECT_EQ(2, histogram->sample_.redundant_count()); | |
| 270 | 270 |
| 271 Histogram::SampleSet snapshot; | 271 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSamples(); |
| 272 histogram->SnapshotSample(&snapshot); | 272 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, |
| 273 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, 0); | 273 histogram->FindCorruption(*snapshot)); |
| 274 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); // No default corruption. | 274 EXPECT_EQ(2, snapshot->redundant_count()); |
| 275 EXPECT_EQ(2, snapshot.redundant_count()); | 275 EXPECT_EQ(2, snapshot->TotalCount()); |
| 276 | 276 |
| 277 snapshot.counts_[3] += 100; // Sample count won't match redundant count. | 277 snapshot->counts_[3] += 100; // Sample count won't match redundant count. |
| 278 EXPECT_EQ(Histogram::COUNT_LOW_ERROR, histogram->FindCorruption(snapshot)); | 278 EXPECT_EQ(Histogram::COUNT_LOW_ERROR, |
| 279 snapshot.counts_[2] -= 200; | 279 histogram->FindCorruption(*snapshot)); |
| 280 EXPECT_EQ(Histogram::COUNT_HIGH_ERROR, histogram->FindCorruption(snapshot)); | 280 snapshot->counts_[2] -= 200; |
| 281 EXPECT_EQ(Histogram::COUNT_HIGH_ERROR, |
| 282 histogram->FindCorruption(*snapshot)); |
| 281 | 283 |
| 282 // But we can't spot a corruption if it is compensated for. | 284 // But we can't spot a corruption if it is compensated for. |
| 283 snapshot.counts_[1] += 100; | 285 snapshot->counts_[1] += 100; |
| 284 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); | 286 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, |
| 287 histogram->FindCorruption(*snapshot)); |
| 285 } | 288 } |
| 286 | 289 |
| 287 TEST(HistogramTest, CorruptBucketBounds) { | 290 TEST(HistogramTest, CorruptBucketBounds) { |
| 288 Histogram* histogram(Histogram::FactoryGet( | 291 Histogram* histogram(Histogram::FactoryGet( |
| 289 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. | 292 "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. |
| 290 | 293 |
| 291 Histogram::SampleSet snapshot; | 294 scoped_ptr<SampleVector> snapshot = histogram->SnapshotSamples(); |
| 292 histogram->SnapshotSample(&snapshot); | 295 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, |
| 293 EXPECT_EQ(Histogram::NO_INCONSISTENCIES, 0); | 296 histogram->FindCorruption(*snapshot)); |
| 294 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); // No default corruption. | |
| 295 | 297 |
| 296 BucketRanges* bucket_ranges = | 298 BucketRanges* bucket_ranges = |
| 297 const_cast<BucketRanges*>(histogram->bucket_ranges()); | 299 const_cast<BucketRanges*>(histogram->bucket_ranges()); |
| 298 HistogramBase::Sample tmp = bucket_ranges->range(1); | 300 HistogramBase::Sample tmp = bucket_ranges->range(1); |
| 299 bucket_ranges->set_range(1, bucket_ranges->range(2)); | 301 bucket_ranges->set_range(1, bucket_ranges->range(2)); |
| 300 bucket_ranges->set_range(2, tmp); | 302 bucket_ranges->set_range(2, tmp); |
| 301 EXPECT_EQ(Histogram::BUCKET_ORDER_ERROR | Histogram::RANGE_CHECKSUM_ERROR, | 303 EXPECT_EQ(Histogram::BUCKET_ORDER_ERROR | Histogram::RANGE_CHECKSUM_ERROR, |
| 302 histogram->FindCorruption(snapshot)); | 304 histogram->FindCorruption(*snapshot)); |
| 303 | 305 |
| 304 bucket_ranges->set_range(2, bucket_ranges->range(1)); | 306 bucket_ranges->set_range(2, bucket_ranges->range(1)); |
| 305 bucket_ranges->set_range(1, tmp); | 307 bucket_ranges->set_range(1, tmp); |
| 306 EXPECT_EQ(0, histogram->FindCorruption(snapshot)); | 308 EXPECT_EQ(0, histogram->FindCorruption(*snapshot)); |
| 307 | 309 |
| 310 // Show that two simple changes don't offset each other |
| 308 bucket_ranges->set_range(3, bucket_ranges->range(3) + 1); | 311 bucket_ranges->set_range(3, bucket_ranges->range(3) + 1); |
| 309 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, | 312 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, |
| 310 histogram->FindCorruption(snapshot)); | 313 histogram->FindCorruption(*snapshot)); |
| 311 | 314 |
| 312 // Show that two simple changes don't offset each other | |
| 313 bucket_ranges->set_range(4, bucket_ranges->range(4) - 1); | 315 bucket_ranges->set_range(4, bucket_ranges->range(4) - 1); |
| 314 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, | 316 EXPECT_EQ(Histogram::RANGE_CHECKSUM_ERROR, |
| 315 histogram->FindCorruption(snapshot)); | 317 histogram->FindCorruption(*snapshot)); |
| 316 | 318 |
| 317 // Repair histogram so that destructor won't DCHECK(). | 319 // Repair histogram so that destructor won't DCHECK(). |
| 318 bucket_ranges->set_range(3, bucket_ranges->range(3) - 1); | 320 bucket_ranges->set_range(3, bucket_ranges->range(3) - 1); |
| 319 bucket_ranges->set_range(4, bucket_ranges->range(4) + 1); | 321 bucket_ranges->set_range(4, bucket_ranges->range(4) + 1); |
| 320 } | 322 } |
| 321 | 323 |
| 322 #if GTEST_HAS_DEATH_TEST | 324 #if GTEST_HAS_DEATH_TEST |
| 323 // For Histogram, LinearHistogram and CustomHistogram, the minimum for a | 325 // For Histogram, LinearHistogram and CustomHistogram, the minimum for a |
| 324 // declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX - | 326 // declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX - |
| 325 // 1). But we accept ranges exceeding those limits, and silently clamped to | 327 // 1). But we accept ranges exceeding those limits, and silently clamped to |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 // CustomHistogram needs at least 1 valid range. | 359 // CustomHistogram needs at least 1 valid range. |
| 358 custom_ranges.clear(); | 360 custom_ranges.clear(); |
| 359 custom_ranges.push_back(0); | 361 custom_ranges.push_back(0); |
| 360 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, | 362 EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges, |
| 361 Histogram::kNoFlags), | 363 Histogram::kNoFlags), |
| 362 ""); | 364 ""); |
| 363 } | 365 } |
| 364 #endif | 366 #endif |
| 365 | 367 |
| 366 } // namespace base | 368 } // namespace base |
| OLD | NEW |