1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be
3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file.
4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/metrics/histogram.h"
6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
70d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <limits.h>
80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stddef.h>
90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stdint.h>
100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <climits>
1294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <memory>
1345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include <string>
14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <vector>
15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/logging.h"
17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/metrics/bucket_ranges.h"
180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/metrics/histogram_macros.h"
1945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include "base/metrics/persistent_histogram_allocator.h"
2045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include "base/metrics/persistent_memory_allocator.h"
21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/metrics/sample_vector.h"
22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/metrics/statistics_recorder.h"
23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/pickle.h"
2445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include "base/strings/stringprintf.h"
25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/time/time.h"
26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "testing/gtest/include/gtest/gtest.h"
27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base {
29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
3045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// Test parameter indicates if a persistent memory allocator should be used
3145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// for histogram allocation. False will allocate histograms from the process
3245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// heap.
3345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoclass HistogramTest : public testing::TestWithParam<bool> {
34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat protected:
3545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  const int32_t kAllocatorMemorySize = 8 << 20;  // 8 MiB
3645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
3745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  HistogramTest() : use_persistent_histogram_allocator_(GetParam()) {}
3845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  void SetUp() override {
4045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    if (use_persistent_histogram_allocator_)
4145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      CreatePersistentHistogramAllocator();
4245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Each test will have a clean state (no Histogram / BucketRanges
44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // registered).
45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    InitializeStatisticsRecorder();
46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
4845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  void TearDown() override {
4945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    if (allocator_) {
5045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      ASSERT_FALSE(allocator_->IsFull());
5145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      ASSERT_FALSE(allocator_->IsCorrupt());
5245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    }
5345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    UninitializeStatisticsRecorder();
5445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    DestroyPersistentHistogramAllocator();
5545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  }
56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  void InitializeStatisticsRecorder() {
5894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    DCHECK(!statistics_recorder_);
590c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    statistics_recorder_ = StatisticsRecorder::CreateTemporaryForTesting();
60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  void UninitializeStatisticsRecorder() {
6394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    statistics_recorder_.reset();
64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
6645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  void CreatePersistentHistogramAllocator() {
6745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    // By getting the results-histogram before any persistent allocator
6845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    // is attached, that histogram is guaranteed not to be stored in
6945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    // any persistent memory segment (which simplifies some tests).
7094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    GlobalHistogramAllocator::GetCreateHistogramResultHistogram();
7145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
7294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    GlobalHistogramAllocator::CreateWithLocalMemory(
7345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko        kAllocatorMemorySize, 0, "HistogramAllocatorTest");
7494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    allocator_ = GlobalHistogramAllocator::Get()->memory_allocator();
7545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  }
7645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
7745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  void DestroyPersistentHistogramAllocator() {
7845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    allocator_ = nullptr;
7994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    GlobalHistogramAllocator::ReleaseForTesting();
8045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  }
8145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
8245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  const bool use_persistent_histogram_allocator_;
8345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
8494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<StatisticsRecorder> statistics_recorder_;
8594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<char[]> allocator_memory_;
8645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  PersistentMemoryAllocator* allocator_ = nullptr;
8745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
8845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko private:
8945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  DISALLOW_COPY_AND_ASSIGN(HistogramTest);
90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat};
91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
9245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// Run all HistogramTest cases with both heap and persistent memory.
9345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoINSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest, testing::Bool());
9445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
9545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Check for basic syntax and use.
9745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, BasicTest) {
98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Try basic construction
99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* histogram = Histogram::FactoryGet(
100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "TestHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(histogram);
102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "TestLinearHistogram", 1, 1000, 10, HistogramBase::kNoFlags);
105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(linear_histogram);
106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<int> custom_ranges;
108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(1);
109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(5);
110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "TestCustomHistogram", custom_ranges, HistogramBase::kNoFlags);
112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(custom_histogram);
113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
11494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // Macros that create hitograms have an internal static variable which will
11594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // continue to point to those from the very first run of this method even
11694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // during subsequent runs.
11794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  static bool already_run = false;
11894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  if (already_run)
11994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    return;
12094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  already_run = true;
12194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Use standard macros (but with fixed samples)
123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1));
124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30);
125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Check that the macro correctly matches histograms by name and records their
130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// data together.
13145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, NameMatchTest) {
13245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // Macros that create hitograms have an internal static variable which will
13345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // continue to point to those from the very first run of this method even
13445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // during subsequent runs.
13545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  static bool already_run = false;
13645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  if (already_run)
13745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    return;
13845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  already_run = true;
13945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LOCAL_HISTOGRAM_PERCENTAGE("DuplicatedHistogram", 10);
142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* histogram = LinearHistogram::FactoryGet(
143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "DuplicatedHistogram", 1, 101, 102, HistogramBase::kNoFlags);
144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
14594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, samples->TotalCount());
147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, samples->GetCount(10));
148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
15094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez// Check that delta calculations work correctly.
15145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, DeltaTest) {
15245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  HistogramBase* histogram =
15345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      Histogram::FactoryGet("DeltaHistogram", 1, 64, 8,
15445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko                            HistogramBase::kNoFlags);
15545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->Add(1);
15645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->Add(10);
15745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->Add(50);
15845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
15994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
16045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(3, samples->TotalCount());
16145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(1, samples->GetCount(1));
16245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(1, samples->GetCount(10));
16345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(1, samples->GetCount(50));
16445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
16545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
16645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  samples = histogram->SnapshotDelta();
16745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(0, samples->TotalCount());
16845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
16945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->Add(10);
17045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->Add(10);
17145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  samples = histogram->SnapshotDelta();
17245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(2, samples->TotalCount());
17345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(2, samples->GetCount(10));
17445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
17545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  samples = histogram->SnapshotDelta();
17645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(0, samples->TotalCount());
17745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko}
17845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
17994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez// Check that final-delta calculations work correctly.
18094ffa55491333f3dcc701befd0d2652922916d99Luis Hector ChavezTEST_P(HistogramTest, FinalDeltaTest) {
18194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  HistogramBase* histogram =
18294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      Histogram::FactoryGet("FinalDeltaHistogram", 1, 64, 8,
18394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez                            HistogramBase::kNoFlags);
18494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  histogram->Add(1);
18594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  histogram->Add(10);
18694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  histogram->Add(50);
18794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
18894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
18994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(3, samples->TotalCount());
19094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(1, samples->GetCount(1));
19194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(1, samples->GetCount(10));
19294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(1, samples->GetCount(50));
19394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
19494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
19594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  histogram->Add(2);
19694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  histogram->Add(50);
19794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
19894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  samples = histogram->SnapshotFinalDelta();
19994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(2, samples->TotalCount());
20094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(1, samples->GetCount(2));
20194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(1, samples->GetCount(50));
20294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  EXPECT_EQ(samples->TotalCount(), samples->redundant_count());
20394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}
20494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
20545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, ExponentialRangesTest) {
2060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Check that we got a nice exponential when there was enough room.
207b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  BucketRanges ranges(9);
208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram::InitializeBucketRanges(1, 64, &ranges);
209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges.range(0));
210b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int power_of_2 = 1;
211b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (int i = 1; i < 8; i++) {
212b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    EXPECT_EQ(power_of_2, ranges.range(i));
213b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    power_of_2 *= 2;
214b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
215b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
216b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
217b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Check the corresponding Histogram will use the correct ranges.
218b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
219b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
220b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
221b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
222b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // When bucket count is limited, exponential ranges will partially look like
223b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // linear.
224b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  BucketRanges ranges2(16);
225b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram::InitializeBucketRanges(1, 32, &ranges2);
226b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
227b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges2.range(0));
228b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(1, ranges2.range(1));
229b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, ranges2.range(2));
230b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(3, ranges2.range(3));
231b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(4, ranges2.range(4));
232b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(5, ranges2.range(5));
233b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(6, ranges2.range(6));
234b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(7, ranges2.range(7));
235b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(9, ranges2.range(8));
236b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(11, ranges2.range(9));
237b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(14, ranges2.range(10));
238b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(17, ranges2.range(11));
239b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(21, ranges2.range(12));
240b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(26, ranges2.range(13));
241b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(32, ranges2.range(14));
242b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(15));
243b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
244b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Check the corresponding Histogram will use the correct ranges.
245b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram2 = static_cast<Histogram*>(
246b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Histogram2", 1, 32, 15, HistogramBase::kNoFlags));
247b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
248b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
249b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
25045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, LinearRangesTest) {
251b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  BucketRanges ranges(9);
252b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LinearHistogram::InitializeBucketRanges(1, 7, &ranges);
253b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Gets a nice linear set of bucket ranges.
254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (int i = 0; i < 8; i++)
255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    EXPECT_EQ(i, ranges.range(i));
256b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges.range(8));
257b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
258b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // The correspoding LinearHistogram should use the correct ranges.
259b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
260b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      LinearHistogram::FactoryGet("Linear", 1, 7, 8, HistogramBase::kNoFlags));
261b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(ranges.Equals(histogram->bucket_ranges()));
262b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
263b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Linear ranges are not divisible.
264b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  BucketRanges ranges2(6);
265b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  LinearHistogram::InitializeBucketRanges(1, 6, &ranges2);
266b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges2.range(0));
267b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(1, ranges2.range(1));
268b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(3, ranges2.range(2));
269b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(4, ranges2.range(3));
270b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(6, ranges2.range(4));
271b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges2.range(5));
272b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // The correspoding LinearHistogram should use the correct ranges.
273b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram2 = static_cast<Histogram*>(
274b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      LinearHistogram::FactoryGet("Linear2", 1, 6, 5, HistogramBase::kNoFlags));
275b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(ranges2.Equals(histogram2->bucket_ranges()));
276b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
277b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
27845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, ArrayToCustomRangesTest) {
279b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  const HistogramBase::Sample ranges[3] = {5, 10, 20};
280b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<HistogramBase::Sample> ranges_vec =
281b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::ArrayToCustomRanges(ranges, 3);
282b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ASSERT_EQ(6u, ranges_vec.size());
283b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(5, ranges_vec[0]);
284b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(6, ranges_vec[1]);
285b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(10, ranges_vec[2]);
286b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(11, ranges_vec[3]);
287b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(20, ranges_vec[4]);
288b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(21, ranges_vec[5]);
289b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
290b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
29145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, CustomHistogramTest) {
292b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // A well prepared custom ranges.
293b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<HistogramBase::Sample> custom_ranges;
294b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(1);
295b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(2);
296b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
297b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
298b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::FactoryGet("TestCustomHistogram1", custom_ranges,
299b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                  HistogramBase::kNoFlags));
300b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  const BucketRanges* ranges = histogram->bucket_ranges();
301b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ASSERT_EQ(4u, ranges->size());
302b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges->range(0));  // Auto added.
303b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(1, ranges->range(1));
304b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, ranges->range(2));
305b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));  // Auto added.
306b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
307b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // A unordered custom ranges.
308b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.clear();
309b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(2);
310b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(1);
311b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram = static_cast<Histogram*>(
312b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::FactoryGet("TestCustomHistogram2", custom_ranges,
313b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                  HistogramBase::kNoFlags));
314b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ranges = histogram->bucket_ranges();
315b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ASSERT_EQ(4u, ranges->size());
316b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges->range(0));
317b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(1, ranges->range(1));
318b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, ranges->range(2));
319b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
320b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
321b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // A custom ranges with duplicated values.
322b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.clear();
323b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(4);
324b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(1);
325b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(4);
326b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram = static_cast<Histogram*>(
327b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::FactoryGet("TestCustomHistogram3", custom_ranges,
328b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                  HistogramBase::kNoFlags));
329b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ranges = histogram->bucket_ranges();
330b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ASSERT_EQ(4u, ranges->size());
331b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges->range(0));
332b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(1, ranges->range(1));
333b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(4, ranges->range(2));
334b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(3));
335b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
336b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
33745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, CustomHistogramWithOnly2Buckets) {
338b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // This test exploits the fact that the CustomHistogram can have 2 buckets,
339b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // while the base class Histogram is *supposed* to have at least 3 buckets.
340b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // We should probably change the restriction on the base class (or not inherit
341b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // the base class!).
342b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
343b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<HistogramBase::Sample> custom_ranges;
344b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(4);
345b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
346b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
347b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::FactoryGet("2BucketsCustomHistogram", custom_ranges,
348b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                  HistogramBase::kNoFlags));
349b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  const BucketRanges* ranges = histogram->bucket_ranges();
350b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ASSERT_EQ(3u, ranges->size());
351b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges->range(0));
352b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(4, ranges->range(1));
353b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
354b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
355b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
35645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, AddCountTest) {
3570d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  const size_t kBucketCount = 50;
3580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  Histogram* histogram = static_cast<Histogram*>(
3590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko      Histogram::FactoryGet("AddCountHistogram", 10, 100, kBucketCount,
3600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                            HistogramBase::kNoFlags));
3610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  histogram->AddCount(20, 15);
3630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  histogram->AddCount(30, 14);
3640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
36594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
3660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  EXPECT_EQ(29, samples->TotalCount());
3670d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  EXPECT_EQ(15, samples->GetCount(20));
3680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  EXPECT_EQ(14, samples->GetCount(30));
3690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
3700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  histogram->AddCount(20, 25);
3710d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  histogram->AddCount(30, 24);
3720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
37394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples();
3740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  EXPECT_EQ(78, samples2->TotalCount());
3750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  EXPECT_EQ(40, samples2->GetCount(20));
3760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  EXPECT_EQ(38, samples2->GetCount(30));
3770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko}
3780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
37945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, AddCount_LargeValuesDontOverflow) {
38045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  const size_t kBucketCount = 50;
38145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  Histogram* histogram = static_cast<Histogram*>(
38245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko      Histogram::FactoryGet("AddCountHistogram", 10, 1000000000, kBucketCount,
38345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko                            HistogramBase::kNoFlags));
38445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
38545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->AddCount(200000000, 15);
38645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->AddCount(300000000, 14);
38745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
38894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
38945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(29, samples->TotalCount());
39045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(15, samples->GetCount(200000000));
39145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(14, samples->GetCount(300000000));
39245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
39345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->AddCount(200000000, 25);
39445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  histogram->AddCount(300000000, 24);
39545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
39694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> samples2 = histogram->SnapshotSamples();
39745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(78, samples2->TotalCount());
39845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(40, samples2->GetCount(200000000));
39945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(38, samples2->GetCount(300000000));
40045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(19400000000LL, samples2->sum());
40145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko}
40245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
403b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Make sure histogram handles out-of-bounds data gracefully.
40445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, BoundsTest) {
405b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  const size_t kBucketCount = 50;
406b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
407b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Bounded", 10, 100, kBucketCount,
408b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                            HistogramBase::kNoFlags));
409b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
410b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Put two samples "out of bounds" above and below.
411b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(5);
412b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(-50);
413b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
414b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(100);
415b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(10000);
416b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
417b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Verify they landed in the underflow, and overflow buckets.
41894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<SampleVector> samples = histogram->SnapshotSampleVector();
419b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, samples->GetCountAtIndex(0));
420b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, samples->GetCountAtIndex(1));
421b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  size_t array_size = histogram->bucket_count();
422b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(kBucketCount, array_size);
423b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, samples->GetCountAtIndex(array_size - 2));
424b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, samples->GetCountAtIndex(array_size - 1));
425b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
426b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<int> custom_ranges;
427b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(10);
428b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(50);
429b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(100);
430b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* test_custom_histogram = static_cast<Histogram*>(
431b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::FactoryGet("TestCustomRangeBoundedHistogram",
432b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                  custom_ranges, HistogramBase::kNoFlags));
433b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
434b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Put two samples "out of bounds" above and below.
435b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  test_custom_histogram->Add(5);
436b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  test_custom_histogram->Add(-50);
437b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  test_custom_histogram->Add(100);
438b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  test_custom_histogram->Add(1000);
439b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  test_custom_histogram->Add(INT_MAX);
440b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
441b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Verify they landed in the underflow, and overflow buckets.
44294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<SampleVector> custom_samples =
443b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      test_custom_histogram->SnapshotSampleVector();
444b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, custom_samples->GetCountAtIndex(0));
445b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, custom_samples->GetCountAtIndex(1));
446b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  size_t bucket_count = test_custom_histogram->bucket_count();
447b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, custom_samples->GetCountAtIndex(bucket_count - 2));
448b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(3, custom_samples->GetCountAtIndex(bucket_count - 1));
449b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
450b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
451b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Check to be sure samples land as expected is "correct" buckets.
45245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, BucketPlacementTest) {
453b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
454b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
455b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
456b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Add i+1 samples to the i'th bucket.
457b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(0);
458b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int power_of_2 = 1;
459b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (int i = 1; i < 8; i++) {
460b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    for (int j = 0; j <= i; j++)
461b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      histogram->Add(power_of_2);
462b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    power_of_2 *= 2;
463b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
464b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
465b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Check to see that the bucket counts reflect our additions.
46694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<SampleVector> samples = histogram->SnapshotSampleVector();
467b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (int i = 0; i < 8; i++)
468b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    EXPECT_EQ(i + 1, samples->GetCountAtIndex(i));
469b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
470b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
47145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, CorruptSampleCounts) {
47294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // The internal code creates histograms via macros and thus keeps static
47394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // pointers to them. If those pointers are to persistent memory which will
47494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // be free'd then any following calls to that code will crash with a
47594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // segmentation violation.
47694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  if (use_persistent_histogram_allocator_)
47794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    return;
47894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
479b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
480b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
481b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
482b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Add some samples.
483b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(20);
484b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->Add(40);
485b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
48694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<SampleVector> snapshot = histogram->SnapshotSampleVector();
487b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
488b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
489b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, snapshot->redundant_count());
490b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(2, snapshot->TotalCount());
491b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
492b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  snapshot->counts_[3] += 100;  // Sample count won't match redundant count.
493b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::COUNT_LOW_ERROR,
494b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
495b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  snapshot->counts_[2] -= 200;
496b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::COUNT_HIGH_ERROR,
497b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
498b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
499b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // But we can't spot a corruption if it is compensated for.
500b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  snapshot->counts_[1] += 100;
501b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
502b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
503b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
504b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
50545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, CorruptBucketBounds) {
506b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
507b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Histogram", 1, 64, 8, HistogramBase::kNoFlags));
508b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
50994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  std::unique_ptr<HistogramSamples> snapshot = histogram->SnapshotSamples();
510b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::NO_INCONSISTENCIES,
511b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
512b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
513b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  BucketRanges* bucket_ranges =
514b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      const_cast<BucketRanges*>(histogram->bucket_ranges());
515b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase::Sample tmp = bucket_ranges->range(1);
516b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(1, bucket_ranges->range(2));
517b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(2, tmp);
518b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(
519b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      HistogramBase::BUCKET_ORDER_ERROR | HistogramBase::RANGE_CHECKSUM_ERROR,
520b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      histogram->FindCorruption(*snapshot));
521b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
522b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(2, bucket_ranges->range(1));
523b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(1, tmp);
52445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(0U, histogram->FindCorruption(*snapshot));
525b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
526b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Show that two simple changes don't offset each other
527b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(3, bucket_ranges->range(3) + 1);
528b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
529b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
530b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
531b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(4, bucket_ranges->range(4) - 1);
532b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::RANGE_CHECKSUM_ERROR,
533b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            histogram->FindCorruption(*snapshot));
534b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
535b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Repair histogram so that destructor won't DCHECK().
536b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(3, bucket_ranges->range(3) - 1);
537b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bucket_ranges->set_range(4, bucket_ranges->range(4) + 1);
538b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
539b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
54045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, HistogramSerializeInfo) {
541b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* histogram = static_cast<Histogram*>(
542b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      Histogram::FactoryGet("Histogram", 1, 64, 8,
543b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                            HistogramBase::kIPCSerializationSourceFlag));
544b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Pickle pickle;
545b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  histogram->SerializeInfo(&pickle);
546b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
547b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  PickleIterator iter(pickle);
548b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
549b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int type;
550b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&type));
551b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HISTOGRAM, type);
552b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
553b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string name;
554b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadString(&name));
555b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ("Histogram", name);
556b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
557b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int flag;
558b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&flag));
55945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(HistogramBase::kIPCSerializationSourceFlag,
56045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko            flag & ~HistogramBase::kIsPersistent);
561b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
562b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int min;
563b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&min));
564b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(1, min);
565b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
566b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int max;
567b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&max));
568b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(64, max);
569b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
57045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  uint32_t bucket_count;
57145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_TRUE(iter.ReadUInt32(&bucket_count));
57245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(8u, bucket_count);
573b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
5740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  uint32_t checksum;
575b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadUInt32(&checksum));
576b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(histogram->bucket_ranges()->checksum(), checksum);
577b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
578b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // No more data in the pickle.
579b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_FALSE(iter.SkipBytes(1));
580b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
581b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
58245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, CustomHistogramSerializeInfo) {
583b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<int> custom_ranges;
584b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(10);
585b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(100);
586b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
587b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
588b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "TestCustomRangeBoundedHistogram",
589b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      custom_ranges,
590b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      HistogramBase::kNoFlags);
591b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Pickle pickle;
592b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_histogram->SerializeInfo(&pickle);
593b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
594b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Validate the pickle.
595b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  PickleIterator iter(pickle);
596b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
597b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int i;
598b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string s;
59945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  uint32_t bucket_count;
6000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  uint32_t ui32;
601b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&i) && iter.ReadString(&s) && iter.ReadInt(&i) &&
602b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat              iter.ReadInt(&i) && iter.ReadInt(&i) &&
60345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko              iter.ReadUInt32(&bucket_count) && iter.ReadUInt32(&ui32));
60445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  EXPECT_EQ(3u, bucket_count);
605b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
606b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int range;
607b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&range));
608b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(10, range);
609b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(iter.ReadInt(&range));
610b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(100, range);
611b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
612b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // No more data in the pickle.
613b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_FALSE(iter.SkipBytes(1));
614b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
615b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
61645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, BadConstruction) {
617b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* histogram = Histogram::FactoryGet(
618b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadConstruction", 0, 100, 8, HistogramBase::kNoFlags);
619b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(histogram->HasConstructionArguments(1, 100, 8));
620b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
621b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Try to get the same histogram name with different arguments.
622b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* bad_histogram = Histogram::FactoryGet(
623b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadConstruction", 0, 100, 7, HistogramBase::kNoFlags);
624b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(NULL, bad_histogram);
625b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bad_histogram = Histogram::FactoryGet(
626b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadConstruction", 0, 99, 8, HistogramBase::kNoFlags);
627b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(NULL, bad_histogram);
628b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
629b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
630b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadConstructionLinear", 0, 100, 8, HistogramBase::kNoFlags);
631b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(linear_histogram->HasConstructionArguments(1, 100, 8));
632b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
633b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Try to get the same histogram name with different arguments.
634b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bad_histogram = LinearHistogram::FactoryGet(
635b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadConstructionLinear", 0, 100, 7, HistogramBase::kNoFlags);
636b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(NULL, bad_histogram);
637b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bad_histogram = LinearHistogram::FactoryGet(
638b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadConstructionLinear", 10, 100, 8, HistogramBase::kNoFlags);
639b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(NULL, bad_histogram);
640b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
641b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
64245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoTEST_P(HistogramTest, FactoryTime) {
64345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  const int kTestCreateCount = 1 << 14;  // Must be power-of-2.
64445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  const int kTestLookupCount = 100000;
64545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  const int kTestAddCount = 1000000;
64645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
64745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // Create all histogram names in advance for accurate timing below.
64845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  std::vector<std::string> histogram_names;
64945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  for (int i = 0; i < kTestCreateCount; ++i) {
65045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    histogram_names.push_back(
65145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko        StringPrintf("TestHistogram.%d", i % kTestCreateCount));
65245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  }
65345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
65445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // Calculate cost of creating histograms.
65545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  TimeTicks create_start = TimeTicks::Now();
65645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  for (int i = 0; i < kTestCreateCount; ++i) {
65794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    Histogram::FactoryGet(histogram_names[i], 1, 100, 10,
65845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko                          HistogramBase::kNoFlags);
65945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  }
66045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  TimeDelta create_ticks = TimeTicks::Now() - create_start;
66145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  int64_t create_ms = create_ticks.InMilliseconds();
66245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
66345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  VLOG(1) << kTestCreateCount << " histogram creations took " << create_ms
66445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << "ms or about "
66545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << (create_ms * 1000000) / kTestCreateCount
66645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << "ns each.";
66745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
66845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // Calculate cost of looking up existing histograms.
66945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  TimeTicks lookup_start = TimeTicks::Now();
67045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  for (int i = 0; i < kTestLookupCount; ++i) {
67145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    // 6007 is co-prime with kTestCreateCount and so will do lookups in an
67245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    // order less likely to be cacheable (but still hit them all) should the
67345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    // underlying storage use the exact histogram name as the key.
67445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    const int i_mult = 6007;
67545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    static_assert(i_mult < INT_MAX / kTestCreateCount, "Multiplier too big");
67645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    int index = (i * i_mult) & (kTestCreateCount - 1);
67794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez    Histogram::FactoryGet(histogram_names[index], 1, 100, 10,
67845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko                          HistogramBase::kNoFlags);
67945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  }
68045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  TimeDelta lookup_ticks = TimeTicks::Now() - lookup_start;
68145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  int64_t lookup_ms = lookup_ticks.InMilliseconds();
68245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
68345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  VLOG(1) << kTestLookupCount << " histogram lookups took " << lookup_ms
68445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << "ms or about "
68545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << (lookup_ms * 1000000) / kTestLookupCount
68645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << "ns each.";
68745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
68845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // Calculate cost of accessing histograms.
68945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  HistogramBase* histogram = Histogram::FactoryGet(
69094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      histogram_names[0], 1, 100, 10, HistogramBase::kNoFlags);
69145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  ASSERT_TRUE(histogram);
69245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  TimeTicks add_start = TimeTicks::Now();
69345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  for (int i = 0; i < kTestAddCount; ++i)
69445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    histogram->Add(i & 127);
69545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  TimeDelta add_ticks = TimeTicks::Now() - add_start;
69645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  int64_t add_ms = add_ticks.InMilliseconds();
69745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
69845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  VLOG(1) << kTestAddCount << " histogram adds took " << add_ms
69945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << "ms or about "
70045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << (add_ms * 1000000) / kTestAddCount
70145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko          << "ns each.";
70245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko}
70345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
704b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if GTEST_HAS_DEATH_TEST
705b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// For Histogram, LinearHistogram and CustomHistogram, the minimum for a
706b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// declared range is 1, while the maximum is (HistogramBase::kSampleType_MAX -
707b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 1). But we accept ranges exceeding those limits, and silently clamped to
708b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// those limits. This is for backwards compatibility.
709b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTEST(HistogramDeathTest, BadRangesTest) {
710b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* histogram = Histogram::FactoryGet(
711b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadRanges", 0, HistogramBase::kSampleType_MAX, 8,
712b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      HistogramBase::kNoFlags);
713b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(
714b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      histogram->HasConstructionArguments(
715b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          1, HistogramBase::kSampleType_MAX - 1, 8));
716b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
717b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
718b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      "BadRangesLinear", 0, HistogramBase::kSampleType_MAX, 8,
719b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      HistogramBase::kNoFlags);
720b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_TRUE(
721b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      linear_histogram->HasConstructionArguments(
722b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          1, HistogramBase::kSampleType_MAX - 1, 8));
723b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
724b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::vector<int> custom_ranges;
725b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(0);
726b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(5);
727b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Histogram* custom_histogram = static_cast<Histogram*>(
728b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      CustomHistogram::FactoryGet(
729b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          "BadRangesCustom", custom_ranges, HistogramBase::kNoFlags));
730b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  const BucketRanges* ranges = custom_histogram->bucket_ranges();
731b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ASSERT_EQ(3u, ranges->size());
732b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(0, ranges->range(0));
733b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(5, ranges->range(1));
734b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_EQ(HistogramBase::kSampleType_MAX, ranges->range(2));
735b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
736b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // CustomHistogram does not accepts kSampleType_MAX as range.
737b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(HistogramBase::kSampleType_MAX);
738b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom2", custom_ranges,
739b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                           HistogramBase::kNoFlags),
740b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat               "");
741b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
742b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // CustomHistogram needs at least 1 valid range.
743b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.clear();
744b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  custom_ranges.push_back(0);
745b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  EXPECT_DEATH(CustomHistogram::FactoryGet("BadRangesCustom3", custom_ranges,
746b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                           HistogramBase::kNoFlags),
747b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat               "");
748b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
749b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif
750b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
751b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace base
752