blob: 5ca3c2fe9e8dd6145f05741fdf6022be49e877e0 [file] [log] [blame]
mlerman@chromium.orga7980682014-08-22 07:00:38 +09001// 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/test/histogram_tester.h"
6
avif09d5392015-12-24 12:28:02 +09007#include <stddef.h>
8
mlerman@chromium.orga7980682014-08-22 07:00:38 +09009#include "base/metrics/histogram.h"
10#include "base/metrics/histogram_samples.h"
bcwhiteca01de92015-12-11 03:36:34 +090011#include "base/metrics/metrics_hashes.h"
vabr4df640b2015-08-03 17:12:54 +090012#include "base/metrics/sample_map.h"
mlerman@chromium.orga7980682014-08-22 07:00:38 +090013#include "base/metrics/statistics_recorder.h"
pkalinnikov5b63bda2017-01-14 03:30:38 +090014#include "base/strings/string_util.h"
mlerman@chromium.orga7980682014-08-22 07:00:38 +090015#include "testing/gtest/include/gtest/gtest.h"
16
17namespace base {
18
19HistogramTester::HistogramTester() {
20 StatisticsRecorder::Initialize(); // Safe to call multiple times.
21
22 // Record any histogram data that exists when the object is created so it can
23 // be subtracted later.
24 StatisticsRecorder::Histograms histograms;
25 StatisticsRecorder::GetSnapshot(std::string(), &histograms);
vmpstr6cd44722017-02-14 06:11:41 +090026 for (const auto* histogram : histograms) {
aviace57a82016-10-27 13:10:51 +090027 histograms_snapshot_[histogram->histogram_name()] =
28 histogram->SnapshotSamples();
mlerman@chromium.orga7980682014-08-22 07:00:38 +090029 }
30}
31
32HistogramTester::~HistogramTester() {
mlerman@chromium.orga7980682014-08-22 07:00:38 +090033}
34
35void HistogramTester::ExpectUniqueSample(
36 const std::string& name,
pkalinnikov5b63bda2017-01-14 03:30:38 +090037 HistogramBase::Sample sample,
38 HistogramBase::Count expected_count) const {
39 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
aviace57a82016-10-27 13:10:51 +090040 EXPECT_NE(nullptr, histogram) << "Histogram \"" << name
41 << "\" does not exist.";
mlerman@chromium.orga7980682014-08-22 07:00:38 +090042
43 if (histogram) {
pkalinnikov5b63bda2017-01-14 03:30:38 +090044 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
mlerman@chromium.orga7980682014-08-22 07:00:38 +090045 CheckBucketCount(name, sample, expected_count, *samples);
46 CheckTotalCount(name, expected_count, *samples);
47 }
48}
49
50void HistogramTester::ExpectBucketCount(
51 const std::string& name,
pkalinnikov5b63bda2017-01-14 03:30:38 +090052 HistogramBase::Sample sample,
53 HistogramBase::Count expected_count) const {
54 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
aviace57a82016-10-27 13:10:51 +090055 EXPECT_NE(nullptr, histogram) << "Histogram \"" << name
56 << "\" does not exist.";
mlerman@chromium.orga7980682014-08-22 07:00:38 +090057
58 if (histogram) {
pkalinnikov5b63bda2017-01-14 03:30:38 +090059 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
mlerman@chromium.orga7980682014-08-22 07:00:38 +090060 CheckBucketCount(name, sample, expected_count, *samples);
61 }
62}
63
64void HistogramTester::ExpectTotalCount(const std::string& name,
pkalinnikov5b63bda2017-01-14 03:30:38 +090065 HistogramBase::Count count) const {
66 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
mlerman@chromium.orga7980682014-08-22 07:00:38 +090067 if (histogram) {
pkalinnikov5b63bda2017-01-14 03:30:38 +090068 std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
mlerman@chromium.orga7980682014-08-22 07:00:38 +090069 CheckTotalCount(name, count, *samples);
70 } else {
71 // No histogram means there were zero samples.
72 EXPECT_EQ(count, 0) << "Histogram \"" << name << "\" does not exist.";
73 }
74}
75
pkalinnikov5b63bda2017-01-14 03:30:38 +090076void HistogramTester::ExpectTimeBucketCount(const std::string& name,
77 TimeDelta sample,
78 HistogramBase::Count count) const {
nikunjb7961de92016-11-15 07:06:25 +090079 ExpectBucketCount(name, sample.InMilliseconds(), count);
80}
81
nickb1c693a2015-07-28 03:29:59 +090082std::vector<Bucket> HistogramTester::GetAllSamples(
83 const std::string& name) const {
twifkak120eb322015-07-01 04:13:21 +090084 std::vector<Bucket> samples;
dchengcc8e4d82016-04-05 06:25:51 +090085 std::unique_ptr<HistogramSamples> snapshot =
twifkak120eb322015-07-01 04:13:21 +090086 GetHistogramSamplesSinceCreation(name);
twifkak0d2133a2015-08-11 01:39:33 +090087 if (snapshot) {
88 for (auto it = snapshot->Iterator(); !it->Done(); it->Next()) {
89 HistogramBase::Sample sample;
90 HistogramBase::Count count;
91 it->Get(&sample, nullptr, &count);
92 samples.push_back(Bucket(sample, count));
93 }
twifkak120eb322015-07-01 04:13:21 +090094 }
95 return samples;
96}
97
nickb1c693a2015-07-28 03:29:59 +090098HistogramTester::CountsMap HistogramTester::GetTotalCountsForPrefix(
pkalinnikov5b63bda2017-01-14 03:30:38 +090099 const std::string& prefix) const {
100 EXPECT_TRUE(prefix.find('.') != std::string::npos)
101 << "|prefix| ought to contain at least one period, to avoid matching too"
nickb1c693a2015-07-28 03:29:59 +0900102 << " many histograms.";
103
pkalinnikov5b63bda2017-01-14 03:30:38 +0900104 // Find candidate matches by using the logic built into GetSnapshot().
105 StatisticsRecorder::Histograms candidate_matches;
106 StatisticsRecorder::GetSnapshot(prefix, &candidate_matches);
nickb1c693a2015-07-28 03:29:59 +0900107
108 CountsMap result;
pkalinnikov5b63bda2017-01-14 03:30:38 +0900109 for (HistogramBase* histogram : candidate_matches) {
110 if (!StartsWith(histogram->histogram_name(), prefix,
111 CompareCase::SENSITIVE)) {
112 continue;
113 }
dchengcc8e4d82016-04-05 06:25:51 +0900114 std::unique_ptr<HistogramSamples> new_samples =
nickb1c693a2015-07-28 03:29:59 +0900115 GetHistogramSamplesSinceCreation(histogram->histogram_name());
116 // Omit unchanged histograms from the result.
117 if (new_samples->TotalCount()) {
118 result[histogram->histogram_name()] = new_samples->TotalCount();
119 }
120 }
121 return result;
122}
123
dchengcc8e4d82016-04-05 06:25:51 +0900124std::unique_ptr<HistogramSamples>
125HistogramTester::GetHistogramSamplesSinceCreation(
nickb1c693a2015-07-28 03:29:59 +0900126 const std::string& histogram_name) const {
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900127 HistogramBase* histogram = StatisticsRecorder::FindHistogram(histogram_name);
vabr4df640b2015-08-03 17:12:54 +0900128 // Whether the histogram exists or not may not depend on the current test
129 // calling this method, but rather on which tests ran before and possibly
130 // generated a histogram or not (see http://crbug.com/473689). To provide a
131 // response which is independent of the previously run tests, this method
132 // creates empty samples in the absence of the histogram, rather than
133 // returning null.
bcwhiteca01de92015-12-11 03:36:34 +0900134 if (!histogram) {
dchengcc8e4d82016-04-05 06:25:51 +0900135 return std::unique_ptr<HistogramSamples>(
bcwhiteca01de92015-12-11 03:36:34 +0900136 new SampleMap(HashMetricName(histogram_name)));
137 }
aviace57a82016-10-27 13:10:51 +0900138 std::unique_ptr<HistogramSamples> named_samples =
139 histogram->SnapshotSamples();
nickb1c693a2015-07-28 03:29:59 +0900140 auto original_samples_it = histograms_snapshot_.find(histogram_name);
141 if (original_samples_it != histograms_snapshot_.end())
aviace57a82016-10-27 13:10:51 +0900142 named_samples->Subtract(*original_samples_it->second.get());
danakj800d2ea2015-11-25 14:29:58 +0900143 return named_samples;
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900144}
145
pkalinnikov5b63bda2017-01-14 03:30:38 +0900146void HistogramTester::CheckBucketCount(const std::string& name,
147 HistogramBase::Sample sample,
148 HistogramBase::Count expected_count,
149 const HistogramSamples& samples) const {
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900150 int actual_count = samples.GetCount(sample);
aviace57a82016-10-27 13:10:51 +0900151 auto histogram_data = histograms_snapshot_.find(name);
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900152 if (histogram_data != histograms_snapshot_.end())
153 actual_count -= histogram_data->second->GetCount(sample);
154
155 EXPECT_EQ(expected_count, actual_count)
156 << "Histogram \"" << name
157 << "\" does not have the right number of samples (" << expected_count
158 << ") in the expected bucket (" << sample << "). It has (" << actual_count
159 << ").";
160}
161
pkalinnikov5b63bda2017-01-14 03:30:38 +0900162void HistogramTester::CheckTotalCount(const std::string& name,
163 HistogramBase::Count expected_count,
164 const HistogramSamples& samples) const {
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900165 int actual_count = samples.TotalCount();
aviace57a82016-10-27 13:10:51 +0900166 auto histogram_data = histograms_snapshot_.find(name);
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900167 if (histogram_data != histograms_snapshot_.end())
168 actual_count -= histogram_data->second->TotalCount();
169
170 EXPECT_EQ(expected_count, actual_count)
171 << "Histogram \"" << name
172 << "\" does not have the right total number of samples ("
173 << expected_count << "). It has (" << actual_count << ").";
174}
175
twifkak120eb322015-07-01 04:13:21 +0900176bool Bucket::operator==(const Bucket& other) const {
177 return min == other.min && count == other.count;
178}
179
180void PrintTo(const Bucket& bucket, std::ostream* os) {
181 *os << "Bucket " << bucket.min << ": " << bucket.count;
182}
183
mlerman@chromium.orga7980682014-08-22 07:00:38 +0900184} // namespace base