1 // Copyright (c) 2012 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.
7 #include "base/json/json_reader.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/metrics/histogram.h"
10 #include "base/metrics/statistics_recorder.h"
11 #include "base/values.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 class StatisticsRecorderTest
: public testing::Test
{
18 void SetUp() override
{
19 // Each test will have a clean state (no Histogram / BucketRanges
21 InitializeStatisticsRecorder();
24 void TearDown() override
{ UninitializeStatisticsRecorder(); }
26 void InitializeStatisticsRecorder() {
27 statistics_recorder_
= new StatisticsRecorder();
30 void UninitializeStatisticsRecorder() {
31 delete statistics_recorder_
;
32 statistics_recorder_
= NULL
;
35 Histogram
* CreateHistogram(const std::string
& name
,
36 HistogramBase::Sample min
,
37 HistogramBase::Sample max
,
38 size_t bucket_count
) {
39 BucketRanges
* ranges
= new BucketRanges(bucket_count
+ 1);
40 Histogram::InitializeBucketRanges(min
, max
, ranges
);
41 const BucketRanges
* registered_ranges
=
42 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges
);
43 return new Histogram(name
, min
, max
, registered_ranges
);
46 void DeleteHistogram(HistogramBase
* histogram
) {
50 StatisticsRecorder
* statistics_recorder_
;
53 TEST_F(StatisticsRecorderTest
, NotInitialized
) {
54 UninitializeStatisticsRecorder();
56 ASSERT_FALSE(StatisticsRecorder::IsActive());
58 StatisticsRecorder::Histograms registered_histograms
;
59 std::vector
<const BucketRanges
*> registered_ranges
;
61 StatisticsRecorder::GetHistograms(®istered_histograms
);
62 EXPECT_EQ(0u, registered_histograms
.size());
64 Histogram
* histogram
= CreateHistogram("TestHistogram", 1, 1000, 10);
66 // When StatisticsRecorder is not initialized, register is a noop.
68 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram
));
69 // Manually delete histogram that was not registered.
70 DeleteHistogram(histogram
);
72 // RegisterOrDeleteDuplicateRanges is a no-op.
73 BucketRanges
* ranges
= new BucketRanges(3);;
74 ranges
->ResetChecksum();
76 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges
));
77 StatisticsRecorder::GetBucketRanges(®istered_ranges
);
78 EXPECT_EQ(0u, registered_ranges
.size());
81 TEST_F(StatisticsRecorderTest
, RegisterBucketRanges
) {
82 std::vector
<const BucketRanges
*> registered_ranges
;
84 BucketRanges
* ranges1
= new BucketRanges(3);;
85 ranges1
->ResetChecksum();
86 BucketRanges
* ranges2
= new BucketRanges(4);;
87 ranges2
->ResetChecksum();
89 // Register new ranges.
91 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1
));
93 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges2
));
94 StatisticsRecorder::GetBucketRanges(®istered_ranges
);
95 ASSERT_EQ(2u, registered_ranges
.size());
97 // Register some ranges again.
99 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1
));
100 registered_ranges
.clear();
101 StatisticsRecorder::GetBucketRanges(®istered_ranges
);
102 ASSERT_EQ(2u, registered_ranges
.size());
103 // Make sure the ranges is still the one we know.
104 ASSERT_EQ(3u, ranges1
->size());
105 EXPECT_EQ(0, ranges1
->range(0));
106 EXPECT_EQ(0, ranges1
->range(1));
107 EXPECT_EQ(0, ranges1
->range(2));
109 // Register ranges with same values.
110 BucketRanges
* ranges3
= new BucketRanges(3);;
111 ranges3
->ResetChecksum();
112 EXPECT_EQ(ranges1
, // returning ranges1
113 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges3
));
114 registered_ranges
.clear();
115 StatisticsRecorder::GetBucketRanges(®istered_ranges
);
116 ASSERT_EQ(2u, registered_ranges
.size());
119 TEST_F(StatisticsRecorderTest
, RegisterHistogram
) {
120 // Create a Histogram that was not registered.
121 Histogram
* histogram
= CreateHistogram("TestHistogram", 1, 1000, 10);
123 StatisticsRecorder::Histograms registered_histograms
;
124 StatisticsRecorder::GetHistograms(®istered_histograms
);
125 EXPECT_EQ(0u, registered_histograms
.size());
127 // Register the Histogram.
129 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram
));
130 StatisticsRecorder::GetHistograms(®istered_histograms
);
131 EXPECT_EQ(1u, registered_histograms
.size());
133 // Register the same Histogram again.
135 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram
));
136 registered_histograms
.clear();
137 StatisticsRecorder::GetHistograms(®istered_histograms
);
138 EXPECT_EQ(1u, registered_histograms
.size());
141 TEST_F(StatisticsRecorderTest
, FindHistogram
) {
142 HistogramBase
* histogram1
= Histogram::FactoryGet(
143 "TestHistogram1", 1, 1000, 10, HistogramBase::kNoFlags
);
144 HistogramBase
* histogram2
= Histogram::FactoryGet(
145 "TestHistogram2", 1, 1000, 10, HistogramBase::kNoFlags
);
147 EXPECT_EQ(histogram1
, StatisticsRecorder::FindHistogram("TestHistogram1"));
148 EXPECT_EQ(histogram2
, StatisticsRecorder::FindHistogram("TestHistogram2"));
149 EXPECT_TRUE(StatisticsRecorder::FindHistogram("TestHistogram") == NULL
);
152 TEST_F(StatisticsRecorderTest
, GetSnapshot
) {
153 Histogram::FactoryGet("TestHistogram1", 1, 1000, 10, Histogram::kNoFlags
);
154 Histogram::FactoryGet("TestHistogram2", 1, 1000, 10, Histogram::kNoFlags
);
155 Histogram::FactoryGet("TestHistogram3", 1, 1000, 10, Histogram::kNoFlags
);
157 StatisticsRecorder::Histograms snapshot
;
158 StatisticsRecorder::GetSnapshot("Test", &snapshot
);
159 EXPECT_EQ(3u, snapshot
.size());
162 StatisticsRecorder::GetSnapshot("1", &snapshot
);
163 EXPECT_EQ(1u, snapshot
.size());
166 StatisticsRecorder::GetSnapshot("hello", &snapshot
);
167 EXPECT_EQ(0u, snapshot
.size());
170 TEST_F(StatisticsRecorderTest
, RegisterHistogramWithFactoryGet
) {
171 StatisticsRecorder::Histograms registered_histograms
;
173 StatisticsRecorder::GetHistograms(®istered_histograms
);
174 ASSERT_EQ(0u, registered_histograms
.size());
176 // Create a histogram.
177 HistogramBase
* histogram
= Histogram::FactoryGet(
178 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags
);
179 registered_histograms
.clear();
180 StatisticsRecorder::GetHistograms(®istered_histograms
);
181 EXPECT_EQ(1u, registered_histograms
.size());
183 // Get an existing histogram.
184 HistogramBase
* histogram2
= Histogram::FactoryGet(
185 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags
);
186 registered_histograms
.clear();
187 StatisticsRecorder::GetHistograms(®istered_histograms
);
188 EXPECT_EQ(1u, registered_histograms
.size());
189 EXPECT_EQ(histogram
, histogram2
);
191 // Create a LinearHistogram.
192 histogram
= LinearHistogram::FactoryGet(
193 "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags
);
194 registered_histograms
.clear();
195 StatisticsRecorder::GetHistograms(®istered_histograms
);
196 EXPECT_EQ(2u, registered_histograms
.size());
198 // Create a BooleanHistogram.
199 histogram
= BooleanHistogram::FactoryGet(
200 "TestBooleanHistogram", HistogramBase::kNoFlags
);
201 registered_histograms
.clear();
202 StatisticsRecorder::GetHistograms(®istered_histograms
);
203 EXPECT_EQ(3u, registered_histograms
.size());
205 // Create a CustomHistogram.
206 std::vector
<int> custom_ranges
;
207 custom_ranges
.push_back(1);
208 custom_ranges
.push_back(5);
209 histogram
= CustomHistogram::FactoryGet(
210 "TestCustomHistogram", custom_ranges
, HistogramBase::kNoFlags
);
211 registered_histograms
.clear();
212 StatisticsRecorder::GetHistograms(®istered_histograms
);
213 EXPECT_EQ(4u, registered_histograms
.size());
216 TEST_F(StatisticsRecorderTest
, RegisterHistogramWithMacros
) {
217 StatisticsRecorder::Histograms registered_histograms
;
219 HistogramBase
* histogram
= Histogram::FactoryGet(
220 "TestHistogramCounts", 1, 1000000, 50, HistogramBase::kNoFlags
);
222 // The histogram we got from macro is the same as from FactoryGet.
223 LOCAL_HISTOGRAM_COUNTS("TestHistogramCounts", 30);
224 registered_histograms
.clear();
225 StatisticsRecorder::GetHistograms(®istered_histograms
);
226 ASSERT_EQ(1u, registered_histograms
.size());
227 EXPECT_EQ(histogram
, registered_histograms
[0]);
229 LOCAL_HISTOGRAM_TIMES("TestHistogramTimes", TimeDelta::FromDays(1));
230 LOCAL_HISTOGRAM_ENUMERATION("TestHistogramEnumeration", 20, 200);
232 registered_histograms
.clear();
233 StatisticsRecorder::GetHistograms(®istered_histograms
);
234 EXPECT_EQ(3u, registered_histograms
.size());
237 TEST_F(StatisticsRecorderTest
, BucketRangesSharing
) {
238 std::vector
<const BucketRanges
*> ranges
;
239 StatisticsRecorder::GetBucketRanges(&ranges
);
240 EXPECT_EQ(0u, ranges
.size());
242 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags
);
243 Histogram::FactoryGet("Histogram2", 1, 64, 8, HistogramBase::kNoFlags
);
245 StatisticsRecorder::GetBucketRanges(&ranges
);
246 EXPECT_EQ(1u, ranges
.size());
248 Histogram::FactoryGet("Histogram3", 1, 64, 16, HistogramBase::kNoFlags
);
251 StatisticsRecorder::GetBucketRanges(&ranges
);
252 EXPECT_EQ(2u, ranges
.size());
255 TEST_F(StatisticsRecorderTest
, ToJSON
) {
256 LOCAL_HISTOGRAM_COUNTS("TestHistogram1", 30);
257 LOCAL_HISTOGRAM_COUNTS("TestHistogram1", 40);
258 LOCAL_HISTOGRAM_COUNTS("TestHistogram2", 30);
259 LOCAL_HISTOGRAM_COUNTS("TestHistogram2", 40);
261 std::string
json(StatisticsRecorder::ToJSON(std::string()));
263 // Check for valid JSON.
264 scoped_ptr
<Value
> root
;
265 root
.reset(JSONReader::Read(json
));
266 ASSERT_TRUE(root
.get());
268 DictionaryValue
* root_dict
= NULL
;
269 ASSERT_TRUE(root
->GetAsDictionary(&root_dict
));
271 // No query should be set.
272 ASSERT_FALSE(root_dict
->HasKey("query"));
274 ListValue
* histogram_list
= NULL
;
275 ASSERT_TRUE(root_dict
->GetList("histograms", &histogram_list
));
276 ASSERT_EQ(2u, histogram_list
->GetSize());
278 // Examine the first histogram.
279 DictionaryValue
* histogram_dict
= NULL
;
280 ASSERT_TRUE(histogram_list
->GetDictionary(0, &histogram_dict
));
283 ASSERT_TRUE(histogram_dict
->GetInteger("count", &sample_count
));
284 EXPECT_EQ(2, sample_count
);
286 // Test the query filter.
287 std::string
query("TestHistogram2");
288 json
= StatisticsRecorder::ToJSON(query
);
290 root
.reset(JSONReader::Read(json
));
291 ASSERT_TRUE(root
.get());
292 ASSERT_TRUE(root
->GetAsDictionary(&root_dict
));
294 std::string query_value
;
295 ASSERT_TRUE(root_dict
->GetString("query", &query_value
));
296 EXPECT_EQ(query
, query_value
);
298 ASSERT_TRUE(root_dict
->GetList("histograms", &histogram_list
));
299 ASSERT_EQ(1u, histogram_list
->GetSize());
301 ASSERT_TRUE(histogram_list
->GetDictionary(0, &histogram_dict
));
303 std::string histogram_name
;
304 ASSERT_TRUE(histogram_dict
->GetString("name", &histogram_name
));
305 EXPECT_EQ("TestHistogram2", histogram_name
);
308 UninitializeStatisticsRecorder();
310 // No data should be returned.
311 json
= StatisticsRecorder::ToJSON(query
);
312 EXPECT_TRUE(json
.empty());