#include "legacy_protobuf.h" #include #include #include #include #include #include #include #include using namespace NMonitoring; TSimple MakeSimpleMessage() { TSimple msg; msg.SetFoo(1); msg.SetBar(2.); msg.SetBaz(42.); return msg; } IMetricEncoderPtr debugPrinter = EncoderText(&Cerr); namespace NMonitoring { inline bool operator<(const TLabel& lhs, const TLabel& rhs) { return lhs.Name() < rhs.Name() || (lhs.Name() == rhs.Name() && lhs.Value() < rhs.Value()); } } void SetLabelValue(NMonProto::TExtraLabelMetrics::TValue& val, TString s) { val.SetlabelValue(s); } void SetLabelValue(NMonProto::TExtraLabelMetrics::TValue& val, ui64 u) { val.SetlabelValueUint(u); } template NMonProto::TExtraLabelMetrics MakeExtra(TString labelName, V labelValue, T value, bool isDeriv) { NMonProto::TExtraLabelMetrics metric; auto* val = metric.Addvalues(); metric.SetlabelName(labelName); SetLabelValue(*val, labelValue); if (isDeriv) { val->SetlongValue(value); } else { val->SetdoubleValue(value); } return metric; } void AssertLabels(const TLabels& expected, const NProto::TMultiSample& actual) { UNIT_ASSERT_EQUAL(actual.LabelsSize(), expected.Size()); TSet actualSet; TSet expectedSet; Transform(expected.begin(), expected.end(), std::inserter(expectedSet, expectedSet.end()), [] (auto&& l) { return TLabel{l.Name(), l.Value()}; }); const auto& l = actual.GetLabels(); Transform(std::begin(l), std::end(l), std::inserter(actualSet, std::begin(actualSet)), [](auto&& elem) -> TLabel { return {elem.GetName(), elem.GetValue()}; }); TVector diff; SetSymmetricDifference(std::begin(expectedSet), std::end(expectedSet), std::begin(actualSet), std::end(actualSet), std::back_inserter(diff)); if (diff.size() > 0) { for (auto&& l : diff) { Cerr << l << Endl; } UNIT_FAIL("Labels don't match"); } } void AssertSimpleMessage(const NProto::TMultiSamplesList& samples, TString pathPrefix = "/") { UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); THashSet expectedValues{pathPrefix + "Foo", pathPrefix + "Bar", pathPrefix + "Baz"}; for (const auto& s : samples.GetSamples()) { UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); const auto labelVal = s.GetLabels(0).GetValue(); UNIT_ASSERT(expectedValues.contains(labelVal)); if (labelVal == pathPrefix + "Foo") { UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_DOUBLES_EQUAL(s.GetPoints(0).GetFloat64(), 1, 1e-6); } else if (labelVal == pathPrefix + "Bar") { UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_DOUBLES_EQUAL(s.GetPoints(0).GetFloat64(), 2, 1e-6); } else if (labelVal == pathPrefix + "Baz") { UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); UNIT_ASSERT_EQUAL(s.GetPoints(0).GetUint64(), 42); } } } Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(SimpleProto) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto msg = MakeSimpleMessage(); DecodeLegacyProto(msg, e.Get()); AssertSimpleMessage(samples); }; Y_UNIT_TEST(RepeatedProto) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); TRepeated msg; msg.AddMessages()->CopyFrom(simple); DecodeLegacyProto(msg, e.Get()); AssertSimpleMessage(samples); } Y_UNIT_TEST(RepeatedProtoWithPath) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); TRepeatedWithPath msg; msg.AddNamespace()->CopyFrom(simple); DecodeLegacyProto(msg, e.Get()); AssertSimpleMessage(samples, "/Namespace/"); } Y_UNIT_TEST(DeepNesting) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); TRepeatedWithPath internal; internal.AddNamespace()->CopyFrom(simple); TDeepNesting msg; msg.MutableNested()->CopyFrom(internal); DecodeLegacyProto(msg, e.Get()); AssertSimpleMessage(samples, "/Namespace/"); } Y_UNIT_TEST(Keys) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); simple.SetLabel("my_label_value"); TNestedWithKeys msg; msg.AddNamespace()->CopyFrom(simple); DecodeLegacyProto(msg, e.Get()); auto i = 0; for (const auto& s : samples.GetSamples()) { UNIT_ASSERT_EQUAL(s.LabelsSize(), 4); bool foundLabel = false; bool foundFixed = false; bool foundNumbered = false; for (const auto& label : s.GetLabels()) { if (label.GetName() == "my_label") { foundLabel = true; UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "my_label_value"); } else if (label.GetName() == "fixed_label") { foundFixed = true; UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "fixed_value"); } else if (label.GetName() == "numbered") { foundNumbered = true; UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), ::ToString(i)); } } UNIT_ASSERT(foundLabel); UNIT_ASSERT(foundFixed); UNIT_ASSERT(foundNumbered); } } Y_UNIT_TEST(NonStringKeys) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); TNonStringKeys msg; msg.SetFoo(42); msg.SetEnum(ENUM); msg.SetInt(43); TRepeatedNonStringKeys msgs; msgs.AddNested()->CopyFrom(msg); DecodeLegacyProto(msgs, e.Get()); for (const auto& s : samples.GetSamples()) { bool foundEnum = false; bool foundInt = false; for (const auto& label : s.GetLabels()) { if (label.GetName() == "enum") { foundEnum = true; UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "ENUM"); } else if (label.GetName() == "int") { foundInt = true; UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "43"); } } UNIT_ASSERT(foundEnum); UNIT_ASSERT(foundInt); UNIT_ASSERT_DOUBLES_EQUAL(s.GetPoints(0).GetFloat64(), 42, 1e-6); } } Y_UNIT_TEST(KeysFromNonLeafNodes) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); simple.SetLabel("label_value"); TRepeatedWithName nested; nested.SetName("my_name"); nested.AddNested()->CopyFrom(simple); TKeysFromNonLeaf msg; msg.AddNested()->CopyFrom(nested); DecodeLegacyProto(msg, e.Get()); AssertLabels({{"my_label", "label_value"}, {"path", "/Nested/Nested/Foo"}, {"name", "my_name"}}, samples.GetSamples(0)); } Y_UNIT_TEST(SpacesAreGetReplaced) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); simple.SetLabel("my label_value"); TNestedWithKeys msg; msg.AddNamespace()->CopyFrom(simple); DecodeLegacyProto(msg, e.Get()); for (const auto& s : samples.GetSamples()) { UNIT_ASSERT_EQUAL(s.LabelsSize(), 4); bool foundLabel = false; for (const auto& label : s.GetLabels()) { if (label.GetName() == "my_label") { foundLabel = true; UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "my_label_value"); } } UNIT_ASSERT(foundLabel); } } Y_UNIT_TEST(ExtraLabels) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); TExtraLabels msg; msg.MutableExtraAsIs()->CopyFrom(MakeExtra("label", "foo", 42, false)); msg.MutableExtraDeriv()->CopyFrom(MakeExtra("deriv_label", "deriv_foo", 43, true)); DecodeLegacyProto(msg, e.Get()); UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2); { auto s = samples.GetSamples(0); AssertLabels({{"label", "foo"}, {"path", "/ExtraAsIs"}}, s); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); auto point = s.GetPoints(0); UNIT_ASSERT_DOUBLES_EQUAL(point.GetFloat64(), 42, 1e-6); } { auto s = samples.GetSamples(1); AssertLabels({{"deriv_label", "deriv_foo"}, {"path", "/ExtraDeriv"}}, s); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); auto point = s.GetPoints(0); UNIT_ASSERT_EQUAL(point.GetUint64(), 43); } } Y_UNIT_TEST(NestedExtraLabels) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); TExtraLabels msg; auto extra = MakeExtra("label", "foo", 42, false); auto* val = extra.Mutablevalues(0); { auto child = MakeExtra("child1", "label1", 24, true); child.Mutablevalues(0)->Settype(NMonProto::EMetricType::RATE); val->Addchildren()->CopyFrom(child); } { auto child = MakeExtra("child2", 34, 23, false); val->Addchildren()->CopyFrom(child); } msg.MutableExtraAsIs()->CopyFrom(extra); DecodeLegacyProto(msg, e.Get()); UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); { auto s = samples.GetSamples(0); AssertLabels({{"label", "foo"}, {"path", "/ExtraAsIs"}}, s); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); auto point = s.GetPoints(0); UNIT_ASSERT_DOUBLES_EQUAL(point.GetFloat64(), 42, 1e-6); } { auto s = samples.GetSamples(1); AssertLabels({{"label", "foo"}, {"child1", "label1"}, {"path", "/ExtraAsIs"}}, s); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); auto point = s.GetPoints(0); UNIT_ASSERT_EQUAL(point.GetUint64(), 24); } { auto s = samples.GetSamples(2); AssertLabels({{"label", "foo"}, {"child2", "34"}, {"path", "/ExtraAsIs"}}, s); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); auto point = s.GetPoints(0); UNIT_ASSERT_EQUAL(point.GetFloat64(), 23); } } Y_UNIT_TEST(RobotLabels) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); TNamedCounter responses; responses.SetName("responses"); responses.SetCount(42); TCrawlerCounters::TStatusCounters statusCounters; statusCounters.AddZoraResponses()->CopyFrom(responses); TCrawlerCounters::TPolicyCounters policyCounters; policyCounters.SetSubComponent("mySubComponent"); policyCounters.SetName("myComponentName"); policyCounters.SetZone("myComponentZone"); policyCounters.MutableStatusCounters()->CopyFrom(statusCounters); TCrawlerCounters counters; counters.SetComponent("myComponent"); counters.AddPoliciesCounters()->CopyFrom(policyCounters); DecodeLegacyProto(counters, e.Get()); UNIT_ASSERT_EQUAL(samples.SamplesSize(), 1); auto s = samples.GetSamples(0); AssertLabels({ {"SubComponent", "mySubComponent"}, {"Policy", "myComponentName"}, {"Zone", "myComponentZone"}, {"ZoraResponse", "responses"}, {"path", "/PoliciesCounters/StatusCounters/ZoraResponses/Count"}}, s); } Y_UNIT_TEST(ZoraLabels) { NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); TTimeLogHist hist; hist.AddBuckets(42); hist.AddBuckets(0); TKiwiCounters counters; counters.MutableTimes()->CopyFrom(hist); DecodeLegacyProto(counters, e.Get()); UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2); auto s = samples.GetSamples(0); AssertLabels({{"slot", "0"}, {"path", "/Times/Buckets"}}, s); UNIT_ASSERT_EQUAL(s.PointsSize(), 1); UNIT_ASSERT_EQUAL(s.GetPoints(0).GetUint64(), 42); s = samples.GetSamples(1); AssertLabels({{"slot", "1"}, {"path", "/Times/Buckets"}}, s); UNIT_ASSERT_EQUAL(s.GetPoints(0).GetUint64(), 0); } }