#include "metric_value.h" #include using namespace NMonitoring; Y_UNIT_TEST_SUITE(TMetricValueTest) { class TTestHistogram: public IHistogramSnapshot { public: TTestHistogram(ui32 count = 1) : Count_{count} {} private: ui32 Count() const override { return Count_; } TBucketBound UpperBound(ui32 /*index*/) const override { return 1234.56; } TBucketValue Value(ui32 /*index*/) const override { return 42; } ui32 Count_{0}; }; IHistogramSnapshotPtr MakeHistogramSnapshot() { return MakeIntrusive(); } ISummaryDoubleSnapshotPtr MakeSummarySnapshot(ui64 count = 0u) { return MakeIntrusive(0.0, 0.0, 0.0, 0.0, count); } TLogHistogramSnapshotPtr MakeLogHistogram(ui64 count = 0) { TVector buckets; for (ui64 i = 0; i < count; ++i) { buckets.push_back(i); } return MakeIntrusive(1.5, 0u, 0, buckets); } Y_UNIT_TEST(Sorted) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); TMetricTimeSeries timeSeries; timeSeries.Add(ts1, 3.14159); timeSeries.Add(ts1, 6.28318); timeSeries.Add(ts2, 2.71828); UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 2); UNIT_ASSERT_EQUAL(ts1, timeSeries[0].GetTime()); UNIT_ASSERT_DOUBLES_EQUAL(6.28318, timeSeries[0].GetValue().AsDouble(), Min()); UNIT_ASSERT_EQUAL(ts2, timeSeries[1].GetTime()); UNIT_ASSERT_DOUBLES_EQUAL(2.71828, timeSeries[1].GetValue().AsDouble(), Min()); } Y_UNIT_TEST(Histograms) { auto ts = TInstant::Now(); auto histogram = MakeIntrusive(); UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); { TMetricTimeSeries timeSeries; timeSeries.Add(ts, histogram.Get()); UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); } UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); } Y_UNIT_TEST(Summary) { auto ts = TInstant::Now(); auto summary = MakeSummarySnapshot(); UNIT_ASSERT_VALUES_EQUAL(1, summary->RefCount()); { TMetricTimeSeries timeSeries; timeSeries.Add(ts, summary.Get()); UNIT_ASSERT_VALUES_EQUAL(2, summary->RefCount()); } UNIT_ASSERT_VALUES_EQUAL(1, summary->RefCount()); } Y_UNIT_TEST(LogHistogram) { auto ts = TInstant::Now(); auto logHist = MakeLogHistogram(); UNIT_ASSERT_VALUES_EQUAL(1, logHist->RefCount()); { TMetricTimeSeries timeSeries; timeSeries.Add(ts, logHist.Get()); UNIT_ASSERT_VALUES_EQUAL(2, logHist->RefCount()); } UNIT_ASSERT_VALUES_EQUAL(1, logHist->RefCount()); } Y_UNIT_TEST(TimeSeriesMovable) { auto ts = TInstant::Now(); auto histogram = MakeIntrusive(); UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); { TMetricTimeSeries timeSeriesA; timeSeriesA.Add(ts, histogram.Get()); UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); TMetricTimeSeries timeSeriesB = std::move(timeSeriesA); UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, timeSeriesB.Size()); UNIT_ASSERT_EQUAL(EMetricValueType::HISTOGRAM, timeSeriesB.GetValueType()); UNIT_ASSERT_VALUES_EQUAL(0, timeSeriesA.Size()); UNIT_ASSERT_EQUAL(EMetricValueType::UNKNOWN, timeSeriesA.GetValueType()); } UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); } Y_UNIT_TEST(HistogramsUnique) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); auto ts3 = ts2 + TDuration::Seconds(1); auto h1 = MakeIntrusive(); auto h2 = MakeIntrusive(); auto h3 = MakeIntrusive(); UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); { TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); // drop at the head timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts2, h2.Get()); // drop in the middle timeSeries.Add(ts2, h2.Get()); timeSeries.Add(ts2, h2.Get()); timeSeries.Add(ts3, h3.Get()); // drop at the end timeSeries.Add(ts3, h3.Get()); timeSeries.Add(ts3, h3.Get()); UNIT_ASSERT_EQUAL(timeSeries.Size(), 9); UNIT_ASSERT_VALUES_EQUAL(4, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(4, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(4, h3->RefCount()); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); UNIT_ASSERT_VALUES_EQUAL(2, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(2, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(2, h3->RefCount()); } UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); } Y_UNIT_TEST(LogHistogramsUnique) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); auto ts3 = ts2 + TDuration::Seconds(1); auto h1 = MakeLogHistogram(); auto h2 = MakeLogHistogram(); auto h3 = MakeLogHistogram(); UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); { TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); // drop at the head timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts2, h2.Get()); // drop in the middle timeSeries.Add(ts2, h2.Get()); timeSeries.Add(ts2, h2.Get()); timeSeries.Add(ts3, h3.Get()); // drop at the end timeSeries.Add(ts3, h3.Get()); timeSeries.Add(ts3, h3.Get()); UNIT_ASSERT_EQUAL(timeSeries.Size(), 9); UNIT_ASSERT_VALUES_EQUAL(4, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(4, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(4, h3->RefCount()); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); UNIT_ASSERT_VALUES_EQUAL(2, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(2, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(2, h3->RefCount()); } UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); } Y_UNIT_TEST(SummaryUnique) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); auto ts3 = ts2 + TDuration::Seconds(1); auto h1 = MakeSummarySnapshot(); auto h2 = MakeSummarySnapshot(); auto h3 = MakeSummarySnapshot(); UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); { TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); // drop at the head timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts2, h2.Get()); // drop in the middle timeSeries.Add(ts2, h2.Get()); timeSeries.Add(ts2, h2.Get()); timeSeries.Add(ts3, h3.Get()); // drop at the end timeSeries.Add(ts3, h3.Get()); timeSeries.Add(ts3, h3.Get()); UNIT_ASSERT_EQUAL(timeSeries.Size(), 9); UNIT_ASSERT_VALUES_EQUAL(4, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(4, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(4, h3->RefCount()); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); UNIT_ASSERT_VALUES_EQUAL(2, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(2, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(2, h3->RefCount()); } UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); } Y_UNIT_TEST(HistogramsUnique2) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); auto ts3 = ts2 + TDuration::Seconds(1); auto ts4 = ts3 + TDuration::Seconds(1); auto ts5 = ts4 + TDuration::Seconds(1); auto h1 = MakeIntrusive(1u); auto h2 = MakeIntrusive(2u); auto h3 = MakeIntrusive(3u); auto h4 = MakeIntrusive(4u); auto h5 = MakeIntrusive(5u); auto h6 = MakeIntrusive(6u); auto h7 = MakeIntrusive(7u); { TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h2.Get()); timeSeries.Add(ts2, h3.Get()); timeSeries.Add(ts3, h4.Get()); timeSeries.Add(ts3, h5.Get()); timeSeries.Add(ts4, h6.Get()); timeSeries.Add(ts5, h7.Get()); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 5); UNIT_ASSERT_EQUAL(timeSeries[0].GetValue().AsHistogram()->Count(), 2); UNIT_ASSERT_EQUAL(timeSeries[1].GetValue().AsHistogram()->Count(), 3); UNIT_ASSERT_EQUAL(timeSeries[2].GetValue().AsHistogram()->Count(), 5); UNIT_ASSERT_EQUAL(timeSeries[3].GetValue().AsHistogram()->Count(), 6); UNIT_ASSERT_EQUAL(timeSeries[4].GetValue().AsHistogram()->Count(), 7); } } Y_UNIT_TEST(LogHistogramsUnique2) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); auto ts3 = ts2 + TDuration::Seconds(1); auto ts4 = ts3 + TDuration::Seconds(1); auto ts5 = ts4 + TDuration::Seconds(1); auto h1 = MakeLogHistogram(1u); auto h2 = MakeLogHistogram(2u); auto h3 = MakeLogHistogram(3u); auto h4 = MakeLogHistogram(4u); auto h5 = MakeLogHistogram(5u); auto h6 = MakeLogHistogram(6u); auto h7 = MakeLogHistogram(7u); { TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h2.Get()); timeSeries.Add(ts2, h3.Get()); timeSeries.Add(ts3, h4.Get()); timeSeries.Add(ts3, h5.Get()); timeSeries.Add(ts4, h6.Get()); timeSeries.Add(ts5, h7.Get()); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 5); UNIT_ASSERT_EQUAL(timeSeries[0].GetValue().AsLogHistogram()->Count(), 2); UNIT_ASSERT_EQUAL(timeSeries[1].GetValue().AsLogHistogram()->Count(), 3); UNIT_ASSERT_EQUAL(timeSeries[2].GetValue().AsLogHistogram()->Count(), 5); UNIT_ASSERT_EQUAL(timeSeries[3].GetValue().AsLogHistogram()->Count(), 6); UNIT_ASSERT_EQUAL(timeSeries[4].GetValue().AsLogHistogram()->Count(), 7); } } Y_UNIT_TEST(SummaryUnique2) { auto ts1 = TInstant::Now(); auto ts2 = ts1 + TDuration::Seconds(1); auto ts3 = ts2 + TDuration::Seconds(1); auto ts4 = ts3 + TDuration::Seconds(1); auto ts5 = ts4 + TDuration::Seconds(1); auto h1 = MakeSummarySnapshot(1u); auto h2 = MakeSummarySnapshot(2u); auto h3 = MakeSummarySnapshot(3u); auto h4 = MakeSummarySnapshot(4u); auto h5 = MakeSummarySnapshot(5u); auto h6 = MakeSummarySnapshot(6u); auto h7 = MakeSummarySnapshot(7u); { TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h2.Get()); timeSeries.Add(ts2, h3.Get()); timeSeries.Add(ts3, h4.Get()); timeSeries.Add(ts3, h5.Get()); timeSeries.Add(ts4, h6.Get()); timeSeries.Add(ts5, h7.Get()); timeSeries.SortByTs(); UNIT_ASSERT_EQUAL(timeSeries.Size(), 5); UNIT_ASSERT_EQUAL(timeSeries[0].GetValue().AsSummaryDouble()->GetCount(), 2); UNIT_ASSERT_EQUAL(timeSeries[1].GetValue().AsSummaryDouble()->GetCount(), 3); UNIT_ASSERT_EQUAL(timeSeries[2].GetValue().AsSummaryDouble()->GetCount(), 5); UNIT_ASSERT_EQUAL(timeSeries[3].GetValue().AsSummaryDouble()->GetCount(), 6); UNIT_ASSERT_EQUAL(timeSeries[4].GetValue().AsSummaryDouble()->GetCount(), 7); } } Y_UNIT_TEST(TMetricValueWithType) { // correct usage { double value = 1.23; TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::DOUBLE); UNIT_ASSERT_VALUES_EQUAL(v.AsDouble(), value); } { ui64 value = 12; TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::UINT64); UNIT_ASSERT_VALUES_EQUAL(v.AsUint64(), value); } { i64 value = i64(-12); TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::INT64); UNIT_ASSERT_VALUES_EQUAL(v.AsInt64(), value); } { auto h = MakeHistogramSnapshot(); UNIT_ASSERT_VALUES_EQUAL(h.RefCount(), 1); { auto value = h.Get(); TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(h.RefCount(), 2); UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(v.AsHistogram(), value); } UNIT_ASSERT_VALUES_EQUAL(h.RefCount(), 1); } { auto s = MakeSummarySnapshot(); auto value = s.Get(); UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); { TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::SUMMARY); UNIT_ASSERT_VALUES_EQUAL(v.AsSummaryDouble(), value); } UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); } { auto s = MakeSummarySnapshot(); auto value = s.Get(); UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); { TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); v.Clear(); UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); } UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); } { auto s = MakeSummarySnapshot(); auto value = s.Get(); { TMetricValueWithType v1{ui64{1}}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); { TMetricValueWithType v2{value}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); v1 = std::move(v2); UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); UNIT_ASSERT_VALUES_EQUAL(v1.AsSummaryDouble(), value); UNIT_ASSERT_VALUES_EQUAL(v1.GetType(), EMetricValueType::SUMMARY); UNIT_ASSERT_VALUES_EQUAL(v2.GetType(), EMetricValueType::UNKNOWN); } UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); } UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); } // incorrect usage { TMetricValueWithType v{1.23}; UNIT_ASSERT_EXCEPTION(v.AsHistogram(), yexception); UNIT_ASSERT_EXCEPTION(v.AsSummaryDouble(), yexception); } { auto h = MakeHistogramSnapshot(); TMetricValueWithType v{h.Get()}; UNIT_ASSERT_EXCEPTION(v.AsUint64(), yexception); UNIT_ASSERT_EXCEPTION(v.AsInt64(), yexception); UNIT_ASSERT_EXCEPTION(v.AsDouble(), yexception); UNIT_ASSERT_EXCEPTION(v.AsSummaryDouble(), yexception); } { auto s = MakeSummarySnapshot(); TMetricValueWithType v{s.Get()}; UNIT_ASSERT_EXCEPTION(v.AsUint64(), yexception); UNIT_ASSERT_EXCEPTION(v.AsInt64(), yexception); UNIT_ASSERT_EXCEPTION(v.AsDouble(), yexception); UNIT_ASSERT_EXCEPTION(v.AsHistogram(), yexception); } } }