| // Copyright 2014 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_TEST_HISTOGRAM_TESTER_H_ | 
 | #define BASE_TEST_HISTOGRAM_TESTER_H_ | 
 |  | 
 | #include <map> | 
 | #include <memory> | 
 | #include <ostream> | 
 | #include <string> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #include "base/macros.h" | 
 | #include "base/metrics/histogram.h" | 
 | #include "base/metrics/histogram_base.h" | 
 | #include "base/time/time.h" | 
 |  | 
 | namespace base { | 
 |  | 
 | struct Bucket; | 
 | class HistogramSamples; | 
 |  | 
 | // HistogramTester provides a simple interface for examining histograms, UMA | 
 | // or otherwise. Tests can use this interface to verify that histogram data is | 
 | // getting logged as intended. | 
 | // | 
 | // Note: When using this class from a browser test, one might have to call | 
 | // SubprocessMetricsProvider::MergeHistogramDeltasForTesting() to sync the | 
 | // histogram data between the renderer and browser processes. If it is in a | 
 | // content browser test, then content::FetchHistogramsFromChildProcesses() | 
 | // should be used to achieve that. | 
 | class HistogramTester { | 
 |  public: | 
 |   using CountsMap = std::map<std::string, HistogramBase::Count>; | 
 |  | 
 |   // Takes a snapshot of all current histograms counts. | 
 |   HistogramTester(); | 
 |   ~HistogramTester(); | 
 |  | 
 |   // We know the exact number of samples in a bucket, and that no other bucket | 
 |   // should have samples. Measures the diff from the snapshot taken when this | 
 |   // object was constructed. | 
 |   void ExpectUniqueSample(const std::string& name, | 
 |                           HistogramBase::Sample sample, | 
 |                           HistogramBase::Count expected_count) const; | 
 |   template <typename T> | 
 |   void ExpectUniqueSample(const std::string& name, | 
 |                           T sample, | 
 |                           HistogramBase::Count expected_count) const { | 
 |     ExpectUniqueSample(name, static_cast<HistogramBase::Sample>(sample), | 
 |                        expected_count); | 
 |   } | 
 |  | 
 |   // We know the exact number of samples in a bucket, but other buckets may | 
 |   // have samples as well. Measures the diff from the snapshot taken when this | 
 |   // object was constructed. | 
 |   void ExpectBucketCount(const std::string& name, | 
 |                          HistogramBase::Sample sample, | 
 |                          HistogramBase::Count expected_count) const; | 
 |   template <typename T> | 
 |   void ExpectBucketCount(const std::string& name, | 
 |                          T sample, | 
 |                          HistogramBase::Count expected_count) const { | 
 |     ExpectBucketCount(name, static_cast<HistogramBase::Sample>(sample), | 
 |                       expected_count); | 
 |   } | 
 |  | 
 |   // We don't know the values of the samples, but we know how many there are. | 
 |   // This measures the diff from the snapshot taken when this object was | 
 |   // constructed. | 
 |   void ExpectTotalCount(const std::string& name, | 
 |                         HistogramBase::Count count) const; | 
 |  | 
 |   // We know exact number of samples for buckets corresponding to a time | 
 |   // interval. Other intervals may have samples too. | 
 |   void ExpectTimeBucketCount(const std::string& name, | 
 |                              TimeDelta sample, | 
 |                              HistogramBase::Count count) const; | 
 |  | 
 |   // Returns a list of all of the buckets recorded since creation of this | 
 |   // object, as vector<Bucket>, where the Bucket represents the min boundary of | 
 |   // the bucket and the count of samples recorded to that bucket since creation. | 
 |   // | 
 |   // Example usage, using gMock: | 
 |   //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"), | 
 |   //               ElementsAre(Bucket(1, 5), Bucket(2, 10), Bucket(3, 5))); | 
 |   // | 
 |   // If you build the expected list programmatically, you can use ContainerEq: | 
 |   //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"), | 
 |   //               ContainerEq(expected_buckets)); | 
 |   // | 
 |   // or EXPECT_EQ if you prefer not to depend on gMock, at the expense of a | 
 |   // slightly less helpful failure message: | 
 |   //   EXPECT_EQ(expected_buckets, | 
 |   //             histogram_tester.GetAllSamples("HistogramName")); | 
 |   std::vector<Bucket> GetAllSamples(const std::string& name) const; | 
 |  | 
 |   // Returns the value of the |sample| bucket for ths histogram |name|. | 
 |   HistogramBase::Count GetBucketCount(const std::string& name, | 
 |                                       HistogramBase::Sample sample) const; | 
 |  | 
 |   // Finds histograms whose names start with |prefix|, and returns them along | 
 |   // with the counts of any samples added since the creation of this object. | 
 |   // Histograms that are unchanged are omitted from the result. The return value | 
 |   // is a map whose keys are the histogram name, and whose values are the sample | 
 |   // count. | 
 |   // | 
 |   // This is useful for cases where the code under test is choosing among a | 
 |   // family of related histograms and incrementing one of them. Typically you | 
 |   // should pass the result of this function directly to EXPECT_THAT. | 
 |   // | 
 |   // Example usage, using gmock (which produces better failure messages): | 
 |   //   #include "testing/gmock/include/gmock/gmock.h" | 
 |   // ... | 
 |   //   base::HistogramTester::CountsMap expected_counts; | 
 |   //   expected_counts["MyMetric.A"] = 1; | 
 |   //   expected_counts["MyMetric.B"] = 1; | 
 |   //   EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("MyMetric."), | 
 |   //               testing::ContainerEq(expected_counts)); | 
 |   CountsMap GetTotalCountsForPrefix(const std::string& prefix) const; | 
 |  | 
 |   // Access a modified HistogramSamples containing only what has been logged | 
 |   // to the histogram since the creation of this object. | 
 |   std::unique_ptr<HistogramSamples> GetHistogramSamplesSinceCreation( | 
 |       const std::string& histogram_name) const; | 
 |  | 
 |  private: | 
 |   // Verifies and asserts that value in the |sample| bucket matches the | 
 |   // |expected_count|. The bucket's current value is determined from |samples| | 
 |   // and is modified based on the snapshot stored for histogram |name|. | 
 |   void CheckBucketCount(const std::string& name, | 
 |                         HistogramBase::Sample sample, | 
 |                         Histogram::Count expected_count, | 
 |                         const HistogramSamples& samples) const; | 
 |  | 
 |   // Verifies that the total number of values recorded for the histogram |name| | 
 |   // is |expected_count|. This is checked against |samples| minus the snapshot | 
 |   // that was taken for |name|. | 
 |   void CheckTotalCount(const std::string& name, | 
 |                        Histogram::Count expected_count, | 
 |                        const HistogramSamples& samples) const; | 
 |  | 
 |   // Sets the value for |count| to be the value in the |sample| bucket. The | 
 |   // bucket's current value is determined from |samples| and is modified based | 
 |   // on the snapshot stored for histogram |name|. | 
 |   void GetBucketCountForSamples(const std::string& name, | 
 |                                 HistogramBase::Sample sample, | 
 |                                 const HistogramSamples& samples, | 
 |                                 HistogramBase::Count* count) const; | 
 |  | 
 |   // Used to determine the histogram changes made during this instance's | 
 |   // lifecycle. | 
 |   std::map<std::string, std::unique_ptr<HistogramSamples>> histograms_snapshot_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(HistogramTester); | 
 | }; | 
 |  | 
 | struct Bucket { | 
 |   Bucket(HistogramBase::Sample min, HistogramBase::Count count) | 
 |       : min(min), count(count) {} | 
 |  | 
 |   bool operator==(const Bucket& other) const; | 
 |  | 
 |   HistogramBase::Sample min; | 
 |   HistogramBase::Count count; | 
 | }; | 
 |  | 
 | void PrintTo(const Bucket& value, std::ostream* os); | 
 |  | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_TEST_HISTOGRAM_TESTER_H_ |