|
@@ -0,0 +1,341 @@
|
|
|
+#include "unistat.h"
|
|
|
+
|
|
|
+#include <library/cpp/monlib/encode/protobuf/protobuf.h>
|
|
|
+#include <library/cpp/monlib/metrics/labels.h>
|
|
|
+
|
|
|
+#include <library/cpp/testing/unittest/registar.h>
|
|
|
+
|
|
|
+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<double> expectedBounds {0, 200, 500, std::numeric_limits<double>::max()};
|
|
|
+ const TVector<ui64> 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<double> expectedBounds = {1, 2, 4, std::numeric_limits<double>::max()};
|
|
|
+ TVector<ui64> 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<double> expectedBounds;
|
|
|
+ for (ui64 i = 0; i < 50; ++i) {
|
|
|
+ expectedBounds.push_back(std::pow(2, i));
|
|
|
+ }
|
|
|
+ expectedBounds.push_back(std::numeric_limits<double>::max());
|
|
|
+
|
|
|
+ TVector<ui64> 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<double> expectedBounds = {1, 2, 4, std::numeric_limits<double>::max()};
|
|
|
+ TVector<ui64> 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");
|
|
|
+ }
|
|
|
+}
|