xref: /aosp_15_r20/external/libchrome/base/test/metrics/histogram_tester.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_TEST_METRICS_HISTOGRAM_TESTER_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_TEST_METRICS_HISTOGRAM_TESTER_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <map>
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker #include <ostream>
11*635a8641SAndroid Build Coastguard Worker #include <string>
12*635a8641SAndroid Build Coastguard Worker #include <utility>
13*635a8641SAndroid Build Coastguard Worker #include <vector>
14*635a8641SAndroid Build Coastguard Worker 
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/metrics/histogram.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/metrics/histogram_base.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker namespace base {
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker struct Bucket;
23*635a8641SAndroid Build Coastguard Worker class HistogramSamples;
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker // HistogramTester provides a simple interface for examining histograms, UMA
26*635a8641SAndroid Build Coastguard Worker // or otherwise. Tests can use this interface to verify that histogram data is
27*635a8641SAndroid Build Coastguard Worker // getting logged as intended.
28*635a8641SAndroid Build Coastguard Worker //
29*635a8641SAndroid Build Coastguard Worker // Note: When using this class from a browser test, one might have to call
30*635a8641SAndroid Build Coastguard Worker // SubprocessMetricsProvider::MergeHistogramDeltasForTesting() to sync the
31*635a8641SAndroid Build Coastguard Worker // histogram data between the renderer and browser processes. If it is in a
32*635a8641SAndroid Build Coastguard Worker // content browser test, then content::FetchHistogramsFromChildProcesses()
33*635a8641SAndroid Build Coastguard Worker // should be used to achieve that.
34*635a8641SAndroid Build Coastguard Worker class HistogramTester {
35*635a8641SAndroid Build Coastguard Worker  public:
36*635a8641SAndroid Build Coastguard Worker   using CountsMap = std::map<std::string, HistogramBase::Count>;
37*635a8641SAndroid Build Coastguard Worker 
38*635a8641SAndroid Build Coastguard Worker   // Takes a snapshot of all current histograms counts.
39*635a8641SAndroid Build Coastguard Worker   HistogramTester();
40*635a8641SAndroid Build Coastguard Worker   ~HistogramTester();
41*635a8641SAndroid Build Coastguard Worker 
42*635a8641SAndroid Build Coastguard Worker   // We know the exact number of samples in a bucket, and that no other bucket
43*635a8641SAndroid Build Coastguard Worker   // should have samples. Measures the diff from the snapshot taken when this
44*635a8641SAndroid Build Coastguard Worker   // object was constructed.
45*635a8641SAndroid Build Coastguard Worker   void ExpectUniqueSample(const std::string& name,
46*635a8641SAndroid Build Coastguard Worker                           HistogramBase::Sample sample,
47*635a8641SAndroid Build Coastguard Worker                           HistogramBase::Count expected_count) const;
48*635a8641SAndroid Build Coastguard Worker   template <typename T>
ExpectUniqueSample(const std::string & name,T sample,HistogramBase::Count expected_count)49*635a8641SAndroid Build Coastguard Worker   void ExpectUniqueSample(const std::string& name,
50*635a8641SAndroid Build Coastguard Worker                           T sample,
51*635a8641SAndroid Build Coastguard Worker                           HistogramBase::Count expected_count) const {
52*635a8641SAndroid Build Coastguard Worker     ExpectUniqueSample(name, static_cast<HistogramBase::Sample>(sample),
53*635a8641SAndroid Build Coastguard Worker                        expected_count);
54*635a8641SAndroid Build Coastguard Worker   }
55*635a8641SAndroid Build Coastguard Worker 
56*635a8641SAndroid Build Coastguard Worker   // We know the exact number of samples in a bucket, but other buckets may
57*635a8641SAndroid Build Coastguard Worker   // have samples as well. Measures the diff from the snapshot taken when this
58*635a8641SAndroid Build Coastguard Worker   // object was constructed.
59*635a8641SAndroid Build Coastguard Worker   void ExpectBucketCount(const std::string& name,
60*635a8641SAndroid Build Coastguard Worker                          HistogramBase::Sample sample,
61*635a8641SAndroid Build Coastguard Worker                          HistogramBase::Count expected_count) const;
62*635a8641SAndroid Build Coastguard Worker   template <typename T>
ExpectBucketCount(const std::string & name,T sample,HistogramBase::Count expected_count)63*635a8641SAndroid Build Coastguard Worker   void ExpectBucketCount(const std::string& name,
64*635a8641SAndroid Build Coastguard Worker                          T sample,
65*635a8641SAndroid Build Coastguard Worker                          HistogramBase::Count expected_count) const {
66*635a8641SAndroid Build Coastguard Worker     ExpectBucketCount(name, static_cast<HistogramBase::Sample>(sample),
67*635a8641SAndroid Build Coastguard Worker                       expected_count);
68*635a8641SAndroid Build Coastguard Worker   }
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker   // We don't know the values of the samples, but we know how many there are.
71*635a8641SAndroid Build Coastguard Worker   // This measures the diff from the snapshot taken when this object was
72*635a8641SAndroid Build Coastguard Worker   // constructed.
73*635a8641SAndroid Build Coastguard Worker   void ExpectTotalCount(const std::string& name,
74*635a8641SAndroid Build Coastguard Worker                         HistogramBase::Count count) const;
75*635a8641SAndroid Build Coastguard Worker 
76*635a8641SAndroid Build Coastguard Worker   // We know exact number of samples for buckets corresponding to a time
77*635a8641SAndroid Build Coastguard Worker   // interval. Other intervals may have samples too.
78*635a8641SAndroid Build Coastguard Worker   void ExpectTimeBucketCount(const std::string& name,
79*635a8641SAndroid Build Coastguard Worker                              TimeDelta sample,
80*635a8641SAndroid Build Coastguard Worker                              HistogramBase::Count count) const;
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   // Returns a list of all of the buckets recorded since creation of this
83*635a8641SAndroid Build Coastguard Worker   // object, as vector<Bucket>, where the Bucket represents the min boundary of
84*635a8641SAndroid Build Coastguard Worker   // the bucket and the count of samples recorded to that bucket since creation.
85*635a8641SAndroid Build Coastguard Worker   //
86*635a8641SAndroid Build Coastguard Worker   // Example usage, using gMock:
87*635a8641SAndroid Build Coastguard Worker   //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"),
88*635a8641SAndroid Build Coastguard Worker   //               ElementsAre(Bucket(1, 5), Bucket(2, 10), Bucket(3, 5)));
89*635a8641SAndroid Build Coastguard Worker   //
90*635a8641SAndroid Build Coastguard Worker   // If you build the expected list programmatically, you can use ContainerEq:
91*635a8641SAndroid Build Coastguard Worker   //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"),
92*635a8641SAndroid Build Coastguard Worker   //               ContainerEq(expected_buckets));
93*635a8641SAndroid Build Coastguard Worker   //
94*635a8641SAndroid Build Coastguard Worker   // or EXPECT_EQ if you prefer not to depend on gMock, at the expense of a
95*635a8641SAndroid Build Coastguard Worker   // slightly less helpful failure message:
96*635a8641SAndroid Build Coastguard Worker   //   EXPECT_EQ(expected_buckets,
97*635a8641SAndroid Build Coastguard Worker   //             histogram_tester.GetAllSamples("HistogramName"));
98*635a8641SAndroid Build Coastguard Worker   std::vector<Bucket> GetAllSamples(const std::string& name) const;
99*635a8641SAndroid Build Coastguard Worker 
100*635a8641SAndroid Build Coastguard Worker   // Returns the value of the |sample| bucket for ths histogram |name|.
101*635a8641SAndroid Build Coastguard Worker   HistogramBase::Count GetBucketCount(const std::string& name,
102*635a8641SAndroid Build Coastguard Worker                                       HistogramBase::Sample sample) const;
103*635a8641SAndroid Build Coastguard Worker 
104*635a8641SAndroid Build Coastguard Worker   // Finds histograms whose names start with |prefix|, and returns them along
105*635a8641SAndroid Build Coastguard Worker   // with the counts of any samples added since the creation of this object.
106*635a8641SAndroid Build Coastguard Worker   // Histograms that are unchanged are omitted from the result. The return value
107*635a8641SAndroid Build Coastguard Worker   // is a map whose keys are the histogram name, and whose values are the sample
108*635a8641SAndroid Build Coastguard Worker   // count.
109*635a8641SAndroid Build Coastguard Worker   //
110*635a8641SAndroid Build Coastguard Worker   // This is useful for cases where the code under test is choosing among a
111*635a8641SAndroid Build Coastguard Worker   // family of related histograms and incrementing one of them. Typically you
112*635a8641SAndroid Build Coastguard Worker   // should pass the result of this function directly to EXPECT_THAT.
113*635a8641SAndroid Build Coastguard Worker   //
114*635a8641SAndroid Build Coastguard Worker   // Example usage, using gmock (which produces better failure messages):
115*635a8641SAndroid Build Coastguard Worker   //   #include "testing/gmock/include/gmock/gmock.h"
116*635a8641SAndroid Build Coastguard Worker   // ...
117*635a8641SAndroid Build Coastguard Worker   //   base::HistogramTester::CountsMap expected_counts;
118*635a8641SAndroid Build Coastguard Worker   //   expected_counts["MyMetric.A"] = 1;
119*635a8641SAndroid Build Coastguard Worker   //   expected_counts["MyMetric.B"] = 1;
120*635a8641SAndroid Build Coastguard Worker   //   EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("MyMetric."),
121*635a8641SAndroid Build Coastguard Worker   //               testing::ContainerEq(expected_counts));
122*635a8641SAndroid Build Coastguard Worker   CountsMap GetTotalCountsForPrefix(const std::string& prefix) const;
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker   // Access a modified HistogramSamples containing only what has been logged
125*635a8641SAndroid Build Coastguard Worker   // to the histogram since the creation of this object.
126*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<HistogramSamples> GetHistogramSamplesSinceCreation(
127*635a8641SAndroid Build Coastguard Worker       const std::string& histogram_name) const;
128*635a8641SAndroid Build Coastguard Worker 
129*635a8641SAndroid Build Coastguard Worker   // Dumps all histograms that have had new samples added to them into a string,
130*635a8641SAndroid Build Coastguard Worker   // for debugging purposes. Note: this will dump the entire contents of any
131*635a8641SAndroid Build Coastguard Worker   // modified histograms and not just the modified buckets.
132*635a8641SAndroid Build Coastguard Worker   std::string GetAllHistogramsRecorded() const;
133*635a8641SAndroid Build Coastguard Worker 
134*635a8641SAndroid Build Coastguard Worker  private:
135*635a8641SAndroid Build Coastguard Worker   // Verifies and asserts that value in the |sample| bucket matches the
136*635a8641SAndroid Build Coastguard Worker   // |expected_count|. The bucket's current value is determined from |samples|
137*635a8641SAndroid Build Coastguard Worker   // and is modified based on the snapshot stored for histogram |name|.
138*635a8641SAndroid Build Coastguard Worker   void CheckBucketCount(const std::string& name,
139*635a8641SAndroid Build Coastguard Worker                         HistogramBase::Sample sample,
140*635a8641SAndroid Build Coastguard Worker                         Histogram::Count expected_count,
141*635a8641SAndroid Build Coastguard Worker                         const HistogramSamples& samples) const;
142*635a8641SAndroid Build Coastguard Worker 
143*635a8641SAndroid Build Coastguard Worker   // Verifies that the total number of values recorded for the histogram |name|
144*635a8641SAndroid Build Coastguard Worker   // is |expected_count|. This is checked against |samples| minus the snapshot
145*635a8641SAndroid Build Coastguard Worker   // that was taken for |name|.
146*635a8641SAndroid Build Coastguard Worker   void CheckTotalCount(const std::string& name,
147*635a8641SAndroid Build Coastguard Worker                        Histogram::Count expected_count,
148*635a8641SAndroid Build Coastguard Worker                        const HistogramSamples& samples) const;
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker   // Sets the value for |count| to be the value in the |sample| bucket. The
151*635a8641SAndroid Build Coastguard Worker   // bucket's current value is determined from |samples| and is modified based
152*635a8641SAndroid Build Coastguard Worker   // on the snapshot stored for histogram |name|.
153*635a8641SAndroid Build Coastguard Worker   void GetBucketCountForSamples(const std::string& name,
154*635a8641SAndroid Build Coastguard Worker                                 HistogramBase::Sample sample,
155*635a8641SAndroid Build Coastguard Worker                                 const HistogramSamples& samples,
156*635a8641SAndroid Build Coastguard Worker                                 HistogramBase::Count* count) const;
157*635a8641SAndroid Build Coastguard Worker 
158*635a8641SAndroid Build Coastguard Worker   // Used to determine the histogram changes made during this instance's
159*635a8641SAndroid Build Coastguard Worker   // lifecycle.
160*635a8641SAndroid Build Coastguard Worker   std::map<std::string, std::unique_ptr<HistogramSamples>> histograms_snapshot_;
161*635a8641SAndroid Build Coastguard Worker 
162*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(HistogramTester);
163*635a8641SAndroid Build Coastguard Worker };
164*635a8641SAndroid Build Coastguard Worker 
165*635a8641SAndroid Build Coastguard Worker struct Bucket {
BucketBucket166*635a8641SAndroid Build Coastguard Worker   Bucket(HistogramBase::Sample min, HistogramBase::Count count)
167*635a8641SAndroid Build Coastguard Worker       : min(min), count(count) {}
168*635a8641SAndroid Build Coastguard Worker 
169*635a8641SAndroid Build Coastguard Worker   bool operator==(const Bucket& other) const;
170*635a8641SAndroid Build Coastguard Worker 
171*635a8641SAndroid Build Coastguard Worker   HistogramBase::Sample min;
172*635a8641SAndroid Build Coastguard Worker   HistogramBase::Count count;
173*635a8641SAndroid Build Coastguard Worker };
174*635a8641SAndroid Build Coastguard Worker 
175*635a8641SAndroid Build Coastguard Worker void PrintTo(const Bucket& value, std::ostream* os);
176*635a8641SAndroid Build Coastguard Worker 
177*635a8641SAndroid Build Coastguard Worker }  // namespace base
178*635a8641SAndroid Build Coastguard Worker 
179*635a8641SAndroid Build Coastguard Worker #endif  // BASE_TEST_METRICS_HISTOGRAM_TESTER_H_
180