hw/arm/virt: introduce DEFINE_VIRT_MACHINE
[qemu/ar7.git] / tests / test-qdist.c
bloba67f26057e9b8a4ed1dbe4b3900673b3e048c38a
1 /*
2 * Copyright (C) 2016, Emilio G. Cota <cota@braap.org>
4 * License: GNU GPL, version 2 or later.
5 * See the COPYING file in the top-level directory.
6 */
7 #include "qemu/osdep.h"
8 #include <glib.h>
9 #include "qemu/qdist.h"
11 #include <math.h>
13 struct entry_desc {
14 double x;
15 unsigned long count;
17 /* 0 prints a space, 1-8 prints from qdist_blocks[] */
18 int fill_code;
21 /* See: https://en.wikipedia.org/wiki/Block_Elements */
22 static const gunichar qdist_blocks[] = {
23 0x2581,
24 0x2582,
25 0x2583,
26 0x2584,
27 0x2585,
28 0x2586,
29 0x2587,
30 0x2588
33 #define QDIST_NR_BLOCK_CODES ARRAY_SIZE(qdist_blocks)
35 static char *pr_hist(const struct entry_desc *darr, size_t n)
37 GString *s = g_string_new("");
38 size_t i;
40 for (i = 0; i < n; i++) {
41 int fill = darr[i].fill_code;
43 if (fill) {
44 assert(fill <= QDIST_NR_BLOCK_CODES);
45 g_string_append_unichar(s, qdist_blocks[fill - 1]);
46 } else {
47 g_string_append_c(s, ' ');
50 return g_string_free(s, FALSE);
53 static void
54 histogram_check(const struct qdist *dist, const struct entry_desc *darr,
55 size_t n, size_t n_bins)
57 char *pr = qdist_pr_plain(dist, n_bins);
58 char *str = pr_hist(darr, n);
60 g_assert_cmpstr(pr, ==, str);
61 g_free(pr);
62 g_free(str);
65 static void histogram_check_single_full(const struct qdist *dist, size_t n_bins)
67 struct entry_desc desc = { .fill_code = 8 };
69 histogram_check(dist, &desc, 1, n_bins);
72 static void
73 entries_check(const struct qdist *dist, const struct entry_desc *darr, size_t n)
75 size_t i;
77 for (i = 0; i < n; i++) {
78 struct qdist_entry *e = &dist->entries[i];
80 g_assert_cmpuint(e->count, ==, darr[i].count);
84 static void
85 entries_insert(struct qdist *dist, const struct entry_desc *darr, size_t n)
87 size_t i;
89 for (i = 0; i < n; i++) {
90 qdist_add(dist, darr[i].x, darr[i].count);
94 static void do_test_bin(const struct entry_desc *a, size_t n_a,
95 const struct entry_desc *b, size_t n_b)
97 struct qdist qda;
98 struct qdist qdb;
100 qdist_init(&qda);
102 entries_insert(&qda, a, n_a);
103 qdist_inc(&qda, a[0].x);
104 qdist_add(&qda, a[0].x, -1);
106 g_assert_cmpuint(qdist_unique_entries(&qda), ==, n_a);
107 g_assert_cmpfloat(qdist_xmin(&qda), ==, a[0].x);
108 g_assert_cmpfloat(qdist_xmax(&qda), ==, a[n_a - 1].x);
109 histogram_check(&qda, a, n_a, 0);
110 histogram_check(&qda, a, n_a, n_a);
112 qdist_bin__internal(&qdb, &qda, n_b);
113 g_assert_cmpuint(qdb.n, ==, n_b);
114 entries_check(&qdb, b, n_b);
115 g_assert_cmpuint(qdist_sample_count(&qda), ==, qdist_sample_count(&qdb));
117 * No histogram_check() for $qdb, since we'd rebin it and that is a bug.
118 * Instead, regenerate it from $qda.
120 histogram_check(&qda, b, n_b, n_b);
122 qdist_destroy(&qdb);
123 qdist_destroy(&qda);
126 static void do_test_pr(uint32_t opt)
128 static const struct entry_desc desc[] = {
129 [0] = { 1, 900, 8 },
130 [1] = { 2, 1, 1 },
131 [2] = { 3, 2, 1 }
133 static const char border[] = "|";
134 const char *llabel = NULL;
135 const char *rlabel = NULL;
136 struct qdist dist;
137 GString *s;
138 char *str;
139 char *pr;
140 size_t n;
142 n = ARRAY_SIZE(desc);
143 qdist_init(&dist);
145 entries_insert(&dist, desc, n);
146 histogram_check(&dist, desc, n, 0);
148 s = g_string_new("");
150 if (opt & QDIST_PR_LABELS) {
151 unsigned int lopts = opt & (QDIST_PR_NODECIMAL |
152 QDIST_PR_PERCENT |
153 QDIST_PR_100X |
154 QDIST_PR_NOBINRANGE);
156 if (lopts == 0) {
157 llabel = "[1.0,1.7)";
158 rlabel = "[2.3,3.0]";
159 } else if (lopts == QDIST_PR_NODECIMAL) {
160 llabel = "[1,2)";
161 rlabel = "[2,3]";
162 } else if (lopts == (QDIST_PR_PERCENT | QDIST_PR_NODECIMAL)) {
163 llabel = "[1,2)%";
164 rlabel = "[2,3]%";
165 } else if (lopts == QDIST_PR_100X) {
166 llabel = "[100.0,166.7)";
167 rlabel = "[233.3,300.0]";
168 } else if (lopts == (QDIST_PR_NOBINRANGE | QDIST_PR_NODECIMAL)) {
169 llabel = "1";
170 rlabel = "3";
171 } else {
172 g_assert_cmpstr("BUG", ==, "This is not meant to be exhaustive");
176 if (llabel) {
177 g_string_append(s, llabel);
179 if (opt & QDIST_PR_BORDER) {
180 g_string_append(s, border);
183 str = pr_hist(desc, n);
184 g_string_append(s, str);
185 g_free(str);
187 if (opt & QDIST_PR_BORDER) {
188 g_string_append(s, border);
190 if (rlabel) {
191 g_string_append(s, rlabel);
194 str = g_string_free(s, FALSE);
195 pr = qdist_pr(&dist, n, opt);
196 g_assert_cmpstr(pr, ==, str);
197 g_free(pr);
198 g_free(str);
200 qdist_destroy(&dist);
203 static inline void do_test_pr_label(uint32_t opt)
205 opt |= QDIST_PR_LABELS;
206 do_test_pr(opt);
209 static void test_pr(void)
211 do_test_pr(0);
213 do_test_pr(QDIST_PR_BORDER);
215 /* 100X should be ignored because we're not setting LABELS */
216 do_test_pr(QDIST_PR_100X);
218 do_test_pr_label(0);
219 do_test_pr_label(QDIST_PR_NODECIMAL);
220 do_test_pr_label(QDIST_PR_PERCENT | QDIST_PR_NODECIMAL);
221 do_test_pr_label(QDIST_PR_100X);
222 do_test_pr_label(QDIST_PR_NOBINRANGE | QDIST_PR_NODECIMAL);
225 static void test_bin_shrink(void)
227 static const struct entry_desc a[] = {
228 [0] = { 0.0, 42922, 7 },
229 [1] = { 0.25, 47834, 8 },
230 [2] = { 0.50, 26628, 0 },
231 [3] = { 0.625, 597, 4 },
232 [4] = { 0.75, 10298, 1 },
233 [5] = { 0.875, 22, 2 },
234 [6] = { 1.0, 2771, 1 }
236 static const struct entry_desc b[] = {
237 [0] = { 0.0, 42922, 7 },
238 [1] = { 0.25, 47834, 8 },
239 [2] = { 0.50, 27225, 3 },
240 [3] = { 0.75, 13091, 1 }
243 return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
246 static void test_bin_expand(void)
248 static const struct entry_desc a[] = {
249 [0] = { 0.0, 11713, 5 },
250 [1] = { 0.25, 20294, 0 },
251 [2] = { 0.50, 17266, 8 },
252 [3] = { 0.625, 1506, 0 },
253 [4] = { 0.75, 10355, 6 },
254 [5] = { 0.833, 2, 1 },
255 [6] = { 0.875, 99, 4 },
256 [7] = { 1.0, 4301, 2 }
258 static const struct entry_desc b[] = {
259 [0] = { 0.0, 11713, 5 },
260 [1] = { 0.0, 0, 0 },
261 [2] = { 0.0, 20294, 8 },
262 [3] = { 0.0, 0, 0 },
263 [4] = { 0.0, 0, 0 },
264 [5] = { 0.0, 17266, 6 },
265 [6] = { 0.0, 1506, 1 },
266 [7] = { 0.0, 10355, 4 },
267 [8] = { 0.0, 101, 1 },
268 [9] = { 0.0, 4301, 2 }
271 return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
274 static void test_bin_precision(void)
276 static const struct entry_desc a[] = {
277 [0] = { 0, 213549, 8 },
278 [1] = { 1, 70, 1 },
280 static const struct entry_desc b[] = {
281 [0] = { 0, 213549, 8 },
282 [1] = { 0, 70, 1 },
285 return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
288 static void test_bin_simple(void)
290 static const struct entry_desc a[] = {
291 [0] = { 10, 101, 8 },
292 [1] = { 11, 0, 0 },
293 [2] = { 12, 2, 1 }
295 static const struct entry_desc b[] = {
296 [0] = { 0, 101, 8 },
297 [1] = { 0, 0, 0 },
298 [2] = { 0, 0, 0 },
299 [3] = { 0, 0, 0 },
300 [4] = { 0, 2, 1 }
303 return do_test_bin(a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
306 static void test_single_full(void)
308 struct qdist dist;
310 qdist_init(&dist);
312 qdist_add(&dist, 3, 102);
313 g_assert_cmpfloat(qdist_avg(&dist), ==, 3);
314 g_assert_cmpfloat(qdist_xmin(&dist), ==, 3);
315 g_assert_cmpfloat(qdist_xmax(&dist), ==, 3);
317 histogram_check_single_full(&dist, 0);
318 histogram_check_single_full(&dist, 1);
319 histogram_check_single_full(&dist, 10);
321 qdist_destroy(&dist);
324 static void test_single_empty(void)
326 struct qdist dist;
327 char *pr;
329 qdist_init(&dist);
331 qdist_add(&dist, 3, 0);
332 g_assert_cmpuint(qdist_sample_count(&dist), ==, 0);
333 g_assert(isnan(qdist_avg(&dist)));
334 g_assert_cmpfloat(qdist_xmin(&dist), ==, 3);
335 g_assert_cmpfloat(qdist_xmax(&dist), ==, 3);
337 pr = qdist_pr_plain(&dist, 0);
338 g_assert_cmpstr(pr, ==, " ");
339 g_free(pr);
341 pr = qdist_pr_plain(&dist, 1);
342 g_assert_cmpstr(pr, ==, " ");
343 g_free(pr);
345 pr = qdist_pr_plain(&dist, 2);
346 g_assert_cmpstr(pr, ==, " ");
347 g_free(pr);
349 qdist_destroy(&dist);
352 static void test_none(void)
354 struct qdist dist;
355 char *pr;
357 qdist_init(&dist);
359 g_assert(isnan(qdist_avg(&dist)));
360 g_assert(isnan(qdist_xmin(&dist)));
361 g_assert(isnan(qdist_xmax(&dist)));
363 pr = qdist_pr_plain(&dist, 0);
364 g_assert(pr == NULL);
366 pr = qdist_pr_plain(&dist, 2);
367 g_assert(pr == NULL);
369 qdist_destroy(&dist);
372 int main(int argc, char *argv[])
374 g_test_init(&argc, &argv, NULL);
375 g_test_add_func("/qdist/none", test_none);
376 g_test_add_func("/qdist/single/empty", test_single_empty);
377 g_test_add_func("/qdist/single/full", test_single_full);
378 g_test_add_func("/qdist/binning/simple", test_bin_simple);
379 g_test_add_func("/qdist/binning/precision", test_bin_precision);
380 g_test_add_func("/qdist/binning/expand", test_bin_expand);
381 g_test_add_func("/qdist/binning/shrink", test_bin_shrink);
382 g_test_add_func("/qdist/pr", test_pr);
383 return g_test_run();