]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/monitoring/histogram_test.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / rocksdb / monitoring / histogram_test.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
5 //
6 #include <cmath>
7
8 #include "monitoring/histogram.h"
9 #include "monitoring/histogram_windowing.h"
10 #include "util/testharness.h"
11
12 namespace rocksdb {
13
14 class HistogramTest : public testing::Test {};
15
16 namespace {
17 const double kIota = 0.1;
18 const HistogramBucketMapper bucketMapper;
19 Env* env = Env::Default();
20 }
21
22 void PopulateHistogram(Histogram& histogram,
23 uint64_t low, uint64_t high, uint64_t loop = 1) {
24 for (; loop > 0; loop--) {
25 for (uint64_t i = low; i <= high; i++) {
26 histogram.Add(i);
27 }
28 }
29 }
30
31 void BasicOperation(Histogram& histogram) {
32 PopulateHistogram(histogram, 1, 100, 10);
33
34 HistogramData data;
35 histogram.Data(&data);
36
37 ASSERT_LE(fabs(histogram.Percentile(100.0) - 100.0), kIota);
38 ASSERT_LE(fabs(data.percentile99 - 99.0), kIota);
39 ASSERT_LE(fabs(data.percentile95 - 95.0), kIota);
40 ASSERT_LE(fabs(data.median - 50.0), kIota);
41 ASSERT_EQ(data.average, 50.5); // avg is acurately calculated.
42 ASSERT_LT(fabs(data.standard_deviation- 28.86), kIota); //sd is ~= 28.86
43 }
44
45 void MergeHistogram(Histogram& histogram, Histogram& other) {
46 PopulateHistogram(histogram, 1, 100);
47 PopulateHistogram(other, 101, 200);
48 histogram.Merge(other);
49
50 HistogramData data;
51 histogram.Data(&data);
52
53 ASSERT_LE(fabs(histogram.Percentile(100.0) - 200.0), kIota);
54 ASSERT_LE(fabs(data.percentile99 - 198.0), kIota);
55 ASSERT_LE(fabs(data.percentile95 - 190.0), kIota);
56 ASSERT_LE(fabs(data.median - 100.0), kIota);
57 ASSERT_EQ(data.average, 100.5); // avg is acurately calculated.
58 ASSERT_LT(fabs(data.standard_deviation - 57.73), kIota); //sd is ~= 57.73
59 }
60
61 void EmptyHistogram(Histogram& histogram) {
62 ASSERT_EQ(histogram.min(), bucketMapper.LastValue());
63 ASSERT_EQ(histogram.max(), 0);
64 ASSERT_EQ(histogram.num(), 0);
65 ASSERT_EQ(histogram.Median(), 0.0);
66 ASSERT_EQ(histogram.Percentile(85.0), 0.0);
67 ASSERT_EQ(histogram.Average(), 0.0);
68 ASSERT_EQ(histogram.StandardDeviation(), 0.0);
69 }
70
71 void ClearHistogram(Histogram& histogram) {
72 for (uint64_t i = 1; i <= 100; i++) {
73 histogram.Add(i);
74 }
75 histogram.Clear();
76 ASSERT_TRUE(histogram.Empty());
77 ASSERT_EQ(histogram.Median(), 0);
78 ASSERT_EQ(histogram.Percentile(85.0), 0);
79 ASSERT_EQ(histogram.Average(), 0);
80 }
81
82 TEST_F(HistogramTest, BasicOperation) {
83 HistogramImpl histogram;
84 BasicOperation(histogram);
85
86 HistogramWindowingImpl histogramWindowing;
87 BasicOperation(histogramWindowing);
88 }
89
90 TEST_F(HistogramTest, MergeHistogram) {
91 HistogramImpl histogram;
92 HistogramImpl other;
93 MergeHistogram(histogram, other);
94
95 HistogramWindowingImpl histogramWindowing;
96 HistogramWindowingImpl otherWindowing;
97 MergeHistogram(histogramWindowing, otherWindowing);
98 }
99
100 TEST_F(HistogramTest, EmptyHistogram) {
101 HistogramImpl histogram;
102 EmptyHistogram(histogram);
103
104 HistogramWindowingImpl histogramWindowing;
105 EmptyHistogram(histogramWindowing);
106 }
107
108 TEST_F(HistogramTest, ClearHistogram) {
109 HistogramImpl histogram;
110 ClearHistogram(histogram);
111
112 HistogramWindowingImpl histogramWindowing;
113 ClearHistogram(histogramWindowing);
114 }
115
116 TEST_F(HistogramTest, HistogramWindowingExpire) {
117 uint64_t num_windows = 3;
118 int micros_per_window = 1000000;
119 uint64_t min_num_per_window = 0;
120
121 HistogramWindowingImpl
122 histogramWindowing(num_windows, micros_per_window, min_num_per_window);
123
124 PopulateHistogram(histogramWindowing, 1, 1, 100);
125 env->SleepForMicroseconds(micros_per_window);
126 ASSERT_EQ(histogramWindowing.num(), 100);
127 ASSERT_EQ(histogramWindowing.min(), 1);
128 ASSERT_EQ(histogramWindowing.max(), 1);
129 ASSERT_EQ(histogramWindowing.Average(), 1);
130
131 PopulateHistogram(histogramWindowing, 2, 2, 100);
132 env->SleepForMicroseconds(micros_per_window);
133 ASSERT_EQ(histogramWindowing.num(), 200);
134 ASSERT_EQ(histogramWindowing.min(), 1);
135 ASSERT_EQ(histogramWindowing.max(), 2);
136 ASSERT_EQ(histogramWindowing.Average(), 1.5);
137
138 PopulateHistogram(histogramWindowing, 3, 3, 100);
139 env->SleepForMicroseconds(micros_per_window);
140 ASSERT_EQ(histogramWindowing.num(), 300);
141 ASSERT_EQ(histogramWindowing.min(), 1);
142 ASSERT_EQ(histogramWindowing.max(), 3);
143 ASSERT_EQ(histogramWindowing.Average(), 2.0);
144
145 // dropping oldest window with value 1, remaining 2 ~ 4
146 PopulateHistogram(histogramWindowing, 4, 4, 100);
147 env->SleepForMicroseconds(micros_per_window);
148 ASSERT_EQ(histogramWindowing.num(), 300);
149 ASSERT_EQ(histogramWindowing.min(), 2);
150 ASSERT_EQ(histogramWindowing.max(), 4);
151 ASSERT_EQ(histogramWindowing.Average(), 3.0);
152
153 // dropping oldest window with value 2, remaining 3 ~ 5
154 PopulateHistogram(histogramWindowing, 5, 5, 100);
155 env->SleepForMicroseconds(micros_per_window);
156 ASSERT_EQ(histogramWindowing.num(), 300);
157 ASSERT_EQ(histogramWindowing.min(), 3);
158 ASSERT_EQ(histogramWindowing.max(), 5);
159 ASSERT_EQ(histogramWindowing.Average(), 4.0);
160 }
161
162 TEST_F(HistogramTest, HistogramWindowingMerge) {
163 uint64_t num_windows = 3;
164 int micros_per_window = 1000000;
165 uint64_t min_num_per_window = 0;
166
167 HistogramWindowingImpl
168 histogramWindowing(num_windows, micros_per_window, min_num_per_window);
169 HistogramWindowingImpl
170 otherWindowing(num_windows, micros_per_window, min_num_per_window);
171
172 PopulateHistogram(histogramWindowing, 1, 1, 100);
173 PopulateHistogram(otherWindowing, 1, 1, 100);
174 env->SleepForMicroseconds(micros_per_window);
175
176 PopulateHistogram(histogramWindowing, 2, 2, 100);
177 PopulateHistogram(otherWindowing, 2, 2, 100);
178 env->SleepForMicroseconds(micros_per_window);
179
180 PopulateHistogram(histogramWindowing, 3, 3, 100);
181 PopulateHistogram(otherWindowing, 3, 3, 100);
182 env->SleepForMicroseconds(micros_per_window);
183
184 histogramWindowing.Merge(otherWindowing);
185 ASSERT_EQ(histogramWindowing.num(), 600);
186 ASSERT_EQ(histogramWindowing.min(), 1);
187 ASSERT_EQ(histogramWindowing.max(), 3);
188 ASSERT_EQ(histogramWindowing.Average(), 2.0);
189
190 // dropping oldest window with value 1, remaining 2 ~ 4
191 PopulateHistogram(histogramWindowing, 4, 4, 100);
192 env->SleepForMicroseconds(micros_per_window);
193 ASSERT_EQ(histogramWindowing.num(), 500);
194 ASSERT_EQ(histogramWindowing.min(), 2);
195 ASSERT_EQ(histogramWindowing.max(), 4);
196
197 // dropping oldest window with value 2, remaining 3 ~ 5
198 PopulateHistogram(histogramWindowing, 5, 5, 100);
199 env->SleepForMicroseconds(micros_per_window);
200 ASSERT_EQ(histogramWindowing.num(), 400);
201 ASSERT_EQ(histogramWindowing.min(), 3);
202 ASSERT_EQ(histogramWindowing.max(), 5);
203 }
204
205 } // namespace rocksdb
206
207 int main(int argc, char** argv) {
208 ::testing::InitGoogleTest(&argc, argv);
209 return RUN_ALL_TESTS();
210 }