• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test/metrics/histogram_tester.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "base/metrics/histogram_macros.h"
11 #include "base/metrics/histogram_samples.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest-spi.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 using ::testing::ElementsAre;
17 using ::testing::IsEmpty;
18 
19 namespace {
20 
21 const char kHistogram1[] = "Test1";
22 const char kHistogram2[] = "Test2";
23 const char kHistogram3[] = "Test3";
24 const char kHistogram4[] = "Test4";
25 const char kHistogram5[] = "Test5";
26 const char kHistogram6[] = "Test6";
27 
28 }  // namespace
29 
30 namespace base {
31 
32 typedef testing::Test HistogramTesterTest;
33 
TEST_F(HistogramTesterTest,Scope)34 TEST_F(HistogramTesterTest, Scope) {
35   // Record a histogram before the creation of the recorder.
36   UMA_HISTOGRAM_BOOLEAN(kHistogram1, true);
37 
38   HistogramTester tester;
39 
40   // Verify that no histogram is recorded.
41   tester.ExpectTotalCount(kHistogram1, 0);
42 
43   // Record a histogram after the creation of the recorder.
44   UMA_HISTOGRAM_BOOLEAN(kHistogram1, true);
45 
46   // Verify that one histogram is recorded.
47   std::unique_ptr<HistogramSamples> samples(
48       tester.GetHistogramSamplesSinceCreation(kHistogram1));
49   EXPECT_TRUE(samples);
50   EXPECT_EQ(1, samples->TotalCount());
51 }
52 
TEST_F(HistogramTesterTest,GetHistogramSamplesSinceCreationNotNull)53 TEST_F(HistogramTesterTest, GetHistogramSamplesSinceCreationNotNull) {
54   // Chose the histogram name uniquely, to ensure nothing was recorded for it so
55   // far.
56   static const char kHistogram[] =
57       "GetHistogramSamplesSinceCreationNotNullHistogram";
58   HistogramTester tester;
59 
60   // Verify that the returned samples are empty but not null.
61   std::unique_ptr<HistogramSamples> samples(
62       tester.GetHistogramSamplesSinceCreation(kHistogram1));
63   EXPECT_TRUE(samples);
64   tester.ExpectTotalCount(kHistogram, 0);
65 }
66 
TEST_F(HistogramTesterTest,TestUniqueSample)67 TEST_F(HistogramTesterTest, TestUniqueSample) {
68   HistogramTester tester;
69 
70   // Emit '2' three times.
71   UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
72   UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
73   UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
74 
75   tester.ExpectUniqueSample(kHistogram2, 2, 3);
76   tester.ExpectUniqueTimeSample(kHistogram2, base::Milliseconds(2), 3);
77 }
78 
79 // Verify that the expectation is violated if the bucket contains an incorrect
80 // number of samples.
TEST_F(HistogramTesterTest,TestUniqueSample_TooManySamplesInActualBucket)81 TEST_F(HistogramTesterTest, TestUniqueSample_TooManySamplesInActualBucket) {
82   auto failing_code = [] {
83     HistogramTester tester;
84 
85     // Emit '2' four times.
86     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
87     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
88     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
89     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
90 
91     // Expect exactly three samples in bucket 2. This is supposed to fail.
92     tester.ExpectUniqueSample(kHistogram2, 2, 3);
93   };
94   EXPECT_NONFATAL_FAILURE(failing_code(),
95                           "Histogram \"Test2\" did not meet its expectations.");
96 }
97 
98 // Verify that the expectation is violated if the bucket contains the correct
99 // number of samples but another bucket contains extra samples.
TEST_F(HistogramTesterTest,TestUniqueSample_OneExtraSampleInWrongBucket)100 TEST_F(HistogramTesterTest, TestUniqueSample_OneExtraSampleInWrongBucket) {
101   auto failing_code = [] {
102     HistogramTester tester;
103 
104     // Emit '2' three times.
105     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
106     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
107     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 2);
108     // Emit one unexpected '3'.
109     UMA_HISTOGRAM_COUNTS_100(kHistogram2, 3);
110 
111     // Expect exactly three samples in bucket 2. This is supposed to fail.
112     tester.ExpectUniqueSample(kHistogram2, 2, 3);
113   };
114   EXPECT_NONFATAL_FAILURE(failing_code(),
115                           "Histogram \"Test2\" did not meet its expectations.");
116 }
117 
TEST_F(HistogramTesterTest,TestBucketsSample)118 TEST_F(HistogramTesterTest, TestBucketsSample) {
119   HistogramTester tester;
120 
121   UMA_HISTOGRAM_COUNTS_100(kHistogram3, 2);
122   UMA_HISTOGRAM_COUNTS_100(kHistogram3, 2);
123   UMA_HISTOGRAM_COUNTS_100(kHistogram3, 2);
124   UMA_HISTOGRAM_COUNTS_100(kHistogram3, 2);
125   UMA_HISTOGRAM_COUNTS_100(kHistogram3, 3);
126 
127   tester.ExpectBucketCount(kHistogram3, 2, 4);
128   tester.ExpectBucketCount(kHistogram3, 3, 1);
129 
130   tester.ExpectTotalCount(kHistogram3, 5);
131 }
132 
TEST_F(HistogramTesterTest,TestBucketsSampleWithScope)133 TEST_F(HistogramTesterTest, TestBucketsSampleWithScope) {
134   // Emit values twice, once before the tester creation and once after.
135   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 2);
136 
137   HistogramTester tester;
138   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 3);
139 
140   tester.ExpectBucketCount(kHistogram4, 2, 0);
141   tester.ExpectBucketCount(kHistogram4, 3, 1);
142 
143   tester.ExpectTotalCount(kHistogram4, 1);
144 }
145 
TEST_F(HistogramTesterTest,TestGetAllSamples)146 TEST_F(HistogramTesterTest, TestGetAllSamples) {
147   HistogramTester tester;
148   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 2, 5);
149   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 3, 5);
150   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 3, 5);
151   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 5, 5);
152 
153   EXPECT_THAT(tester.GetAllSamples(kHistogram5),
154               ElementsAre(Bucket(2, 1), Bucket(3, 2), Bucket(5, 1)));
155 }
156 
TEST_F(HistogramTesterTest,TestGetAllSamples_NoSamples)157 TEST_F(HistogramTesterTest, TestGetAllSamples_NoSamples) {
158   HistogramTester tester;
159   EXPECT_THAT(tester.GetAllSamples(kHistogram5), IsEmpty());
160 }
161 
TEST_F(HistogramTesterTest,TestGetTotalSum)162 TEST_F(HistogramTesterTest, TestGetTotalSum) {
163   // Emit values twice, once before the tester creation and once after.
164   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 2);
165 
166   HistogramTester tester;
167   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 3);
168   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 4);
169 
170   EXPECT_EQ(7, tester.GetTotalSum(kHistogram4));
171 }
172 
TEST_F(HistogramTesterTest,TestGetTotalCountsForPrefix)173 TEST_F(HistogramTesterTest, TestGetTotalCountsForPrefix) {
174   HistogramTester tester;
175   UMA_HISTOGRAM_ENUMERATION("Test1.Test2.Test3", 2, 5);
176 
177   // Regression check for bug https://crbug.com/659977.
178   EXPECT_TRUE(tester.GetTotalCountsForPrefix("Test2.").empty());
179 
180   EXPECT_EQ(1u, tester.GetTotalCountsForPrefix("Test1.").size());
181 }
182 
TEST_F(HistogramTesterTest,TestGetAllChangedHistograms)183 TEST_F(HistogramTesterTest, TestGetAllChangedHistograms) {
184   // Emit multiple values, some before tester creation.
185   UMA_HISTOGRAM_COUNTS_100(kHistogram6, true);
186   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 4);
187 
188   HistogramTester tester;
189   UMA_HISTOGRAM_COUNTS_100(kHistogram4, 3);
190 
191   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 2, 5);
192   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 3, 5);
193   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 4, 5);
194   UMA_HISTOGRAM_ENUMERATION(kHistogram5, 5, 5);
195 
196   UMA_HISTOGRAM_ENUMERATION("Test1.Test2.Test3", 2, 5);
197   std::string results = tester.GetAllHistogramsRecorded();
198 
199   EXPECT_EQ(std::string::npos, results.find("Histogram: Test1 recorded"));
200   EXPECT_NE(std::string::npos,
201             results.find("Histogram: Test4 recorded 1 new samples"));
202   EXPECT_NE(std::string::npos,
203             results.find("Histogram: Test5 recorded 4 new samples"));
204   EXPECT_NE(
205       std::string::npos,
206       results.find("Histogram: Test1.Test2.Test3 recorded 1 new samples"));
207 }
208 
TEST_F(HistogramTesterTest,MissingHistogramMeansEmptyBuckets)209 TEST_F(HistogramTesterTest, MissingHistogramMeansEmptyBuckets) {
210   // When a histogram hasn't been instantiated, expecting counts of zero should
211   // still succeed.
212   static const char kHistogram[] = "MissingHistogramMeansEmptyBucketsHistogram";
213   HistogramTester tester;
214 
215   tester.ExpectBucketCount(kHistogram, 42, 0);
216   tester.ExpectTotalCount(kHistogram, 0);
217   EXPECT_TRUE(tester.GetAllSamples(kHistogram).empty());
218   EXPECT_EQ(0, tester.GetTotalSum(kHistogram));
219   EXPECT_EQ(0, tester.GetBucketCount(kHistogram, 42));
220   EXPECT_EQ(0,
221             tester.GetHistogramSamplesSinceCreation(kHistogram)->TotalCount());
222 }
223 
TEST_F(HistogramTesterTest,BucketsAre)224 TEST_F(HistogramTesterTest, BucketsAre) {
225   // Auxiliary functions for keeping the lines short.
226   auto a = [](std::vector<Bucket> b) { return b; };
227   auto b = [](base::Histogram::Sample min, base::Histogram::Count count) {
228     return Bucket(min, count);
229   };
230   using ::testing::Not;
231 
232   EXPECT_THAT(a({}), BucketsAre());
233   EXPECT_THAT(a({}), BucketsAre(b(0, 0)));
234   EXPECT_THAT(a({}), BucketsAre(b(1, 0)));
235   EXPECT_THAT(a({}), BucketsAre(b(0, 0), b(1, 0)));
236   EXPECT_THAT(a({}), Not(BucketsAre(b(1, 1))));
237 
238   EXPECT_THAT(a({b(1, 1)}), BucketsAre(b(1, 1)));
239   EXPECT_THAT(a({b(1, 1)}), BucketsAre(b(0, 0), b(1, 1)));
240   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre()));
241   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(0, 0))));
242   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(1, 0))));
243   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(2, 1))));
244   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(2, 2))));
245   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(0, 0), b(1, 0))));
246   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(0, 0), b(1, 1), b(2, 2))));
247   EXPECT_THAT(a({b(1, 1)}), Not(BucketsAre(b(0, 0), b(1, 0), b(2, 0))));
248 
249   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsAre(b(1, 1), b(2, 2)));
250   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsAre(b(0, 0), b(1, 1), b(2, 2)));
251   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre()));
252   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(0, 0))));
253   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(1, 1))));
254   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(2, 2))));
255   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(0, 0), b(1, 1))));
256   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(1, 0))));
257   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(2, 1))));
258   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsAre(b(0, 0), b(1, 0))));
259   EXPECT_THAT(a({b(1, 1), b(2, 2)}),
260               Not(BucketsAre(b(0, 0), b(1, 0), b(2, 0))));
261 }
262 
TEST_F(HistogramTesterTest,BucketsInclude)263 TEST_F(HistogramTesterTest, BucketsInclude) {
264   // Auxiliary function for the "actual" values to shorten lines.
265   auto a = [](std::vector<Bucket> b) { return b; };
266   auto b = [](base::Histogram::Sample min, base::Histogram::Count count) {
267     return Bucket(min, count);
268   };
269   using ::testing::Not;
270 
271   EXPECT_THAT(a({}), BucketsInclude());
272   EXPECT_THAT(a({}), BucketsInclude(b(0, 0)));
273   EXPECT_THAT(a({}), BucketsInclude(b(1, 0)));
274   EXPECT_THAT(a({}), BucketsInclude(b(0, 0), b(1, 0)));
275   EXPECT_THAT(a({}), Not(BucketsInclude(b(1, 1))));
276 
277   EXPECT_THAT(a({b(1, 1)}), BucketsInclude());
278   EXPECT_THAT(a({b(1, 1)}), BucketsInclude(b(0, 0)));
279   EXPECT_THAT(a({b(1, 1)}), BucketsInclude(b(1, 1)));
280   EXPECT_THAT(a({b(1, 1)}), BucketsInclude(b(0, 0), b(1, 1)));
281   EXPECT_THAT(a({b(1, 1)}), Not(BucketsInclude(b(1, 0))));
282   EXPECT_THAT(a({b(1, 1)}), Not(BucketsInclude(b(2, 1))));
283   EXPECT_THAT(a({b(1, 1)}), Not(BucketsInclude(b(2, 2))));
284   EXPECT_THAT(a({b(1, 1)}), Not(BucketsInclude(b(0, 0), b(1, 0))));
285   EXPECT_THAT(a({b(1, 1)}), Not(BucketsInclude(b(0, 0), b(1, 1), b(2, 2))));
286   EXPECT_THAT(a({b(1, 1)}), Not(BucketsInclude(b(0, 0), b(1, 0), b(2, 0))));
287 
288   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude());
289   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude(b(0, 0)));
290   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude(b(1, 1)));
291   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude(b(2, 2)));
292   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude(b(0, 0), b(1, 1)));
293   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude(b(1, 1), b(2, 2)));
294   EXPECT_THAT(a({b(1, 1), b(2, 2)}), BucketsInclude(b(0, 0), b(1, 1), b(2, 2)));
295   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsInclude(b(1, 0))));
296   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsInclude(b(2, 1))));
297   EXPECT_THAT(a({b(1, 1), b(2, 2)}), Not(BucketsInclude(b(0, 0), b(1, 0))));
298   EXPECT_THAT(a({b(1, 1), b(2, 2)}),
299               Not(BucketsInclude(b(0, 0), b(1, 0), b(2, 0))));
300 }
301 
302 }  // namespace base
303