Home | History | Annotate | Download | only in metrics
      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 <vector>
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/metrics/bucket_ranges.h"
      9 #include "base/metrics/histogram.h"
     10 #include "base/metrics/sample_vector.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 using std::vector;
     14 
     15 namespace base {
     16 namespace {
     17 
     18 TEST(SampleVectorTest, AccumulateTest) {
     19   // Custom buckets: [1, 5) [5, 10)
     20   BucketRanges ranges(3);
     21   ranges.set_range(0, 1);
     22   ranges.set_range(1, 5);
     23   ranges.set_range(2, 10);
     24   SampleVector samples(&ranges);
     25 
     26   samples.Accumulate(1, 200);
     27   samples.Accumulate(2, -300);
     28   EXPECT_EQ(-100, samples.GetCountAtIndex(0));
     29 
     30   samples.Accumulate(5, 200);
     31   EXPECT_EQ(200, samples.GetCountAtIndex(1));
     32 
     33   EXPECT_EQ(600, samples.sum());
     34   EXPECT_EQ(100, samples.redundant_count());
     35   EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
     36 
     37   samples.Accumulate(5, -100);
     38   EXPECT_EQ(100, samples.GetCountAtIndex(1));
     39 
     40   EXPECT_EQ(100, samples.sum());
     41   EXPECT_EQ(0, samples.redundant_count());
     42   EXPECT_EQ(samples.TotalCount(), samples.redundant_count());
     43 }
     44 
     45 TEST(SampleVectorTest, AddSubtractTest) {
     46   // Custom buckets: [0, 1) [1, 2) [2, 3) [3, INT_MAX)
     47   BucketRanges ranges(5);
     48   ranges.set_range(0, 0);
     49   ranges.set_range(1, 1);
     50   ranges.set_range(2, 2);
     51   ranges.set_range(3, 3);
     52   ranges.set_range(4, INT_MAX);
     53 
     54   SampleVector samples1(&ranges);
     55   samples1.Accumulate(0, 100);
     56   samples1.Accumulate(2, 100);
     57   samples1.Accumulate(4, 100);
     58   EXPECT_EQ(600, samples1.sum());
     59   EXPECT_EQ(300, samples1.TotalCount());
     60   EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
     61 
     62   SampleVector samples2(&ranges);
     63   samples2.Accumulate(1, 200);
     64   samples2.Accumulate(2, 200);
     65   samples2.Accumulate(4, 200);
     66   EXPECT_EQ(1400, samples2.sum());
     67   EXPECT_EQ(600, samples2.TotalCount());
     68   EXPECT_EQ(samples2.redundant_count(), samples2.TotalCount());
     69 
     70   samples1.Add(samples2);
     71   EXPECT_EQ(100, samples1.GetCountAtIndex(0));
     72   EXPECT_EQ(200, samples1.GetCountAtIndex(1));
     73   EXPECT_EQ(300, samples1.GetCountAtIndex(2));
     74   EXPECT_EQ(300, samples1.GetCountAtIndex(3));
     75   EXPECT_EQ(2000, samples1.sum());
     76   EXPECT_EQ(900, samples1.TotalCount());
     77   EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
     78 
     79   samples1.Subtract(samples2);
     80   EXPECT_EQ(100, samples1.GetCountAtIndex(0));
     81   EXPECT_EQ(0, samples1.GetCountAtIndex(1));
     82   EXPECT_EQ(100, samples1.GetCountAtIndex(2));
     83   EXPECT_EQ(100, samples1.GetCountAtIndex(3));
     84   EXPECT_EQ(600, samples1.sum());
     85   EXPECT_EQ(300, samples1.TotalCount());
     86   EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
     87 }
     88 
     89 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
     90 TEST(SampleVectorDeathTest, BucketIndexTest) {
     91   // 8 buckets with exponential layout:
     92   // [0, 1) [1, 2) [2, 4) [4, 8) [8, 16) [16, 32) [32, 64) [64, INT_MAX)
     93   BucketRanges ranges(9);
     94   Histogram::InitializeBucketRanges(1, 64, &ranges);
     95   SampleVector samples(&ranges);
     96 
     97   // Normal case
     98   samples.Accumulate(0, 1);
     99   samples.Accumulate(3, 2);
    100   samples.Accumulate(64, 3);
    101   EXPECT_EQ(1, samples.GetCount(0));
    102   EXPECT_EQ(2, samples.GetCount(2));
    103   EXPECT_EQ(3, samples.GetCount(65));
    104 
    105   // Extreme case.
    106   EXPECT_DEATH(samples.Accumulate(INT_MIN, 100), "");
    107   EXPECT_DEATH(samples.Accumulate(-1, 100), "");
    108   EXPECT_DEATH(samples.Accumulate(INT_MAX, 100), "");
    109 
    110   // Custom buckets: [1, 5) [5, 10)
    111   // Note, this is not a valid BucketRanges for Histogram because it does not
    112   // have overflow buckets.
    113   BucketRanges ranges2(3);
    114   ranges2.set_range(0, 1);
    115   ranges2.set_range(1, 5);
    116   ranges2.set_range(2, 10);
    117   SampleVector samples2(&ranges2);
    118 
    119   // Normal case.
    120   samples2.Accumulate(1, 1);
    121   samples2.Accumulate(4, 1);
    122   samples2.Accumulate(5, 2);
    123   samples2.Accumulate(9, 2);
    124   EXPECT_EQ(2, samples2.GetCount(1));
    125   EXPECT_EQ(4, samples2.GetCount(5));
    126 
    127   // Extreme case.
    128   EXPECT_DEATH(samples2.Accumulate(0, 100), "");
    129   EXPECT_DEATH(samples2.Accumulate(10, 100), "");
    130 }
    131 
    132 TEST(SampleVectorDeathTest, AddSubtractBucketNotMatchTest) {
    133   // Custom buckets 1: [1, 3) [3, 5)
    134   BucketRanges ranges1(3);
    135   ranges1.set_range(0, 1);
    136   ranges1.set_range(1, 3);
    137   ranges1.set_range(2, 5);
    138   SampleVector samples1(&ranges1);
    139 
    140   // Custom buckets 2: [0, 1) [1, 3) [3, 6) [6, 7)
    141   BucketRanges ranges2(5);
    142   ranges2.set_range(0, 0);
    143   ranges2.set_range(1, 1);
    144   ranges2.set_range(2, 3);
    145   ranges2.set_range(3, 6);
    146   ranges2.set_range(4, 7);
    147   SampleVector samples2(&ranges2);
    148 
    149   samples2.Accumulate(1, 100);
    150   samples1.Add(samples2);
    151   EXPECT_EQ(100, samples1.GetCountAtIndex(0));
    152 
    153   // Extra bucket in the beginning.
    154   samples2.Accumulate(0, 100);
    155   EXPECT_DEATH(samples1.Add(samples2), "");
    156   EXPECT_DEATH(samples1.Subtract(samples2), "");
    157 
    158   // Extra bucket in the end.
    159   samples2.Accumulate(0, -100);
    160   samples2.Accumulate(6, 100);
    161   EXPECT_DEATH(samples1.Add(samples2), "");
    162   EXPECT_DEATH(samples1.Subtract(samples2), "");
    163 
    164   // Bucket not match: [3, 5) VS [3, 6)
    165   samples2.Accumulate(6, -100);
    166   samples2.Accumulate(3, 100);
    167   EXPECT_DEATH(samples1.Add(samples2), "");
    168   EXPECT_DEATH(samples1.Subtract(samples2), "");
    169 }
    170 
    171 #endif
    172 // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
    173 
    174 TEST(SampleVectorIteratorTest, IterateTest) {
    175   BucketRanges ranges(5);
    176   ranges.set_range(0, 0);
    177   ranges.set_range(1, 1);
    178   ranges.set_range(2, 2);
    179   ranges.set_range(3, 3);
    180   ranges.set_range(4, 4);
    181 
    182   vector<HistogramBase::Count> counts(3);
    183   counts[0] = 1;
    184   counts[1] = 0;  // Iterator will bypass this empty bucket.
    185   counts[2] = 2;
    186 
    187   // BucketRanges can have larger size than counts.
    188   SampleVectorIterator it(&counts, &ranges);
    189   size_t index;
    190 
    191   HistogramBase::Sample min;
    192   HistogramBase::Sample max;
    193   HistogramBase::Count count;
    194   it.Get(&min, &max, &count);
    195   EXPECT_EQ(0, min);
    196   EXPECT_EQ(1, max);
    197   EXPECT_EQ(1, count);
    198   EXPECT_TRUE(it.GetBucketIndex(&index));
    199   EXPECT_EQ(0u, index);
    200 
    201   it.Next();
    202   it.Get(&min, &max, &count);
    203   EXPECT_EQ(2, min);
    204   EXPECT_EQ(3, max);
    205   EXPECT_EQ(2, count);
    206   EXPECT_TRUE(it.GetBucketIndex(&index));
    207   EXPECT_EQ(2u, index);
    208 
    209   it.Next();
    210   EXPECT_TRUE(it.Done());
    211 
    212   // Create iterator from SampleVector.
    213   SampleVector samples(&ranges);
    214   samples.Accumulate(0, 0);
    215   samples.Accumulate(1, 1);
    216   samples.Accumulate(2, 2);
    217   samples.Accumulate(3, 3);
    218   scoped_ptr<SampleCountIterator> it2 = samples.Iterator();
    219 
    220   int i;
    221   for (i = 1; !it2->Done(); i++, it2->Next()) {
    222     it2->Get(&min, &max, &count);
    223     EXPECT_EQ(i, min);
    224     EXPECT_EQ(i + 1, max);
    225     EXPECT_EQ(i, count);
    226 
    227     size_t index;
    228     EXPECT_TRUE(it2->GetBucketIndex(&index));
    229     EXPECT_EQ(static_cast<size_t>(i), index);
    230   }
    231   EXPECT_EQ(4, i);
    232 }
    233 
    234 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
    235 
    236 TEST(SampleVectorIteratorDeathTest, IterateDoneTest) {
    237   BucketRanges ranges(5);
    238   ranges.set_range(0, 0);
    239   ranges.set_range(1, 1);
    240   ranges.set_range(2, 2);
    241   ranges.set_range(3, 3);
    242   ranges.set_range(4, INT_MAX);
    243   SampleVector samples(&ranges);
    244 
    245   scoped_ptr<SampleCountIterator> it = samples.Iterator();
    246 
    247   EXPECT_TRUE(it->Done());
    248 
    249   HistogramBase::Sample min;
    250   HistogramBase::Sample max;
    251   HistogramBase::Count count;
    252   EXPECT_DEATH(it->Get(&min, &max, &count), "");
    253 
    254   EXPECT_DEATH(it->Next(), "");
    255 
    256   samples.Accumulate(2, 100);
    257   it = samples.Iterator();
    258   EXPECT_FALSE(it->Done());
    259 }
    260 
    261 #endif
    262 // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
    263 
    264 }  // namespace
    265 }  // namespace base
    266