// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/metrics/sparse_histogram.h" #include #include "base/memory/scoped_ptr.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_samples.h" #include "base/metrics/sample_map.h" #include "base/metrics/statistics_recorder.h" #include "base/pickle.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { class SparseHistogramTest : public testing::Test { protected: void SetUp() override { // Each test will have a clean state (no Histogram / BucketRanges // registered). InitializeStatisticsRecorder(); } void TearDown() override { UninitializeStatisticsRecorder(); } void InitializeStatisticsRecorder() { statistics_recorder_ = new StatisticsRecorder(); } void UninitializeStatisticsRecorder() { delete statistics_recorder_; statistics_recorder_ = NULL; } scoped_ptr NewSparseHistogram(const std::string& name) { return scoped_ptr(new SparseHistogram(name)); } StatisticsRecorder* statistics_recorder_; }; TEST_F(SparseHistogramTest, BasicTest) { scoped_ptr histogram(NewSparseHistogram("Sparse")); scoped_ptr snapshot(histogram->SnapshotSamples()); EXPECT_EQ(0, snapshot->TotalCount()); EXPECT_EQ(0, snapshot->sum()); histogram->Add(100); scoped_ptr snapshot1(histogram->SnapshotSamples()); EXPECT_EQ(1, snapshot1->TotalCount()); EXPECT_EQ(1, snapshot1->GetCount(100)); histogram->Add(100); histogram->Add(101); scoped_ptr snapshot2(histogram->SnapshotSamples()); EXPECT_EQ(3, snapshot2->TotalCount()); EXPECT_EQ(2, snapshot2->GetCount(100)); EXPECT_EQ(1, snapshot2->GetCount(101)); } TEST_F(SparseHistogramTest, BasicTestAddCount) { scoped_ptr histogram(NewSparseHistogram("Sparse")); scoped_ptr snapshot(histogram->SnapshotSamples()); EXPECT_EQ(0, snapshot->TotalCount()); EXPECT_EQ(0, snapshot->sum()); histogram->AddCount(100, 15); scoped_ptr snapshot1(histogram->SnapshotSamples()); EXPECT_EQ(15, snapshot1->TotalCount()); EXPECT_EQ(15, snapshot1->GetCount(100)); histogram->AddCount(100, 15); histogram->AddCount(101, 25); scoped_ptr snapshot2(histogram->SnapshotSamples()); EXPECT_EQ(55, snapshot2->TotalCount()); EXPECT_EQ(30, snapshot2->GetCount(100)); EXPECT_EQ(25, snapshot2->GetCount(101)); } TEST_F(SparseHistogramTest, AddCount_LargeValuesDontOverflow) { scoped_ptr histogram(NewSparseHistogram("Sparse")); scoped_ptr snapshot(histogram->SnapshotSamples()); EXPECT_EQ(0, snapshot->TotalCount()); EXPECT_EQ(0, snapshot->sum()); histogram->AddCount(1000000000, 15); scoped_ptr snapshot1(histogram->SnapshotSamples()); EXPECT_EQ(15, snapshot1->TotalCount()); EXPECT_EQ(15, snapshot1->GetCount(1000000000)); histogram->AddCount(1000000000, 15); histogram->AddCount(1010000000, 25); scoped_ptr snapshot2(histogram->SnapshotSamples()); EXPECT_EQ(55, snapshot2->TotalCount()); EXPECT_EQ(30, snapshot2->GetCount(1000000000)); EXPECT_EQ(25, snapshot2->GetCount(1010000000)); EXPECT_EQ(55250000000LL, snapshot2->sum()); } TEST_F(SparseHistogramTest, MacroBasicTest) { UMA_HISTOGRAM_SPARSE_SLOWLY("Sparse", 100); UMA_HISTOGRAM_SPARSE_SLOWLY("Sparse", 200); UMA_HISTOGRAM_SPARSE_SLOWLY("Sparse", 100); StatisticsRecorder::Histograms histograms; StatisticsRecorder::GetHistograms(&histograms); ASSERT_EQ(1U, histograms.size()); HistogramBase* sparse_histogram = histograms[0]; EXPECT_EQ(SPARSE_HISTOGRAM, sparse_histogram->GetHistogramType()); EXPECT_EQ("Sparse", sparse_histogram->histogram_name()); EXPECT_EQ(HistogramBase::kUmaTargetedHistogramFlag, sparse_histogram->flags()); scoped_ptr samples = sparse_histogram->SnapshotSamples(); EXPECT_EQ(3, samples->TotalCount()); EXPECT_EQ(2, samples->GetCount(100)); EXPECT_EQ(1, samples->GetCount(200)); } TEST_F(SparseHistogramTest, MacroInLoopTest) { // Unlike the macros in histogram.h, SparseHistogram macros can have a // variable as histogram name. for (int i = 0; i < 2; i++) { std::string name = StringPrintf("Sparse%d", i + 1); UMA_HISTOGRAM_SPARSE_SLOWLY(name, 100); } StatisticsRecorder::Histograms histograms; StatisticsRecorder::GetHistograms(&histograms); ASSERT_EQ(2U, histograms.size()); std::string name1 = histograms[0]->histogram_name(); std::string name2 = histograms[1]->histogram_name(); EXPECT_TRUE(("Sparse1" == name1 && "Sparse2" == name2) || ("Sparse2" == name1 && "Sparse1" == name2)); } TEST_F(SparseHistogramTest, Serialize) { scoped_ptr histogram(NewSparseHistogram("Sparse")); histogram->SetFlags(HistogramBase::kIPCSerializationSourceFlag); Pickle pickle; histogram->SerializeInfo(&pickle); PickleIterator iter(pickle); int type; EXPECT_TRUE(iter.ReadInt(&type)); EXPECT_EQ(SPARSE_HISTOGRAM, type); std::string name; EXPECT_TRUE(iter.ReadString(&name)); EXPECT_EQ("Sparse", name); int flag; EXPECT_TRUE(iter.ReadInt(&flag)); EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag, flag); // No more data in the pickle. EXPECT_FALSE(iter.SkipBytes(1)); } } // namespace base