histogram_snapshot_ut.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "histogram_snapshot.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <random>
  4. using namespace NMonitoring;
  5. Y_UNIT_TEST_SUITE(THistogramSnapshotTest) {
  6. struct Buckets {
  7. TBucketBounds Bounds;
  8. TBucketValues Values;
  9. };
  10. Buckets MakeBuckets(uint32_t nBackets) {
  11. Buckets result;
  12. for (uint32_t i = 0; i < nBackets; ++i) {
  13. result.Bounds.push_back(i + 1);
  14. result.Values.push_back(i + 1);
  15. }
  16. return result;
  17. }
  18. Y_UNIT_TEST(SimpleTest) {
  19. for (uint32_t nBuckets = HISTOGRAM_MAX_BUCKETS_COUNT; nBuckets <= 3 * HISTOGRAM_MAX_BUCKETS_COUNT; ++nBuckets) {
  20. auto buckets = MakeBuckets(nBuckets);
  21. auto snapshot = ExplicitHistogramSnapshot(buckets.Bounds, buckets.Values, true);
  22. UNIT_ASSERT_VALUES_EQUAL(snapshot->Count(), std::min(HISTOGRAM_MAX_BUCKETS_COUNT, nBuckets));
  23. uint64_t sumValues{0};
  24. for (uint32_t i = 0; i < snapshot->Count(); ++i) {
  25. sumValues += snapshot->Value(i);
  26. }
  27. UNIT_ASSERT_VALUES_EQUAL(sumValues, nBuckets * (nBuckets + 1) / 2);
  28. }
  29. auto backets = MakeBuckets(HISTOGRAM_MAX_BUCKETS_COUNT + 10);
  30. UNIT_ASSERT_EXCEPTION(ExplicitHistogramSnapshot(backets.Bounds, backets.Values, false), yexception);
  31. }
  32. Y_UNIT_TEST(InfSimpleTest) {
  33. for (uint32_t nBuckets = 1; nBuckets <= 3 * HISTOGRAM_MAX_BUCKETS_COUNT; ++nBuckets) {
  34. auto buckets = MakeBuckets(nBuckets);
  35. buckets.Bounds.back() = Max<TBucketBound>();
  36. auto snapshot = ExplicitHistogramSnapshot(buckets.Bounds, buckets.Values, true);
  37. auto nBucketsReal = std::min(HISTOGRAM_MAX_BUCKETS_COUNT, nBuckets);
  38. UNIT_ASSERT_VALUES_EQUAL(snapshot->Count(), nBucketsReal);
  39. UNIT_ASSERT_DOUBLES_EQUAL(snapshot->UpperBound(nBucketsReal - 1), Max<TBucketBound>(), 1e-6);
  40. uint64_t sumValues{0};
  41. for (uint32_t i = 0; i < snapshot->Count(); ++i) {
  42. sumValues += snapshot->Value(i);
  43. }
  44. UNIT_ASSERT_VALUES_EQUAL(sumValues, nBuckets * (nBuckets + 1) / 2);
  45. }
  46. }
  47. Y_UNIT_TEST(BacketsTest) {
  48. for (uint32_t nBuckets = HISTOGRAM_MAX_BUCKETS_COUNT; nBuckets <= 3 * HISTOGRAM_MAX_BUCKETS_COUNT; ++nBuckets) {
  49. auto overlap = nBuckets % HISTOGRAM_MAX_BUCKETS_COUNT;
  50. auto divided = nBuckets / HISTOGRAM_MAX_BUCKETS_COUNT;
  51. auto buckets = MakeBuckets(nBuckets);
  52. auto snapshot = ExplicitHistogramSnapshot(buckets.Bounds, buckets.Values, true);
  53. UNIT_ASSERT_DOUBLES_EQUAL(snapshot->UpperBound(HISTOGRAM_MAX_BUCKETS_COUNT - 1), nBuckets, 1e-6);
  54. uint64_t sumBuckets{0};
  55. uint64_t sumSnapshot{0};
  56. size_t idx{0};
  57. for (uint32_t i = 0; i < HISTOGRAM_MAX_BUCKETS_COUNT; ++i) {
  58. sumSnapshot += snapshot->Value(i);
  59. auto delta = (i < HISTOGRAM_MAX_BUCKETS_COUNT - overlap) ? 0ull : (i - (HISTOGRAM_MAX_BUCKETS_COUNT - overlap) + 1);
  60. auto endIdx = divided * (i + 1) + delta;
  61. UNIT_ASSERT_VALUES_EQUAL(snapshot->UpperBound(i), endIdx);
  62. while (idx < endIdx) {
  63. sumBuckets += buckets.Values[idx];
  64. ++idx;
  65. }
  66. UNIT_ASSERT_VALUES_EQUAL(sumBuckets, sumSnapshot);
  67. }
  68. }
  69. }
  70. Y_UNIT_TEST(CompareHistTest) {
  71. uint32_t K = 4;
  72. uint32_t N = K * HISTOGRAM_MAX_BUCKETS_COUNT;
  73. Buckets bucketsBig;
  74. Buckets bucketsSmall;
  75. for (uint32_t i = 1; i <= N; ++i) {
  76. if (i % K == 0) {
  77. bucketsSmall.Bounds.push_back(i);
  78. bucketsSmall.Values.push_back(0);
  79. }
  80. bucketsBig.Bounds.push_back(i);
  81. bucketsBig.Values.push_back(0);
  82. }
  83. UNIT_ASSERT_VALUES_EQUAL(bucketsBig.Values.size(), N);
  84. UNIT_ASSERT_VALUES_EQUAL(bucketsSmall.Values.size(), N / K);
  85. UNIT_ASSERT_VALUES_EQUAL(bucketsBig.Bounds.back(), N);
  86. UNIT_ASSERT_VALUES_EQUAL(bucketsSmall.Bounds.back(), N);
  87. std::random_device rd;
  88. std::mt19937 gen(rd());
  89. std::uniform_int_distribution<> distrib(1, N);
  90. for (int i = 0; i < 1000; ++i) {
  91. auto rndValue = distrib(gen);
  92. ++bucketsBig.Values[rndValue - 1];
  93. ++bucketsSmall.Values[(rndValue - 1) / K];
  94. }
  95. UNIT_ASSERT_VALUES_EQUAL(bucketsSmall.Bounds.back(), N);
  96. UNIT_ASSERT_VALUES_EQUAL(bucketsBig.Bounds.back(), N);
  97. auto snapshotBig = ExplicitHistogramSnapshot(bucketsBig.Bounds, bucketsBig.Values, true);
  98. auto snapshotSmall = ExplicitHistogramSnapshot(bucketsSmall.Bounds, bucketsSmall.Values, true);
  99. UNIT_ASSERT_VALUES_EQUAL(snapshotBig->Count(), snapshotSmall->Count());
  100. for (uint32_t i = 0; i < snapshotSmall->Count(); ++i) {
  101. UNIT_ASSERT_VALUES_EQUAL(snapshotSmall->Value(i), snapshotBig->Value(i));
  102. }
  103. }
  104. }