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. 4 5#include <vector> 6 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" 13 14namespace base { 15 16class StatisticsRecorderTest : public testing::Test { 17 protected: 18 virtual void SetUp() { 19 // Each test will have a clean state (no Histogram / BucketRanges 20 // registered). 21 InitializeStatisticsRecorder(); 22 } 23 24 virtual void TearDown() { 25 UninitializeStatisticsRecorder(); 26 } 27 28 void InitializeStatisticsRecorder() { 29 statistics_recorder_ = new StatisticsRecorder(); 30 } 31 32 void UninitializeStatisticsRecorder() { 33 delete statistics_recorder_; 34 statistics_recorder_ = NULL; 35 } 36 37 Histogram* CreateHistogram(const std::string& name, 38 HistogramBase::Sample min, 39 HistogramBase::Sample max, 40 size_t bucket_count) { 41 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 42 Histogram::InitializeBucketRanges(min, max, ranges); 43 const BucketRanges* registered_ranges = 44 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 45 return new Histogram(name, min, max, registered_ranges); 46 } 47 48 void DeleteHistogram(HistogramBase* histogram) { 49 delete histogram; 50 } 51 52 StatisticsRecorder* statistics_recorder_; 53}; 54 55TEST_F(StatisticsRecorderTest, NotInitialized) { 56 UninitializeStatisticsRecorder(); 57 58 ASSERT_FALSE(StatisticsRecorder::IsActive()); 59 60 StatisticsRecorder::Histograms registered_histograms; 61 std::vector<const BucketRanges*> registered_ranges; 62 63 StatisticsRecorder::GetHistograms(®istered_histograms); 64 EXPECT_EQ(0u, registered_histograms.size()); 65 66 Histogram* histogram = CreateHistogram("TestHistogram", 1, 1000, 10); 67 68 // When StatisticsRecorder is not initialized, register is a noop. 69 EXPECT_EQ(histogram, 70 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram)); 71 // Manually delete histogram that was not registered. 72 DeleteHistogram(histogram); 73 74 // RegisterOrDeleteDuplicateRanges is a no-op. 75 BucketRanges* ranges = new BucketRanges(3);; 76 ranges->ResetChecksum(); 77 EXPECT_EQ(ranges, 78 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges)); 79 StatisticsRecorder::GetBucketRanges(®istered_ranges); 80 EXPECT_EQ(0u, registered_ranges.size()); 81} 82 83TEST_F(StatisticsRecorderTest, RegisterBucketRanges) { 84 std::vector<const BucketRanges*> registered_ranges; 85 86 BucketRanges* ranges1 = new BucketRanges(3);; 87 ranges1->ResetChecksum(); 88 BucketRanges* ranges2 = new BucketRanges(4);; 89 ranges2->ResetChecksum(); 90 91 // Register new ranges. 92 EXPECT_EQ(ranges1, 93 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1)); 94 EXPECT_EQ(ranges2, 95 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges2)); 96 StatisticsRecorder::GetBucketRanges(®istered_ranges); 97 ASSERT_EQ(2u, registered_ranges.size()); 98 99 // Register some ranges again. 100 EXPECT_EQ(ranges1, 101 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges1)); 102 registered_ranges.clear(); 103 StatisticsRecorder::GetBucketRanges(®istered_ranges); 104 ASSERT_EQ(2u, registered_ranges.size()); 105 // Make sure the ranges is still the one we know. 106 ASSERT_EQ(3u, ranges1->size()); 107 EXPECT_EQ(0, ranges1->range(0)); 108 EXPECT_EQ(0, ranges1->range(1)); 109 EXPECT_EQ(0, ranges1->range(2)); 110 111 // Register ranges with same values. 112 BucketRanges* ranges3 = new BucketRanges(3);; 113 ranges3->ResetChecksum(); 114 EXPECT_EQ(ranges1, // returning ranges1 115 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges3)); 116 registered_ranges.clear(); 117 StatisticsRecorder::GetBucketRanges(®istered_ranges); 118 ASSERT_EQ(2u, registered_ranges.size()); 119} 120 121TEST_F(StatisticsRecorderTest, RegisterHistogram) { 122 // Create a Histogram that was not registered. 123 Histogram* histogram = CreateHistogram("TestHistogram", 1, 1000, 10); 124 125 StatisticsRecorder::Histograms registered_histograms; 126 StatisticsRecorder::GetHistograms(®istered_histograms); 127 EXPECT_EQ(0u, registered_histograms.size()); 128 129 // Register the Histogram. 130 EXPECT_EQ(histogram, 131 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram)); 132 StatisticsRecorder::GetHistograms(®istered_histograms); 133 EXPECT_EQ(1u, registered_histograms.size()); 134 135 // Register the same Histogram again. 136 EXPECT_EQ(histogram, 137 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram)); 138 registered_histograms.clear(); 139 StatisticsRecorder::GetHistograms(®istered_histograms); 140 EXPECT_EQ(1u, registered_histograms.size()); 141} 142 143TEST_F(StatisticsRecorderTest, FindHistogram) { 144 HistogramBase* histogram1 = Histogram::FactoryGet( 145 "TestHistogram1", 1, 1000, 10, HistogramBase::kNoFlags); 146 HistogramBase* histogram2 = Histogram::FactoryGet( 147 "TestHistogram2", 1, 1000, 10, HistogramBase::kNoFlags); 148 149 EXPECT_EQ(histogram1, StatisticsRecorder::FindHistogram("TestHistogram1")); 150 EXPECT_EQ(histogram2, StatisticsRecorder::FindHistogram("TestHistogram2")); 151 EXPECT_TRUE(StatisticsRecorder::FindHistogram("TestHistogram") == NULL); 152} 153 154TEST_F(StatisticsRecorderTest, GetSnapshot) { 155 Histogram::FactoryGet("TestHistogram1", 1, 1000, 10, Histogram::kNoFlags); 156 Histogram::FactoryGet("TestHistogram2", 1, 1000, 10, Histogram::kNoFlags); 157 Histogram::FactoryGet("TestHistogram3", 1, 1000, 10, Histogram::kNoFlags); 158 159 StatisticsRecorder::Histograms snapshot; 160 StatisticsRecorder::GetSnapshot("Test", &snapshot); 161 EXPECT_EQ(3u, snapshot.size()); 162 163 snapshot.clear(); 164 StatisticsRecorder::GetSnapshot("1", &snapshot); 165 EXPECT_EQ(1u, snapshot.size()); 166 167 snapshot.clear(); 168 StatisticsRecorder::GetSnapshot("hello", &snapshot); 169 EXPECT_EQ(0u, snapshot.size()); 170} 171 172TEST_F(StatisticsRecorderTest, RegisterHistogramWithFactoryGet) { 173 StatisticsRecorder::Histograms registered_histograms; 174 175 StatisticsRecorder::GetHistograms(®istered_histograms); 176 ASSERT_EQ(0u, registered_histograms.size()); 177 178 // Create a histogram. 179 HistogramBase* histogram = Histogram::FactoryGet( 180 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags); 181 registered_histograms.clear(); 182 StatisticsRecorder::GetHistograms(®istered_histograms); 183 EXPECT_EQ(1u, registered_histograms.size()); 184 185 // Get an existing histogram. 186 HistogramBase* histogram2 = Histogram::FactoryGet( 187 "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags); 188 registered_histograms.clear(); 189 StatisticsRecorder::GetHistograms(®istered_histograms); 190 EXPECT_EQ(1u, registered_histograms.size()); 191 EXPECT_EQ(histogram, histogram2); 192 193 // Create a LinearHistogram. 194 histogram = LinearHistogram::FactoryGet( 195 "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags); 196 registered_histograms.clear(); 197 StatisticsRecorder::GetHistograms(®istered_histograms); 198 EXPECT_EQ(2u, registered_histograms.size()); 199 200 // Create a BooleanHistogram. 201 histogram = BooleanHistogram::FactoryGet( 202 "TestBooleanHistogram", HistogramBase::kNoFlags); 203 registered_histograms.clear(); 204 StatisticsRecorder::GetHistograms(®istered_histograms); 205 EXPECT_EQ(3u, registered_histograms.size()); 206 207 // Create a CustomHistogram. 208 std::vector<int> custom_ranges; 209 custom_ranges.push_back(1); 210 custom_ranges.push_back(5); 211 histogram = CustomHistogram::FactoryGet( 212 "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags); 213 registered_histograms.clear(); 214 StatisticsRecorder::GetHistograms(®istered_histograms); 215 EXPECT_EQ(4u, registered_histograms.size()); 216} 217 218TEST_F(StatisticsRecorderTest, RegisterHistogramWithMacros) { 219 StatisticsRecorder::Histograms registered_histograms; 220 221 HistogramBase* histogram = Histogram::FactoryGet( 222 "TestHistogramCounts", 1, 1000000, 50, HistogramBase::kNoFlags); 223 224 // The histogram we got from macro is the same as from FactoryGet. 225 LOCAL_HISTOGRAM_COUNTS("TestHistogramCounts", 30); 226 registered_histograms.clear(); 227 StatisticsRecorder::GetHistograms(®istered_histograms); 228 ASSERT_EQ(1u, registered_histograms.size()); 229 EXPECT_EQ(histogram, registered_histograms[0]); 230 231 LOCAL_HISTOGRAM_TIMES("TestHistogramTimes", TimeDelta::FromDays(1)); 232 LOCAL_HISTOGRAM_ENUMERATION("TestHistogramEnumeration", 20, 200); 233 234 registered_histograms.clear(); 235 StatisticsRecorder::GetHistograms(®istered_histograms); 236 EXPECT_EQ(3u, registered_histograms.size()); 237} 238 239TEST_F(StatisticsRecorderTest, BucketRangesSharing) { 240 std::vector<const BucketRanges*> ranges; 241 StatisticsRecorder::GetBucketRanges(&ranges); 242 EXPECT_EQ(0u, ranges.size()); 243 244 Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags); 245 Histogram::FactoryGet("Histogram2", 1, 64, 8, HistogramBase::kNoFlags); 246 247 StatisticsRecorder::GetBucketRanges(&ranges); 248 EXPECT_EQ(1u, ranges.size()); 249 250 Histogram::FactoryGet("Histogram3", 1, 64, 16, HistogramBase::kNoFlags); 251 252 ranges.clear(); 253 StatisticsRecorder::GetBucketRanges(&ranges); 254 EXPECT_EQ(2u, ranges.size()); 255} 256 257TEST_F(StatisticsRecorderTest, ToJSON) { 258 LOCAL_HISTOGRAM_COUNTS("TestHistogram1", 30); 259 LOCAL_HISTOGRAM_COUNTS("TestHistogram1", 40); 260 LOCAL_HISTOGRAM_COUNTS("TestHistogram2", 30); 261 LOCAL_HISTOGRAM_COUNTS("TestHistogram2", 40); 262 263 std::string json(StatisticsRecorder::ToJSON(std::string())); 264 265 // Check for valid JSON. 266 scoped_ptr<Value> root; 267 root.reset(JSONReader::Read(json)); 268 ASSERT_TRUE(root.get()); 269 270 DictionaryValue* root_dict = NULL; 271 ASSERT_TRUE(root->GetAsDictionary(&root_dict)); 272 273 // No query should be set. 274 ASSERT_FALSE(root_dict->HasKey("query")); 275 276 ListValue* histogram_list = NULL; 277 ASSERT_TRUE(root_dict->GetList("histograms", &histogram_list)); 278 ASSERT_EQ(2u, histogram_list->GetSize()); 279 280 // Examine the first histogram. 281 DictionaryValue* histogram_dict = NULL; 282 ASSERT_TRUE(histogram_list->GetDictionary(0, &histogram_dict)); 283 284 int sample_count; 285 ASSERT_TRUE(histogram_dict->GetInteger("count", &sample_count)); 286 EXPECT_EQ(2, sample_count); 287 288 // Test the query filter. 289 std::string query("TestHistogram2"); 290 json = StatisticsRecorder::ToJSON(query); 291 292 root.reset(JSONReader::Read(json)); 293 ASSERT_TRUE(root.get()); 294 ASSERT_TRUE(root->GetAsDictionary(&root_dict)); 295 296 std::string query_value; 297 ASSERT_TRUE(root_dict->GetString("query", &query_value)); 298 EXPECT_EQ(query, query_value); 299 300 ASSERT_TRUE(root_dict->GetList("histograms", &histogram_list)); 301 ASSERT_EQ(1u, histogram_list->GetSize()); 302 303 ASSERT_TRUE(histogram_list->GetDictionary(0, &histogram_dict)); 304 305 std::string histogram_name; 306 ASSERT_TRUE(histogram_dict->GetString("name", &histogram_name)); 307 EXPECT_EQ("TestHistogram2", histogram_name); 308 309 json.clear(); 310 UninitializeStatisticsRecorder(); 311 312 // No data should be returned. 313 json = StatisticsRecorder::ToJSON(query); 314 EXPECT_TRUE(json.empty()); 315} 316 317} // namespace base 318