xref: /spdk/test/unit/include/spdk/histogram_data.h/histogram_ut.c (revision ea941caeaf896fdf2aef7685f86f37023060faed)
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