xref: /aosp_15_r20/external/cronet/base/metrics/histogram_snapshot_manager_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 The Chromium Authors
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 <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/containers/contains.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/metrics/histogram_delta_serialization.h"
14 #include "base/metrics/histogram_functions.h"
15 #include "base/metrics/sample_vector.h"
16 #include "base/metrics/statistics_recorder.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace base {
20 
21 namespace {
22 
23 const std::string kHistogramName = "UmaHistogram";
24 
25 const std::string kStabilityHistogramName = "UmaStabilityHistogram";
26 
UmaStabilityHistogramBoolean(const std::string & name,bool sample)27 void UmaStabilityHistogramBoolean(const std::string& name, bool sample) {
28   HistogramBase* histogram = BooleanHistogram::FactoryGet(
29       name, HistogramBase::kUmaStabilityHistogramFlag);
30   histogram->Add(sample);
31 }
32 
33 }  // namespace
34 
35 class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
36  public:
37   HistogramFlattenerDeltaRecorder() = default;
38 
39   HistogramFlattenerDeltaRecorder(const HistogramFlattenerDeltaRecorder&) =
40       delete;
41   HistogramFlattenerDeltaRecorder& operator=(
42       const HistogramFlattenerDeltaRecorder&) = delete;
43 
RecordDelta(const HistogramBase & histogram,const HistogramSamples & snapshot)44   void RecordDelta(const HistogramBase& histogram,
45                    const HistogramSamples& snapshot) override {
46     recorded_delta_histograms_.push_back(&histogram);
47     // Use CHECK instead of ASSERT to get full stack-trace and thus origin.
48     CHECK(!Contains(recorded_delta_histogram_sum_, histogram.histogram_name()));
49     // Keep pointer to snapshot for testing. This really isn't ideal but the
50     // snapshot-manager keeps the snapshot alive until it's "forgotten".
51     recorded_delta_histogram_sum_[histogram.histogram_name()] = snapshot.sum();
52   }
53 
Reset()54   void Reset() {
55     recorded_delta_histograms_.clear();
56     recorded_delta_histogram_sum_.clear();
57   }
58 
59   std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
GetRecordedDeltaHistograms()60   GetRecordedDeltaHistograms() {
61     return recorded_delta_histograms_;
62   }
63 
GetRecordedDeltaHistogramSum(const std::string & name)64   int64_t GetRecordedDeltaHistogramSum(const std::string& name) {
65     EXPECT_TRUE(Contains(recorded_delta_histogram_sum_, name));
66     return recorded_delta_histogram_sum_[name];
67   }
68 
69  private:
70   std::vector<raw_ptr<const HistogramBase, VectorExperimental>>
71       recorded_delta_histograms_;
72   std::map<std::string, int64_t> recorded_delta_histogram_sum_;
73 };
74 
75 class HistogramSnapshotManagerTest : public testing::Test {
76  protected:
HistogramSnapshotManagerTest()77   HistogramSnapshotManagerTest()
78       : statistics_recorder_(StatisticsRecorder::CreateTemporaryForTesting()),
79         histogram_snapshot_manager_(&histogram_flattener_delta_recorder_) {}
80 
81   ~HistogramSnapshotManagerTest() override = default;
82 
GetRecordedDeltaHistogramSum(const std::string & name)83   int64_t GetRecordedDeltaHistogramSum(const std::string& name) {
84     return histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramSum(
85         name);
86   }
87 
88   std::unique_ptr<StatisticsRecorder> statistics_recorder_;
89   HistogramFlattenerDeltaRecorder histogram_flattener_delta_recorder_;
90   HistogramSnapshotManager histogram_snapshot_manager_;
91 };
92 
TEST_F(HistogramSnapshotManagerTest,PrepareDeltasNoFlagsFilter)93 TEST_F(HistogramSnapshotManagerTest, PrepareDeltasNoFlagsFilter) {
94   // kNoFlags filter should record all histograms.
95   base::UmaHistogramBoolean(kHistogramName, true);
96   UmaStabilityHistogramBoolean(kStabilityHistogramName, true);
97 
98   StatisticsRecorder::PrepareDeltas(
99       /*include_persistent=*/false, /*flags_to_set=*/HistogramBase::kNoFlags,
100       /*required_flags=*/HistogramBase::kNoFlags, &histogram_snapshot_manager_);
101 
102   // Verify that the snapshots were recorded.
103   const std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
104       histograms =
105           histogram_flattener_delta_recorder_.GetRecordedDeltaHistograms();
106   ASSERT_EQ(2U, histograms.size());
107   ASSERT_EQ(kHistogramName, histograms[0]->histogram_name());
108   EXPECT_EQ(GetRecordedDeltaHistogramSum(kHistogramName), 1);
109   ASSERT_EQ(kStabilityHistogramName, histograms[1]->histogram_name());
110   EXPECT_EQ(GetRecordedDeltaHistogramSum(kStabilityHistogramName), 1);
111 
112   // The samples should have been marked as logged.
113   EXPECT_EQ(histograms[0]->SnapshotUnloggedSamples()->TotalCount(), 0);
114   EXPECT_EQ(histograms[1]->SnapshotUnloggedSamples()->TotalCount(), 0);
115 }
116 
TEST_F(HistogramSnapshotManagerTest,PrepareDeltasUmaHistogramFlagFilter)117 TEST_F(HistogramSnapshotManagerTest, PrepareDeltasUmaHistogramFlagFilter) {
118   // Note that kUmaStabilityHistogramFlag includes kUmaTargetedHistogramFlag.
119   base::UmaHistogramBoolean(kHistogramName, true);
120   UmaStabilityHistogramBoolean(kStabilityHistogramName, true);
121 
122   StatisticsRecorder::PrepareDeltas(
123       /*include_persistent=*/false, /*flags_to_set=*/HistogramBase::kNoFlags,
124       /*required_flags=*/HistogramBase::kUmaTargetedHistogramFlag,
125       &histogram_snapshot_manager_);
126 
127   // Verify that the snapshots were recorded.
128   const std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
129       histograms =
130           histogram_flattener_delta_recorder_.GetRecordedDeltaHistograms();
131   ASSERT_EQ(2U, histograms.size());
132   ASSERT_EQ(kHistogramName, histograms[0]->histogram_name());
133   EXPECT_EQ(GetRecordedDeltaHistogramSum(kHistogramName), 1);
134   ASSERT_EQ(kStabilityHistogramName, histograms[1]->histogram_name());
135   EXPECT_EQ(GetRecordedDeltaHistogramSum(kStabilityHistogramName), 1);
136 
137   // The samples should have been marked as logged.
138   EXPECT_EQ(histograms[0]->SnapshotUnloggedSamples()->TotalCount(), 0);
139   EXPECT_EQ(histograms[1]->SnapshotUnloggedSamples()->TotalCount(), 0);
140 }
141 
TEST_F(HistogramSnapshotManagerTest,PrepareDeltasUmaStabilityHistogramFlagFilter)142 TEST_F(HistogramSnapshotManagerTest,
143        PrepareDeltasUmaStabilityHistogramFlagFilter) {
144   base::UmaHistogramBoolean(kHistogramName, true);
145   UmaStabilityHistogramBoolean(kStabilityHistogramName, true);
146 
147   StatisticsRecorder::PrepareDeltas(
148       /*include_persistent=*/false, /*flags_to_set=*/HistogramBase::kNoFlags,
149       /*required_flags=*/HistogramBase::kUmaStabilityHistogramFlag,
150       &histogram_snapshot_manager_);
151 
152   // Verify that only the stability histogram was snapshotted and recorded.
153   const std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
154       histograms =
155           histogram_flattener_delta_recorder_.GetRecordedDeltaHistograms();
156   ASSERT_EQ(1U, histograms.size());
157   ASSERT_EQ(kStabilityHistogramName, histograms[0]->histogram_name());
158   EXPECT_EQ(GetRecordedDeltaHistogramSum(kStabilityHistogramName), 1);
159 
160   // The samples should have been marked as logged.
161   EXPECT_EQ(histograms[0]->SnapshotUnloggedSamples()->TotalCount(), 0);
162 }
163 
TEST_F(HistogramSnapshotManagerTest,SnapshotUnloggedSamplesNoFlagsFilter)164 TEST_F(HistogramSnapshotManagerTest, SnapshotUnloggedSamplesNoFlagsFilter) {
165   // kNoFlags filter should record all histograms.
166   base::UmaHistogramBoolean(kHistogramName, true);
167   UmaStabilityHistogramBoolean(kStabilityHistogramName, true);
168 
169   StatisticsRecorder::SnapshotUnloggedSamples(
170       /*required_flags=*/HistogramBase::kNoFlags, &histogram_snapshot_manager_);
171 
172   // Verify that the snapshots were recorded.
173   const std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
174       histograms =
175           histogram_flattener_delta_recorder_.GetRecordedDeltaHistograms();
176   ASSERT_EQ(2U, histograms.size());
177   ASSERT_EQ(kHistogramName, histograms[0]->histogram_name());
178   EXPECT_EQ(GetRecordedDeltaHistogramSum(kHistogramName), 1);
179   ASSERT_EQ(kStabilityHistogramName, histograms[1]->histogram_name());
180   EXPECT_EQ(GetRecordedDeltaHistogramSum(kStabilityHistogramName), 1);
181 
182   // The samples should NOT have been marked as logged.
183   std::unique_ptr<HistogramSamples> samples =
184       histograms[0]->SnapshotUnloggedSamples();
185   EXPECT_EQ(samples->TotalCount(), 1);
186   EXPECT_EQ(samples->sum(), 1);
187   samples = histograms[1]->SnapshotUnloggedSamples();
188   EXPECT_EQ(samples->TotalCount(), 1);
189   EXPECT_EQ(samples->sum(), 1);
190 
191   // Mark the samples as logged and verify that they are correctly marked as so.
192   histogram_snapshot_manager_.MarkUnloggedSamplesAsLogged();
193   EXPECT_EQ(histograms[0]->SnapshotUnloggedSamples()->TotalCount(), 0);
194   EXPECT_EQ(histograms[1]->SnapshotUnloggedSamples()->TotalCount(), 0);
195 }
196 
TEST_F(HistogramSnapshotManagerTest,SnapshotUnloggedSamplesUmaHistogramFlagFilter)197 TEST_F(HistogramSnapshotManagerTest,
198        SnapshotUnloggedSamplesUmaHistogramFlagFilter) {
199   // Note that kUmaStabilityHistogramFlag includes kUmaTargetedHistogramFlag.
200   base::UmaHistogramBoolean(kHistogramName, true);
201   UmaStabilityHistogramBoolean(kStabilityHistogramName, true);
202 
203   StatisticsRecorder::SnapshotUnloggedSamples(
204       /*required_flags=*/HistogramBase::kUmaTargetedHistogramFlag,
205       &histogram_snapshot_manager_);
206 
207   // Verify that the snapshots were recorded.
208   const std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
209       histograms =
210           histogram_flattener_delta_recorder_.GetRecordedDeltaHistograms();
211   ASSERT_EQ(2U, histograms.size());
212   ASSERT_EQ(kHistogramName, histograms[0]->histogram_name());
213   EXPECT_EQ(GetRecordedDeltaHistogramSum(kHistogramName), 1);
214   ASSERT_EQ(kStabilityHistogramName, histograms[1]->histogram_name());
215   EXPECT_EQ(GetRecordedDeltaHistogramSum(kStabilityHistogramName), 1);
216 
217   // The samples should NOT have been marked as logged.
218   std::unique_ptr<HistogramSamples> samples =
219       histograms[0]->SnapshotUnloggedSamples();
220   EXPECT_EQ(samples->TotalCount(), 1);
221   EXPECT_EQ(samples->sum(), 1);
222   samples = histograms[1]->SnapshotUnloggedSamples();
223   EXPECT_EQ(samples->TotalCount(), 1);
224   EXPECT_EQ(samples->sum(), 1);
225 
226   // Mark the samples as logged and verify that they are correctly marked as so.
227   histogram_snapshot_manager_.MarkUnloggedSamplesAsLogged();
228   EXPECT_EQ(histograms[0]->SnapshotUnloggedSamples()->TotalCount(), 0);
229   EXPECT_EQ(histograms[1]->SnapshotUnloggedSamples()->TotalCount(), 0);
230 }
231 
TEST_F(HistogramSnapshotManagerTest,SnapshotUnloggedSamplesUmaStabilityHistogramFlagFilter)232 TEST_F(HistogramSnapshotManagerTest,
233        SnapshotUnloggedSamplesUmaStabilityHistogramFlagFilter) {
234   base::UmaHistogramBoolean(kHistogramName, true);
235   UmaStabilityHistogramBoolean(kStabilityHistogramName, true);
236 
237   StatisticsRecorder::SnapshotUnloggedSamples(
238       /*required_flags=*/HistogramBase::kUmaStabilityHistogramFlag,
239       &histogram_snapshot_manager_);
240 
241   // Verify that only the stability histogram was snapshotted and recorded.
242   const std::vector<raw_ptr<const HistogramBase, VectorExperimental>>&
243       histograms =
244           histogram_flattener_delta_recorder_.GetRecordedDeltaHistograms();
245   ASSERT_EQ(1U, histograms.size());
246   ASSERT_EQ(kStabilityHistogramName, histograms[0]->histogram_name());
247   EXPECT_EQ(GetRecordedDeltaHistogramSum(kStabilityHistogramName), 1);
248 
249   // The samples should NOT have been marked as logged.
250   std::unique_ptr<HistogramSamples> samples =
251       histograms[0]->SnapshotUnloggedSamples();
252   EXPECT_EQ(samples->TotalCount(), 1);
253   EXPECT_EQ(samples->sum(), 1);
254 
255   // Mark the samples as logged and verify that they are correctly marked as so.
256   histogram_snapshot_manager_.MarkUnloggedSamplesAsLogged();
257   EXPECT_EQ(histograms[0]->SnapshotUnloggedSamples()->TotalCount(), 0);
258 }
259 
260 }  // namespace base
261