1 | /* |
2 | * Copyright 2018-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #include <folly/stats/QuantileEstimator-defs.h> |
18 | |
19 | #include <folly/portability/GTest.h> |
20 | |
21 | using namespace folly; |
22 | |
23 | struct MockClock { |
24 | public: |
25 | using duration = std::chrono::steady_clock::duration; |
26 | using time_point = std::chrono::steady_clock::time_point; |
27 | static constexpr auto is_steady = true; |
28 | |
29 | static time_point now() { |
30 | return Now; |
31 | } |
32 | |
33 | static time_point Now; |
34 | }; |
35 | |
36 | MockClock::time_point MockClock::Now = MockClock::time_point{}; |
37 | |
38 | TEST(SimpleQuantileEstimatorTest, EstimateQuantiles) { |
39 | SimpleQuantileEstimator<MockClock> estimator; |
40 | for (size_t i = 1; i <= 100; ++i) { |
41 | estimator.addValue(i); |
42 | } |
43 | |
44 | MockClock::Now += std::chrono::seconds{1}; |
45 | |
46 | auto estimates = estimator.estimateQuantiles( |
47 | std::array<double, 5>{{.001, .01, .5, .99, .999}}); |
48 | |
49 | EXPECT_EQ(5050, estimates.sum); |
50 | EXPECT_EQ(100, estimates.count); |
51 | |
52 | EXPECT_EQ(0.001, estimates.quantiles[0].first); |
53 | EXPECT_EQ(0.01, estimates.quantiles[1].first); |
54 | EXPECT_EQ(0.5, estimates.quantiles[2].first); |
55 | EXPECT_EQ(0.99, estimates.quantiles[3].first); |
56 | EXPECT_EQ(0.999, estimates.quantiles[4].first); |
57 | |
58 | EXPECT_EQ(1, estimates.quantiles[0].second); |
59 | EXPECT_EQ(2.0 - 0.5, estimates.quantiles[1].second); |
60 | EXPECT_EQ(50.375, estimates.quantiles[2].second); |
61 | EXPECT_EQ(100.0 - 0.5, estimates.quantiles[3].second); |
62 | EXPECT_EQ(100, estimates.quantiles[4].second); |
63 | } |
64 | |
65 | TEST(SlidingWindowQuantileEstimatorTest, EstimateQuantiles) { |
66 | SlidingWindowQuantileEstimator<MockClock> estimator(std::chrono::seconds{1}); |
67 | for (size_t i = 1; i <= 100; ++i) { |
68 | estimator.addValue(i); |
69 | } |
70 | |
71 | MockClock::Now += std::chrono::seconds{1}; |
72 | |
73 | auto estimates = estimator.estimateQuantiles( |
74 | std::array<double, 5>{{.001, .01, .5, .99, .999}}); |
75 | |
76 | EXPECT_EQ(5050, estimates.sum); |
77 | EXPECT_EQ(100, estimates.count); |
78 | |
79 | EXPECT_EQ(0.001, estimates.quantiles[0].first); |
80 | EXPECT_EQ(0.01, estimates.quantiles[1].first); |
81 | EXPECT_EQ(0.5, estimates.quantiles[2].first); |
82 | EXPECT_EQ(0.99, estimates.quantiles[3].first); |
83 | EXPECT_EQ(0.999, estimates.quantiles[4].first); |
84 | |
85 | EXPECT_EQ(1, estimates.quantiles[0].second); |
86 | EXPECT_EQ(2.0 - 0.5, estimates.quantiles[1].second); |
87 | EXPECT_EQ(50.375, estimates.quantiles[2].second); |
88 | EXPECT_EQ(100.0 - 0.5, estimates.quantiles[3].second); |
89 | EXPECT_EQ(100, estimates.quantiles[4].second); |
90 | } |
91 | |