1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2017 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #include "spdk_internal/cunit.h"
7
8 #include "spdk/histogram_data.h"
9 #include "spdk/util.h"
10
11 uint64_t g_values[] = {
12 1,
13 10,
14 1000,
15 50000,
16 (1ULL << 63),
17 UINT64_MAX
18 };
19
20 uint64_t *g_values_end = &g_values[SPDK_COUNTOF(g_values)];
21 uint64_t g_total;
22 uint64_t g_number_of_merged_histograms;
23
24 static void
check_values(void * ctx,uint64_t start,uint64_t end,uint64_t count,uint64_t total,uint64_t so_far)25 check_values(void *ctx, uint64_t start, uint64_t end, uint64_t count,
26 uint64_t total, uint64_t so_far)
27 {
28 uint64_t **values = ctx;
29
30 if (count == 0) {
31 return;
32 }
33
34 CU_ASSERT(so_far == (g_total + count));
35
36 /*
37 * The bucket for this iteration does not include end, but
38 * subtract one anyways to account for the last bucket
39 * which will have end = 0x0 (UINT64_MAX + 1).
40 */
41 end--;
42
43 while (1) {
44 CU_ASSERT(**values >= start);
45 /*
46 * We subtracted one from end above, so it's OK here for
47 * **values to equal end.
48 */
49 CU_ASSERT(**values <= end);
50 g_total += g_number_of_merged_histograms;
51 count -= g_number_of_merged_histograms;
52 (*values)++;
53 if (*values == g_values_end || **values > end) {
54 break;
55 }
56 }
57 CU_ASSERT(count == 0);
58 }
59
60 static void
histogram_test(void)61 histogram_test(void)
62 {
63 struct spdk_histogram_data *h;
64 uint64_t *values = g_values;
65 uint32_t i;
66
67 h = spdk_histogram_data_alloc();
68
69 for (i = 0; i < SPDK_COUNTOF(g_values); i++) {
70 spdk_histogram_data_tally(h, g_values[i]);
71 }
72 g_total = 0;
73 g_number_of_merged_histograms = 1;
74 spdk_histogram_data_iterate(h, check_values, &values);
75
76 spdk_histogram_data_free(h);
77 }
78
79 static void
histogram_merge(void)80 histogram_merge(void)
81 {
82 struct spdk_histogram_data *h1, *h2;
83 uint64_t *values = g_values;
84 uint32_t i;
85 int rc;
86
87 h1 = spdk_histogram_data_alloc();
88 h2 = spdk_histogram_data_alloc();
89
90 for (i = 0; i < SPDK_COUNTOF(g_values); i++) {
91 spdk_histogram_data_tally(h1, g_values[i]);
92 spdk_histogram_data_tally(h2, g_values[i]);
93 }
94
95 rc = spdk_histogram_data_merge(h1, h2);
96 CU_ASSERT(rc == 0);
97
98 g_total = 0;
99 g_number_of_merged_histograms = 2;
100 spdk_histogram_data_iterate(h1, check_values, &values);
101
102 spdk_histogram_data_free(h1);
103 spdk_histogram_data_free(h2);
104
105 h1 = spdk_histogram_data_alloc_sized(SPDK_HISTOGRAM_BUCKET_SHIFT_DEFAULT);
106 h2 = spdk_histogram_data_alloc_sized(SPDK_HISTOGRAM_BUCKET_SHIFT_DEFAULT - 1);
107
108 rc = spdk_histogram_data_merge(h1, h2);
109 CU_ASSERT(rc == -EINVAL);
110
111 spdk_histogram_data_free(h1);
112 spdk_histogram_data_free(h2);
113 }
114
115 int
main(int argc,char ** argv)116 main(int argc, char **argv)
117 {
118 CU_pSuite suite = NULL;
119 unsigned int num_failures;
120
121 if (CU_initialize_registry() != CUE_SUCCESS) {
122 return CU_get_error();
123 }
124
125 suite = CU_add_suite("histogram", NULL, NULL);
126 if (suite == NULL) {
127 CU_cleanup_registry();
128 return CU_get_error();
129 }
130
131 if (
132 CU_add_test(suite, "histogram_test", histogram_test) == NULL ||
133 CU_add_test(suite, "histogram_merge", histogram_merge) == NULL
134 ) {
135 CU_cleanup_registry();
136 return CU_get_error();
137 }
138
139 num_failures = spdk_ut_run_tests(argc, argv, NULL);
140 CU_cleanup_registry();
141 return num_failures;
142 }
143