15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test of Histogram class
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <climits>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/bucket_ranges.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/sample_vector.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/statistics_recorder.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistogramTest : public testing::Test {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Each test will have a clean state (no Histogram / BucketRanges
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // registered).
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeStatisticsRecorder();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UninitializeStatisticsRecorder();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeStatisticsRecorder() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    statistics_recorder_ = new StatisticsRecorder();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UninitializeStatisticsRecorder() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete statistics_recorder_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    statistics_recorder_ = NULL;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StatisticsRecorder* statistics_recorder_;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check for basic syntax and use.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, BasicTest) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try basic construction
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* histogram = Histogram::FactoryGet(
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(histogram);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(linear_histogram);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<int> custom_ranges;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(1);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(5);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(custom_histogram);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use standard macros (but with fixed samples)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM_COUNTS("Test3Histogram", 30);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DHISTOGRAM_COUNTS("Test5Histogram", 30);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the macro correctly matches histograms by name and records their
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data together.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, NameMatchTest) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* histogram = LinearHistogram::FactoryGet(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, samples->TotalCount());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, samples->GetCount(10));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, ExponentialRangesTest) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that we got a nice exponential when there was enough rooom.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BucketRanges ranges(9);
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Histogram::InitializeBucketRanges(1, 64, &ranges);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges.range(0));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int power_of_2 = 1;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i < 8; i++) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(power_of_2, ranges.range(i));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    power_of_2 *= 2;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the corresponding Histogram will use the correct ranges.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When bucket count is limited, exponential ranges will partially look like
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // linear.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BucketRanges ranges2(16);
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Histogram::InitializeBucketRanges(1, 32, &ranges2);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges2.range(0));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ranges2.range(1));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, ranges2.range(2));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, ranges2.range(3));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, ranges2.range(4));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, ranges2.range(5));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, ranges2.range(6));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(7, ranges2.range(7));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(9, ranges2.range(8));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11, ranges2.range(9));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14, ranges2.range(10));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(17, ranges2.range(11));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(21, ranges2.range(12));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(26, ranges2.range(13));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(32, ranges2.range(14));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(15));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the corresponding Histogram will use the correct ranges.
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram2 = static_cast<Histogram*>(
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Histogram2", 1, 32, 15, HistogramBase::kNoFlags));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, LinearRangesTest) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BucketRanges ranges(9);
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LinearHistogram::InitializeBucketRanges(1, 7, &ranges);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets a nice linear set of bucket ranges.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 8; i++)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(i, ranges.range(i));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The correspoding LinearHistogram should use the correct ranges.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LinearHistogram::FactoryGet("Linear", 1, 7, 8, HistogramBase::kNoFlags));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Linear ranges are not divisible.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BucketRanges ranges2(6);
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LinearHistogram::InitializeBucketRanges(1, 6, &ranges2);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges2.range(0));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ranges2.range(1));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, ranges2.range(2));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, ranges2.range(3));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, ranges2.range(4));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(5));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The correspoding LinearHistogram should use the correct ranges.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram2 = static_cast<Histogram*>(
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LinearHistogram::FactoryGet("Linear2", 1, 6, 5, HistogramBase::kNoFlags));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, ArrayToCustomRangesTest) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HistogramBase::Sample ranges[3] = {5, 10, 20};
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<HistogramBase::Sample> ranges_vec =
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CustomHistogram::ArrayToCustomRanges(ranges, 3);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(6u, ranges_vec.size());
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, ranges_vec[0]);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, ranges_vec[1]);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, ranges_vec[2]);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11, ranges_vec[3]);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20, ranges_vec[4]);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(21, ranges_vec[5]);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, CustomHistogramTest) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A well prepared custom ranges.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<HistogramBase::Sample> custom_ranges;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(1);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(2);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CustomHistogram::FactoryGet("TestCustomHistogram1", custom_ranges,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  HistogramBase::kNoFlags));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const BucketRanges* ranges = histogram->bucket_ranges();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, ranges->size());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges->range(0));  // Auto added.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ranges->range(1));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, ranges->range(2));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));  // Auto added.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A unordered custom ranges.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.clear();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(2);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(1);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  histogram = static_cast<Histogram*>(
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CustomHistogram::FactoryGet("TestCustomHistogram2", custom_ranges,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  HistogramBase::kNoFlags));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ranges = histogram->bucket_ranges();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, ranges->size());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges->range(0));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ranges->range(1));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, ranges->range(2));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A custom ranges with duplicated values.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.clear();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(4);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(1);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(4);
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  histogram = static_cast<Histogram*>(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CustomHistogram::FactoryGet("TestCustomHistogram3", custom_ranges,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  HistogramBase::kNoFlags));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ranges = histogram->bucket_ranges();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, ranges->size());
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges->range(0));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, ranges->range(1));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, ranges->range(2));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, CustomHistogramWithOnly2Buckets) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test exploits the fact that the CustomHistogram can have 2 buckets,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // while the base class Histogram is *supposed* to have at least 3 buckets.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should probably change the restriction on the base class (or not inherit
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the base class!).
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<HistogramBase::Sample> custom_ranges;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(4);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CustomHistogram::FactoryGet("2BucketsCustomHistogram", custom_ranges,
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  HistogramBase::kNoFlags));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const BucketRanges* ranges = histogram->bucket_ranges();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, ranges->size());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges->range(0));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, ranges->range(1));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure histogram handles out-of-bounds data gracefully.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, BoundsTest) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kBucketCount = 50;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Bounded", 10, 100, kBucketCount,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            HistogramBase::kNoFlags));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put two samples "out of bounds" above and below.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(5);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(-50);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(100);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(10000);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify they landed in the underflow, and overflow buckets.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, samples->GetCountAtIndex(0));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, samples->GetCountAtIndex(1));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t array_size = histogram->bucket_count();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kBucketCount, array_size);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<int> custom_ranges;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(10);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(50);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(100);
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* test_custom_histogram = static_cast<Histogram*>(
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram",
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  custom_ranges, HistogramBase::kNoFlags));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put two samples "out of bounds" above and below.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_custom_histogram->Add(5);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_custom_histogram->Add(-50);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_custom_histogram->Add(100);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_custom_histogram->Add(1000);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_custom_histogram->Add(INT_MAX);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify they landed in the underflow, and overflow buckets.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SampleVector> custom_samples =
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_custom_histogram->SnapshotSampleVector();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, custom_samples->GetCountAtIndex(0));
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, custom_samples->GetCountAtIndex(1));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t bucket_count = test_custom_histogram->bucket_count();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check to be sure samples land as expected is "correct" buckets.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, BucketPlacementTest) {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add i+1 samples to the i'th bucket.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(0);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int power_of_2 = 1;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i < 8; i++) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int j = 0; j <= i; j++)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      histogram->Add(power_of_2);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    power_of_2 *= 2;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see that the bucket counts reflect our additions.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SampleVector> samples = histogram->SnapshotSampleVector();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 8; i++)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(i + 1, samples->GetCountAtIndex(i));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, CorruptSampleCounts) {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add some samples.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(20);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram->Add(40);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector();
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, snapshot->redundant_count());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, snapshot->TotalCount());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  snapshot->counts_[3] += 100;  // Sample count won't match redundant count.
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  snapshot->counts_[2] -= 200;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But we can't spot a corruption if it is compensated for.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  snapshot->counts_[1] += 100;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(HistogramTest, CorruptBucketBounds) {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector();
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BucketRanges* bucket_ranges =
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const_cast<BucketRanges*>(histogram->bucket_ranges());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistogramBase::Sample tmp = bucket_ranges->range(1);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(1, bucket_ranges->range(2));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(2, tmp);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR,
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      histogram->FindCorruption(*snapshot));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(2, bucket_ranges->range(1));
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(1, tmp);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, histogram->FindCorruption(*snapshot));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Show that two simple changes don't offset each other
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(3, bucket_ranges->range(3) + 1);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(4, bucket_ranges->range(4) - 1);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            histogram->FindCorruption(*snapshot));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Repair histogram so that destructor won't DCHECK().
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(3, bucket_ranges->range(3) - 1);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bucket_ranges->set_range(4, bucket_ranges->range(4) + 1);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistogramTest, HistogramSerializeInfo) {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* histogram = static_cast<Histogram*>(
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Histogram::FactoryGet("Histogram", 1, 64, 8,
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            HistogramBase::kIPCSerializationSourceFlag));
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Pickle pickle;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  histogram->SerializeInfo(&pickle);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PickleIterator iter(pickle);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int type;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&type));
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HISTOGRAM, type);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string name;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadString(&name));
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Histogram", name);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int flag;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&flag));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag, flag);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int min;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&min));
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, min);
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&max));
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(64, max);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 bucket_count;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt64(&bucket_count));
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(8, bucket_count);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 checksum;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadUInt32(&checksum));
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(histogram->bucket_ranges()->checksum(), checksum);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No more data in the pickle.
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(iter.SkipBytes(1));
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(HistogramTest, CustomHistogramSerializeInfo) {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vector<int> custom_ranges;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  custom_ranges.push_back(10);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  custom_ranges.push_back(100);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "TestCustomRangeBoundedHistogram",
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      custom_ranges,
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HistogramBase::kNoFlags);
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Pickle pickle;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  custom_histogram->SerializeInfo(&pickle);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Validate the pickle.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PickleIterator iter(pickle);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int i;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string s;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 bucket_count;
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 ui32;
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&i) && iter.ReadString(&s) && iter.ReadInt(&i) &&
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              iter.ReadInt(&i) && iter.ReadInt(&i) &&
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              iter.ReadInt64(&bucket_count) && iter.ReadUInt32(&ui32));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, bucket_count);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int range;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&range));
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(10, range);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(iter.ReadInt(&range));
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(100, range);
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No more data in the pickle.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(iter.SkipBytes(1));
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if GTEST_HAS_DEATH_TEST
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For Histogram, LinearHistogram and CustomHistogram, the minimum for a
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX -
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1). But we accept ranges exceeding those limits, and silently clamped to
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// those limits. This is for backwards compatibility.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(HistogramDeathTest, BadRangesTest) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* histogram = Histogram::FactoryGet(
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "BadRanges", 0, HistogramBase::kSampleType_MAX, 8,
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HistogramBase::kNoFlags);
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      histogram->HasConstructionArguments(
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          1, HistogramBase::kSampleType_MAX - 1, 8));
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "BadRangesLinear", 0, HistogramBase::kSampleType_MAX, 8,
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HistogramBase::kNoFlags);
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      linear_histogram->HasConstructionArguments(
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          1, HistogramBase::kSampleType_MAX - 1, 8));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<int> custom_ranges;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(0);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(5);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Histogram* custom_histogram = static_cast<Histogram*>(
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CustomHistogram::FactoryGet(
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "BadRangesCustom", custom_ranges, HistogramBase::kNoFlags));
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const BucketRanges* ranges = custom_histogram->bucket_ranges();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, ranges->size());
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, ranges->range(0));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, ranges->range(1));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CustomHistogram does not accepts kSampleType_MAX as range.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(HistogramBase::kSampleType_MAX);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom2", custom_ranges,
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           HistogramBase::kNoFlags),
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "");
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CustomHistogram needs at least 1 valid range.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.clear();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  custom_ranges.push_back(0);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges,
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           HistogramBase::kNoFlags),
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "");
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
494