diff options
Diffstat (limited to 'library/cpp/monlib/encode/json')
-rw-r--r-- | library/cpp/monlib/encode/json/fuzz/main.cpp | 28 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/fuzz/ya.make | 20 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/json.h | 4 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/json_decoder.cpp | 2 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/json_encoder.cpp | 222 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/json_ut.cpp | 566 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/ut/buffered_test.json | 72 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/ut/buffered_ts_merge.json | 24 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/ut/empty_series.json | 24 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/ut/merged.json | 26 | ||||
-rw-r--r-- | library/cpp/monlib/encode/json/ut/ya.make | 10 |
11 files changed, 499 insertions, 499 deletions
diff --git a/library/cpp/monlib/encode/json/fuzz/main.cpp b/library/cpp/monlib/encode/json/fuzz/main.cpp index b85a973a1b..4f40310e06 100644 --- a/library/cpp/monlib/encode/json/fuzz/main.cpp +++ b/library/cpp/monlib/encode/json/fuzz/main.cpp @@ -1,16 +1,16 @@ #include <library/cpp/monlib/encode/json/json.h> #include <library/cpp/monlib/encode/fake/fake.h> - -#include <util/generic/strbuf.h> - - -extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) { - auto encoder = NMonitoring::EncoderFake(); - - try { - NMonitoring::DecodeJson({reinterpret_cast<const char*>(data), size}, encoder.Get()); - } catch (...) { - } - - return 0; -} + +#include <util/generic/strbuf.h> + + +extern "C" int LLVMFuzzerTestOneInput(const ui8* data, size_t size) { + auto encoder = NMonitoring::EncoderFake(); + + try { + NMonitoring::DecodeJson({reinterpret_cast<const char*>(data), size}, encoder.Get()); + } catch (...) { + } + + return 0; +} diff --git a/library/cpp/monlib/encode/json/fuzz/ya.make b/library/cpp/monlib/encode/json/fuzz/ya.make index 85a12a37f0..75baa77716 100644 --- a/library/cpp/monlib/encode/json/fuzz/ya.make +++ b/library/cpp/monlib/encode/json/fuzz/ya.make @@ -1,19 +1,19 @@ -FUZZ() - +FUZZ() + OWNER( g:solomon msherbakov ) - -PEERDIR( + +PEERDIR( library/cpp/monlib/encode/json library/cpp/monlib/encode/fake -) - -SIZE(MEDIUM) - +) + +SIZE(MEDIUM) + SRCS( main.cpp ) - -END() + +END() diff --git a/library/cpp/monlib/encode/json/json.h b/library/cpp/monlib/encode/json/json.h index 9f4db4a743..21530f20c3 100644 --- a/library/cpp/monlib/encode/json/json.h +++ b/library/cpp/monlib/encode/json/json.h @@ -13,9 +13,9 @@ namespace NMonitoring { IMetricEncoderPtr EncoderJson(IOutputStream* out, int indentation = 0); - /// Buffered encoder will merge series with same labels into one. + /// Buffered encoder will merge series with same labels into one. IMetricEncoderPtr BufferedEncoderJson(IOutputStream* out, int indentation = 0); - + IMetricEncoderPtr EncoderCloudJson(IOutputStream* out, int indentation = 0, TStringBuf metricNameLabel = "name"); diff --git a/library/cpp/monlib/encode/json/json_decoder.cpp b/library/cpp/monlib/encode/json/json_decoder.cpp index 9468ea6447..d44ff5fd28 100644 --- a/library/cpp/monlib/encode/json/json_decoder.cpp +++ b/library/cpp/monlib/encode/json/json_decoder.cpp @@ -879,7 +879,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ State_.ToNext(TState::METRIC_LOG_HIST); } break; - + case TState::METRIC_HIST: if (key == TStringBuf("bounds")) { State_.ToNext(TState::METRIC_HIST_BOUNDS); diff --git a/library/cpp/monlib/encode/json/json_encoder.cpp b/library/cpp/monlib/encode/json/json_encoder.cpp index 95c7b2949f..20d2bb6283 100644 --- a/library/cpp/monlib/encode/json/json_encoder.cpp +++ b/library/cpp/monlib/encode/json/json_encoder.cpp @@ -10,8 +10,8 @@ #include <library/cpp/json/writer/json.h> #include <util/charset/utf8.h> -#include <util/generic/algorithm.h> - +#include <util/generic/algorithm.h> + namespace NMonitoring { namespace { enum class EJsonStyle { @@ -22,7 +22,7 @@ namespace NMonitoring { /////////////////////////////////////////////////////////////////////// // TJsonWriter /////////////////////////////////////////////////////////////////////// - class TJsonWriter { + class TJsonWriter { public: TJsonWriter(IOutputStream* out, int indentation, EJsonStyle style, TStringBuf metricNameLabel) : Buf_(NJsonWriter::HEM_UNSAFE, out) @@ -34,32 +34,32 @@ namespace NMonitoring { Buf_.SetWriteNanAsString(); } - void WriteTime(TInstant time) { - if (time != TInstant::Zero()) { + void WriteTime(TInstant time) { + if (time != TInstant::Zero()) { Buf_.WriteKey(TStringBuf("ts")); if (Style_ == EJsonStyle::Solomon) { Buf_.WriteULongLong(time.Seconds()); } else { Buf_.WriteString(time.ToString()); } - } - } - - void WriteValue(double value) { + } + } + + void WriteValue(double value) { Buf_.WriteKey(TStringBuf("value")); - Buf_.WriteDouble(value); - } - + Buf_.WriteDouble(value); + } + void WriteValue(i64 value) { Buf_.WriteKey(TStringBuf("value")); Buf_.WriteLongLong(value); } - void WriteValue(ui64 value) { + void WriteValue(ui64 value) { Buf_.WriteKey(TStringBuf("value")); - Buf_.WriteULongLong(value); - } - + Buf_.WriteULongLong(value); + } + void WriteValue(IHistogramSnapshot* s) { Y_ENSURE(Style_ == EJsonStyle::Solomon); @@ -143,19 +143,19 @@ namespace NMonitoring { } void WriteValue(EMetricValueType type, TMetricValue value) { - switch (type) { + switch (type) { case EMetricValueType::DOUBLE: WriteValue(value.AsDouble()); - break; - + break; + case EMetricValueType::INT64: WriteValue(value.AsInt64()); break; case EMetricValueType::UINT64: WriteValue(value.AsUint64()); - break; - + break; + case EMetricValueType::HISTOGRAM: WriteValue(value.AsHistogram()); break; @@ -170,20 +170,20 @@ namespace NMonitoring { case EMetricValueType::UNKNOWN: ythrow yexception() << "unknown metric value type"; - } - } - - void WriteLabel(TStringBuf name, TStringBuf value) { - Y_ENSURE(IsUtf(name), "label name is not valid UTF-8 string"); - Y_ENSURE(IsUtf(value), "label value is not valid UTF-8 string"); + } + } + + void WriteLabel(TStringBuf name, TStringBuf value) { + Y_ENSURE(IsUtf(name), "label name is not valid UTF-8 string"); + Y_ENSURE(IsUtf(value), "label value is not valid UTF-8 string"); if (Style_ == EJsonStyle::Cloud && name == MetricNameLabel_) { CurrentMetricName_ = value; } else { Buf_.WriteKey(name); Buf_.WriteString(value); } - } - + } + void WriteMetricType(EMetricType type) { if (Style_ == EJsonStyle::Cloud) { Buf_.WriteKey("type"); @@ -222,23 +222,23 @@ namespace NMonitoring { } } - protected: - NJsonWriter::TBuf Buf_; + protected: + NJsonWriter::TBuf Buf_; EJsonStyle Style_; TString MetricNameLabel_; TString CurrentMetricName_; - }; - + }; + /////////////////////////////////////////////////////////////////////// // TEncoderJson /////////////////////////////////////////////////////////////////////// class TEncoderJson final: public IMetricEncoder, public TJsonWriter { - public: + public: TEncoderJson(IOutputStream* out, int indentation, EJsonStyle style, TStringBuf metricNameLabel) : TJsonWriter{out, indentation, style, metricNameLabel} - { - } - + { + } + ~TEncoderJson() override { Close(); } @@ -308,8 +308,8 @@ namespace NMonitoring { State_.ThrowInvalid("expected METRIC or ROOT"); } Buf_.BeginObject(); - - EmptyLabels_ = true; + + EmptyLabels_ = true; } void OnLabelsEnd() override { @@ -320,8 +320,8 @@ namespace NMonitoring { } else { State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); } - - Y_ENSURE(!EmptyLabels_, "Labels cannot be empty"); + + Y_ENSURE(!EmptyLabels_, "Labels cannot be empty"); Buf_.EndObject(); if (State_ == TEncoderState::EState::METRIC) { WriteName(); @@ -330,12 +330,12 @@ namespace NMonitoring { void OnLabel(TStringBuf name, TStringBuf value) override { if (State_ == TEncoderState::EState::METRIC_LABELS || State_ == TEncoderState::EState::COMMON_LABELS) { - WriteLabel(name, value); + WriteLabel(name, value); } else { State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); } - - EmptyLabels_ = false; + + EmptyLabels_ = false; } void OnDouble(TInstant time, double value) override { @@ -385,7 +385,7 @@ namespace NMonitoring { Buf_.BeginList(); Buf_.BeginObject(); Y_ENSURE(LastPoint_.GetTime() != TInstant::Zero(), - "time cannot be empty or zero in a timeseries point"); + "time cannot be empty or zero in a timeseries point"); WriteTime(LastPoint_.GetTime()); WriteValue(LastPoint_.GetValueType(), LastPoint_.GetValue()); Buf_.EndObject(); @@ -394,8 +394,8 @@ namespace NMonitoring { if (TimeSeries_) { Buf_.BeginObject(); - Y_ENSURE(time != TInstant::Zero(), - "time cannot be empty or zero in a timeseries point"); + Y_ENSURE(time != TInstant::Zero(), + "time cannot be empty or zero in a timeseries point"); WriteTime(time); WriteValue(value); @@ -408,26 +408,26 @@ namespace NMonitoring { LastPoint_ = {}; } - private: - TEncoderState State_; + private: + TEncoderState State_; TTypedPoint LastPoint_; - bool TimeSeries_ = false; - bool EmptyLabels_ = false; - }; - + bool TimeSeries_ = false; + bool EmptyLabels_ = false; + }; + /////////////////////////////////////////////////////////////////////// // TBufferedJsonEncoder /////////////////////////////////////////////////////////////////////// - class TBufferedJsonEncoder : public TBufferedEncoderBase, public TJsonWriter { - public: + class TBufferedJsonEncoder : public TBufferedEncoderBase, public TJsonWriter { + public: TBufferedJsonEncoder(IOutputStream* out, int indentation, EJsonStyle style, TStringBuf metricNameLabel) : TJsonWriter{out, indentation, style, metricNameLabel} - { + { MetricsMergingMode_ = EMetricsMergingMode::MERGE_METRICS; } ~TBufferedJsonEncoder() override { - Close(); + Close(); } void OnLabelsBegin() override { @@ -445,54 +445,54 @@ namespace NMonitoring { EmptyLabels_ = false; } - void OnLabelsEnd() override { - TBufferedEncoderBase::OnLabelsEnd(); + void OnLabelsEnd() override { + TBufferedEncoderBase::OnLabelsEnd(); Y_ENSURE(!EmptyLabels_, "Labels cannot be empty"); - } - + } + void Close() final { - if (Closed_) { - return; - } - - Closed_ = true; + if (Closed_) { + return; + } - LabelValuesPool_.Build(); - LabelNamesPool_.Build(); + Closed_ = true; - Buf_.BeginObject(); + LabelValuesPool_.Build(); + LabelNamesPool_.Build(); + + Buf_.BeginObject(); - WriteTime(CommonTime_); - if (CommonLabels_.size() > 0) { + WriteTime(CommonTime_); + if (CommonLabels_.size() > 0) { Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "commonLabels": "labels")); WriteLabels(CommonLabels_, true); } - + if (Metrics_.size() > 0) { Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "sensors" : "metrics")); WriteMetrics(); - } - - Buf_.EndObject(); + } + + Buf_.EndObject(); } private: void WriteMetrics() { - Buf_.BeginList(); + Buf_.BeginList(); for (auto&& metric : Metrics_) { WriteMetric(metric); - } - Buf_.EndList(); - } - + } + Buf_.EndList(); + } + void WriteMetric(TMetric& metric) { - Buf_.BeginObject(); - + Buf_.BeginObject(); + WriteMetricType(metric.MetricType); - + Buf_.WriteKey(TStringBuf("labels")); WriteLabels(metric.Labels, false); - + metric.TimeSeries.SortByTs(); if (metric.TimeSeries.Size() == 1) { const auto& point = metric.TimeSeries[0]; @@ -500,40 +500,40 @@ namespace NMonitoring { WriteValue(metric.TimeSeries.GetValueType(), point.GetValue()); } else if (metric.TimeSeries.Size() > 1) { Buf_.WriteKey(TStringBuf("timeseries")); - Buf_.BeginList(); + Buf_.BeginList(); metric.TimeSeries.ForEach([this](TInstant time, EMetricValueType type, TMetricValue value) { - Buf_.BeginObject(); - // make gcc 6.1 happy https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 + Buf_.BeginObject(); + // make gcc 6.1 happy https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 this->WriteTime(time); this->WriteValue(type, value); - Buf_.EndObject(); - }); - - Buf_.EndList(); - } - - Buf_.EndObject(); - } - + Buf_.EndObject(); + }); + + Buf_.EndList(); + } + + Buf_.EndObject(); + } + void WriteLabels(const TPooledLabels& labels, bool isCommon) { - Buf_.BeginObject(); - - for (auto i = 0u; i < labels.size(); ++i) { - TStringBuf name = LabelNamesPool_.Get(labels[i].Key->Index); - TStringBuf value = LabelValuesPool_.Get(labels[i].Value->Index); - - WriteLabel(name, value); - } - - Buf_.EndObject(); + Buf_.BeginObject(); + + for (auto i = 0u; i < labels.size(); ++i) { + TStringBuf name = LabelNamesPool_.Get(labels[i].Key->Index); + TStringBuf value = LabelValuesPool_.Get(labels[i].Value->Index); + + WriteLabel(name, value); + } + + Buf_.EndObject(); if (!isCommon) { WriteName(); } - } - - private: - bool Closed_{false}; + } + + private: + bool Closed_{false}; bool EmptyLabels_ = false; }; } @@ -544,7 +544,7 @@ namespace NMonitoring { IMetricEncoderPtr BufferedEncoderJson(IOutputStream* out, int indentation) { return MakeHolder<TBufferedJsonEncoder>(out, indentation, EJsonStyle::Solomon, ""); - } + } IMetricEncoderPtr EncoderCloudJson(IOutputStream* out, int indentation, TStringBuf metricNameLabel) { return MakeHolder<TEncoderJson>(out, indentation, EJsonStyle::Cloud, metricNameLabel); diff --git a/library/cpp/monlib/encode/json/json_ut.cpp b/library/cpp/monlib/encode/json/json_ut.cpp index b3c3b879d4..09e7909289 100644 --- a/library/cpp/monlib/encode/json/json_ut.cpp +++ b/library/cpp/monlib/encode/json/json_ut.cpp @@ -14,93 +14,93 @@ using namespace NMonitoring; -namespace NMonitoring { - bool operator<(const TLabel& lhs, const TLabel& rhs) { - return lhs.Name() < rhs.Name() || - (lhs.Name() == rhs.Name() && lhs.Value() < rhs.Value()); - } -} -namespace { - void AssertLabels(const NProto::TMultiSample& actual, const TLabels& expected) { - UNIT_ASSERT_EQUAL(actual.LabelsSize(), expected.Size()); - - TSet<TLabel> actualSet; - TSet<TLabel> 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<TLabel> 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 AssertLabelEqual(const NProto::TLabel& l, TStringBuf name, TStringBuf value) { - UNIT_ASSERT_STRINGS_EQUAL(l.GetName(), name); - UNIT_ASSERT_STRINGS_EQUAL(l.GetValue(), value); - } - - void AssertPointEqual(const NProto::TPoint& p, TInstant time, double value) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); - UNIT_ASSERT_DOUBLES_EQUAL(p.GetFloat64(), value, std::numeric_limits<double>::epsilon()); - } - - void AssertPointEqualNan(const NProto::TPoint& p, TInstant time) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); - UNIT_ASSERT(std::isnan(p.GetFloat64())); - } - - void AssertPointEqualInf(const NProto::TPoint& p, TInstant time, int sign) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); - UNIT_ASSERT(std::isinf(p.GetFloat64())); - if (sign < 0) { - UNIT_ASSERT(p.GetFloat64() < 0); - } - } - - void AssertPointEqual(const NProto::TPoint& p, TInstant time, ui64 value) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kUint64); - UNIT_ASSERT_VALUES_EQUAL(p.GetUint64(), value); - } - - void AssertPointEqual(const NProto::TPoint& p, TInstant time, i64 value) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kInt64); - UNIT_ASSERT_VALUES_EQUAL(p.GetInt64(), value); - } - - void AssertPointEqual(const NProto::TPoint& p, TInstant time, const IHistogramSnapshot& expected) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kHistogram); - - const NProto::THistogram& h = p.GetHistogram(); - UNIT_ASSERT_VALUES_EQUAL(h.BoundsSize(), expected.Count()); - UNIT_ASSERT_VALUES_EQUAL(h.ValuesSize(), expected.Count()); - - for (size_t i = 0; i < h.BoundsSize(); i++) { - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(i), expected.UpperBound(i), Min<double>()); - UNIT_ASSERT_VALUES_EQUAL(h.GetValues(i), expected.Value(i)); - } - } - +namespace NMonitoring { + bool operator<(const TLabel& lhs, const TLabel& rhs) { + return lhs.Name() < rhs.Name() || + (lhs.Name() == rhs.Name() && lhs.Value() < rhs.Value()); + } +} +namespace { + void AssertLabels(const NProto::TMultiSample& actual, const TLabels& expected) { + UNIT_ASSERT_EQUAL(actual.LabelsSize(), expected.Size()); + + TSet<TLabel> actualSet; + TSet<TLabel> 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<TLabel> 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 AssertLabelEqual(const NProto::TLabel& l, TStringBuf name, TStringBuf value) { + UNIT_ASSERT_STRINGS_EQUAL(l.GetName(), name); + UNIT_ASSERT_STRINGS_EQUAL(l.GetValue(), value); + } + + void AssertPointEqual(const NProto::TPoint& p, TInstant time, double value) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); + UNIT_ASSERT_DOUBLES_EQUAL(p.GetFloat64(), value, std::numeric_limits<double>::epsilon()); + } + + void AssertPointEqualNan(const NProto::TPoint& p, TInstant time) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); + UNIT_ASSERT(std::isnan(p.GetFloat64())); + } + + void AssertPointEqualInf(const NProto::TPoint& p, TInstant time, int sign) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); + UNIT_ASSERT(std::isinf(p.GetFloat64())); + if (sign < 0) { + UNIT_ASSERT(p.GetFloat64() < 0); + } + } + + void AssertPointEqual(const NProto::TPoint& p, TInstant time, ui64 value) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kUint64); + UNIT_ASSERT_VALUES_EQUAL(p.GetUint64(), value); + } + + void AssertPointEqual(const NProto::TPoint& p, TInstant time, i64 value) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kInt64); + UNIT_ASSERT_VALUES_EQUAL(p.GetInt64(), value); + } + + void AssertPointEqual(const NProto::TPoint& p, TInstant time, const IHistogramSnapshot& expected) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kHistogram); + + const NProto::THistogram& h = p.GetHistogram(); + UNIT_ASSERT_VALUES_EQUAL(h.BoundsSize(), expected.Count()); + UNIT_ASSERT_VALUES_EQUAL(h.ValuesSize(), expected.Count()); + + for (size_t i = 0; i < h.BoundsSize(); i++) { + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(i), expected.UpperBound(i), Min<double>()); + UNIT_ASSERT_VALUES_EQUAL(h.GetValues(i), expected.Value(i)); + } + } + void AssertPointEqual(const NProto::TPoint& p, TInstant time, const TLogHistogramSnapshot& expected) { UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kLogHistogram); @@ -129,9 +129,9 @@ namespace { UNIT_ASSERT_VALUES_EQUAL(actual.GetCount(), expected.GetCount()); } -} // namespace - - +} // namespace + + Y_UNIT_TEST_SUITE(TJsonTest) { const TInstant now = TInstant::ParseIso8601Deprecated("2017-11-05T01:02:03Z"); @@ -304,53 +304,53 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } Y_UNIT_TEST(MetricsWithDifferentLabelOrderGetMerged) { - TString json; - TStringOutput out(json); - auto e = BufferedEncoderJson(&out, 2); + TString json; + TStringOutput out(json); + auto e = BufferedEncoderJson(&out, 2); - e->OnStreamBegin(); - { + e->OnStreamBegin(); + { e->OnMetricBegin(EMetricType::RATE); - { - e->OnLabelsBegin(); + { + e->OnLabelsBegin(); e->OnLabel("metric", "hello"); - e->OnLabel("label", "world"); - e->OnLabelsEnd(); - } - e->OnUint64(TInstant::Zero(), 0); + e->OnLabel("label", "world"); + e->OnLabelsEnd(); + } + e->OnUint64(TInstant::Zero(), 0); e->OnMetricEnd(); } - { + { e->OnMetricBegin(EMetricType::RATE); - { - e->OnLabelsBegin(); - e->OnLabel("label", "world"); + { + e->OnLabelsBegin(); + e->OnLabel("label", "world"); e->OnLabel("metric", "hello"); - e->OnLabelsEnd(); - } - e->OnUint64(TInstant::Zero(), 1); + e->OnLabelsEnd(); + } + e->OnUint64(TInstant::Zero(), 1); e->OnMetricEnd(); - } - e->OnStreamEnd(); - e->Close(); - json += "\n"; + } + e->OnStreamEnd(); + e->Close(); + json += "\n"; - TString expectedJson = NResource::Find("/merged.json"); - // we cannot be sure regarding the label order in the result, - // so we'll have to parse the expected value and then compare it with actual + TString expectedJson = NResource::Find("/merged.json"); + // we cannot be sure regarding the label order in the result, + // so we'll have to parse the expected value and then compare it with actual - NProto::TMultiSamplesList samples; + NProto::TMultiSamplesList samples; IMetricEncoderPtr d = EncoderProtobuf(&samples); - DecodeJson(expectedJson, d.Get()); + DecodeJson(expectedJson, d.Get()); - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); - { - const NProto::TMultiSample& s = samples.GetSamples(0); + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); + { + const NProto::TMultiSample& s = samples.GetSamples(0); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); AssertLabels(s, TLabels{{"metric", "hello"}, {"label", "world"}}); - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); } } Y_UNIT_TEST(Decode1) { @@ -453,7 +453,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { AssertLabelEqual(samples.GetCommonLabels(1), "cluster", "man"); AssertLabelEqual(samples.GetCommonLabels(2), "service", "stockpile"); - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 4); + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 4); { const NProto::TMultiSample& s = samples.GetSamples(0); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); @@ -484,7 +484,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { AssertPointEqual(s.GetPoints(0), ts, 3.14159); } { - const NProto::TMultiSample& s = samples.GetSamples(3); + const NProto::TMultiSample& s = samples.GetSamples(3); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "metric", "Writes"); @@ -558,7 +558,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { AssertPointEqual(s.GetPoints(1), ts2, 20.0); } } - + Y_UNIT_TEST(DecodeToEncoder) { auto testJson = NResource::Find("/test_decode_to_encode.json"); @@ -575,154 +575,154 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } void WriteEmptySeries(const IMetricEncoderPtr& e) { - e->OnStreamBegin(); - { + e->OnStreamBegin(); + { e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("foo", "bar"); - e->OnLabelsEnd(); - } + { + e->OnLabelsBegin(); + e->OnLabel("foo", "bar"); + e->OnLabelsEnd(); + } e->OnMetricEnd(); - } - - e->OnStreamEnd(); - e->Close(); - } - - Y_UNIT_TEST(EncodeEmptySeries) { - TString json; - TStringOutput out(json); - - auto e = EncoderJson(&out, 2); - WriteEmptySeries(e); - json += "\n"; - - TString expectedJson = NResource::Find("/empty_series.json"); - UNIT_ASSERT_NO_DIFF(json, expectedJson); - } - + } + + e->OnStreamEnd(); + e->Close(); + } + + Y_UNIT_TEST(EncodeEmptySeries) { + TString json; + TStringOutput out(json); + + auto e = EncoderJson(&out, 2); + WriteEmptySeries(e); + json += "\n"; + + TString expectedJson = NResource::Find("/empty_series.json"); + UNIT_ASSERT_NO_DIFF(json, expectedJson); + } + void WriteEmptyLabels(IMetricEncoderPtr& e) { - e->OnStreamBegin(); + e->OnStreamBegin(); e->OnMetricBegin(EMetricType::COUNTER); - - e->OnLabelsBegin(); - UNIT_ASSERT_EXCEPTION(e->OnLabelsEnd(), yexception); - } - - Y_UNIT_TEST(LabelsCannotBeEmpty) { - TString json; - TStringOutput out(json); - - auto e = EncoderJson(&out, 2); - WriteEmptyLabels(e); - } - - Y_UNIT_TEST(LabelsCannotBeEmptyBuffered) { - TString json; - TStringOutput out(json); - - auto e = BufferedEncoderJson(&out, 2); - WriteEmptyLabels(e); - } - - Y_UNIT_TEST(EncodeEmptySeriesBuffered) { - TString json; - TStringOutput out(json); - - auto e = BufferedEncoderJson(&out, 2); - WriteEmptySeries(e); - json += "\n"; - - TString expectedJson = NResource::Find("/empty_series.json"); - UNIT_ASSERT_NO_DIFF(json, expectedJson); - } - + + e->OnLabelsBegin(); + UNIT_ASSERT_EXCEPTION(e->OnLabelsEnd(), yexception); + } + + Y_UNIT_TEST(LabelsCannotBeEmpty) { + TString json; + TStringOutput out(json); + + auto e = EncoderJson(&out, 2); + WriteEmptyLabels(e); + } + + Y_UNIT_TEST(LabelsCannotBeEmptyBuffered) { + TString json; + TStringOutput out(json); + + auto e = BufferedEncoderJson(&out, 2); + WriteEmptyLabels(e); + } + + Y_UNIT_TEST(EncodeEmptySeriesBuffered) { + TString json; + TStringOutput out(json); + + auto e = BufferedEncoderJson(&out, 2); + WriteEmptySeries(e); + json += "\n"; + + TString expectedJson = NResource::Find("/empty_series.json"); + UNIT_ASSERT_NO_DIFF(json, expectedJson); + } + Y_UNIT_TEST(BufferedEncoderMergesMetrics) { - TString json; - TStringOutput out(json); - - auto e = BufferedEncoderJson(&out, 2); - auto ts = 1; - + TString json; + TStringOutput out(json); + + auto e = BufferedEncoderJson(&out, 2); + auto ts = 1; + auto writeMetric = [&] (const TString& val) { e->OnMetricBegin(EMetricType::COUNTER); - - e->OnLabelsBegin(); - e->OnLabel("foo", val); - e->OnLabelsEnd(); - e->OnUint64(TInstant::Seconds(ts++), 42); - + + e->OnLabelsBegin(); + e->OnLabel("foo", val); + e->OnLabelsEnd(); + e->OnUint64(TInstant::Seconds(ts++), 42); + e->OnMetricEnd(); - }; - - e->OnStreamBegin(); + }; + + e->OnStreamBegin(); writeMetric("bar"); writeMetric("bar"); writeMetric("baz"); writeMetric("bar"); - e->OnStreamEnd(); - e->Close(); - - json += "\n"; - - TString expectedJson = NResource::Find("/buffered_test.json"); - UNIT_ASSERT_NO_DIFF(json, expectedJson); - } - - Y_UNIT_TEST(JsonEncoderDisallowsValuesInTimeseriesWithoutTs) { - TStringStream out; - - auto e = EncoderJson(&out); - auto writePreamble = [&] { - e->OnStreamBegin(); + e->OnStreamEnd(); + e->Close(); + + json += "\n"; + + TString expectedJson = NResource::Find("/buffered_test.json"); + UNIT_ASSERT_NO_DIFF(json, expectedJson); + } + + Y_UNIT_TEST(JsonEncoderDisallowsValuesInTimeseriesWithoutTs) { + TStringStream out; + + auto e = EncoderJson(&out); + auto writePreamble = [&] { + e->OnStreamBegin(); e->OnMetricBegin(EMetricType::COUNTER); - e->OnLabelsBegin(); - e->OnLabel("foo", "bar"); - e->OnLabelsEnd(); - }; - + e->OnLabelsBegin(); + e->OnLabel("foo", "bar"); + e->OnLabelsEnd(); + }; + // writing two values for a metric in a row will trigger - // timeseries object construction - writePreamble(); - e->OnUint64(TInstant::Zero(), 42); - UNIT_ASSERT_EXCEPTION(e->OnUint64(TInstant::Zero(), 42), yexception); - - e = EncoderJson(&out); - writePreamble(); - e->OnUint64(TInstant::Zero(), 42); - UNIT_ASSERT_EXCEPTION(e->OnUint64(TInstant::Now(), 42), yexception); - - e = EncoderJson(&out); - writePreamble(); - e->OnUint64(TInstant::Now(), 42); - UNIT_ASSERT_EXCEPTION(e->OnUint64(TInstant::Zero(), 42), yexception); - } - - Y_UNIT_TEST(BufferedJsonEncoderMergesTimeseriesWithoutTs) { - TStringStream out; - - { - auto e = BufferedEncoderJson(&out, 2); - e->OnStreamBegin(); + // timeseries object construction + writePreamble(); + e->OnUint64(TInstant::Zero(), 42); + UNIT_ASSERT_EXCEPTION(e->OnUint64(TInstant::Zero(), 42), yexception); + + e = EncoderJson(&out); + writePreamble(); + e->OnUint64(TInstant::Zero(), 42); + UNIT_ASSERT_EXCEPTION(e->OnUint64(TInstant::Now(), 42), yexception); + + e = EncoderJson(&out); + writePreamble(); + e->OnUint64(TInstant::Now(), 42); + UNIT_ASSERT_EXCEPTION(e->OnUint64(TInstant::Zero(), 42), yexception); + } + + Y_UNIT_TEST(BufferedJsonEncoderMergesTimeseriesWithoutTs) { + TStringStream out; + + { + auto e = BufferedEncoderJson(&out, 2); + e->OnStreamBegin(); e->OnMetricBegin(EMetricType::COUNTER); - e->OnLabelsBegin(); - e->OnLabel("foo", "bar"); - e->OnLabelsEnd(); - // in buffered mode we are able to find values with same (in this case zero) - // timestamp and discard duplicates - e->OnUint64(TInstant::Zero(), 42); - e->OnUint64(TInstant::Zero(), 43); - e->OnUint64(TInstant::Zero(), 44); - e->OnUint64(TInstant::Zero(), 45); + e->OnLabelsBegin(); + e->OnLabel("foo", "bar"); + e->OnLabelsEnd(); + // in buffered mode we are able to find values with same (in this case zero) + // timestamp and discard duplicates + e->OnUint64(TInstant::Zero(), 42); + e->OnUint64(TInstant::Zero(), 43); + e->OnUint64(TInstant::Zero(), 44); + e->OnUint64(TInstant::Zero(), 45); e->OnMetricEnd(); - e->OnStreamEnd(); - } - - out << "\n"; - UNIT_ASSERT_NO_DIFF(out.Str(), NResource::Find("/buffered_ts_merge.json")); + e->OnStreamEnd(); + } + + out << "\n"; + UNIT_ASSERT_NO_DIFF(out.Str(), NResource::Find("/buffered_ts_merge.json")); } - + template <typename TFactory, typename TConsumer> TString EncodeToString(TFactory factory, TConsumer consumer) { TStringStream out; @@ -732,7 +732,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } out << '\n'; return out.Str(); - } + } Y_UNIT_TEST(SummaryValueEncode) { auto writeDocument = [](IMetricEncoder* e) { @@ -1235,35 +1235,35 @@ Y_UNIT_TEST_SUITE(TJsonTest) { AssertPointEqual(s.GetPoints(2), now + TDuration::Seconds(2), i64(0)); AssertPointEqual(s.GetPoints(3), now + TDuration::Seconds(3), Max<i64>()); } - - Y_UNIT_TEST(FuzzerRegression) { - NProto::TMultiSamplesList samples; - { + + Y_UNIT_TEST(FuzzerRegression) { + NProto::TMultiSamplesList samples; + { IMetricEncoderPtr e = EncoderProtobuf(&samples); - - for (auto f : { "/hist_crash.json", "/crash.json" }) { - TString testJson = NResource::Find(f); - UNIT_ASSERT_EXCEPTION(DecodeJson(testJson, e.Get()), yexception); - } - } - } - - Y_UNIT_TEST(LegacyNegativeRateThrows) { - const auto input = R"({ - "sensors": [ - { - "mode": "deriv", - "value": -1, + + for (auto f : { "/hist_crash.json", "/crash.json" }) { + TString testJson = NResource::Find(f); + UNIT_ASSERT_EXCEPTION(DecodeJson(testJson, e.Get()), yexception); + } + } + } + + Y_UNIT_TEST(LegacyNegativeRateThrows) { + const auto input = R"({ + "sensors": [ + { + "mode": "deriv", + "value": -1, "labels": { "metric": "SystemTime" } - }, - } - ]}")"; - - NProto::TMultiSamplesList samples; + }, + } + ]}")"; + + NProto::TMultiSamplesList samples; IMetricEncoderPtr e = EncoderProtobuf(&samples); - UNIT_ASSERT_EXCEPTION(DecodeJson(input, e.Get()), yexception); - } - + UNIT_ASSERT_EXCEPTION(DecodeJson(input, e.Get()), yexception); + } + Y_UNIT_TEST(DecodeNamedMetrics) { NProto::TMultiSamplesList samples; { diff --git a/library/cpp/monlib/encode/json/ut/buffered_test.json b/library/cpp/monlib/encode/json/ut/buffered_test.json index 580b929de0..53212cf8e1 100644 --- a/library/cpp/monlib/encode/json/ut/buffered_test.json +++ b/library/cpp/monlib/encode/json/ut/buffered_test.json @@ -1,36 +1,36 @@ -{ - "sensors": - [ - { - "kind":"COUNTER", - "labels": - { - "foo":"bar" - }, - "timeseries": - [ - { - "ts":1, - "value":42 - }, - { - "ts":2, - "value":42 - }, - { - "ts":4, - "value":42 - } - ] - }, - { - "kind":"COUNTER", - "labels": - { - "foo":"baz" - }, - "ts":3, - "value":42 - } - ] -} +{ + "sensors": + [ + { + "kind":"COUNTER", + "labels": + { + "foo":"bar" + }, + "timeseries": + [ + { + "ts":1, + "value":42 + }, + { + "ts":2, + "value":42 + }, + { + "ts":4, + "value":42 + } + ] + }, + { + "kind":"COUNTER", + "labels": + { + "foo":"baz" + }, + "ts":3, + "value":42 + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json b/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json index e71c9dd206..1d27efacb0 100644 --- a/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json +++ b/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json @@ -1,13 +1,13 @@ -{ - "sensors": - [ - { - "kind":"COUNTER", - "labels": - { - "foo":"bar" - }, +{ + "sensors": + [ + { + "kind":"COUNTER", + "labels": + { + "foo":"bar" + }, "value":45 - } - ] -} + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/empty_series.json b/library/cpp/monlib/encode/json/ut/empty_series.json index 877c957cab..641e10cdea 100644 --- a/library/cpp/monlib/encode/json/ut/empty_series.json +++ b/library/cpp/monlib/encode/json/ut/empty_series.json @@ -1,12 +1,12 @@ -{ - "sensors": - [ - { - "kind":"COUNTER", - "labels": - { - "foo":"bar" - } - } - ] -} +{ + "sensors": + [ + { + "kind":"COUNTER", + "labels": + { + "foo":"bar" + } + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/merged.json b/library/cpp/monlib/encode/json/ut/merged.json index fe39861f95..ea2c99a33c 100644 --- a/library/cpp/monlib/encode/json/ut/merged.json +++ b/library/cpp/monlib/encode/json/ut/merged.json @@ -1,14 +1,14 @@ -{ - "sensors": - [ - { - "kind":"RATE", - "labels": - { +{ + "sensors": + [ + { + "kind":"RATE", + "labels": + { "metric":"hello", - "label":"world" - }, - "value":1 - } - ] -} + "label":"world" + }, + "value":1 + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/ya.make b/library/cpp/monlib/encode/json/ut/ya.make index 96b4cef0c5..e50c4f4903 100644 --- a/library/cpp/monlib/encode/json/ut/ya.make +++ b/library/cpp/monlib/encode/json/ut/ya.make @@ -11,14 +11,14 @@ SRCS( ) RESOURCE( - buffered_test.json /buffered_test.json - buffered_ts_merge.json /buffered_ts_merge.json + buffered_test.json /buffered_test.json + buffered_ts_merge.json /buffered_ts_merge.json empty_series.json /empty_series.json expected.json /expected.json expected_buffered.json /expected_buffered.json expected_cloud.json /expected_cloud.json expected_cloud_buffered.json /expected_cloud_buffered.json - merged.json /merged.json + merged.json /merged.json histogram_timeseries.json /histogram_timeseries.json histogram_value.json /histogram_value.json histogram_value_inf_before_bounds.json /histogram_value_inf_before_bounds.json @@ -27,8 +27,8 @@ RESOURCE( metrics.json /metrics.json named_metrics.json /named_metrics.json test_decode_to_encode.json /test_decode_to_encode.json - crash.json /crash.json - hist_crash.json /hist_crash.json + crash.json /crash.json + hist_crash.json /hist_crash.json summary_value.json /summary_value.json summary_inf.json /summary_inf.json summary_timeseries.json /summary_timeseries.json |