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/json/json_reader.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/metrics/histogram.h"
     10 #include "base/metrics/statistics_recorder.h"
     11 #include "base/values.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace base {
     15 
     16 class StatisticsRecorderTest : public testing::Test {
     17  protected:
     18   virtual void SetUp() {
     19     // Each test will have a clean state (no Histogram / BucketRanges
     20     // registered).
     21     InitializeStatisticsRecorder();
     22   }
     23 
     24   virtual void TearDown() {
     25     UninitializeStatisticsRecorder();
     26   }
     27 
     28   void InitializeStatisticsRecorder() {
     29     statistics_recorder_ = new StatisticsRecorder();
     30   }
     31 
     32   void UninitializeStatisticsRecorder() {
     33     delete statistics_recorder_;
     34     statistics_recorder_ = NULL;
     35   }
     36 
     37   Histogram* CreateHistogram(const std::string& name,
     38                              HistogramBase::Sample min,
     39                              HistogramBase::Sample max,
     40                              size_t bucket_count) {
     41     BucketRanges* ranges = new BucketRanges(bucket_count + 1);
     42     Histogram::InitializeBucketRanges(min, max, ranges);
     43     const BucketRanges* registered_ranges =
     44         StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
     45     return new Histogram(name, min, max, registered_ranges);
     46   }
     47 
     48   void DeleteHistogram(HistogramBase* histogram) {
     49     delete histogram;
     50   }
     51 
     52   StatisticsRecorder* statistics_recorder_;
     53 };
     54 
     55 TEST_F(StatisticsRecorderTest, NotInitialized) {
     56   UninitializeStatisticsRecorder();
     57 
     58   ASSERT_FALSE(StatisticsRecorder::IsActive());
     59 
     60   StatisticsRecorder::Histograms registered_histograms;
     61   std::vector<const BucketRanges*> registered_ranges;
     62 
     63   StatisticsRecorder::GetHistograms(&registered_histograms);
     64   EXPECT_EQ(0u, registered_histograms.size());
     65 
     66   Histogram* histogram = CreateHistogram("TestHistogram", 1, 1000, 10);
     67 
     68   // When StatisticsRecorder is not initialized, register is a noop.
     69   EXPECT_EQ(histogram,
     70             StatisticsRecorder::RegisterOrDeleteDuplicate(histogram));
     71   // Manually delete histogram that was not registered.
     72   DeleteHistogram(histogram);
     73 
     74   // RegisterOrDeleteDuplicateRanges is a no-op.
     75   BucketRanges* ranges = new BucketRanges(3);;
     76   ranges->ResetChecksum();
     77   EXPECT_EQ(ranges,
     78             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges));
     79   StatisticsRecorder::GetBucketRanges(&registered_ranges);
     80   EXPECT_EQ(0u, registered_ranges.size());
     81 }
     82 
     83 TEST_F(StatisticsRecorderTest, RegisterBucketRanges) {
     84   std::vector<const BucketRanges*> registered_ranges;
     85 
     86   BucketRanges* ranges1 = new BucketRanges(3);;
     87   ranges1->ResetChecksum();
     88   BucketRanges* ranges2 = new BucketRanges(4);;
     89   ranges2->ResetChecksum();
     90 
     91   // Register new ranges.
     92   EXPECT_EQ(ranges1,
     93             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1));
     94   EXPECT_EQ(ranges2,
     95             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges2));
     96   StatisticsRecorder::GetBucketRanges(&registered_ranges);
     97   ASSERT_EQ(2u, registered_ranges.size());
     98 
     99   // Register some ranges again.
    100   EXPECT_EQ(ranges1,
    101             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1));
    102   registered_ranges.clear();
    103   StatisticsRecorder::GetBucketRanges(&registered_ranges);
    104   ASSERT_EQ(2u, registered_ranges.size());
    105   // Make sure the ranges is still the one we know.
    106   ASSERT_EQ(3u, ranges1->size());
    107   EXPECT_EQ(0, ranges1->range(0));
    108   EXPECT_EQ(0, ranges1->range(1));
    109   EXPECT_EQ(0, ranges1->range(2));
    110 
    111   // Register ranges with same values.
    112   BucketRanges* ranges3 = new BucketRanges(3);;
    113   ranges3->ResetChecksum();
    114   EXPECT_EQ(ranges1,  // returning ranges1
    115             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges3));
    116   registered_ranges.clear();
    117   StatisticsRecorder::GetBucketRanges(&registered_ranges);
    118   ASSERT_EQ(2u, registered_ranges.size());
    119 }
    120 
    121 TEST_F(StatisticsRecorderTest, RegisterHistogram) {
    122   // Create a Histogram that was not registered.
    123   Histogram* histogram = CreateHistogram("TestHistogram", 1, 1000, 10);
    124 
    125   StatisticsRecorder::Histograms registered_histograms;
    126   StatisticsRecorder::GetHistograms(&registered_histograms);
    127   EXPECT_EQ(0u, registered_histograms.size());
    128 
    129   // Register the Histogram.
    130   EXPECT_EQ(histogram,
    131             StatisticsRecorder::RegisterOrDeleteDuplicate(histogram));
    132   StatisticsRecorder::GetHistograms(&registered_histograms);
    133   EXPECT_EQ(1u, registered_histograms.size());
    134 
    135   // Register the same Histogram again.
    136   EXPECT_EQ(histogram,
    137             StatisticsRecorder::RegisterOrDeleteDuplicate(histogram));
    138   registered_histograms.clear();
    139   StatisticsRecorder::GetHistograms(&registered_histograms);
    140   EXPECT_EQ(1u, registered_histograms.size());
    141 }
    142 
    143 TEST_F(StatisticsRecorderTest, FindHistogram) {
    144   HistogramBase* histogram1 = Histogram::FactoryGet(
    145       "TestHistogram1", 1, 1000, 10, HistogramBase::kNoFlags);
    146   HistogramBase* histogram2 = Histogram::FactoryGet(
    147       "TestHistogram2", 1, 1000, 10, HistogramBase::kNoFlags);
    148 
    149   EXPECT_EQ(histogram1, StatisticsRecorder::FindHistogram("TestHistogram1"));
    150   EXPECT_EQ(histogram2, StatisticsRecorder::FindHistogram("TestHistogram2"));
    151   EXPECT_TRUE(StatisticsRecorder::FindHistogram("TestHistogram") == NULL);
    152 }
    153 
    154 TEST_F(StatisticsRecorderTest, GetSnapshot) {
    155   Histogram::FactoryGet("TestHistogram1", 1, 1000, 10, Histogram::kNoFlags);
    156   Histogram::FactoryGet("TestHistogram2", 1, 1000, 10, Histogram::kNoFlags);
    157   Histogram::FactoryGet("TestHistogram3", 1, 1000, 10, Histogram::kNoFlags);
    158 
    159   StatisticsRecorder::Histograms snapshot;
    160   StatisticsRecorder::GetSnapshot("Test", &snapshot);
    161   EXPECT_EQ(3u, snapshot.size());
    162 
    163   snapshot.clear();
    164   StatisticsRecorder::GetSnapshot("1", &snapshot);
    165   EXPECT_EQ(1u, snapshot.size());
    166 
    167   snapshot.clear();
    168   StatisticsRecorder::GetSnapshot("hello", &snapshot);
    169   EXPECT_EQ(0u, snapshot.size());
    170 }
    171 
    172 TEST_F(StatisticsRecorderTest, RegisterHistogramWithFactoryGet) {
    173   StatisticsRecorder::Histograms registered_histograms;
    174 
    175   StatisticsRecorder::GetHistograms(&registered_histograms);
    176   ASSERT_EQ(0u, registered_histograms.size());
    177 
    178   // Create a histogram.
    179   HistogramBase* histogram = Histogram::FactoryGet(
    180       "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    181   registered_histograms.clear();
    182   StatisticsRecorder::GetHistograms(&registered_histograms);
    183   EXPECT_EQ(1u, registered_histograms.size());
    184 
    185   // Get an existing histogram.
    186   HistogramBase* histogram2 = Histogram::FactoryGet(
    187       "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    188   registered_histograms.clear();
    189   StatisticsRecorder::GetHistograms(&registered_histograms);
    190   EXPECT_EQ(1u, registered_histograms.size());
    191   EXPECT_EQ(histogram, histogram2);
    192 
    193   // Create a LinearHistogram.
    194   histogram = LinearHistogram::FactoryGet(
    195       "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    196   registered_histograms.clear();
    197   StatisticsRecorder::GetHistograms(&registered_histograms);
    198   EXPECT_EQ(2u, registered_histograms.size());
    199 
    200   // Create a BooleanHistogram.
    201   histogram = BooleanHistogram::FactoryGet(
    202       "TestBooleanHistogram", HistogramBase::kNoFlags);
    203   registered_histograms.clear();
    204   StatisticsRecorder::GetHistograms(&registered_histograms);
    205   EXPECT_EQ(3u, registered_histograms.size());
    206 
    207   // Create a CustomHistogram.
    208   std::vector<int> custom_ranges;
    209   custom_ranges.push_back(1);
    210   custom_ranges.push_back(5);
    211   histogram = CustomHistogram::FactoryGet(
    212       "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
    213   registered_histograms.clear();
    214   StatisticsRecorder::GetHistograms(&registered_histograms);
    215   EXPECT_EQ(4u, registered_histograms.size());
    216 }
    217 
    218 TEST_F(StatisticsRecorderTest, RegisterHistogramWithMacros) {
    219   StatisticsRecorder::Histograms registered_histograms;
    220 
    221   HistogramBase* histogram = Histogram::FactoryGet(
    222       "TestHistogramCounts", 1, 1000000, 50, HistogramBase::kNoFlags);
    223 
    224   // The histogram we got from macro is the same as from FactoryGet.
    225   LOCAL_HISTOGRAM_COUNTS("TestHistogramCounts", 30);
    226   registered_histograms.clear();
    227   StatisticsRecorder::GetHistograms(&registered_histograms);
    228   ASSERT_EQ(1u, registered_histograms.size());
    229   EXPECT_EQ(histogram, registered_histograms[0]);
    230 
    231   LOCAL_HISTOGRAM_TIMES("TestHistogramTimes", TimeDelta::FromDays(1));
    232   LOCAL_HISTOGRAM_ENUMERATION("TestHistogramEnumeration", 20, 200);
    233 
    234   registered_histograms.clear();
    235   StatisticsRecorder::GetHistograms(&registered_histograms);
    236   EXPECT_EQ(3u, registered_histograms.size());
    237 }
    238 
    239 TEST_F(StatisticsRecorderTest, BucketRangesSharing) {
    240   std::vector<const BucketRanges*> ranges;
    241   StatisticsRecorder::GetBucketRanges(&ranges);
    242   EXPECT_EQ(0u, ranges.size());
    243 
    244   Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags);
    245   Histogram::FactoryGet("Histogram2", 1, 64, 8, HistogramBase::kNoFlags);
    246 
    247   StatisticsRecorder::GetBucketRanges(&ranges);
    248   EXPECT_EQ(1u, ranges.size());
    249 
    250   Histogram::FactoryGet("Histogram3", 1, 64, 16, HistogramBase::kNoFlags);
    251 
    252   ranges.clear();
    253   StatisticsRecorder::GetBucketRanges(&ranges);
    254   EXPECT_EQ(2u, ranges.size());
    255 }
    256 
    257 TEST_F(StatisticsRecorderTest, ToJSON) {
    258   LOCAL_HISTOGRAM_COUNTS("TestHistogram1", 30);
    259   LOCAL_HISTOGRAM_COUNTS("TestHistogram1", 40);
    260   LOCAL_HISTOGRAM_COUNTS("TestHistogram2", 30);
    261   LOCAL_HISTOGRAM_COUNTS("TestHistogram2", 40);
    262 
    263   std::string json(StatisticsRecorder::ToJSON(std::string()));
    264 
    265   // Check for valid JSON.
    266   scoped_ptr<Value> root;
    267   root.reset(JSONReader::Read(json));
    268   ASSERT_TRUE(root.get());
    269 
    270   DictionaryValue* root_dict = NULL;
    271   ASSERT_TRUE(root->GetAsDictionary(&root_dict));
    272 
    273   // No query should be set.
    274   ASSERT_FALSE(root_dict->HasKey("query"));
    275 
    276   ListValue* histogram_list = NULL;
    277   ASSERT_TRUE(root_dict->GetList("histograms", &histogram_list));
    278   ASSERT_EQ(2u, histogram_list->GetSize());
    279 
    280   // Examine the first histogram.
    281   DictionaryValue* histogram_dict = NULL;
    282   ASSERT_TRUE(histogram_list->GetDictionary(0, &histogram_dict));
    283 
    284   int sample_count;
    285   ASSERT_TRUE(histogram_dict->GetInteger("count", &sample_count));
    286   EXPECT_EQ(2, sample_count);
    287 
    288   // Test the query filter.
    289   std::string query("TestHistogram2");
    290   json = StatisticsRecorder::ToJSON(query);
    291 
    292   root.reset(JSONReader::Read(json));
    293   ASSERT_TRUE(root.get());
    294   ASSERT_TRUE(root->GetAsDictionary(&root_dict));
    295 
    296   std::string query_value;
    297   ASSERT_TRUE(root_dict->GetString("query", &query_value));
    298   EXPECT_EQ(query, query_value);
    299 
    300   ASSERT_TRUE(root_dict->GetList("histograms", &histogram_list));
    301   ASSERT_EQ(1u, histogram_list->GetSize());
    302 
    303   ASSERT_TRUE(histogram_list->GetDictionary(0, &histogram_dict));
    304 
    305   std::string histogram_name;
    306   ASSERT_TRUE(histogram_dict->GetString("name", &histogram_name));
    307   EXPECT_EQ("TestHistogram2", histogram_name);
    308 
    309   json.clear();
    310   UninitializeStatisticsRecorder();
    311 
    312   // No data should be returned.
    313   json = StatisticsRecorder::ToJSON(query);
    314   EXPECT_TRUE(json.empty());
    315 }
    316 
    317 }  // namespace base
    318