]> git.proxmox.com Git - ovs.git/blob - tests/test-stopwatch.c
Fix ovs-dpctl-top by removing 3 wrong hunks in py3-compat.patch.
[ovs.git] / tests / test-stopwatch.c
1 /*
2 * Copyright (c) 2018 Red Hat, 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 <config.h>
18 #undef NDEBUG
19 #include "stopwatch.h"
20 #include <assert.h>
21 #include <math.h>
22 #include <stdio.h>
23 #include "ovstest.h"
24 #include "util.h"
25
26 #define MAX_SAMPLES 100
27 #define UNIT SW_MS
28
29 struct test_data {
30 const char *name;
31 unsigned long long samples[MAX_SAMPLES];
32 size_t num_samples;
33 struct stopwatch_stats expected_stats;
34 };
35
36 static struct test_data data_sets[] = {
37 {
38 .name = "1-interval-zero-length",
39 .samples = { 0, 0 },
40 .num_samples = 2,
41 .expected_stats = {
42 .count = 1,
43 .unit = UNIT,
44 .max = 0,
45 .min = 0,
46 .pctl_95 = 0,
47 .ewma_50 = 0,
48 .ewma_1 = 0,
49 },
50 },
51 {
52 .name = "1-interval-unit-length",
53 .samples = { 0, 1 },
54 .num_samples = 2,
55 .expected_stats = {
56 .count = 1,
57 .unit = UNIT,
58 .max = 1,
59 .min = 1,
60 .pctl_95 = 0,
61 .ewma_50 = 1,
62 .ewma_1 = 1,
63 },
64 },
65 {
66 .name = "10-intervals-unit-length",
67 .samples = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
68 .num_samples = 11,
69 .expected_stats = {
70 .count = 10,
71 .unit = UNIT,
72 .max = 1,
73 .min = 1,
74 .pctl_95 = 1,
75 .ewma_50 = 1,
76 .ewma_1 = 1,
77 },
78 },
79 {
80 .name = "10-intervals-linear-growth",
81 .samples = { 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 56 },
82 .num_samples = 11,
83 .expected_stats = {
84 .count = 10,
85 .unit = UNIT,
86 .max = 10,
87 .min = 1,
88 .pctl_95 = 10.0,
89 .ewma_50 = 9.0,
90 .ewma_1 = 1.4,
91 },
92 },
93 {
94 .name = "60-intervals-unit-length",
95 .samples = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
96 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
97 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
98 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
99 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
100 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
101 61, },
102 .num_samples = 61,
103 .expected_stats = {
104 .count = 60,
105 .unit = UNIT,
106 .max = 1,
107 .min = 1,
108 .pctl_95 = 1,
109 .ewma_50 = 1,
110 .ewma_1 = 1,
111 },
112 },
113 {
114 .name = "60-intervals-linear-growth",
115 .samples = { 1, 2, 4, 7, 11, 16, 22, 29, 37, 46,
116 56, 67, 79, 92, 106, 121, 137, 154, 172, 191,
117 211, 232, 254, 277, 301, 326, 352, 379, 407, 436,
118 466, 497, 529, 562, 596, 631, 667, 704, 742, 781,
119 821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226,
120 1276, 1327, 1379, 1432, 1486, 1541, 1597, 1654, 1712, 1771,
121 1831, },
122 .num_samples = 61,
123 .expected_stats = {
124 .count = 60,
125 .unit = UNIT,
126 .max = 60,
127 .min = 1,
128 /* 95th percentile is actually closer to 57, but the estimate is
129 * pretty dang close */
130 .pctl_95 = 56,
131 .ewma_50 = 59,
132 .ewma_1 = 15.7,
133 },
134 },
135 };
136
137 #define ASSERT_MSG(COND, MSG, ...) \
138 if (!(COND)) { \
139 fprintf(stderr, MSG "\n", ##__VA_ARGS__); \
140 assert(COND); \
141 }
142
143 #define ASSERT_ULL_EQ(a, b) \
144 ASSERT_MSG(a == b, \
145 "Assertion '%s == %s' failed: %llu == %llu", \
146 #a, #b, a, b)
147
148 #define ASSERT_DOUBLE_EQ(a, b, eps) \
149 ASSERT_MSG(fabs(a - b) < eps, \
150 "Assertion '|%s - %s| < %s' failed: |%g - %g| < %g", \
151 #a, #b, #eps, a, b, eps)
152
153 #define ASSERT_STATS_EQ(a, b) \
154 do { \
155 ASSERT_ULL_EQ((a)->count, (b)->count); \
156 ASSERT_ULL_EQ((a)->max, (b)->max); \
157 ASSERT_ULL_EQ((a)->min, (b)->min); \
158 ASSERT_DOUBLE_EQ((a)->pctl_95, (b)->pctl_95, 1e-1); \
159 ASSERT_DOUBLE_EQ((a)->ewma_50, (b)->ewma_50, 1e-1); \
160 ASSERT_DOUBLE_EQ((a)->ewma_1, (b)->ewma_1, 1e-1); \
161 } while (0)
162
163 static void
164 test_stopwatch_calculate_stats(void)
165 {
166 struct test_data *d;
167
168 for (size_t i = 0; i < ARRAY_SIZE(data_sets); i++) {
169 d = &data_sets[i];
170
171 fprintf(stderr, "TEST '%s'\n", d->name);
172
173 stopwatch_create(d->name, UNIT);
174 for (size_t j = 0; j < d->num_samples - 1; j ++) {
175 stopwatch_start(d->name, d->samples[j]);
176 stopwatch_stop(d->name, d->samples[j + 1]);
177 }
178 stopwatch_sync();
179
180 struct stopwatch_stats stats = { .unit = UNIT };
181 stopwatch_get_stats(d->name, &stats);
182 ASSERT_STATS_EQ(&stats, &d->expected_stats);
183
184 printf(".");
185 }
186 }
187
188 static void
189 test_stopwatch_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
190 {
191 test_stopwatch_calculate_stats();
192 printf("\n");
193 }
194
195 OVSTEST_REGISTER("test-stopwatch", test_stopwatch_main);