1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include "test/core/util/histogram.h"
20 #include <grpc/support/log.h>
21 
22 #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x);
23 
test_no_op(void)24 static void test_no_op(void) {
25   grpc_histogram_destroy(grpc_histogram_create(0.01, 60e9));
26 }
27 
expect_percentile(grpc_histogram * h,double percentile,double min_expect,double max_expect)28 static void expect_percentile(grpc_histogram* h, double percentile,
29                               double min_expect, double max_expect) {
30   double got = grpc_histogram_percentile(h, percentile);
31   gpr_log(GPR_INFO, "@%f%%, expect %f <= %f <= %f", percentile, min_expect, got,
32           max_expect);
33   GPR_ASSERT(min_expect <= got);
34   GPR_ASSERT(got <= max_expect);
35 }
36 
test_simple(void)37 static void test_simple(void) {
38   grpc_histogram* h;
39 
40   LOG_TEST("test_simple");
41 
42   h = grpc_histogram_create(0.01, 60e9);
43   grpc_histogram_add(h, 10000);
44   grpc_histogram_add(h, 10000);
45   grpc_histogram_add(h, 11000);
46   grpc_histogram_add(h, 11000);
47 
48   expect_percentile(h, 50, 10001, 10999);
49   GPR_ASSERT(grpc_histogram_mean(h) == 10500);
50 
51   grpc_histogram_destroy(h);
52 }
53 
test_percentile(void)54 static void test_percentile(void) {
55   grpc_histogram* h;
56   double last;
57   double i;
58   double cur;
59 
60   LOG_TEST("test_percentile");
61 
62   h = grpc_histogram_create(0.05, 1e9);
63   grpc_histogram_add(h, 2.5);
64   grpc_histogram_add(h, 2.5);
65   grpc_histogram_add(h, 8);
66   grpc_histogram_add(h, 4);
67 
68   GPR_ASSERT(grpc_histogram_count(h) == 4);
69   GPR_ASSERT(grpc_histogram_minimum(h) == 2.5);
70   GPR_ASSERT(grpc_histogram_maximum(h) == 8);
71   GPR_ASSERT(grpc_histogram_sum(h) == 17);
72   GPR_ASSERT(grpc_histogram_sum_of_squares(h) == 92.5);
73   GPR_ASSERT(grpc_histogram_mean(h) == 4.25);
74   GPR_ASSERT(grpc_histogram_variance(h) == 5.0625);
75   GPR_ASSERT(grpc_histogram_stddev(h) == 2.25);
76 
77   expect_percentile(h, -10, 2.5, 2.5);
78   expect_percentile(h, 0, 2.5, 2.5);
79   expect_percentile(h, 12.5, 2.5, 2.5);
80   expect_percentile(h, 25, 2.5, 2.5);
81   expect_percentile(h, 37.5, 2.5, 2.8);
82   expect_percentile(h, 50, 3.0, 3.5);
83   expect_percentile(h, 62.5, 3.5, 4.5);
84   expect_percentile(h, 75, 5, 7.9);
85   expect_percentile(h, 100, 8, 8);
86   expect_percentile(h, 110, 8, 8);
87 
88   /* test monotonicity */
89   last = 0.0;
90   for (i = 0; i < 100.0; i += 0.01) {
91     cur = grpc_histogram_percentile(h, i);
92     GPR_ASSERT(cur >= last);
93     last = cur;
94   }
95 
96   grpc_histogram_destroy(h);
97 }
98 
test_merge(void)99 static void test_merge(void) {
100   grpc_histogram *h1, *h2;
101   double last;
102   double i;
103   double cur;
104 
105   LOG_TEST("test_merge");
106 
107   h1 = grpc_histogram_create(0.05, 1e9);
108   grpc_histogram_add(h1, 2.5);
109   grpc_histogram_add(h1, 2.5);
110   grpc_histogram_add(h1, 8);
111   grpc_histogram_add(h1, 4);
112 
113   h2 = grpc_histogram_create(0.01, 1e9);
114   GPR_ASSERT(grpc_histogram_merge(h1, h2) == 0);
115   grpc_histogram_destroy(h2);
116 
117   h2 = grpc_histogram_create(0.05, 1e10);
118   GPR_ASSERT(grpc_histogram_merge(h1, h2) == 0);
119   grpc_histogram_destroy(h2);
120 
121   h2 = grpc_histogram_create(0.05, 1e9);
122   GPR_ASSERT(grpc_histogram_merge(h1, h2) == 1);
123   GPR_ASSERT(grpc_histogram_count(h1) == 4);
124   GPR_ASSERT(grpc_histogram_minimum(h1) == 2.5);
125   GPR_ASSERT(grpc_histogram_maximum(h1) == 8);
126   GPR_ASSERT(grpc_histogram_sum(h1) == 17);
127   GPR_ASSERT(grpc_histogram_sum_of_squares(h1) == 92.5);
128   GPR_ASSERT(grpc_histogram_mean(h1) == 4.25);
129   GPR_ASSERT(grpc_histogram_variance(h1) == 5.0625);
130   GPR_ASSERT(grpc_histogram_stddev(h1) == 2.25);
131   grpc_histogram_destroy(h2);
132 
133   h2 = grpc_histogram_create(0.05, 1e9);
134   grpc_histogram_add(h2, 7.0);
135   grpc_histogram_add(h2, 17.0);
136   grpc_histogram_add(h2, 1.0);
137   GPR_ASSERT(grpc_histogram_merge(h1, h2) == 1);
138   GPR_ASSERT(grpc_histogram_count(h1) == 7);
139   GPR_ASSERT(grpc_histogram_minimum(h1) == 1.0);
140   GPR_ASSERT(grpc_histogram_maximum(h1) == 17.0);
141   GPR_ASSERT(grpc_histogram_sum(h1) == 42.0);
142   GPR_ASSERT(grpc_histogram_sum_of_squares(h1) == 431.5);
143   GPR_ASSERT(grpc_histogram_mean(h1) == 6.0);
144 
145   /* test monotonicity */
146   last = 0.0;
147   for (i = 0; i < 100.0; i += 0.01) {
148     cur = grpc_histogram_percentile(h1, i);
149     GPR_ASSERT(cur >= last);
150     last = cur;
151   }
152 
153   grpc_histogram_destroy(h1);
154   grpc_histogram_destroy(h2);
155 }
156 
main(void)157 int main(void) {
158   test_no_op();
159   test_simple();
160   test_percentile();
161   test_merge();
162   return 0;
163 }
164