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 "src/core/lib/iomgr/time_averaged_stats.h"
20
21 #include <math.h>
22
23 #include <grpc/support/log.h>
24 #include "test/core/util/test_config.h"
25
26 #define EXPECT_EQ(a, b) GPR_ASSERT((a) == (b))
27 #define EXPECT_DOUBLE_EQ(a, b) GPR_ASSERT(fabs((a) - (b)) < 1e-9)
28
no_regress_no_persist_test_1(void)29 static void no_regress_no_persist_test_1(void) {
30 grpc_time_averaged_stats tas;
31 grpc_time_averaged_stats_init(&tas, 1000, 0, 0.0);
32 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
33 EXPECT_DOUBLE_EQ(0, tas.aggregate_total_weight);
34
35 /* Should have no effect */
36 grpc_time_averaged_stats_update_average(&tas);
37 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
38 EXPECT_DOUBLE_EQ(0, tas.aggregate_total_weight);
39
40 /* Should replace old average */
41 grpc_time_averaged_stats_add_sample(&tas, 2000);
42 grpc_time_averaged_stats_update_average(&tas);
43 EXPECT_DOUBLE_EQ(2000, tas.aggregate_weighted_avg);
44 EXPECT_DOUBLE_EQ(1, tas.aggregate_total_weight);
45 }
46
no_regress_no_persist_test_2(void)47 static void no_regress_no_persist_test_2(void) {
48 grpc_time_averaged_stats tas;
49 grpc_time_averaged_stats_init(&tas, 1000, 0, 0.0);
50 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
51 /* Should replace init value */
52 grpc_time_averaged_stats_add_sample(&tas, 2000);
53 grpc_time_averaged_stats_update_average(&tas);
54 EXPECT_DOUBLE_EQ(2000, tas.aggregate_weighted_avg);
55 EXPECT_DOUBLE_EQ(1, tas.aggregate_total_weight);
56
57 grpc_time_averaged_stats_add_sample(&tas, 3000);
58 grpc_time_averaged_stats_update_average(&tas);
59 EXPECT_DOUBLE_EQ(3000, tas.aggregate_weighted_avg);
60 EXPECT_DOUBLE_EQ(1, tas.aggregate_total_weight);
61 }
62
no_regress_no_persist_test_3(void)63 static void no_regress_no_persist_test_3(void) {
64 grpc_time_averaged_stats tas;
65 grpc_time_averaged_stats_init(&tas, 1000, 0, 0.0);
66 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
67 /* Should replace init value */
68 grpc_time_averaged_stats_add_sample(&tas, 2500);
69 grpc_time_averaged_stats_update_average(&tas);
70 EXPECT_DOUBLE_EQ(2500, tas.aggregate_weighted_avg);
71 EXPECT_DOUBLE_EQ(1, tas.aggregate_total_weight);
72
73 grpc_time_averaged_stats_add_sample(&tas, 3500);
74 grpc_time_averaged_stats_add_sample(&tas, 4500);
75 grpc_time_averaged_stats_update_average(&tas);
76 EXPECT_DOUBLE_EQ(4000, tas.aggregate_weighted_avg);
77 EXPECT_DOUBLE_EQ(2, tas.aggregate_total_weight);
78 }
79
some_regress_no_persist_test(void)80 static void some_regress_no_persist_test(void) {
81 grpc_time_averaged_stats tas;
82 grpc_time_averaged_stats_init(&tas, 1000, 0.5, 0.0);
83 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
84 EXPECT_DOUBLE_EQ(0, tas.aggregate_total_weight);
85 grpc_time_averaged_stats_add_sample(&tas, 2000);
86 grpc_time_averaged_stats_add_sample(&tas, 2000);
87 grpc_time_averaged_stats_update_average(&tas);
88 /* (2 * 2000 + 0.5 * 1000) / 2.5 */
89 EXPECT_DOUBLE_EQ(1800, tas.aggregate_weighted_avg);
90 EXPECT_DOUBLE_EQ(2.5, tas.aggregate_total_weight);
91 }
92
some_decay_test(void)93 static void some_decay_test(void) {
94 grpc_time_averaged_stats tas;
95 grpc_time_averaged_stats_init(&tas, 1000, 1, 0.0);
96 EXPECT_EQ(1000, tas.aggregate_weighted_avg);
97 /* Should avg with init value */
98 grpc_time_averaged_stats_add_sample(&tas, 2000);
99 grpc_time_averaged_stats_update_average(&tas);
100 EXPECT_DOUBLE_EQ(1500, tas.aggregate_weighted_avg);
101 EXPECT_DOUBLE_EQ(2, tas.aggregate_total_weight);
102
103 grpc_time_averaged_stats_add_sample(&tas, 2000);
104 grpc_time_averaged_stats_update_average(&tas);
105 EXPECT_DOUBLE_EQ(1500, tas.aggregate_weighted_avg);
106 EXPECT_DOUBLE_EQ(2, tas.aggregate_total_weight);
107
108 grpc_time_averaged_stats_add_sample(&tas, 2000);
109 grpc_time_averaged_stats_update_average(&tas);
110 EXPECT_DOUBLE_EQ(1500, tas.aggregate_weighted_avg);
111 EXPECT_DOUBLE_EQ(2, tas.aggregate_total_weight);
112 }
113
no_regress_full_persist_test(void)114 static void no_regress_full_persist_test(void) {
115 grpc_time_averaged_stats tas;
116 grpc_time_averaged_stats_init(&tas, 1000, 0, 1.0);
117 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
118 EXPECT_DOUBLE_EQ(0, tas.aggregate_total_weight);
119
120 /* Should replace init value */
121 grpc_time_averaged_stats_add_sample(&tas, 2000);
122 grpc_time_averaged_stats_update_average(&tas);
123 EXPECT_EQ(2000, tas.aggregate_weighted_avg);
124 EXPECT_EQ(1, tas.aggregate_total_weight);
125
126 /* Will result in average of the 3 samples. */
127 grpc_time_averaged_stats_add_sample(&tas, 2300);
128 grpc_time_averaged_stats_add_sample(&tas, 2300);
129 grpc_time_averaged_stats_update_average(&tas);
130 EXPECT_DOUBLE_EQ(2200, tas.aggregate_weighted_avg);
131 EXPECT_DOUBLE_EQ(3, tas.aggregate_total_weight);
132 }
133
no_regress_some_persist_test(void)134 static void no_regress_some_persist_test(void) {
135 grpc_time_averaged_stats tas;
136 grpc_time_averaged_stats_init(&tas, 1000, 0, 0.5);
137 /* Should replace init value */
138 grpc_time_averaged_stats_add_sample(&tas, 2000);
139 grpc_time_averaged_stats_update_average(&tas);
140 EXPECT_DOUBLE_EQ(2000, tas.aggregate_weighted_avg);
141 EXPECT_DOUBLE_EQ(1, tas.aggregate_total_weight);
142
143 grpc_time_averaged_stats_add_sample(&tas, 2500);
144 grpc_time_averaged_stats_add_sample(&tas, 4000);
145 grpc_time_averaged_stats_update_average(&tas);
146 EXPECT_DOUBLE_EQ(3000, tas.aggregate_weighted_avg);
147 EXPECT_DOUBLE_EQ(2.5, tas.aggregate_total_weight);
148 }
149
some_regress_some_persist_test(void)150 static void some_regress_some_persist_test(void) {
151 grpc_time_averaged_stats tas;
152 grpc_time_averaged_stats_init(&tas, 1000, 0.4, 0.6);
153 /* Sample weight = 0 */
154 EXPECT_EQ(1000, tas.aggregate_weighted_avg);
155 EXPECT_EQ(0, tas.aggregate_total_weight);
156
157 grpc_time_averaged_stats_update_average(&tas);
158 /* (0.6 * 0 * 1000 + 0.4 * 1000 / 0.4) */
159 EXPECT_DOUBLE_EQ(1000, tas.aggregate_weighted_avg);
160 EXPECT_DOUBLE_EQ(0.4, tas.aggregate_total_weight);
161
162 grpc_time_averaged_stats_add_sample(&tas, 2640);
163 grpc_time_averaged_stats_update_average(&tas);
164 /* (1 * 2640 + 0.6 * 0.4 * 1000 + 0.4 * 1000 / (1 + 0.6 * 0.4 + 0.4) */
165 EXPECT_DOUBLE_EQ(2000, tas.aggregate_weighted_avg);
166 EXPECT_DOUBLE_EQ(1.64, tas.aggregate_total_weight);
167
168 grpc_time_averaged_stats_add_sample(&tas, 2876.8);
169 grpc_time_averaged_stats_update_average(&tas);
170 /* (1 * 2876.8 + 0.6 * 1.64 * 2000 + 0.4 * 1000 / (1 + 0.6 * 1.64 + 0.4) */
171 EXPECT_DOUBLE_EQ(2200, tas.aggregate_weighted_avg);
172 EXPECT_DOUBLE_EQ(2.384, tas.aggregate_total_weight);
173
174 grpc_time_averaged_stats_add_sample(&tas, 4944.32);
175 grpc_time_averaged_stats_update_average(&tas);
176 /* (1 * 4944.32 + 0.6 * 2.384 * 2200 + 0.4 * 1000) /
177 (1 + 0.6 * 2.384 + 0.4) */
178 EXPECT_DOUBLE_EQ(3000, tas.aggregate_weighted_avg);
179 EXPECT_DOUBLE_EQ(2.8304, tas.aggregate_total_weight);
180 }
181
main(int argc,char ** argv)182 int main(int argc, char** argv) {
183 grpc_test_init(argc, argv);
184 no_regress_no_persist_test_1();
185 no_regress_no_persist_test_2();
186 no_regress_no_persist_test_3();
187 some_regress_no_persist_test();
188 some_decay_test();
189 no_regress_full_persist_test();
190 no_regress_some_persist_test();
191 some_regress_some_persist_test();
192 return 0;
193 }
194