// Copyright 2014 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/histogram_snapshot_manager.h" #include #include #include "base/macros.h" #include "base/metrics/histogram_delta_serialization.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sample_vector.h" #include "base/metrics/statistics_recorder.h" #include "base/stl_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { class HistogramFlattenerDeltaRecorder : public HistogramFlattener { public: HistogramFlattenerDeltaRecorder() {} void RecordDelta(const HistogramBase& histogram, const HistogramSamples& snapshot) override { recorded_delta_histogram_names_.push_back(histogram.histogram_name()); ASSERT_FALSE(ContainsKey(recorded_delta_histogram_sum_, histogram.histogram_name())); // Keep pointer to snapshot for testing. This really isn't ideal but the // snapshot-manager keeps the snapshot alive until it's "forgotten". recorded_delta_histogram_sum_[histogram.histogram_name()] = snapshot.sum(); } void InconsistencyDetected(HistogramBase::Inconsistency problem) override { ASSERT_TRUE(false); } void UniqueInconsistencyDetected( HistogramBase::Inconsistency problem) override { ASSERT_TRUE(false); } void InconsistencyDetectedInLoggedCount(int amount) override { ASSERT_TRUE(false); } void Reset() { recorded_delta_histogram_names_.clear(); recorded_delta_histogram_sum_.clear(); } std::vector GetRecordedDeltaHistogramNames() { return recorded_delta_histogram_names_; } int64_t GetRecordedDeltaHistogramSum(const std::string& name) { EXPECT_TRUE(ContainsKey(recorded_delta_histogram_sum_, name)); return recorded_delta_histogram_sum_[name]; } private: std::vector recorded_delta_histogram_names_; std::map recorded_delta_histogram_sum_; DISALLOW_COPY_AND_ASSIGN(HistogramFlattenerDeltaRecorder); }; class HistogramSnapshotManagerTest : public testing::Test { protected: HistogramSnapshotManagerTest() : histogram_snapshot_manager_(&histogram_flattener_delta_recorder_) {} ~HistogramSnapshotManagerTest() override {} StatisticsRecorder statistics_recorder_; HistogramFlattenerDeltaRecorder histogram_flattener_delta_recorder_; HistogramSnapshotManager histogram_snapshot_manager_; }; TEST_F(HistogramSnapshotManagerTest, PrepareDeltasNoFlagsFilter) { // kNoFlags filter should record all histograms. UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4); UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2); histogram_snapshot_manager_.PrepareDeltas( StatisticsRecorder::begin(false), StatisticsRecorder::end(), HistogramBase::kNoFlags, HistogramBase::kNoFlags); const std::vector& histograms = histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames(); EXPECT_EQ(2U, histograms.size()); EXPECT_EQ("UmaHistogram", histograms[0]); EXPECT_EQ("UmaStabilityHistogram", histograms[1]); } TEST_F(HistogramSnapshotManagerTest, PrepareDeltasUmaHistogramFlagFilter) { // Note that kUmaStabilityHistogramFlag includes kUmaTargetedHistogramFlag. UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4); UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2); histogram_snapshot_manager_.PrepareDeltas( StatisticsRecorder::begin(false), StatisticsRecorder::end(), HistogramBase::kNoFlags, HistogramBase::kUmaTargetedHistogramFlag); const std::vector& histograms = histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames(); EXPECT_EQ(2U, histograms.size()); EXPECT_EQ("UmaHistogram", histograms[0]); EXPECT_EQ("UmaStabilityHistogram", histograms[1]); } TEST_F(HistogramSnapshotManagerTest, PrepareDeltasUmaStabilityHistogramFlagFilter) { UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4); UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2); histogram_snapshot_manager_.PrepareDeltas( StatisticsRecorder::begin(false), StatisticsRecorder::end(), HistogramBase::kNoFlags, HistogramBase::kUmaStabilityHistogramFlag); const std::vector& histograms = histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames(); EXPECT_EQ(1U, histograms.size()); EXPECT_EQ("UmaStabilityHistogram", histograms[0]); } TEST_F(HistogramSnapshotManagerTest, CheckMerge) { UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4); UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2); base::HistogramBase* h1 = base::LinearHistogram::FactoryGet( "UmaHistogram", 1, 4, 5, 0); ASSERT_TRUE(h1); base::HistogramBase* h2 = base::LinearHistogram::FactoryGet( "UmaStabilityHistogram", 1, 2, 3, 0); ASSERT_TRUE(h2); histogram_snapshot_manager_.StartDeltas(); histogram_snapshot_manager_.PrepareDelta(h1); histogram_snapshot_manager_.PrepareDelta(h1); // Delta will be zero. histogram_snapshot_manager_.PrepareDelta(h2); h1->Add(2); h2->Add(1); histogram_snapshot_manager_.PrepareDelta(h2); histogram_snapshot_manager_.PrepareDelta(h1); histogram_snapshot_manager_.FinishDeltas(); { const std::vector histograms = histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames(); EXPECT_EQ(2U, histograms.size()); EXPECT_EQ(3, histogram_flattener_delta_recorder_. GetRecordedDeltaHistogramSum("UmaHistogram")); EXPECT_EQ(2, histogram_flattener_delta_recorder_. GetRecordedDeltaHistogramSum("UmaStabilityHistogram")); } } } // namespace base