Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2022 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "spdk_internal/cunit.h"
9 : :
10 : : #include "ftl/utils/ftl_bitmap.c"
11 : :
12 : : #define BITMAP_SIZE 64
13 : : #define BITMAP_CAPACITY (BITMAP_SIZE * 8)
14 : :
15 : : #define TEST_BIT(bi, bbi) \
16 : : { .byte_idx = (bi), .byte_bit_idx = (bbi), .bit_idx = (((bi) * 8) + (bbi)) }
17 : :
18 : : static struct {
19 : : size_t byte_idx;
20 : : uint8_t byte_bit_idx;
21 : : uint64_t bit_idx;
22 : : } g_test_bits[] = {
23 : : TEST_BIT(0, 0),
24 : : TEST_BIT(0, 1),
25 : : TEST_BIT(0, 2),
26 : : TEST_BIT(1, 3),
27 : : TEST_BIT(2, 4),
28 : : TEST_BIT(3, 5),
29 : : TEST_BIT(15, 7),
30 : : TEST_BIT(42, 6),
31 : : TEST_BIT(BITMAP_SIZE - 1, 0),
32 : : TEST_BIT(BITMAP_SIZE - 1, 7),
33 : : };
34 : : static const size_t g_test_bits_count = sizeof(g_test_bits) / sizeof(*g_test_bits);
35 : :
36 : : static unsigned long g_buf[BITMAP_SIZE / sizeof(unsigned long)];
37 : : static struct ftl_bitmap *g_bitmap;
38 : :
39 : : static uint64_t
40 : 24 : count_set_bits(const struct ftl_bitmap *bitmap)
41 : : {
42 : 24 : uint64_t n = 0;
43 : : uint64_t i;
44 : :
45 [ + + ]: 12312 : for (i = 0; i < BITMAP_CAPACITY; i++) {
46 [ + + ]: 12288 : if (ftl_bitmap_get(bitmap, i)) {
47 : 3192 : n++;
48 : : }
49 : : }
50 : :
51 : 24 : return n;
52 : : }
53 : :
54 : : static void
55 : 6 : test_ftl_bitmap_create(void)
56 : : {
57 : : struct ftl_bitmap *ret;
58 : :
59 : : /* unaligned buffer */
60 : 6 : ret = ftl_bitmap_create(((uint8_t *)g_buf) + 1, BITMAP_SIZE);
61 : 6 : CU_ASSERT_EQUAL(ret, NULL);
62 : :
63 : : /* wrong size */
64 : 6 : ret = ftl_bitmap_create(g_buf, BITMAP_SIZE - 1);
65 : 6 : CU_ASSERT_EQUAL(ret, NULL);
66 : 6 : }
67 : :
68 : : static void
69 : 6 : test_ftl_bitmap_get(void)
70 : : {
71 : 6 : uint8_t *buf = (uint8_t *)g_buf;
72 : : size_t i;
73 : :
74 [ - + ]: 6 : memset(g_buf, 0, BITMAP_SIZE);
75 : :
76 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
77 [ - + ]: 60 : buf[g_test_bits[i].byte_idx] += (1 << g_test_bits[i].byte_bit_idx);
78 : : }
79 : :
80 : 6 : CU_ASSERT_EQUAL(count_set_bits(g_bitmap), g_test_bits_count);
81 : :
82 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
83 : 60 : CU_ASSERT_TRUE(ftl_bitmap_get(g_bitmap, g_test_bits[i].bit_idx));
84 : : }
85 : 6 : }
86 : :
87 : : static void
88 : 6 : test_ftl_bitmap_set(void)
89 : : {
90 : : size_t i;
91 : :
92 [ - + ]: 6 : memset(g_buf, 0, BITMAP_SIZE);
93 : :
94 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
95 : 60 : ftl_bitmap_set(g_bitmap, g_test_bits[i].bit_idx);
96 : : }
97 : :
98 : 6 : CU_ASSERT_EQUAL(count_set_bits(g_bitmap), g_test_bits_count);
99 : :
100 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
101 : 60 : CU_ASSERT_TRUE(ftl_bitmap_get(g_bitmap, g_test_bits[i].bit_idx));
102 : : }
103 : 6 : }
104 : :
105 : : static void
106 : 6 : test_ftl_bitmap_clear(void)
107 : : {
108 : : size_t i;
109 : :
110 [ - + ]: 6 : memset(g_buf, 0xff, BITMAP_SIZE);
111 : :
112 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
113 : 60 : ftl_bitmap_clear(g_bitmap, g_test_bits[i].bit_idx);
114 : : }
115 : :
116 : 6 : CU_ASSERT_EQUAL(count_set_bits(g_bitmap), BITMAP_CAPACITY - g_test_bits_count);
117 : :
118 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
119 : 60 : CU_ASSERT_FALSE(ftl_bitmap_get(g_bitmap, g_test_bits[i].bit_idx));
120 : : }
121 : 6 : }
122 : :
123 : : static void
124 : 6 : test_ftl_bitmap_find_first_set(void)
125 : : {
126 : : size_t i;
127 : : uint64_t bit;
128 : :
129 [ - + ]: 6 : memset(g_buf, 0, BITMAP_SIZE);
130 : :
131 : 6 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, UINT64_MAX), UINT64_MAX);
132 : :
133 [ + + ]: 66 : for (i = 1; i <= g_test_bits_count; i++) {
134 : 60 : bit = g_test_bits[g_test_bits_count - i].bit_idx;
135 : :
136 : 60 : ftl_bitmap_set(g_bitmap, bit);
137 : :
138 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, UINT64_MAX), bit);
139 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, bit), bit);
140 [ + + ]: 60 : if (bit > 0) {
141 : 54 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, bit - 1), UINT64_MAX);
142 : : }
143 : : }
144 : :
145 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
146 : 60 : bit = g_test_bits[i].bit_idx;
147 : :
148 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, bit, UINT64_MAX), bit);
149 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, bit, bit), bit);
150 : : }
151 : 6 : }
152 : :
153 : : static void
154 : 6 : test_ftl_bitmap_find_first_clear(void)
155 : : {
156 : : size_t i;
157 : : uint64_t bit;
158 : :
159 [ - + ]: 6 : memset(g_buf, 0xff, BITMAP_SIZE);
160 : :
161 : 6 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, UINT64_MAX), UINT64_MAX);
162 : :
163 [ + + ]: 66 : for (i = 1; i <= g_test_bits_count; i++) {
164 : 60 : bit = g_test_bits[g_test_bits_count - i].bit_idx;
165 : :
166 : 60 : ftl_bitmap_clear(g_bitmap, bit);
167 : :
168 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, UINT64_MAX), bit);
169 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, bit), bit);
170 [ + + ]: 60 : if (bit > 0) {
171 : 54 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, bit - 1), UINT64_MAX);
172 : : }
173 : : }
174 : :
175 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
176 : 60 : bit = g_test_bits[i].bit_idx;
177 : :
178 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, bit, UINT64_MAX), bit);
179 : 60 : CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, bit, bit), bit);
180 : : }
181 : 6 : }
182 : :
183 : : static void
184 : 6 : test_ftl_bitmap_count_set(void)
185 : : {
186 : : size_t i;
187 : :
188 [ - + ]: 6 : memset(g_buf, 0, BITMAP_SIZE);
189 : :
190 [ + + ]: 66 : for (i = 0; i < g_test_bits_count; i++) {
191 : 60 : ftl_bitmap_set(g_bitmap, g_test_bits[i].bit_idx);
192 : : }
193 : :
194 : 6 : CU_ASSERT_EQUAL(g_test_bits_count, ftl_bitmap_count_set(g_bitmap));
195 : 6 : CU_ASSERT_EQUAL(count_set_bits(g_bitmap), ftl_bitmap_count_set(g_bitmap));
196 : 6 : }
197 : :
198 : : static int
199 : 6 : test_setup(void)
200 : : {
201 : 6 : g_bitmap = ftl_bitmap_create(g_buf, BITMAP_SIZE);
202 [ - + ]: 6 : if (!g_bitmap) {
203 : 0 : return -ENOMEM;
204 : : }
205 : :
206 : 6 : return 0;
207 : : }
208 : :
209 : : static int
210 : 6 : test_cleanup(void)
211 : : {
212 : 6 : free(g_bitmap);
213 : 6 : g_bitmap = NULL;
214 : 6 : return 0;
215 : : }
216 : :
217 : : int
218 : 6 : main(int argc, char **argv)
219 : : {
220 : 6 : CU_pSuite suite = NULL;
221 : : unsigned int num_failures;
222 : :
223 : 6 : CU_initialize_registry();
224 : :
225 : 6 : suite = CU_add_suite("ftl_bitmap", test_setup, test_cleanup);
226 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_create);
227 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_get);
228 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_set);
229 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_clear);
230 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_find_first_set);
231 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_find_first_clear);
232 : 6 : CU_ADD_TEST(suite, test_ftl_bitmap_count_set);
233 : :
234 : 6 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
235 : 6 : CU_cleanup_registry();
236 : :
237 : 6 : return num_failures;
238 : : }
|