summaryrefslogtreecommitdiffstats
path: root/src/lib/test-stats-dist.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:36:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:36:47 +0000
commit0441d265f2bb9da249c7abf333f0f771fadb4ab5 (patch)
tree3f3789daa2f6db22da6e55e92bee0062a7d613fe /src/lib/test-stats-dist.c
parentInitial commit. (diff)
downloaddovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.tar.xz
dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.zip
Adding upstream version 1:2.3.21+dfsg1.upstream/1%2.3.21+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/test-stats-dist.c')
-rw-r--r--src/lib/test-stats-dist.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/lib/test-stats-dist.c b/src/lib/test-stats-dist.c
new file mode 100644
index 0000000..795c22f
--- /dev/null
+++ b/src/lib/test-stats-dist.c
@@ -0,0 +1,132 @@
+/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "stats-dist.h"
+#include "sort.h"
+#include "math.h"
+
+#define DBL_EQ(a, b) (fabs((a)-(b)) < 0.001)
+
+static void
+test_stats_dist_verify(struct stats_dist *t, const int64_t *input,
+ unsigned int input_size)
+{
+ uint64_t min = INT_MAX, max = 0, sum = 0;
+ uint64_t *copy;
+ unsigned int i;
+
+ i_assert(input_size > 0);
+
+ copy = i_new(uint64_t, input_size);
+ for (i = 0; i < input_size; i++) {
+ uint64_t value = input[i];
+
+ if (min > value)
+ min = value;
+ if (max < value)
+ max = value;
+ sum += value;
+ copy[i] = value;
+ }
+ i_qsort(copy, input_size, sizeof(*copy), uint64_cmp);
+
+ test_assert_idx(stats_dist_get_count(t) == input_size, input_size);
+ test_assert_idx(stats_dist_get_sum(t) == sum, input_size);
+ test_assert_idx(stats_dist_get_min(t) == min, input_size);
+ test_assert_idx(stats_dist_get_max(t) == max, input_size);
+ test_assert_idx(DBL_EQ(stats_dist_get_avg(t), (double)sum/input_size),
+ input_size);
+
+ /* these aren't always fully accurate: */
+ test_assert_idx(stats_dist_get_median(t) >= copy[(input_size-1)/2] &&
+ stats_dist_get_median(t) <= copy[input_size/2],
+ input_size);
+ /* when we have 20 elements, [19] is the max, not the 95th %ile, so subtract 1 */
+ test_assert_idx(stats_dist_get_95th(t) == copy[input_size*95/100 - ((input_size%20) == 0 ? 1 : 0)],
+ input_size);
+
+ i_free(copy);
+}
+
+static void test_stats_dist_get_variance(void)
+{
+ static const struct {
+ int64_t in[10];
+ double out;
+ } tests[] = {
+ { .in = { 2, 2, 2, -1 }, .out = 0.0 },
+ { .in = { -1 }, .out = 0.0 },
+ { .in = { 1, 2, 3, 4, 5, 6, 7, 8, -1 }, .out = 5.25 },
+ };
+
+ struct stats_dist *t;
+ unsigned int i, j;
+
+ test_begin("stats_dists_get_variance");
+
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ t = stats_dist_init();
+ for (j = 0; tests[i].in[j] >= 0; j++) {
+ stats_dist_add(t, tests[i].in[j]);
+ test_stats_dist_verify(t, tests[i].in, j+1);
+ }
+ test_assert_idx(DBL_EQ(stats_dist_get_variance(t),
+ tests[i].out), i);
+
+ stats_dist_deinit(&t);
+ }
+
+ test_end();
+}
+
+void test_stats_dist(void)
+{
+ static int64_t test_input1[] = {
+ 20, 19, 18, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, -1
+ };
+ static int64_t test_input2[] = {
+ 20, 21, 19, 18, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, -1
+ };
+ static int64_t test_input3[] = {
+ 20, 21, 19, 18, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 22, -1
+ };
+ static int64_t *test_inputs[] = {
+ test_input1, test_input2, test_input3
+ };
+ struct stats_dist *t;
+ unsigned int i, j;
+
+ for (i = 0; i < N_ELEMENTS(test_inputs); i++) {
+ test_begin(t_strdup_printf("stats_dists %u", i));
+ t = stats_dist_init();
+ for (j = 0; test_inputs[i][j] >= 0; j++) {
+ stats_dist_add(t, test_inputs[i][j]);
+ test_stats_dist_verify(t, test_inputs[i], j+1);
+ }
+ stats_dist_reset(t);
+ test_assert(stats_dist_get_count(t) == 0);
+ test_assert(stats_dist_get_max(t) == 0);
+ stats_dist_deinit(&t);
+ test_end();
+ }
+
+ test_begin("stats_dists large");
+ t = stats_dist_init();
+ for (i = 0; i < 10000; i++)
+ stats_dist_add(t, i);
+ test_assert(stats_dist_get_count(t) == i);
+ test_assert(stats_dist_get_sum(t) == (i-1)*i/2);
+ test_assert(stats_dist_get_min(t) == 0);
+ test_assert(stats_dist_get_max(t) == i-1);
+ test_assert(DBL_EQ(stats_dist_get_avg(t), 4999.500000));
+ /* just test that these work: */
+ test_assert(stats_dist_get_median(t) > 0 && stats_dist_get_median(t) < i-1);
+ test_assert(stats_dist_get_95th(t) > 0 && stats_dist_get_95th(t) < i-1);
+ stats_dist_deinit(&t);
+ test_end();
+
+ test_stats_dist_get_variance();
+}