1 // Copyright 2014 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/histogram_snapshot_manager.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/macros.h"
11 #include "base/metrics/histogram_delta_serialization.h"
12 #include "base/metrics/histogram_macros.h"
13 #include "base/metrics/sample_vector.h"
14 #include "base/metrics/statistics_recorder.h"
15 #include "base/stl_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19
20 class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
21 public:
HistogramFlattenerDeltaRecorder()22 HistogramFlattenerDeltaRecorder() {}
23
RecordDelta(const HistogramBase & histogram,const HistogramSamples & snapshot)24 void RecordDelta(const HistogramBase& histogram,
25 const HistogramSamples& snapshot) override {
26 recorded_delta_histogram_names_.push_back(histogram.histogram_name());
27 // Use CHECK instead of ASSERT to get full stack-trace and thus origin.
28 CHECK(!ContainsKey(recorded_delta_histogram_sum_,
29 histogram.histogram_name()));
30 // Keep pointer to snapshot for testing. This really isn't ideal but the
31 // snapshot-manager keeps the snapshot alive until it's "forgotten".
32 recorded_delta_histogram_sum_[histogram.histogram_name()] = snapshot.sum();
33 }
34
InconsistencyDetected(HistogramBase::Inconsistency problem)35 void InconsistencyDetected(HistogramBase::Inconsistency problem) override {
36 ASSERT_TRUE(false);
37 }
38
UniqueInconsistencyDetected(HistogramBase::Inconsistency problem)39 void UniqueInconsistencyDetected(
40 HistogramBase::Inconsistency problem) override {
41 ASSERT_TRUE(false);
42 }
43
InconsistencyDetectedInLoggedCount(int amount)44 void InconsistencyDetectedInLoggedCount(int amount) override {
45 ASSERT_TRUE(false);
46 }
47
Reset()48 void Reset() {
49 recorded_delta_histogram_names_.clear();
50 recorded_delta_histogram_sum_.clear();
51 }
52
GetRecordedDeltaHistogramNames()53 std::vector<std::string> GetRecordedDeltaHistogramNames() {
54 return recorded_delta_histogram_names_;
55 }
56
GetRecordedDeltaHistogramSum(const std::string & name)57 int64_t GetRecordedDeltaHistogramSum(const std::string& name) {
58 EXPECT_TRUE(ContainsKey(recorded_delta_histogram_sum_, name));
59 return recorded_delta_histogram_sum_[name];
60 }
61
62 private:
63 std::vector<std::string> recorded_delta_histogram_names_;
64 std::map<std::string, int64_t> recorded_delta_histogram_sum_;
65
66 DISALLOW_COPY_AND_ASSIGN(HistogramFlattenerDeltaRecorder);
67 };
68
69 class HistogramSnapshotManagerTest : public testing::Test {
70 protected:
HistogramSnapshotManagerTest()71 HistogramSnapshotManagerTest()
72 : statistics_recorder_(StatisticsRecorder::CreateTemporaryForTesting()),
73 histogram_snapshot_manager_(&histogram_flattener_delta_recorder_) {}
74
~HistogramSnapshotManagerTest()75 ~HistogramSnapshotManagerTest() override {}
76
77 std::unique_ptr<StatisticsRecorder> statistics_recorder_;
78 HistogramFlattenerDeltaRecorder histogram_flattener_delta_recorder_;
79 HistogramSnapshotManager histogram_snapshot_manager_;
80 };
81
TEST_F(HistogramSnapshotManagerTest,PrepareDeltasNoFlagsFilter)82 TEST_F(HistogramSnapshotManagerTest, PrepareDeltasNoFlagsFilter) {
83 // kNoFlags filter should record all histograms.
84 UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4);
85 UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2);
86
87 histogram_snapshot_manager_.PrepareDeltas(
88 StatisticsRecorder::begin(false), StatisticsRecorder::end(),
89 HistogramBase::kNoFlags, HistogramBase::kNoFlags);
90
91 const std::vector<std::string>& histograms =
92 histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames();
93 EXPECT_EQ(2U, histograms.size());
94 EXPECT_EQ("UmaHistogram", histograms[0]);
95 EXPECT_EQ("UmaStabilityHistogram", histograms[1]);
96 }
97
TEST_F(HistogramSnapshotManagerTest,PrepareDeltasUmaHistogramFlagFilter)98 TEST_F(HistogramSnapshotManagerTest, PrepareDeltasUmaHistogramFlagFilter) {
99 // Note that kUmaStabilityHistogramFlag includes kUmaTargetedHistogramFlag.
100 UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4);
101 UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2);
102
103 histogram_snapshot_manager_.PrepareDeltas(
104 StatisticsRecorder::begin(false), StatisticsRecorder::end(),
105 HistogramBase::kNoFlags, HistogramBase::kUmaTargetedHistogramFlag);
106
107 const std::vector<std::string>& histograms =
108 histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames();
109 EXPECT_EQ(2U, histograms.size());
110 EXPECT_EQ("UmaHistogram", histograms[0]);
111 EXPECT_EQ("UmaStabilityHistogram", histograms[1]);
112 }
113
TEST_F(HistogramSnapshotManagerTest,PrepareDeltasUmaStabilityHistogramFlagFilter)114 TEST_F(HistogramSnapshotManagerTest,
115 PrepareDeltasUmaStabilityHistogramFlagFilter) {
116 UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 4);
117 UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2);
118
119 histogram_snapshot_manager_.PrepareDeltas(
120 StatisticsRecorder::begin(false), StatisticsRecorder::end(),
121 HistogramBase::kNoFlags, HistogramBase::kUmaStabilityHistogramFlag);
122
123 const std::vector<std::string>& histograms =
124 histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames();
125 EXPECT_EQ(1U, histograms.size());
126 EXPECT_EQ("UmaStabilityHistogram", histograms[0]);
127 }
128
129 } // namespace base
130