unistat_ut.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. #include "unistat.h"
  2. #include <library/cpp/monlib/encode/protobuf/protobuf.h>
  3. #include <library/cpp/monlib/metrics/labels.h>
  4. #include <library/cpp/testing/unittest/registar.h>
  5. using namespace NMonitoring;
  6. Y_UNIT_TEST_SUITE(TUnistatDecoderTest) {
  7. Y_UNIT_TEST(MetricNameLabel) {
  8. constexpr auto input = TStringBuf(R"([["something_axxx", 42]])");
  9. NProto::TMultiSamplesList samples;
  10. auto encoder = EncoderProtobuf(&samples);
  11. DecodeUnistat(input, encoder.Get(), "metric_name_label");
  12. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1);
  13. auto sample = samples.GetSamples(0);
  14. auto label = sample.GetLabels(0);
  15. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "metric_name_label");
  16. }
  17. Y_UNIT_TEST(ScalarMetric) {
  18. constexpr auto input = TStringBuf(R"([["something_axxx", 42]])");
  19. NProto::TMultiSamplesList samples;
  20. auto encoder = EncoderProtobuf(&samples);
  21. DecodeUnistat(input, encoder.Get());
  22. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1);
  23. auto sample = samples.GetSamples(0);
  24. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE);
  25. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  26. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  27. auto label = sample.GetLabels(0);
  28. auto point = sample.GetPoints(0);
  29. UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.);
  30. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor");
  31. UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx");
  32. }
  33. Y_UNIT_TEST(OverriddenTags) {
  34. constexpr auto input = TStringBuf(R"([["ctype=foo;prj=bar;custom_tag=qwe;something_axxx", 42]])");
  35. NProto::TMultiSamplesList samples;
  36. auto encoder = EncoderProtobuf(&samples);
  37. DecodeUnistat(input, encoder.Get());
  38. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1);
  39. auto sample = samples.GetSamples(0);
  40. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  41. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 4);
  42. const auto& labels = sample.GetLabels();
  43. TLabels actual;
  44. for (auto&& l : labels) {
  45. actual.Add(l.GetName(), l.GetValue());
  46. }
  47. TLabels expected{{"ctype", "foo"}, {"prj", "bar"}, {"custom_tag", "qwe"}, {"sensor", "something_axxx"}};
  48. UNIT_ASSERT_VALUES_EQUAL(actual.size(), expected.size());
  49. for (auto&& l : actual) {
  50. UNIT_ASSERT(expected.Extract(l.Name())->Value() == l.Value());
  51. }
  52. }
  53. Y_UNIT_TEST(ThrowsOnTopLevelObject) {
  54. constexpr auto input = TStringBuf(R"({["something_axxx", 42]})");
  55. NProto::TMultiSamplesList samples;
  56. auto encoder = EncoderProtobuf(&samples);
  57. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  58. }
  59. Y_UNIT_TEST(ThrowsOnUnwrappedMetric) {
  60. constexpr auto input = TStringBuf(R"(["something_axxx", 42])");
  61. NProto::TMultiSamplesList samples;
  62. auto encoder = EncoderProtobuf(&samples);
  63. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  64. }
  65. Y_UNIT_TEST(HistogramMetric) {
  66. constexpr auto input = TStringBuf(R"([["something_hgram", [[0, 1], [200, 2], [500, 3]] ]])");
  67. NProto::TMultiSamplesList samples;
  68. auto encoder = EncoderProtobuf(&samples);
  69. DecodeUnistat(input, encoder.Get());
  70. auto sample = samples.GetSamples(0);
  71. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HIST_RATE);
  72. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  73. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  74. auto label = sample.GetLabels(0);
  75. const auto point = sample.GetPoints(0);
  76. const auto histogram = point.GetHistogram();
  77. const auto size = histogram.BoundsSize();
  78. UNIT_ASSERT_VALUES_EQUAL(size, 4);
  79. const TVector<double> expectedBounds {0, 200, 500, std::numeric_limits<double>::max()};
  80. const TVector<ui64> expectedValues {0, 1, 2, 3};
  81. for (auto i = 0; i < 4; ++i) {
  82. UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]);
  83. UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]);
  84. }
  85. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor");
  86. UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_hgram");
  87. }
  88. Y_UNIT_TEST(AbsoluteHistogram) {
  89. constexpr auto input = TStringBuf(R"([["something_ahhh", [[0, 1], [200, 2], [500, 3]] ]])");
  90. NProto::TMultiSamplesList samples;
  91. auto encoder = EncoderProtobuf(&samples);
  92. DecodeUnistat(input, encoder.Get());
  93. auto sample = samples.GetSamples(0);
  94. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM);
  95. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  96. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  97. }
  98. Y_UNIT_TEST(LogHistogram) {
  99. constexpr auto input = TStringBuf(R"([["something_ahhh", [1, 2, 3] ]])");
  100. NProto::TMultiSamplesList samples;
  101. auto encoder = EncoderProtobuf(&samples);
  102. DecodeUnistat(input, encoder.Get());
  103. auto sample = samples.GetSamples(0);
  104. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM);
  105. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  106. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  107. auto histogram = sample.GetPoints(0).GetHistogram();
  108. UNIT_ASSERT_VALUES_EQUAL(histogram.BoundsSize(), 4);
  109. TVector<double> expectedBounds = {1, 2, 4, std::numeric_limits<double>::max()};
  110. TVector<ui64> expectedValues = {1, 1, 1, 0};
  111. for (auto i = 0; i < 4; ++i) {
  112. UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]);
  113. UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]);
  114. }
  115. }
  116. Y_UNIT_TEST(LogHistogramOverflow) {
  117. constexpr auto input = TStringBuf(R"([["something_ahhh", [1125899906842624, 2251799813685248] ]])");
  118. NProto::TMultiSamplesList samples;
  119. auto encoder = EncoderProtobuf(&samples);
  120. DecodeUnistat(input, encoder.Get());
  121. auto sample = samples.GetSamples(0);
  122. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM);
  123. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  124. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  125. auto histogram = sample.GetPoints(0).GetHistogram();
  126. UNIT_ASSERT_VALUES_EQUAL(histogram.BoundsSize(), HISTOGRAM_MAX_BUCKETS_COUNT);
  127. TVector<double> expectedBounds;
  128. for (ui64 i = 0; i < 50; ++i) {
  129. expectedBounds.push_back(std::pow(2, i));
  130. }
  131. expectedBounds.push_back(std::numeric_limits<double>::max());
  132. TVector<ui64> expectedValues;
  133. for (ui64 i = 0; i < 50; ++i) {
  134. expectedValues.push_back(0);
  135. }
  136. expectedValues.push_back(2);
  137. for (auto i = 0; i < 4; ++i) {
  138. UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]);
  139. UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]);
  140. }
  141. }
  142. Y_UNIT_TEST(LogHistogramSingle) {
  143. constexpr auto input = TStringBuf(R"([["something_ahhh", 4 ]])");
  144. NProto::TMultiSamplesList samples;
  145. auto encoder = EncoderProtobuf(&samples);
  146. DecodeUnistat(input, encoder.Get());
  147. auto sample = samples.GetSamples(0);
  148. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM);
  149. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  150. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  151. auto histogram = sample.GetPoints(0).GetHistogram();
  152. UNIT_ASSERT_VALUES_EQUAL(histogram.BoundsSize(), 4);
  153. TVector<double> expectedBounds = {1, 2, 4, std::numeric_limits<double>::max()};
  154. TVector<ui64> expectedValues = {0, 0, 1, 0};
  155. for (auto i = 0; i < 4; ++i) {
  156. UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]);
  157. UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]);
  158. }
  159. }
  160. Y_UNIT_TEST(LogHistogramInvalid) {
  161. NProto::TMultiSamplesList samples;
  162. auto encoder = EncoderProtobuf(&samples);
  163. {
  164. constexpr auto input = TStringBuf(R"([["something_ahhh", [1, 2, [3, 4]] ]])");
  165. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  166. }
  167. {
  168. constexpr auto input = TStringBuf(R"([["something_ahhh", [[3, 4], 1, 2] ]])");
  169. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  170. }
  171. {
  172. constexpr auto input = TStringBuf(R"([["something_hgram", 1, 2, 3, 4 ]])");
  173. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  174. }
  175. }
  176. Y_UNIT_TEST(AllowedMetricNames) {
  177. NProto::TMultiSamplesList samples;
  178. auto encoder = EncoderProtobuf(&samples);
  179. {
  180. constexpr auto input = TStringBuf(R"([["a/A-b/c_D/__G_dmmm", [[0, 1], [200, 2], [500, 3]] ]])");
  181. UNIT_ASSERT_NO_EXCEPTION(DecodeUnistat(input, encoder.Get()));
  182. }
  183. }
  184. Y_UNIT_TEST(DisallowedMetricNames) {
  185. NProto::TMultiSamplesList samples;
  186. auto encoder = EncoderProtobuf(&samples);
  187. {
  188. constexpr auto input = TStringBuf(R"([["someth!ng_ahhh", [[0, 1], [200, 2], [500, 3]] ]])");
  189. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  190. }
  191. {
  192. constexpr auto input = TStringBuf(R"([["foo_a", [[0, 1], [200, 2], [500, 3]] ]])");
  193. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  194. }
  195. {
  196. constexpr auto input = TStringBuf(R"([["foo_ahhh;tag=value", [[0, 1], [200, 2], [500, 3]] ]])");
  197. UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception);
  198. }
  199. }
  200. Y_UNIT_TEST(MultipleMetrics) {
  201. constexpr auto input = TStringBuf(R"([["something_axxx", 42], ["some-other_dhhh", 53]])");
  202. NProto::TMultiSamplesList samples;
  203. auto encoder = EncoderProtobuf(&samples);
  204. DecodeUnistat(input, encoder.Get());
  205. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 2);
  206. auto sample = samples.GetSamples(0);
  207. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE);
  208. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  209. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  210. auto label = sample.GetLabels(0);
  211. auto point = sample.GetPoints(0);
  212. UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.);
  213. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor");
  214. UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx");
  215. sample = samples.GetSamples(1);
  216. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE);
  217. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  218. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  219. label = sample.GetLabels(0);
  220. point = sample.GetPoints(0);
  221. UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 53);
  222. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor");
  223. UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "some-other_dhhh");
  224. }
  225. Y_UNIT_TEST(UnderscoreName) {
  226. constexpr auto input = TStringBuf(R"([["something_anything_dmmm", 42]])");
  227. NProto::TMultiSamplesList samples;
  228. auto encoder = EncoderProtobuf(&samples);
  229. DecodeUnistat(input, encoder.Get());
  230. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1);
  231. auto sample = samples.GetSamples(0);
  232. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE);
  233. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  234. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  235. auto label = sample.GetLabels(0);
  236. auto point = sample.GetPoints(0);
  237. UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 42);
  238. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor");
  239. UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_dmmm");
  240. }
  241. Y_UNIT_TEST(MaxAggr) {
  242. constexpr auto input = TStringBuf(R"([["something_anything_max", 42]])");
  243. NProto::TMultiSamplesList samples;
  244. auto encoder = EncoderProtobuf(&samples);
  245. DecodeUnistat(input, encoder.Get());
  246. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1);
  247. auto sample = samples.GetSamples(0);
  248. UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE);
  249. UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1);
  250. UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1);
  251. auto label = sample.GetLabels(0);
  252. auto point = sample.GetPoints(0);
  253. UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.);
  254. UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor");
  255. UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_max");
  256. }
  257. }