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 "base/metrics/statistics_recorder.h"
      6 
      7 #include <stddef.h>
      8 
      9 #include <memory>
     10 #include <vector>
     11 
     12 #include "base/bind.h"
     13 #include "base/json/json_reader.h"
     14 #include "base/logging.h"
     15 #include "base/metrics/histogram_macros.h"
     16 #include "base/metrics/persistent_histogram_allocator.h"
     17 #include "base/metrics/sparse_histogram.h"
     18 #include "base/values.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace {
     22 
     23 // Class to make sure any manipulations we do to the min log level are
     24 // contained (i.e., do not affect other unit tests).
     25 class LogStateSaver {
     26  public:
     27   LogStateSaver() : old_min_log_level_(logging::GetMinLogLevel()) {}
     28 
     29   ~LogStateSaver() {
     30     logging::SetMinLogLevel(old_min_log_level_);
     31     logging::SetLogAssertHandler(nullptr);
     32   }
     33 
     34  private:
     35   int old_min_log_level_;
     36 
     37   DISALLOW_COPY_AND_ASSIGN(LogStateSaver);
     38 };
     39 
     40 }  // namespace
     41 
     42 namespace base {
     43 
     44 class StatisticsRecorderTest : public testing::TestWithParam<bool> {
     45  protected:
     46   const int32_t kAllocatorMemorySize = 64 << 10;  // 64 KiB
     47 
     48   StatisticsRecorderTest() : use_persistent_histogram_allocator_(GetParam()) {
     49     // Get this first so it never gets created in persistent storage and will
     50     // not appear in the StatisticsRecorder after it is re-initialized.
     51     PersistentHistogramAllocator::GetCreateHistogramResultHistogram();
     52 
     53     // Each test will have a clean state (no Histogram / BucketRanges
     54     // registered).
     55     InitializeStatisticsRecorder();
     56 
     57     // Use persistent memory for histograms if so indicated by test parameter.
     58     if (use_persistent_histogram_allocator_) {
     59       GlobalHistogramAllocator::CreateWithLocalMemory(
     60           kAllocatorMemorySize, 0, "StatisticsRecorderTest");
     61     }
     62   }
     63 
     64   ~StatisticsRecorderTest() override {
     65     GlobalHistogramAllocator::ReleaseForTesting();
     66     UninitializeStatisticsRecorder();
     67   }
     68 
     69   void InitializeStatisticsRecorder() {
     70     DCHECK(!statistics_recorder_);
     71     StatisticsRecorder::UninitializeForTesting();
     72     statistics_recorder_ = StatisticsRecorder::CreateTemporaryForTesting();
     73   }
     74 
     75   void UninitializeStatisticsRecorder() {
     76     statistics_recorder_.reset();
     77     StatisticsRecorder::UninitializeForTesting();
     78   }
     79 
     80   Histogram* CreateHistogram(const std::string& name,
     81                              HistogramBase::Sample min,
     82                              HistogramBase::Sample max,
     83                              size_t bucket_count) {
     84     BucketRanges* ranges = new BucketRanges(bucket_count + 1);
     85     Histogram::InitializeBucketRanges(min, max, ranges);
     86     const BucketRanges* registered_ranges =
     87         StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
     88     return new Histogram(name, min, max, registered_ranges);
     89   }
     90 
     91   void DeleteHistogram(HistogramBase* histogram) {
     92     delete histogram;
     93   }
     94 
     95   int CountIterableHistograms(StatisticsRecorder::HistogramIterator* iter) {
     96     int count = 0;
     97     for (; *iter != StatisticsRecorder::end(); ++*iter) {
     98       ++count;
     99     }
    100     return count;
    101   }
    102 
    103   void InitLogOnShutdown() {
    104     DCHECK(statistics_recorder_);
    105     statistics_recorder_->InitLogOnShutdownWithoutLock();
    106   }
    107 
    108   bool VLogInitialized() {
    109     DCHECK(statistics_recorder_);
    110     return statistics_recorder_->vlog_initialized_;
    111   }
    112 
    113   const bool use_persistent_histogram_allocator_;
    114 
    115   std::unique_ptr<StatisticsRecorder> statistics_recorder_;
    116   std::unique_ptr<GlobalHistogramAllocator> old_global_allocator_;
    117 
    118  private:
    119   LogStateSaver log_state_saver_;
    120 
    121   DISALLOW_COPY_AND_ASSIGN(StatisticsRecorderTest);
    122 };
    123 
    124 // Run all HistogramTest cases with both heap and persistent memory.
    125 INSTANTIATE_TEST_CASE_P(Allocator, StatisticsRecorderTest, testing::Bool());
    126 
    127 TEST_P(StatisticsRecorderTest, NotInitialized) {
    128   UninitializeStatisticsRecorder();
    129 
    130   ASSERT_FALSE(StatisticsRecorder::IsActive());
    131 
    132   StatisticsRecorder::Histograms registered_histograms;
    133   std::vector<const BucketRanges*> registered_ranges;
    134 
    135   StatisticsRecorder::GetHistograms(&registered_histograms);
    136   EXPECT_EQ(0u, registered_histograms.size());
    137 
    138   Histogram* histogram = CreateHistogram("TestHistogram", 1, 1000, 10);
    139 
    140   // When StatisticsRecorder is not initialized, register is a noop.
    141   EXPECT_EQ(histogram,
    142             StatisticsRecorder::RegisterOrDeleteDuplicate(histogram));
    143   // Manually delete histogram that was not registered.
    144   DeleteHistogram(histogram);
    145 
    146   // RegisterOrDeleteDuplicateRanges is a no-op.
    147   BucketRanges* ranges = new BucketRanges(3);
    148   ranges->ResetChecksum();
    149   EXPECT_EQ(ranges,
    150             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges));
    151   StatisticsRecorder::GetBucketRanges(&registered_ranges);
    152   EXPECT_EQ(0u, registered_ranges.size());
    153 }
    154 
    155 TEST_P(StatisticsRecorderTest, RegisterBucketRanges) {
    156   std::vector<const BucketRanges*> registered_ranges;
    157 
    158   BucketRanges* ranges1 = new BucketRanges(3);
    159   ranges1->ResetChecksum();
    160   BucketRanges* ranges2 = new BucketRanges(4);
    161   ranges2->ResetChecksum();
    162 
    163   // Register new ranges.
    164   EXPECT_EQ(ranges1,
    165             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1));
    166   EXPECT_EQ(ranges2,
    167             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges2));
    168   StatisticsRecorder::GetBucketRanges(&registered_ranges);
    169   ASSERT_EQ(2u, registered_ranges.size());
    170 
    171   // Register some ranges again.
    172   EXPECT_EQ(ranges1,
    173             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1));
    174   registered_ranges.clear();
    175   StatisticsRecorder::GetBucketRanges(&registered_ranges);
    176   ASSERT_EQ(2u, registered_ranges.size());
    177   // Make sure the ranges is still the one we know.
    178   ASSERT_EQ(3u, ranges1->size());
    179   EXPECT_EQ(0, ranges1->range(0));
    180   EXPECT_EQ(0, ranges1->range(1));
    181   EXPECT_EQ(0, ranges1->range(2));
    182 
    183   // Register ranges with same values.
    184   BucketRanges* ranges3 = new BucketRanges(3);
    185   ranges3->ResetChecksum();
    186   EXPECT_EQ(ranges1,  // returning ranges1
    187             StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges3));
    188   registered_ranges.clear();
    189   StatisticsRecorder::GetBucketRanges(&registered_ranges);
    190   ASSERT_EQ(2u, registered_ranges.size());
    191 }
    192 
    193 TEST_P(StatisticsRecorderTest, RegisterHistogram) {
    194   // Create a Histogram that was not registered.
    195   Histogram* histogram = CreateHistogram("TestHistogram", 1, 1000, 10);
    196 
    197   StatisticsRecorder::Histograms registered_histograms;
    198   StatisticsRecorder::GetHistograms(&registered_histograms);
    199   EXPECT_EQ(0u, registered_histograms.size());
    200 
    201   // Register the Histogram.
    202   EXPECT_EQ(histogram,
    203             StatisticsRecorder::RegisterOrDeleteDuplicate(histogram));
    204   StatisticsRecorder::GetHistograms(&registered_histograms);
    205   EXPECT_EQ(1u, registered_histograms.size());
    206 
    207   // Register the same Histogram again.
    208   EXPECT_EQ(histogram,
    209             StatisticsRecorder::RegisterOrDeleteDuplicate(histogram));
    210   registered_histograms.clear();
    211   StatisticsRecorder::GetHistograms(&registered_histograms);
    212   EXPECT_EQ(1u, registered_histograms.size());
    213 }
    214 
    215 TEST_P(StatisticsRecorderTest, FindHistogram) {
    216   HistogramBase* histogram1 = Histogram::FactoryGet(
    217       "TestHistogram1", 1, 1000, 10, HistogramBase::kNoFlags);
    218   HistogramBase* histogram2 = Histogram::FactoryGet(
    219       "TestHistogram2", 1, 1000, 10, HistogramBase::kNoFlags);
    220 
    221   EXPECT_EQ(histogram1, StatisticsRecorder::FindHistogram("TestHistogram1"));
    222   EXPECT_EQ(histogram2, StatisticsRecorder::FindHistogram("TestHistogram2"));
    223   EXPECT_FALSE(StatisticsRecorder::FindHistogram("TestHistogram"));
    224 
    225   // Create a new global allocator using the same memory as the old one. Any
    226   // old one is kept around so the memory doesn't get released.
    227   old_global_allocator_ = GlobalHistogramAllocator::ReleaseForTesting();
    228   if (use_persistent_histogram_allocator_) {
    229     GlobalHistogramAllocator::CreateWithPersistentMemory(
    230         const_cast<void*>(old_global_allocator_->data()),
    231         old_global_allocator_->length(), 0, old_global_allocator_->Id(),
    232         old_global_allocator_->Name());
    233   }
    234 
    235   // Reset statistics-recorder to validate operation from a clean start.
    236   UninitializeStatisticsRecorder();
    237   InitializeStatisticsRecorder();
    238 
    239   if (use_persistent_histogram_allocator_) {
    240     EXPECT_TRUE(StatisticsRecorder::FindHistogram("TestHistogram1"));
    241     EXPECT_TRUE(StatisticsRecorder::FindHistogram("TestHistogram2"));
    242   } else {
    243     EXPECT_FALSE(StatisticsRecorder::FindHistogram("TestHistogram1"));
    244     EXPECT_FALSE(StatisticsRecorder::FindHistogram("TestHistogram2"));
    245   }
    246   EXPECT_FALSE(StatisticsRecorder::FindHistogram("TestHistogram"));
    247 }
    248 
    249 TEST_P(StatisticsRecorderTest, GetSnapshot) {
    250   Histogram::FactoryGet("TestHistogram1", 1, 1000, 10, Histogram::kNoFlags);
    251   Histogram::FactoryGet("TestHistogram2", 1, 1000, 10, Histogram::kNoFlags);
    252   Histogram::FactoryGet("TestHistogram3", 1, 1000, 10, Histogram::kNoFlags);
    253 
    254   StatisticsRecorder::Histograms snapshot;
    255   StatisticsRecorder::GetSnapshot("Test", &snapshot);
    256   EXPECT_EQ(3u, snapshot.size());
    257 
    258   snapshot.clear();
    259   StatisticsRecorder::GetSnapshot("1", &snapshot);
    260   EXPECT_EQ(1u, snapshot.size());
    261 
    262   snapshot.clear();
    263   StatisticsRecorder::GetSnapshot("hello", &snapshot);
    264   EXPECT_EQ(0u, snapshot.size());
    265 }
    266 
    267 TEST_P(StatisticsRecorderTest, RegisterHistogramWithFactoryGet) {
    268   StatisticsRecorder::Histograms registered_histograms;
    269 
    270   StatisticsRecorder::GetHistograms(&registered_histograms);
    271   ASSERT_EQ(0u, registered_histograms.size());
    272 
    273   // Create a histogram.
    274   HistogramBase* histogram = Histogram::FactoryGet(
    275       "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    276   registered_histograms.clear();
    277   StatisticsRecorder::GetHistograms(&registered_histograms);
    278   EXPECT_EQ(1u, registered_histograms.size());
    279 
    280   // Get an existing histogram.
    281   HistogramBase* histogram2 = Histogram::FactoryGet(
    282       "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    283   registered_histograms.clear();
    284   StatisticsRecorder::GetHistograms(&registered_histograms);
    285   EXPECT_EQ(1u, registered_histograms.size());
    286   EXPECT_EQ(histogram, histogram2);
    287 
    288   // Create a LinearHistogram.
    289   histogram = LinearHistogram::FactoryGet(
    290       "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    291   registered_histograms.clear();
    292   StatisticsRecorder::GetHistograms(&registered_histograms);
    293   EXPECT_EQ(2u, registered_histograms.size());
    294 
    295   // Create a BooleanHistogram.
    296   histogram = BooleanHistogram::FactoryGet(
    297       "TestBooleanHistogram", HistogramBase::kNoFlags);
    298   registered_histograms.clear();
    299   StatisticsRecorder::GetHistograms(&registered_histograms);
    300   EXPECT_EQ(3u, registered_histograms.size());
    301 
    302   // Create a CustomHistogram.
    303   std::vector<int> custom_ranges;
    304   custom_ranges.push_back(1);
    305   custom_ranges.push_back(5);
    306   histogram = CustomHistogram::FactoryGet(
    307       "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
    308   registered_histograms.clear();
    309   StatisticsRecorder::GetHistograms(&registered_histograms);
    310   EXPECT_EQ(4u, registered_histograms.size());
    311 }
    312 
    313 TEST_P(StatisticsRecorderTest, RegisterHistogramWithMacros) {
    314   // Macros cache pointers and so tests that use them can only be run once.
    315   // Stop immediately if this test has run previously.
    316   static bool already_run = false;
    317   if (already_run)
    318     return;
    319   already_run = true;
    320 
    321   StatisticsRecorder::Histograms registered_histograms;
    322 
    323   HistogramBase* histogram = Histogram::FactoryGet(
    324       "TestHistogramCounts", 1, 1000000, 50, HistogramBase::kNoFlags);
    325 
    326   // The histogram we got from macro is the same as from FactoryGet.
    327   LOCAL_HISTOGRAM_COUNTS("TestHistogramCounts", 30);
    328   registered_histograms.clear();
    329   StatisticsRecorder::GetHistograms(&registered_histograms);
    330   ASSERT_EQ(1u, registered_histograms.size());
    331   EXPECT_EQ(histogram, registered_histograms[0]);
    332 
    333   LOCAL_HISTOGRAM_TIMES("TestHistogramTimes", TimeDelta::FromDays(1));
    334   LOCAL_HISTOGRAM_ENUMERATION("TestHistogramEnumeration", 20, 200);
    335 
    336   registered_histograms.clear();
    337   StatisticsRecorder::GetHistograms(&registered_histograms);
    338   EXPECT_EQ(3u, registered_histograms.size());
    339 }
    340 
    341 TEST_P(StatisticsRecorderTest, BucketRangesSharing) {
    342   std::vector<const BucketRanges*> ranges;
    343   StatisticsRecorder::GetBucketRanges(&ranges);
    344   EXPECT_EQ(0u, ranges.size());
    345 
    346   Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags);
    347   Histogram::FactoryGet("Histogram2", 1, 64, 8, HistogramBase::kNoFlags);
    348 
    349   StatisticsRecorder::GetBucketRanges(&ranges);
    350   EXPECT_EQ(1u, ranges.size());
    351 
    352   Histogram::FactoryGet("Histogram3", 1, 64, 16, HistogramBase::kNoFlags);
    353 
    354   ranges.clear();
    355   StatisticsRecorder::GetBucketRanges(&ranges);
    356   EXPECT_EQ(2u, ranges.size());
    357 }
    358 
    359 TEST_P(StatisticsRecorderTest, ToJSON) {
    360   Histogram::FactoryGet("TestHistogram1", 1, 1000, 50, HistogramBase::kNoFlags)
    361       ->Add(30);
    362   Histogram::FactoryGet("TestHistogram1", 1, 1000, 50, HistogramBase::kNoFlags)
    363       ->Add(40);
    364   Histogram::FactoryGet("TestHistogram2", 1, 1000, 50, HistogramBase::kNoFlags)
    365       ->Add(30);
    366   Histogram::FactoryGet("TestHistogram2", 1, 1000, 50, HistogramBase::kNoFlags)
    367       ->Add(40);
    368 
    369   std::string json(StatisticsRecorder::ToJSON(std::string()));
    370 
    371   // Check for valid JSON.
    372   std::unique_ptr<Value> root = JSONReader::Read(json);
    373   ASSERT_TRUE(root.get());
    374 
    375   DictionaryValue* root_dict = NULL;
    376   ASSERT_TRUE(root->GetAsDictionary(&root_dict));
    377 
    378   // No query should be set.
    379   ASSERT_FALSE(root_dict->HasKey("query"));
    380 
    381   ListValue* histogram_list = NULL;
    382   ASSERT_TRUE(root_dict->GetList("histograms", &histogram_list));
    383   ASSERT_EQ(2u, histogram_list->GetSize());
    384 
    385   // Examine the first histogram.
    386   DictionaryValue* histogram_dict = NULL;
    387   ASSERT_TRUE(histogram_list->GetDictionary(0, &histogram_dict));
    388 
    389   int sample_count;
    390   ASSERT_TRUE(histogram_dict->GetInteger("count", &sample_count));
    391   EXPECT_EQ(2, sample_count);
    392 
    393   // Test the query filter.
    394   std::string query("TestHistogram2");
    395   json = StatisticsRecorder::ToJSON(query);
    396 
    397   root = JSONReader::Read(json);
    398   ASSERT_TRUE(root.get());
    399   ASSERT_TRUE(root->GetAsDictionary(&root_dict));
    400 
    401   std::string query_value;
    402   ASSERT_TRUE(root_dict->GetString("query", &query_value));
    403   EXPECT_EQ(query, query_value);
    404 
    405   ASSERT_TRUE(root_dict->GetList("histograms", &histogram_list));
    406   ASSERT_EQ(1u, histogram_list->GetSize());
    407 
    408   ASSERT_TRUE(histogram_list->GetDictionary(0, &histogram_dict));
    409 
    410   std::string histogram_name;
    411   ASSERT_TRUE(histogram_dict->GetString("name", &histogram_name));
    412   EXPECT_EQ("TestHistogram2", histogram_name);
    413 
    414   json.clear();
    415   UninitializeStatisticsRecorder();
    416 
    417   // No data should be returned.
    418   json = StatisticsRecorder::ToJSON(query);
    419   EXPECT_TRUE(json.empty());
    420 }
    421 
    422 TEST_P(StatisticsRecorderTest, IterationTest) {
    423   Histogram::FactoryGet("IterationTest1", 1, 64, 16, HistogramBase::kNoFlags);
    424   Histogram::FactoryGet("IterationTest2", 1, 64, 16, HistogramBase::kNoFlags);
    425 
    426   StatisticsRecorder::HistogramIterator i1 = StatisticsRecorder::begin(true);
    427   EXPECT_EQ(2, CountIterableHistograms(&i1));
    428 
    429   StatisticsRecorder::HistogramIterator i2 = StatisticsRecorder::begin(false);
    430   EXPECT_EQ(use_persistent_histogram_allocator_ ? 0 : 2,
    431             CountIterableHistograms(&i2));
    432 
    433   // Create a new global allocator using the same memory as the old one. Any
    434   // old one is kept around so the memory doesn't get released.
    435   old_global_allocator_ = GlobalHistogramAllocator::ReleaseForTesting();
    436   if (use_persistent_histogram_allocator_) {
    437     GlobalHistogramAllocator::CreateWithPersistentMemory(
    438         const_cast<void*>(old_global_allocator_->data()),
    439         old_global_allocator_->length(), 0, old_global_allocator_->Id(),
    440         old_global_allocator_->Name());
    441   }
    442 
    443   // Reset statistics-recorder to validate operation from a clean start.
    444   UninitializeStatisticsRecorder();
    445   InitializeStatisticsRecorder();
    446 
    447   StatisticsRecorder::HistogramIterator i3 = StatisticsRecorder::begin(true);
    448   EXPECT_EQ(use_persistent_histogram_allocator_ ? 2 : 0,
    449             CountIterableHistograms(&i3));
    450 
    451   StatisticsRecorder::HistogramIterator i4 = StatisticsRecorder::begin(false);
    452   EXPECT_EQ(0, CountIterableHistograms(&i4));
    453 }
    454 
    455 namespace {
    456 
    457 // CallbackCheckWrapper is simply a convenient way to check and store that
    458 // a callback was actually run.
    459 struct CallbackCheckWrapper {
    460   CallbackCheckWrapper() : called(false), last_histogram_value(0) {}
    461 
    462   void OnHistogramChanged(base::HistogramBase::Sample histogram_value) {
    463     called = true;
    464     last_histogram_value = histogram_value;
    465   }
    466 
    467   bool called;
    468   base::HistogramBase::Sample last_histogram_value;
    469 };
    470 
    471 }  // namespace
    472 
    473 // Check that you can't overwrite the callback with another.
    474 TEST_P(StatisticsRecorderTest, SetCallbackFailsWithoutHistogramTest) {
    475   CallbackCheckWrapper callback_wrapper;
    476 
    477   bool result = base::StatisticsRecorder::SetCallback(
    478       "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    479                                   base::Unretained(&callback_wrapper)));
    480   EXPECT_TRUE(result);
    481 
    482   result = base::StatisticsRecorder::SetCallback(
    483       "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    484                                   base::Unretained(&callback_wrapper)));
    485   EXPECT_FALSE(result);
    486 }
    487 
    488 // Check that you can't overwrite the callback with another.
    489 TEST_P(StatisticsRecorderTest, SetCallbackFailsWithHistogramTest) {
    490   HistogramBase* histogram = Histogram::FactoryGet("TestHistogram", 1, 1000, 10,
    491                                                    HistogramBase::kNoFlags);
    492   EXPECT_TRUE(histogram);
    493 
    494   CallbackCheckWrapper callback_wrapper;
    495 
    496   bool result = base::StatisticsRecorder::SetCallback(
    497       "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    498                                   base::Unretained(&callback_wrapper)));
    499   EXPECT_TRUE(result);
    500   EXPECT_EQ(histogram->flags() & base::HistogramBase::kCallbackExists,
    501             base::HistogramBase::kCallbackExists);
    502 
    503   result = base::StatisticsRecorder::SetCallback(
    504       "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    505                                   base::Unretained(&callback_wrapper)));
    506   EXPECT_FALSE(result);
    507   EXPECT_EQ(histogram->flags() & base::HistogramBase::kCallbackExists,
    508             base::HistogramBase::kCallbackExists);
    509 
    510   histogram->Add(1);
    511 
    512   EXPECT_TRUE(callback_wrapper.called);
    513 }
    514 
    515 // Check that you can't overwrite the callback with another.
    516 TEST_P(StatisticsRecorderTest, ClearCallbackSuceedsWithHistogramTest) {
    517   HistogramBase* histogram = Histogram::FactoryGet("TestHistogram", 1, 1000, 10,
    518                                                    HistogramBase::kNoFlags);
    519   EXPECT_TRUE(histogram);
    520 
    521   CallbackCheckWrapper callback_wrapper;
    522 
    523   bool result = base::StatisticsRecorder::SetCallback(
    524       "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    525                                   base::Unretained(&callback_wrapper)));
    526   EXPECT_TRUE(result);
    527   EXPECT_EQ(histogram->flags() & base::HistogramBase::kCallbackExists,
    528             base::HistogramBase::kCallbackExists);
    529 
    530   base::StatisticsRecorder::ClearCallback("TestHistogram");
    531   EXPECT_EQ(histogram->flags() & base::HistogramBase::kCallbackExists, 0);
    532 
    533   histogram->Add(1);
    534 
    535   EXPECT_FALSE(callback_wrapper.called);
    536 }
    537 
    538 // Check that callback is used.
    539 TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
    540   {
    541     HistogramBase* histogram = Histogram::FactoryGet(
    542         "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    543     EXPECT_TRUE(histogram);
    544 
    545     CallbackCheckWrapper callback_wrapper;
    546 
    547     base::StatisticsRecorder::SetCallback(
    548         "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    549                                     base::Unretained(&callback_wrapper)));
    550 
    551     histogram->Add(1);
    552 
    553     EXPECT_TRUE(callback_wrapper.called);
    554     EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
    555   }
    556 
    557   {
    558     HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
    559         "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
    560 
    561     CallbackCheckWrapper callback_wrapper;
    562 
    563     base::StatisticsRecorder::SetCallback(
    564         "TestLinearHistogram",
    565         base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    566                    base::Unretained(&callback_wrapper)));
    567 
    568     linear_histogram->Add(1);
    569 
    570     EXPECT_TRUE(callback_wrapper.called);
    571     EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
    572   }
    573 
    574   {
    575     std::vector<int> custom_ranges;
    576     custom_ranges.push_back(1);
    577     custom_ranges.push_back(5);
    578     HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
    579         "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
    580 
    581     CallbackCheckWrapper callback_wrapper;
    582 
    583     base::StatisticsRecorder::SetCallback(
    584         "TestCustomHistogram",
    585         base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    586                    base::Unretained(&callback_wrapper)));
    587 
    588     custom_histogram->Add(1);
    589 
    590     EXPECT_TRUE(callback_wrapper.called);
    591     EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
    592   }
    593 
    594   {
    595     HistogramBase* custom_histogram = SparseHistogram::FactoryGet(
    596         "TestSparseHistogram", HistogramBase::kNoFlags);
    597 
    598     CallbackCheckWrapper callback_wrapper;
    599 
    600     base::StatisticsRecorder::SetCallback(
    601         "TestSparseHistogram",
    602         base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    603                    base::Unretained(&callback_wrapper)));
    604 
    605     custom_histogram->Add(1);
    606 
    607     EXPECT_TRUE(callback_wrapper.called);
    608     EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
    609   }
    610 }
    611 
    612 // Check that setting a callback before the histogram exists works.
    613 TEST_P(StatisticsRecorderTest, CallbackUsedBeforeHistogramCreatedTest) {
    614   CallbackCheckWrapper callback_wrapper;
    615 
    616   base::StatisticsRecorder::SetCallback(
    617       "TestHistogram", base::Bind(&CallbackCheckWrapper::OnHistogramChanged,
    618                                   base::Unretained(&callback_wrapper)));
    619 
    620   HistogramBase* histogram = Histogram::FactoryGet("TestHistogram", 1, 1000, 10,
    621                                                    HistogramBase::kNoFlags);
    622   EXPECT_TRUE(histogram);
    623   histogram->Add(1);
    624 
    625   EXPECT_TRUE(callback_wrapper.called);
    626   EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
    627 }
    628 
    629 TEST_P(StatisticsRecorderTest, LogOnShutdownNotInitialized) {
    630   UninitializeStatisticsRecorder();
    631   logging::SetMinLogLevel(logging::LOG_WARNING);
    632   InitializeStatisticsRecorder();
    633   EXPECT_FALSE(VLOG_IS_ON(1));
    634   EXPECT_FALSE(VLogInitialized());
    635   InitLogOnShutdown();
    636   EXPECT_FALSE(VLogInitialized());
    637 }
    638 
    639 TEST_P(StatisticsRecorderTest, LogOnShutdownInitializedExplicitly) {
    640   UninitializeStatisticsRecorder();
    641   logging::SetMinLogLevel(logging::LOG_WARNING);
    642   InitializeStatisticsRecorder();
    643   EXPECT_FALSE(VLOG_IS_ON(1));
    644   EXPECT_FALSE(VLogInitialized());
    645   logging::SetMinLogLevel(logging::LOG_VERBOSE);
    646   EXPECT_TRUE(VLOG_IS_ON(1));
    647   InitLogOnShutdown();
    648   EXPECT_TRUE(VLogInitialized());
    649 }
    650 
    651 TEST_P(StatisticsRecorderTest, LogOnShutdownInitialized) {
    652   UninitializeStatisticsRecorder();
    653   logging::SetMinLogLevel(logging::LOG_VERBOSE);
    654   InitializeStatisticsRecorder();
    655   EXPECT_TRUE(VLOG_IS_ON(1));
    656   EXPECT_TRUE(VLogInitialized());
    657 }
    658 
    659 }  // namespace base
    660