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