diff --git a/envoy/stats/store.h b/envoy/stats/store.h index f18dc16d37793..a7be0c6d57738 100644 --- a/envoy/stats/store.h +++ b/envoy/stats/store.h @@ -67,6 +67,7 @@ class Store : public Scope { virtual void forEachCounter(SizeFn f_size, StatFn f_stat) const PURE; virtual void forEachGauge(SizeFn f_size, StatFn f_stat) const PURE; virtual void forEachTextReadout(SizeFn f_size, StatFn f_stat) const PURE; + virtual void forEachHistogram(SizeFn f_size, StatFn f_stat) const PURE; virtual void forEachScope(SizeFn f_size, StatFn f_stat) const PURE; /** diff --git a/source/common/stats/isolated_store_impl.h b/source/common/stats/isolated_store_impl.h index 99b06eb85dd4f..879648189977d 100644 --- a/source/common/stats/isolated_store_impl.h +++ b/source/common/stats/isolated_store_impl.h @@ -227,6 +227,11 @@ class IsolatedStoreImpl : public StoreImpl { text_readouts_.forEachStat(f_size, f_stat); } + void forEachHistogram(SizeFn f_size, StatFn f_stat) const override { + UNREFERENCED_PARAMETER(f_size); + UNREFERENCED_PARAMETER(f_stat); + } + void forEachScope(SizeFn f_size, StatFn f_stat) const override { if (f_size != nullptr) { f_size(1); diff --git a/source/common/stats/thread_local_store.cc b/source/common/stats/thread_local_store.cc index 6dc693ab1a7c3..6bc37b85f3bc0 100644 --- a/source/common/stats/thread_local_store.cc +++ b/source/common/stats/thread_local_store.cc @@ -179,14 +179,10 @@ std::vector ThreadLocalStoreImpl::textReadouts() const { std::vector ThreadLocalStoreImpl::histograms() const { std::vector ret; - Thread::LockGuard lock(hist_mutex_); - { - ret.reserve(histogram_set_.size()); - for (const auto& histogram_ptr : histogram_set_) { - ret.emplace_back(histogram_ptr); - } - } - + forEachHistogram([&ret](std::size_t size) mutable { ret.reserve(size); }, + [&ret](ParentHistogram& histogram) mutable { + ret.emplace_back(ParentHistogramSharedPtr(&histogram)); + }); return ret; } @@ -241,9 +237,7 @@ void ThreadLocalStoreImpl::mergeHistograms(PostMergeCb merge_complete_cb) { void ThreadLocalStoreImpl::mergeInternal(PostMergeCb merge_complete_cb) { if (!shutting_down_) { - for (const ParentHistogramSharedPtr& histogram : histograms()) { - histogram->merge(); - } + forEachHistogram(nullptr, [](ParentHistogram& histogram) { histogram.merge(); }); merge_complete_cb(); merge_in_progress_ = false; } @@ -967,6 +961,16 @@ void ThreadLocalStoreImpl::forEachTextReadout(SizeFn f_size, StatFn alloc_.forEachTextReadout(f_size, f_stat); } +void ThreadLocalStoreImpl::forEachHistogram(SizeFn f_size, StatFn f_stat) const { + Thread::LockGuard lock(hist_mutex_); + if (f_size != nullptr) { + f_size(histogram_set_.size()); + } + for (ParentHistogramImpl* histogram : histogram_set_) { + f_stat(*histogram); + } +} + void ThreadLocalStoreImpl::forEachScope(std::function f_size, StatFn f_scope) const { Thread::LockGuard lock(lock_); diff --git a/source/common/stats/thread_local_store.h b/source/common/stats/thread_local_store.h index cfd64f97d3575..e7e973cd6acc7 100644 --- a/source/common/stats/thread_local_store.h +++ b/source/common/stats/thread_local_store.h @@ -247,6 +247,7 @@ class ThreadLocalStoreImpl : Logger::Loggable, public StoreRo void forEachCounter(SizeFn f_size, StatFn f_stat) const override; void forEachGauge(SizeFn f_size, StatFn f_stat) const override; void forEachTextReadout(SizeFn f_size, StatFn f_stat) const override; + void forEachHistogram(SizeFn f_size, StatFn f_stat) const override; void forEachScope(SizeFn f_size, StatFn f_stat) const override; // Stats::StoreRoot diff --git a/source/server/server.cc b/source/server/server.cc index 929a59faece63..57aeb9b225fbe 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -180,34 +180,38 @@ void InstanceImpl::failHealthcheck(bool fail) { MetricSnapshotImpl::MetricSnapshotImpl(Stats::Store& store, TimeSource& time_source) { store.forEachSinkedCounter( - [this](std::size_t size) mutable { + [this](std::size_t size) { snapped_counters_.reserve(size); counters_.reserve(size); }, - [this](Stats::Counter& counter) mutable { + [this](Stats::Counter& counter) { snapped_counters_.push_back(Stats::CounterSharedPtr(&counter)); counters_.push_back({counter.latch(), counter}); }); store.forEachSinkedGauge( - [this](std::size_t size) mutable { + [this](std::size_t size) { snapped_gauges_.reserve(size); gauges_.reserve(size); }, - [this](Stats::Gauge& gauge) mutable { + [this](Stats::Gauge& gauge) { ASSERT(gauge.importMode() != Stats::Gauge::ImportMode::Uninitialized); snapped_gauges_.push_back(Stats::GaugeSharedPtr(&gauge)); gauges_.push_back(gauge); }); - snapped_histograms_ = store.histograms(); - histograms_.reserve(snapped_histograms_.size()); - for (const auto& histogram : snapped_histograms_) { - histograms_.push_back(*histogram); - } + store.forEachHistogram( + [this](std::size_t size) { + snapped_histograms_.reserve(size); + histograms_.reserve(size); + }, + [this](Stats::ParentHistogram& histogram) { + snapped_histograms_.push_back(Stats::ParentHistogramSharedPtr(&histogram)); + histograms_.push_back(histogram); + }); store.forEachSinkedTextReadout( - [this](std::size_t size) mutable { + [this](std::size_t size) { snapped_text_readouts_.reserve(size); text_readouts_.reserve(size); }, diff --git a/test/common/stats/thread_local_store_test.cc b/test/common/stats/thread_local_store_test.cc index e5f17a6e50cbe..edb0faa12d40f 100644 --- a/test/common/stats/thread_local_store_test.cc +++ b/test/common/stats/thread_local_store_test.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "envoy/config/metrics/v3/stats.pb.h" @@ -248,8 +249,8 @@ TEST_F(StatsThreadLocalStoreTest, NoTls) { g1.set(0); EXPECT_EQ(0, found_gauge->get().value()); - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - EXPECT_EQ(&h1, &store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified)); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + EXPECT_EQ(&h1, &store_->histogramFromString("h1", Histogram::Unit::Unspecified)); StatNameManagedStorage h1_name("h1", symbol_table_); auto found_histogram = store_->findHistogram(h1_name.statName()); ASSERT_TRUE(found_histogram.has_value()); @@ -302,8 +303,8 @@ TEST_F(StatsThreadLocalStoreTest, Tls) { g1.set(0); EXPECT_EQ(0, found_gauge->get().value()); - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - EXPECT_EQ(&h1, &store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified)); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + EXPECT_EQ(&h1, &store_->histogramFromString("h1", Histogram::Unit::Unspecified)); StatNameManagedStorage h1_name("h1", symbol_table_); auto found_histogram = store_->findHistogram(h1_name.statName()); ASSERT_TRUE(found_histogram.has_value()); @@ -369,8 +370,8 @@ TEST_F(StatsThreadLocalStoreTest, BasicScope) { ASSERT_TRUE(found_gauge2.has_value()); EXPECT_EQ(&g2, &found_gauge2->get()); - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - Histogram& h2 = scope1->histogramFromString("h2", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + Histogram& h2 = scope1->histogramFromString("h2", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); EXPECT_EQ("scope1.h2", h2.name()); EXPECT_CALL(sink_, onHistogramComplete(Ref(h1), 100)); @@ -413,12 +414,11 @@ TEST_F(StatsThreadLocalStoreTest, BasicScope) { } { StatNameManagedStorage storage("h3", symbol_table_); - Histogram& histogram = scope1->histogramFromStatNameWithTags( - StatName(storage.statName()), tags, Stats::Histogram::Unit::Unspecified); + Histogram& histogram = scope1->histogramFromStatNameWithTags(StatName(storage.statName()), tags, + Histogram::Unit::Unspecified); EXPECT_EQ(expectedTags, histogram.tags()); - EXPECT_EQ(&histogram, - &scope1->histogramFromStatNameWithTags(StatName(storage.statName()), tags, - Stats::Histogram::Unit::Unspecified)); + EXPECT_EQ(&histogram, &scope1->histogramFromStatNameWithTags(StatName(storage.statName()), tags, + Histogram::Unit::Unspecified)); } tls_.shutdownGlobalThreading(); @@ -770,9 +770,8 @@ TEST_F(LookupWithStatNameTest, All) { EXPECT_EQ(0, g1.tags().size()); Histogram& h1 = - store_->Store::histogramFromStatName(makeStatName("h1"), Stats::Histogram::Unit::Unspecified); - Histogram& h2 = - scope1->histogramFromStatName(makeStatName("h2"), Stats::Histogram::Unit::Unspecified); + store_->Store::histogramFromStatName(makeStatName("h1"), Histogram::Unit::Unspecified); + Histogram& h2 = scope1->histogramFromStatName(makeStatName("h2"), Histogram::Unit::Unspecified); scope1->deliverHistogramToSinks(h2, 0); EXPECT_EQ("h1", h1.name()); EXPECT_EQ("scope1.h2", h2.name()); @@ -816,7 +815,7 @@ class StatsMatcherTLSTest : public StatsThreadLocalStoreTest { uint64_t memoryConsumedAddingClusterStats() { StatNamePool pool(symbol_table_); std::vector stat_names; - Stats::TestUtil::forEachSampleStat(1000, false, [&pool, &stat_names](absl::string_view name) { + TestUtil::forEachSampleStat(1000, false, [&pool, &stat_names](absl::string_view name) { stat_names.push_back(pool.add(name)); }); @@ -893,12 +892,12 @@ TEST_F(StatsMatcherTLSTest, TestNoOpStatImpls) { // Histogram Histogram& noop_histogram = - store_->histogramFromString("noop_histogram", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("noop_histogram", Histogram::Unit::Unspecified); EXPECT_EQ(noop_histogram.name(), ""); EXPECT_FALSE(noop_histogram.used()); - EXPECT_EQ(Stats::Histogram::Unit::Null, noop_histogram.unit()); + EXPECT_EQ(Histogram::Unit::Null, noop_histogram.unit()); Histogram& noop_histogram_2 = - store_->histogramFromString("noop_histogram_2", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("noop_histogram_2", Histogram::Unit::Unspecified); EXPECT_EQ(&noop_histogram, &noop_histogram_2); } @@ -921,7 +920,7 @@ TEST_F(StatsMatcherTLSTest, TestExclusionRegex) { store_->gaugeFromString("lowercase_gauge", Gauge::ImportMode::Accumulate); EXPECT_EQ(lowercase_gauge.name(), "lowercase_gauge"); Histogram& lowercase_histogram = - store_->histogramFromString("lowercase_histogram", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("lowercase_histogram", Histogram::Unit::Unspecified); EXPECT_EQ(lowercase_histogram.name(), "lowercase_histogram"); TextReadout& lowercase_string = store_->textReadoutFromString("lowercase_string"); @@ -950,7 +949,7 @@ TEST_F(StatsMatcherTLSTest, TestExclusionRegex) { // Histograms are harder to query and test, so we resort to testing that name() returns the empty // string. Histogram& uppercase_histogram = - store_->histogramFromString("upperCASE_histogram", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("upperCASE_histogram", Histogram::Unit::Unspecified); EXPECT_EQ(uppercase_histogram.name(), ""); // Adding another exclusion rule -- now we reject not just uppercase stats but those starting with @@ -987,15 +986,15 @@ TEST_F(StatsMatcherTLSTest, TestExclusionRegex) { EXPECT_EQ(invalid_gauge_2.value(), 0); Histogram& valid_histogram = - store_->histogramFromString("valid_histogram", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("valid_histogram", Histogram::Unit::Unspecified); EXPECT_EQ(valid_histogram.name(), "valid_histogram"); Histogram& invalid_histogram_1 = - store_->histogramFromString("invalid_histogram", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("invalid_histogram", Histogram::Unit::Unspecified); EXPECT_EQ(invalid_histogram_1.name(), ""); Histogram& invalid_histogram_2 = - store_->histogramFromString("also_INVALID_histogram", Stats::Histogram::Unit::Unspecified); + store_->histogramFromString("also_INVALID_histogram", Histogram::Unit::Unspecified); EXPECT_EQ(invalid_histogram_2.name(), ""); TextReadout& valid_string = store_->textReadoutFromString("valid_string"); @@ -1020,7 +1019,7 @@ TEST_F(StatsMatcherTLSTest, RejectPrefixDot) { store_->initializeThreading(main_thread_dispatcher_, tls_); stats_config_.mutable_stats_matcher()->mutable_exclusion_list()->add_patterns()->set_prefix( "cluster."); // Prefix match can be executed symbolically. - store_->setStatsMatcher(std::make_unique(stats_config_, symbol_table_)); + store_->setStatsMatcher(std::make_unique(stats_config_, symbol_table_)); uint64_t mem_consumed = memoryConsumedAddingClusterStats(); // No memory is consumed at all while rejecting stats from "prefix." @@ -1036,7 +1035,7 @@ TEST_F(StatsMatcherTLSTest, RejectPrefixNoDot) { store_->initializeThreading(main_thread_dispatcher_, tls_); stats_config_.mutable_stats_matcher()->mutable_exclusion_list()->add_patterns()->set_prefix( "cluster"); // No dot at the end means we have to compare as strings. - store_->setStatsMatcher(std::make_unique(stats_config_, symbol_table_)); + store_->setStatsMatcher(std::make_unique(stats_config_, symbol_table_)); uint64_t mem_consumed = memoryConsumedAddingClusterStats(); // Memory is consumed at all while rejecting stats from "prefix" in proportion @@ -1157,7 +1156,7 @@ class RememberStatsMatcherTest : public testing::TestWithParam { LookupStatFn lookupHistogramFn() { return [this](const std::string& stat_name) -> std::string { - return scope_->histogramFromString(stat_name, Stats::Histogram::Unit::Unspecified).name(); + return scope_->histogramFromString(stat_name, Histogram::Unit::Unspecified).name(); }; } @@ -1220,7 +1219,7 @@ TEST_F(StatsThreadLocalStoreTest, RemoveRejectedStats) { store_->initializeThreading(main_thread_dispatcher_, tls_); Counter& counter = store_->counterFromString("c1"); Gauge& gauge = store_->gaugeFromString("g1", Gauge::ImportMode::Accumulate); - Histogram& histogram = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); + Histogram& histogram = store_->histogramFromString("h1", Histogram::Unit::Unspecified); TextReadout& textReadout = store_->textReadoutFromString("t1"); ASSERT_EQ(1, store_->counters().size()); // "c1". EXPECT_TRUE(&counter == store_->counters()[0].get() || @@ -1402,7 +1401,7 @@ TEST_F(StatsThreadLocalStoreTest, MergeDuringShutDown) { InSequence s; store_->initializeThreading(main_thread_dispatcher_, tls_); - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); EXPECT_CALL(sink_, onHistogramComplete(Ref(h1), 1)); @@ -1438,7 +1437,7 @@ TEST(ThreadLocalStoreThreadTest, ConstructDestruct) { // Histogram tests TEST_F(HistogramTest, BasicSingleHistogramMerge) { - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); expectCallAndAccumulate(h1, 0); @@ -1454,8 +1453,8 @@ TEST_F(HistogramTest, BasicSingleHistogramMerge) { } TEST_F(HistogramTest, BasicMultiHistogramMerge) { - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - Histogram& h2 = store_->histogramFromString("h2", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + Histogram& h2 = store_->histogramFromString("h2", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); EXPECT_EQ("h2", h2.name()); @@ -1467,8 +1466,8 @@ TEST_F(HistogramTest, BasicMultiHistogramMerge) { } TEST_F(HistogramTest, MultiHistogramMultipleMerges) { - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - Histogram& h2 = store_->histogramFromString("h2", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + Histogram& h2 = store_->histogramFromString("h2", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); EXPECT_EQ("h2", h2.name()); @@ -1498,8 +1497,8 @@ TEST_F(HistogramTest, MultiHistogramMultipleMerges) { TEST_F(HistogramTest, BasicScopeHistogramMerge) { ScopePtr scope1 = store_->createScope("scope1."); - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - Histogram& h2 = scope1->histogramFromString("h2", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + Histogram& h2 = scope1->histogramFromString("h2", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); EXPECT_EQ("scope1.h2", h2.name()); @@ -1509,8 +1508,8 @@ TEST_F(HistogramTest, BasicScopeHistogramMerge) { } TEST_F(HistogramTest, BasicHistogramSummaryValidate) { - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - Histogram& h2 = store_->histogramFromString("h2", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + Histogram& h2 = store_->histogramFromString("h2", Histogram::Unit::Unspecified); expectCallAndAccumulate(h1, 1); @@ -1549,7 +1548,7 @@ TEST_F(HistogramTest, BasicHistogramSummaryValidate) { // Validates the summary after known value merge in to same histogram. TEST_F(HistogramTest, BasicHistogramMergeSummary) { - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); for (size_t i = 0; i < 50; ++i) { expectCallAndAccumulate(h1, i); @@ -1577,8 +1576,8 @@ TEST_F(HistogramTest, BasicHistogramMergeSummary) { TEST_F(HistogramTest, BasicHistogramUsed) { ScopePtr scope1 = store_->createScope("scope1."); - Histogram& h1 = store_->histogramFromString("h1", Stats::Histogram::Unit::Unspecified); - Histogram& h2 = scope1->histogramFromString("h2", Stats::Histogram::Unit::Unspecified); + Histogram& h1 = store_->histogramFromString("h1", Histogram::Unit::Unspecified); + Histogram& h2 = scope1->histogramFromString("h2", Histogram::Unit::Unspecified); EXPECT_EQ("h1", h1.name()); EXPECT_EQ("scope1.h2", h2.name()); @@ -1607,8 +1606,7 @@ TEST_F(HistogramTest, BasicHistogramUsed) { TEST_F(HistogramTest, ParentHistogramBucketSummary) { ScopePtr scope1 = store_->createScope("scope1."); - Histogram& histogram = - store_->histogramFromString("histogram", Stats::Histogram::Unit::Unspecified); + Histogram& histogram = store_->histogramFromString("histogram", Histogram::Unit::Unspecified); store_->mergeHistograms([]() -> void {}); ASSERT_EQ(1, store_->histograms().size()); ParentHistogramSharedPtr parent_histogram = store_->histograms()[0]; @@ -1624,6 +1622,40 @@ TEST_F(HistogramTest, ParentHistogramBucketSummary) { parent_histogram->bucketSummary()); } +TEST_F(HistogramTest, ForEachHistogram) { + std::vector> histograms; + + const size_t num_stats = 11; + for (size_t idx = 0; idx < num_stats; ++idx) { + auto stat_name = absl::StrCat("histogram.", idx); + histograms.emplace_back(store_->histogramFromString(stat_name, Histogram::Unit::Unspecified)); + } + EXPECT_EQ(histograms.size(), 11); + + size_t num_histograms = 0; + size_t num_iterations = 0; + store_->forEachHistogram([&num_histograms](std::size_t size) { num_histograms = size; }, + [&num_iterations](ParentHistogram&) { ++num_iterations; }); + EXPECT_EQ(num_histograms, 11); + EXPECT_EQ(num_iterations, 11); + + Histogram& deleted_histogram = histograms[4]; + + // Verify that rejecting histograms removes them from the iteration set. + envoy::config::metrics::v3::StatsConfig stats_config_; + stats_config_.mutable_stats_matcher()->set_reject_all(true); + store_->setStatsMatcher(std::make_unique(stats_config_, symbol_table_)); + num_histograms = 0; + num_iterations = 0; + store_->forEachHistogram([&num_histograms](std::size_t size) { num_histograms = size; }, + [&num_iterations](ParentHistogram&) { ++num_iterations; }); + EXPECT_EQ(num_histograms, 0); + EXPECT_EQ(num_iterations, 0); + + // Verify that we can access the local reference without a crash. + EXPECT_EQ(deleted_histogram.unit(), Histogram::Unit::Unspecified); +} + class ThreadLocalRealThreadsTestBase : public Thread::RealThreadsTestHelper, public ThreadLocalStoreNoMocksTestBase { protected: @@ -1794,8 +1826,7 @@ class HistogramThreadTest : public ThreadLocalRealThreadsTestBase { TEST_F(HistogramThreadTest, MakeHistogramsAndRecordValues) { foreachThread([this]() { - Histogram& histogram = - store_->histogramFromString("my_hist", Stats::Histogram::Unit::Unspecified); + Histogram& histogram = store_->histogramFromString("my_hist", Histogram::Unit::Unspecified); histogram.recordValue(42); }); diff --git a/test/integration/server.h b/test/integration/server.h index ab369c281026c..6c228624a3206 100644 --- a/test/integration/server.h +++ b/test/integration/server.h @@ -295,6 +295,10 @@ class TestIsolatedStoreImpl : public StoreRoot { Thread::LockGuard lock(lock_); store_.forEachTextReadout(f_size, f_stat); } + void forEachHistogram(Stats::SizeFn f_size, StatFn f_stat) const override { + Thread::LockGuard lock(lock_); + store_.forEachHistogram(f_size, f_stat); + } void forEachScope(std::function f_size, StatFn f_scope) const override { Thread::LockGuard lock(lock_); diff --git a/test/mocks/stats/mocks.h b/test/mocks/stats/mocks.h index fd3d245395510..42837995662a5 100644 --- a/test/mocks/stats/mocks.h +++ b/test/mocks/stats/mocks.h @@ -298,6 +298,7 @@ class MockStore : public TestUtil::TestStore { MOCK_METHOD(void, forEachCounter, (SizeFn, StatFn), (const)); MOCK_METHOD(void, forEachGauge, (SizeFn, StatFn), (const)); MOCK_METHOD(void, forEachTextReadout, (SizeFn, StatFn), (const)); + MOCK_METHOD(void, forEachHistogram, (SizeFn, StatFn), (const)); MOCK_METHOD(CounterOptConstRef, findCounter, (StatName), (const)); MOCK_METHOD(GaugeOptConstRef, findGauge, (StatName), (const)); diff --git a/test/server/server_test.cc b/test/server/server_test.cc index 8e6acff4fe85d..5230712b2ec54 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -91,7 +91,16 @@ TEST(ServerInstanceUtil, flushHelper) { NiceMock mock_store; Stats::ParentHistogramSharedPtr parent_histogram(new Stats::MockParentHistogram()); std::vector parent_histograms = {parent_histogram}; - ON_CALL(mock_store, histograms).WillByDefault(Return(parent_histograms)); + ON_CALL(mock_store, forEachHistogram) + .WillByDefault([&](std::function f_size, + std::function f_stat) { + if (f_size != nullptr) { + f_size(parent_histograms.size()); + } + for (auto& histogram : parent_histograms) { + f_stat(*histogram); + } + }); EXPECT_CALL(*sink, flush(_)).WillOnce(Invoke([](Stats::MetricSnapshot& snapshot) { EXPECT_TRUE(snapshot.counters().empty()); EXPECT_TRUE(snapshot.gauges().empty());