#include "unistat.h" #include #include #include using namespace NMonitoring; Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { Y_UNIT_TEST(MetricNameLabel) { constexpr auto input = TStringBuf(R"([["something_axxx", 42]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get(), "metric_name_label"); UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); auto label = sample.GetLabels(0); UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "metric_name_label"); } Y_UNIT_TEST(ScalarMetric) { constexpr auto input = TStringBuf(R"([["something_axxx", 42]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto label = sample.GetLabels(0); auto point = sample.GetPoints(0); UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); } Y_UNIT_TEST(OverriddenTags) { constexpr auto input = TStringBuf(R"([["ctype=foo;prj=bar;custom_tag=qwe;something_axxx", 42]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 4); const auto& labels = sample.GetLabels(); TLabels actual; for (auto&& l : labels) { actual.Add(l.GetName(), l.GetValue()); } TLabels expected{{"ctype", "foo"}, {"prj", "bar"}, {"custom_tag", "qwe"}, {"sensor", "something_axxx"}}; UNIT_ASSERT_VALUES_EQUAL(actual.size(), expected.size()); for (auto&& l : actual) { UNIT_ASSERT(expected.Extract(l.Name())->Value() == l.Value()); } } Y_UNIT_TEST(ThrowsOnTopLevelObject) { constexpr auto input = TStringBuf(R"({["something_axxx", 42]})"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } Y_UNIT_TEST(ThrowsOnUnwrappedMetric) { constexpr auto input = TStringBuf(R"(["something_axxx", 42])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } Y_UNIT_TEST(HistogramMetric) { constexpr auto input = TStringBuf(R"([["something_hgram", [[0, 1], [200, 2], [500, 3]] ]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HIST_RATE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto label = sample.GetLabels(0); const auto point = sample.GetPoints(0); const auto histogram = point.GetHistogram(); const auto size = histogram.BoundsSize(); UNIT_ASSERT_VALUES_EQUAL(size, 4); const TVector expectedBounds {0, 200, 500, std::numeric_limits::max()}; const TVector expectedValues {0, 1, 2, 3}; for (auto i = 0; i < 4; ++i) { UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]); UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]); } UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_hgram"); } Y_UNIT_TEST(AbsoluteHistogram) { constexpr auto input = TStringBuf(R"([["something_ahhh", [[0, 1], [200, 2], [500, 3]] ]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); } Y_UNIT_TEST(LogHistogram) { constexpr auto input = TStringBuf(R"([["something_ahhh", [1, 2, 3] ]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto histogram = sample.GetPoints(0).GetHistogram(); UNIT_ASSERT_VALUES_EQUAL(histogram.BoundsSize(), 4); TVector expectedBounds = {1, 2, 4, std::numeric_limits::max()}; TVector expectedValues = {1, 1, 1, 0}; for (auto i = 0; i < 4; ++i) { UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]); UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]); } } Y_UNIT_TEST(LogHistogramOverflow) { constexpr auto input = TStringBuf(R"([["something_ahhh", [1125899906842624, 2251799813685248] ]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto histogram = sample.GetPoints(0).GetHistogram(); UNIT_ASSERT_VALUES_EQUAL(histogram.BoundsSize(), HISTOGRAM_MAX_BUCKETS_COUNT); TVector expectedBounds; for (ui64 i = 0; i < 50; ++i) { expectedBounds.push_back(std::pow(2, i)); } expectedBounds.push_back(std::numeric_limits::max()); TVector expectedValues; for (ui64 i = 0; i < 50; ++i) { expectedValues.push_back(0); } expectedValues.push_back(2); for (auto i = 0; i < 4; ++i) { UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]); UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]); } } Y_UNIT_TEST(LogHistogramSingle) { constexpr auto input = TStringBuf(R"([["something_ahhh", 4 ]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto histogram = sample.GetPoints(0).GetHistogram(); UNIT_ASSERT_VALUES_EQUAL(histogram.BoundsSize(), 4); TVector expectedBounds = {1, 2, 4, std::numeric_limits::max()}; TVector expectedValues = {0, 0, 1, 0}; for (auto i = 0; i < 4; ++i) { UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]); UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]); } } Y_UNIT_TEST(LogHistogramInvalid) { NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); { constexpr auto input = TStringBuf(R"([["something_ahhh", [1, 2, [3, 4]] ]])"); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } { constexpr auto input = TStringBuf(R"([["something_ahhh", [[3, 4], 1, 2] ]])"); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } { constexpr auto input = TStringBuf(R"([["something_hgram", 1, 2, 3, 4 ]])"); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } } Y_UNIT_TEST(AllowedMetricNames) { NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); { constexpr auto input = TStringBuf(R"([["a/A-b/c_D/__G_dmmm", [[0, 1], [200, 2], [500, 3]] ]])"); UNIT_ASSERT_NO_EXCEPTION(DecodeUnistat(input, encoder.Get())); } } Y_UNIT_TEST(DisallowedMetricNames) { NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); { constexpr auto input = TStringBuf(R"([["someth!ng_ahhh", [[0, 1], [200, 2], [500, 3]] ]])"); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } { constexpr auto input = TStringBuf(R"([["foo_a", [[0, 1], [200, 2], [500, 3]] ]])"); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } { constexpr auto input = TStringBuf(R"([["foo_ahhh;tag=value", [[0, 1], [200, 2], [500, 3]] ]])"); UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); } } Y_UNIT_TEST(MultipleMetrics) { constexpr auto input = TStringBuf(R"([["something_axxx", 42], ["some-other_dhhh", 53]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 2); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto label = sample.GetLabels(0); auto point = sample.GetPoints(0); UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); sample = samples.GetSamples(1); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); label = sample.GetLabels(0); point = sample.GetPoints(0); UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 53); UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "some-other_dhhh"); } Y_UNIT_TEST(UnderscoreName) { constexpr auto input = TStringBuf(R"([["something_anything_dmmm", 42]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto label = sample.GetLabels(0); auto point = sample.GetPoints(0); UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 42); UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_dmmm"); } Y_UNIT_TEST(MaxAggr) { constexpr auto input = TStringBuf(R"([["something_anything_max", 42]])"); NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); DecodeUnistat(input, encoder.Get()); UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); auto label = sample.GetLabels(0); auto point = sample.GetPoints(0); UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_max"); } }