Chromium Code Reviews| Index: base/metrics/sample_vector_unittest.cc |
| diff --git a/base/metrics/sample_vector_unittest.cc b/base/metrics/sample_vector_unittest.cc |
| index 2d77d2376b83a7442fd2e0929e5e21d832d6ba88..40782fbd42c72dd898cd31f6d820ca51dc4cd70f 100644 |
| --- a/base/metrics/sample_vector_unittest.cc |
| +++ b/base/metrics/sample_vector_unittest.cc |
| @@ -7,18 +7,27 @@ |
| #include <limits.h> |
| #include <stddef.h> |
| +#include <atomic> |
| #include <memory> |
| #include <vector> |
| #include "base/metrics/bucket_ranges.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/metrics/persistent_memory_allocator.h" |
| #include "base/test/gtest_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| namespace base { |
| -namespace { |
| -TEST(SampleVectorTest, AccumulateTest) { |
| +class SampleVectorTest : public testing::Test { |
| + public: |
| + const HistogramBase::AtomicCount* GetSamplesCounts( |
|
Alexei Svitkine (slow)
2017/04/12 17:38:07
Nit: Seems like this can just be a free-standing f
bcwhite
2017/04/13 00:06:01
It's accessing a protected method off of SampleVec
Alexei Svitkine (slow)
2017/04/18 20:52:19
Ah, I missed that it was using a protected method.
bcwhite
2017/04/19 18:13:01
Done.
|
| + const SampleVectorBase& samples) { |
| + return samples.counts(); |
| + } |
| +}; |
| + |
| +TEST_F(SampleVectorTest, AccumulateTest) { |
| // Custom buckets: [1, 5) [5, 10) |
| BucketRanges ranges(3); |
| ranges.set_range(0, 1); |
| @@ -45,7 +54,7 @@ TEST(SampleVectorTest, AccumulateTest) { |
| EXPECT_EQ(samples.TotalCount(), samples.redundant_count()); |
| } |
| -TEST(SampleVectorTest, Accumulate_LargeValuesDontOverflow) { |
| +TEST_F(SampleVectorTest, Accumulate_LargeValuesDontOverflow) { |
| // Custom buckets: [1, 250000000) [250000000, 500000000) |
| BucketRanges ranges(3); |
| ranges.set_range(0, 1); |
| @@ -72,7 +81,7 @@ TEST(SampleVectorTest, Accumulate_LargeValuesDontOverflow) { |
| EXPECT_EQ(samples.TotalCount(), samples.redundant_count()); |
| } |
| -TEST(SampleVectorTest, AddSubtractTest) { |
| +TEST_F(SampleVectorTest, AddSubtractTest) { |
| // Custom buckets: [0, 1) [1, 2) [2, 3) [3, INT_MAX) |
| BucketRanges ranges(5); |
| ranges.set_range(0, 0); |
| @@ -116,7 +125,7 @@ TEST(SampleVectorTest, AddSubtractTest) { |
| EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount()); |
| } |
| -TEST(SampleVectorDeathTest, BucketIndexTest) { |
| +TEST_F(SampleVectorTest, BucketIndexDeathTest) { |
| // 8 buckets with exponential layout: |
| // [0, 1) [1, 2) [2, 4) [4, 8) [8, 16) [16, 32) [32, 64) [64, INT_MAX) |
| BucketRanges ranges(9); |
| @@ -158,7 +167,7 @@ TEST(SampleVectorDeathTest, BucketIndexTest) { |
| EXPECT_DCHECK_DEATH(samples2.Accumulate(10, 100)); |
| } |
| -TEST(SampleVectorDeathTest, AddSubtractBucketNotMatchTest) { |
| +TEST_F(SampleVectorTest, AddSubtractBucketNotMatchDeathTest) { |
| // Custom buckets 1: [1, 3) [3, 5) |
| BucketRanges ranges1(3); |
| ranges1.set_range(0, 1); |
| @@ -197,7 +206,7 @@ TEST(SampleVectorDeathTest, AddSubtractBucketNotMatchTest) { |
| EXPECT_DCHECK_DEATH(samples1.Subtract(samples2)); |
| } |
| -TEST(SampleVectorIteratorTest, IterateTest) { |
| +TEST_F(SampleVectorTest, IterateTest) { |
| BucketRanges ranges(5); |
| ranges.set_range(0, 0); |
| ranges.set_range(1, 1); |
| @@ -257,7 +266,7 @@ TEST(SampleVectorIteratorTest, IterateTest) { |
| EXPECT_EQ(4, i); |
| } |
| -TEST(SampleVectorIteratorDeathTest, IterateDoneTest) { |
| +TEST_F(SampleVectorTest, IterateDoneDeathTest) { |
| BucketRanges ranges(5); |
| ranges.set_range(0, 0); |
| ranges.set_range(1, 1); |
| @@ -282,5 +291,218 @@ TEST(SampleVectorIteratorDeathTest, IterateDoneTest) { |
| EXPECT_FALSE(it->Done()); |
| } |
| -} // namespace |
| +TEST_F(SampleVectorTest, SingleSampleTest) { |
| + // Custom buckets: [1, 5) [5, 10) |
| + BucketRanges ranges(3); |
| + ranges.set_range(0, 1); |
| + ranges.set_range(1, 5); |
| + ranges.set_range(2, 10); |
| + SampleVector samples(&ranges); |
| + |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + samples.Accumulate(3, 200); |
| + EXPECT_EQ(200, samples.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + samples.Accumulate(3, 500); |
| + EXPECT_EQ(700, samples.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + samples.Accumulate(3, -100); |
| + EXPECT_EQ(600, samples.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + EXPECT_EQ(3 * 600, samples.sum()); |
| + EXPECT_EQ(600, samples.TotalCount()); |
| + EXPECT_EQ(600, samples.redundant_count()); |
| + |
| + HistogramBase::Sample min; |
| + HistogramBase::Sample max; |
| + HistogramBase::Count count; |
| + std::unique_ptr<SampleCountIterator> it = samples.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(600, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| + |
| + samples.Accumulate(8, 100); |
| + EXPECT_TRUE(GetSamplesCounts(samples)); |
| + EXPECT_EQ(600, samples.GetCount(3)); |
| + EXPECT_EQ(100, samples.GetCount(8)); |
| + EXPECT_EQ(3 * 600 + 8 * 100, samples.sum()); |
| + EXPECT_EQ(700, samples.TotalCount()); |
| + EXPECT_EQ(700, samples.redundant_count()); |
| + |
| + it = samples.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(600, count); |
| + it->Next(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(5, min); |
| + EXPECT_EQ(10, max); |
| + EXPECT_EQ(100, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| +} |
| + |
| +TEST_F(SampleVectorTest, PersistentSampleVectorTest) { |
| + LocalPersistentMemoryAllocator allocator(64 << 10, 0, ""); |
| + std::atomic<PersistentMemoryAllocator::Reference> samples_ref; |
| + samples_ref.store(0, std::memory_order_relaxed); |
| + HistogramSamples::Metadata samples_meta; |
| + memset(&samples_meta, 0, sizeof(samples_meta)); |
| + |
| + // Custom buckets: [1, 5) [5, 10) |
| + BucketRanges ranges(3); |
| + ranges.set_range(0, 1); |
| + ranges.set_range(1, 5); |
| + ranges.set_range(2, 10); |
| + |
| + // Persistent allocation. |
| + const size_t counts_bytes = |
| + sizeof(HistogramBase::AtomicCount) * ranges.bucket_count(); |
| + const DelayedPersistentAllocation allocation(&allocator, &samples_ref, 0, |
| + counts_bytes); |
| + |
| + PersistentSampleVector samples1(0, &ranges, &samples_meta, allocation); |
| + EXPECT_FALSE(GetSamplesCounts(samples1)); |
| + samples1.Accumulate(3, 200); |
| + EXPECT_EQ(200, samples1.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples1)); |
| + EXPECT_EQ(0, samples1.GetCount(8)); |
| + EXPECT_FALSE(GetSamplesCounts(samples1)); |
| + |
| + PersistentSampleVector samples2(0, &ranges, &samples_meta, allocation); |
| + EXPECT_EQ(200, samples2.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples2)); |
| + |
| + HistogramBase::Sample min; |
| + HistogramBase::Sample max; |
| + HistogramBase::Count count; |
| + std::unique_ptr<SampleCountIterator> it = samples2.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(200, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| + |
| + samples1.Accumulate(8, 100); |
| + EXPECT_TRUE(GetSamplesCounts(samples1)); |
| + |
| + EXPECT_FALSE(GetSamplesCounts(samples2)); |
| + EXPECT_EQ(200, samples2.GetCount(3)); |
| + EXPECT_EQ(100, samples2.GetCount(8)); |
| + EXPECT_TRUE(GetSamplesCounts(samples2)); |
| + EXPECT_EQ(3 * 200 + 8 * 100, samples2.sum()); |
| + EXPECT_EQ(300, samples2.TotalCount()); |
| + EXPECT_EQ(300, samples2.redundant_count()); |
| + |
| + it = samples2.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(200, count); |
| + it->Next(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(5, min); |
| + EXPECT_EQ(10, max); |
| + EXPECT_EQ(100, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| + |
| + PersistentSampleVector samples3(0, &ranges, &samples_meta, allocation); |
| + EXPECT_TRUE(GetSamplesCounts(samples2)); |
| + EXPECT_EQ(200, samples3.GetCount(3)); |
| + EXPECT_EQ(100, samples3.GetCount(8)); |
| + EXPECT_EQ(3 * 200 + 8 * 100, samples3.sum()); |
| + EXPECT_EQ(300, samples3.TotalCount()); |
| + EXPECT_EQ(300, samples3.redundant_count()); |
| + |
| + it = samples3.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(200, count); |
| + it->Next(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(5, min); |
| + EXPECT_EQ(10, max); |
| + EXPECT_EQ(100, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| +} |
| + |
| +TEST_F(SampleVectorTest, PersistentSampleVectorTestWithOutsideAlloc) { |
| + LocalPersistentMemoryAllocator allocator(64 << 10, 0, ""); |
| + std::atomic<PersistentMemoryAllocator::Reference> samples_ref; |
| + samples_ref.store(0, std::memory_order_relaxed); |
| + HistogramSamples::Metadata samples_meta; |
| + memset(&samples_meta, 0, sizeof(samples_meta)); |
| + |
| + // Custom buckets: [1, 5) [5, 10) |
| + BucketRanges ranges(3); |
| + ranges.set_range(0, 1); |
| + ranges.set_range(1, 5); |
| + ranges.set_range(2, 10); |
| + |
| + // Persistent allocation. |
| + const size_t counts_bytes = |
| + sizeof(HistogramBase::AtomicCount) * ranges.bucket_count(); |
| + const DelayedPersistentAllocation allocation(&allocator, &samples_ref, 0, |
| + counts_bytes); |
| + |
| + PersistentSampleVector samples(0, &ranges, &samples_meta, allocation); |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + samples.Accumulate(3, 200); |
| + EXPECT_EQ(200, samples.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + |
| + // Because the delayed allocation can be shared with other objects (the |
| + // |offset| parameter allows concatinating multiple data blocks into the |
| + // same allocation), it's possible that the allocation gets realized from |
| + // the outside even though the data block being accessed is all zero. |
| + allocation.Get(); |
| + EXPECT_EQ(200, samples.GetCount(3)); |
| + EXPECT_FALSE(GetSamplesCounts(samples)); |
| + |
| + HistogramBase::Sample min; |
| + HistogramBase::Sample max; |
| + HistogramBase::Count count; |
| + std::unique_ptr<SampleCountIterator> it = samples.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(200, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| + |
| + samples.Accumulate(3, 100); |
| + EXPECT_EQ(300, samples.GetCount(3)); |
| + |
| + it = samples.Iterator(); |
| + ASSERT_FALSE(it->Done()); |
| + it->Get(&min, &max, &count); |
| + EXPECT_EQ(1, min); |
| + EXPECT_EQ(5, max); |
| + EXPECT_EQ(300, count); |
| + it->Next(); |
| + EXPECT_TRUE(it->Done()); |
| + |
| + samples.Accumulate(8, 100); |
| + EXPECT_TRUE(GetSamplesCounts(samples)); |
| + EXPECT_EQ(300, samples.GetCount(3)); |
| + EXPECT_EQ(100, samples.GetCount(8)); |
| +} |
| + |
| } // namespace base |