1// Copyright (c) 2016 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/persistent_sample_map.h" 6 7#include <memory> 8 9#include "base/memory/ptr_util.h" 10#include "base/metrics/persistent_histogram_allocator.h" 11#include "base/test/gtest_util.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14namespace base { 15namespace { 16 17std::unique_ptr<PersistentHistogramAllocator> CreateHistogramAllocator( 18 size_t bytes) { 19 return MakeUnique<PersistentHistogramAllocator>( 20 MakeUnique<LocalPersistentMemoryAllocator>(bytes, 0, "")); 21} 22 23std::unique_ptr<PersistentHistogramAllocator> DuplicateHistogramAllocator( 24 PersistentHistogramAllocator* original) { 25 return MakeUnique<PersistentHistogramAllocator>( 26 MakeUnique<PersistentMemoryAllocator>( 27 const_cast<void*>(original->data()), original->length(), 0, 28 original->Id(), original->Name(), false)); 29} 30 31TEST(PersistentSampleMapTest, AccumulateTest) { 32 std::unique_ptr<PersistentHistogramAllocator> allocator = 33 CreateHistogramAllocator(64 << 10); // 64 KiB 34 HistogramSamples::LocalMetadata meta; 35 PersistentSampleMap samples(1, allocator.get(), &meta); 36 37 samples.Accumulate(1, 100); 38 samples.Accumulate(2, 200); 39 samples.Accumulate(1, -200); 40 EXPECT_EQ(-100, samples.GetCount(1)); 41 EXPECT_EQ(200, samples.GetCount(2)); 42 43 EXPECT_EQ(300, samples.sum()); 44 EXPECT_EQ(100, samples.TotalCount()); 45 EXPECT_EQ(samples.redundant_count(), samples.TotalCount()); 46} 47 48TEST(PersistentSampleMapTest, Accumulate_LargeValuesDontOverflow) { 49 std::unique_ptr<PersistentHistogramAllocator> allocator = 50 CreateHistogramAllocator(64 << 10); // 64 KiB 51 HistogramSamples::LocalMetadata meta; 52 PersistentSampleMap samples(1, allocator.get(), &meta); 53 54 samples.Accumulate(250000000, 100); 55 samples.Accumulate(500000000, 200); 56 samples.Accumulate(250000000, -200); 57 EXPECT_EQ(-100, samples.GetCount(250000000)); 58 EXPECT_EQ(200, samples.GetCount(500000000)); 59 60 EXPECT_EQ(75000000000LL, samples.sum()); 61 EXPECT_EQ(100, samples.TotalCount()); 62 EXPECT_EQ(samples.redundant_count(), samples.TotalCount()); 63} 64 65TEST(PersistentSampleMapTest, AddSubtractTest) { 66 std::unique_ptr<PersistentHistogramAllocator> allocator1 = 67 CreateHistogramAllocator(64 << 10); // 64 KiB 68 HistogramSamples::LocalMetadata meta1; 69 PersistentSampleMap samples1(1, allocator1.get(), &meta1); 70 samples1.Accumulate(1, 100); 71 samples1.Accumulate(2, 100); 72 samples1.Accumulate(3, 100); 73 74 std::unique_ptr<PersistentHistogramAllocator> allocator2 = 75 DuplicateHistogramAllocator(allocator1.get()); 76 HistogramSamples::LocalMetadata meta2; 77 PersistentSampleMap samples2(2, allocator2.get(), &meta2); 78 samples2.Accumulate(1, 200); 79 samples2.Accumulate(2, 200); 80 samples2.Accumulate(4, 200); 81 82 samples1.Add(samples2); 83 EXPECT_EQ(300, samples1.GetCount(1)); 84 EXPECT_EQ(300, samples1.GetCount(2)); 85 EXPECT_EQ(100, samples1.GetCount(3)); 86 EXPECT_EQ(200, samples1.GetCount(4)); 87 EXPECT_EQ(2000, samples1.sum()); 88 EXPECT_EQ(900, samples1.TotalCount()); 89 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount()); 90 91 samples1.Subtract(samples2); 92 EXPECT_EQ(100, samples1.GetCount(1)); 93 EXPECT_EQ(100, samples1.GetCount(2)); 94 EXPECT_EQ(100, samples1.GetCount(3)); 95 EXPECT_EQ(0, samples1.GetCount(4)); 96 EXPECT_EQ(600, samples1.sum()); 97 EXPECT_EQ(300, samples1.TotalCount()); 98 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount()); 99} 100 101TEST(PersistentSampleMapTest, PersistenceTest) { 102 std::unique_ptr<PersistentHistogramAllocator> allocator1 = 103 CreateHistogramAllocator(64 << 10); // 64 KiB 104 HistogramSamples::LocalMetadata meta12; 105 PersistentSampleMap samples1(12, allocator1.get(), &meta12); 106 samples1.Accumulate(1, 100); 107 samples1.Accumulate(2, 200); 108 samples1.Accumulate(1, -200); 109 samples1.Accumulate(-1, 1); 110 EXPECT_EQ(-100, samples1.GetCount(1)); 111 EXPECT_EQ(200, samples1.GetCount(2)); 112 EXPECT_EQ(1, samples1.GetCount(-1)); 113 EXPECT_EQ(299, samples1.sum()); 114 EXPECT_EQ(101, samples1.TotalCount()); 115 EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount()); 116 117 std::unique_ptr<PersistentHistogramAllocator> allocator2 = 118 DuplicateHistogramAllocator(allocator1.get()); 119 PersistentSampleMap samples2(12, allocator2.get(), &meta12); 120 EXPECT_EQ(samples1.id(), samples2.id()); 121 EXPECT_EQ(samples1.sum(), samples2.sum()); 122 EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count()); 123 EXPECT_EQ(samples1.TotalCount(), samples2.TotalCount()); 124 EXPECT_EQ(-100, samples2.GetCount(1)); 125 EXPECT_EQ(200, samples2.GetCount(2)); 126 EXPECT_EQ(1, samples2.GetCount(-1)); 127 EXPECT_EQ(299, samples2.sum()); 128 EXPECT_EQ(101, samples2.TotalCount()); 129 EXPECT_EQ(samples2.redundant_count(), samples2.TotalCount()); 130 131 samples1.Accumulate(-1, -1); 132 EXPECT_EQ(0, samples2.GetCount(3)); 133 EXPECT_EQ(0, samples1.GetCount(3)); 134 samples2.Accumulate(3, 300); 135 EXPECT_EQ(300, samples2.GetCount(3)); 136 EXPECT_EQ(300, samples1.GetCount(3)); 137 EXPECT_EQ(samples1.sum(), samples2.sum()); 138 EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count()); 139 EXPECT_EQ(samples1.TotalCount(), samples2.TotalCount()); 140 141 EXPECT_EQ(0, samples2.GetCount(4)); 142 EXPECT_EQ(0, samples1.GetCount(4)); 143 samples1.Accumulate(4, 400); 144 EXPECT_EQ(400, samples2.GetCount(4)); 145 EXPECT_EQ(400, samples1.GetCount(4)); 146 samples2.Accumulate(4, 4000); 147 EXPECT_EQ(4400, samples2.GetCount(4)); 148 EXPECT_EQ(4400, samples1.GetCount(4)); 149 EXPECT_EQ(samples1.sum(), samples2.sum()); 150 EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count()); 151 EXPECT_EQ(samples1.TotalCount(), samples2.TotalCount()); 152} 153 154TEST(PersistentSampleMapIteratorTest, IterateTest) { 155 std::unique_ptr<PersistentHistogramAllocator> allocator = 156 CreateHistogramAllocator(64 << 10); // 64 KiB 157 HistogramSamples::LocalMetadata meta; 158 PersistentSampleMap samples(1, allocator.get(), &meta); 159 samples.Accumulate(1, 100); 160 samples.Accumulate(2, 200); 161 samples.Accumulate(4, -300); 162 samples.Accumulate(5, 0); 163 164 std::unique_ptr<SampleCountIterator> it = samples.Iterator(); 165 166 HistogramBase::Sample min; 167 HistogramBase::Sample max; 168 HistogramBase::Count count; 169 170 it->Get(&min, &max, &count); 171 EXPECT_EQ(1, min); 172 EXPECT_EQ(2, max); 173 EXPECT_EQ(100, count); 174 EXPECT_FALSE(it->GetBucketIndex(NULL)); 175 176 it->Next(); 177 it->Get(&min, &max, &count); 178 EXPECT_EQ(2, min); 179 EXPECT_EQ(3, max); 180 EXPECT_EQ(200, count); 181 182 it->Next(); 183 it->Get(&min, &max, &count); 184 EXPECT_EQ(4, min); 185 EXPECT_EQ(5, max); 186 EXPECT_EQ(-300, count); 187 188 it->Next(); 189 EXPECT_TRUE(it->Done()); 190} 191 192TEST(PersistentSampleMapIteratorTest, SkipEmptyRanges) { 193 std::unique_ptr<PersistentHistogramAllocator> allocator1 = 194 CreateHistogramAllocator(64 << 10); // 64 KiB 195 HistogramSamples::LocalMetadata meta1; 196 PersistentSampleMap samples1(1, allocator1.get(), &meta1); 197 samples1.Accumulate(5, 1); 198 samples1.Accumulate(10, 2); 199 samples1.Accumulate(15, 3); 200 samples1.Accumulate(20, 4); 201 samples1.Accumulate(25, 5); 202 203 std::unique_ptr<PersistentHistogramAllocator> allocator2 = 204 DuplicateHistogramAllocator(allocator1.get()); 205 HistogramSamples::LocalMetadata meta2; 206 PersistentSampleMap samples2(2, allocator2.get(), &meta2); 207 samples2.Accumulate(5, 1); 208 samples2.Accumulate(20, 4); 209 samples2.Accumulate(25, 5); 210 211 samples1.Subtract(samples2); 212 213 std::unique_ptr<SampleCountIterator> it = samples1.Iterator(); 214 EXPECT_FALSE(it->Done()); 215 216 HistogramBase::Sample min; 217 HistogramBase::Sample max; 218 HistogramBase::Count count; 219 220 it->Get(&min, &max, &count); 221 EXPECT_EQ(10, min); 222 EXPECT_EQ(11, max); 223 EXPECT_EQ(2, count); 224 225 it->Next(); 226 EXPECT_FALSE(it->Done()); 227 228 it->Get(&min, &max, &count); 229 EXPECT_EQ(15, min); 230 EXPECT_EQ(16, max); 231 EXPECT_EQ(3, count); 232 233 it->Next(); 234 EXPECT_TRUE(it->Done()); 235} 236 237TEST(PersistentSampleMapIteratorDeathTest, IterateDoneTest) { 238 std::unique_ptr<PersistentHistogramAllocator> allocator = 239 CreateHistogramAllocator(64 << 10); // 64 KiB 240 HistogramSamples::LocalMetadata meta; 241 PersistentSampleMap samples(1, allocator.get(), &meta); 242 243 std::unique_ptr<SampleCountIterator> it = samples.Iterator(); 244 245 EXPECT_TRUE(it->Done()); 246 247 HistogramBase::Sample min; 248 HistogramBase::Sample max; 249 HistogramBase::Count count; 250 EXPECT_DCHECK_DEATH(it->Get(&min, &max, &count)); 251 252 EXPECT_DCHECK_DEATH(it->Next()); 253 254 samples.Accumulate(1, 100); 255 it = samples.Iterator(); 256 EXPECT_FALSE(it->Done()); 257} 258 259} // namespace 260} // namespace base 261