#include "metric_value.h"
#include <library/cpp/testing/unittest/registar.h>
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<TTestHistogram>();
}
ISummaryDoubleSnapshotPtr MakeSummarySnapshot(ui64 count = 0u) {
return MakeIntrusive<TSummaryDoubleSnapshot>(0.0, 0.0, 0.0, 0.0, count);
}
TLogHistogramSnapshotPtr MakeLogHistogram(ui64 count = 0) {
TVector<double> buckets;
for (ui64 i = 0; i < count; ++i) {
buckets.push_back(i);
}
return MakeIntrusive<TLogHistogramSnapshot>(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<double>());
UNIT_ASSERT_EQUAL(ts2, timeSeries[1].GetTime());
UNIT_ASSERT_DOUBLES_EQUAL(2.71828, timeSeries[1].GetValue().AsDouble(), Min<double>());
}
Y_UNIT_TEST(Histograms) {
auto ts = TInstant::Now();
auto histogram = MakeIntrusive<TTestHistogram>();
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<TTestHistogram>();
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<TTestHistogram>();
auto h2 = MakeIntrusive<TTestHistogram>();
auto h3 = MakeIntrusive<TTestHistogram>();
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<TTestHistogram>(1u);
auto h2 = MakeIntrusive<TTestHistogram>(2u);
auto h3 = MakeIntrusive<TTestHistogram>(3u);
auto h4 = MakeIntrusive<TTestHistogram>(4u);
auto h5 = MakeIntrusive<TTestHistogram>(5u);
auto h6 = MakeIntrusive<TTestHistogram>(6u);
auto h7 = MakeIntrusive<TTestHistogram>(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);
}
}
}