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
18namespace base {
19
20class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
21 public:
22  HistogramFlattenerDeltaRecorder() {}
23
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
35  void InconsistencyDetected(HistogramBase::Inconsistency problem) override {
36    ASSERT_TRUE(false);
37  }
38
39  void UniqueInconsistencyDetected(
40      HistogramBase::Inconsistency problem) override {
41    ASSERT_TRUE(false);
42  }
43
44  void InconsistencyDetectedInLoggedCount(int amount) override {
45    ASSERT_TRUE(false);
46  }
47
48  void Reset() {
49    recorded_delta_histogram_names_.clear();
50    recorded_delta_histogram_sum_.clear();
51  }
52
53  std::vector<std::string> GetRecordedDeltaHistogramNames() {
54    return recorded_delta_histogram_names_;
55  }
56
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
69class HistogramSnapshotManagerTest : public testing::Test {
70 protected:
71  HistogramSnapshotManagerTest()
72      : statistics_recorder_(StatisticsRecorder::CreateTemporaryForTesting()),
73        histogram_snapshot_manager_(&histogram_flattener_delta_recorder_) {}
74
75  ~HistogramSnapshotManagerTest() override {}
76
77  std::unique_ptr<StatisticsRecorder> statistics_recorder_;
78  HistogramFlattenerDeltaRecorder histogram_flattener_delta_recorder_;
79  HistogramSnapshotManager histogram_snapshot_manager_;
80};
81
82TEST_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
98TEST_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
114TEST_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