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