blob: e2cbd43d193cff9de5e92f5a7e85fd9f53790210
1 | /* |
2 | * Test cases for printf facility. |
3 | */ |
4 | |
5 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
6 | |
7 | #include <linux/bitmap.h> |
8 | #include <linux/init.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> |
11 | #include <linux/printk.h> |
12 | #include <linux/slab.h> |
13 | #include <linux/string.h> |
14 | |
15 | static unsigned total_tests __initdata; |
16 | static unsigned failed_tests __initdata; |
17 | |
18 | static char pbl_buffer[PAGE_SIZE] __initdata; |
19 | |
20 | |
21 | static bool __init |
22 | __check_eq_uint(const char *srcfile, unsigned int line, |
23 | const unsigned int exp_uint, unsigned int x) |
24 | { |
25 | if (exp_uint != x) { |
26 | pr_warn("[%s:%u] expected %u, got %u\n", |
27 | srcfile, line, exp_uint, x); |
28 | return false; |
29 | } |
30 | return true; |
31 | } |
32 | |
33 | |
34 | static bool __init |
35 | __check_eq_bitmap(const char *srcfile, unsigned int line, |
36 | const unsigned long *exp_bmap, unsigned int exp_nbits, |
37 | const unsigned long *bmap, unsigned int nbits) |
38 | { |
39 | if (exp_nbits != nbits) { |
40 | pr_warn("[%s:%u] bitmap length mismatch: expected %u, got %u\n", |
41 | srcfile, line, exp_nbits, nbits); |
42 | return false; |
43 | } |
44 | |
45 | if (!bitmap_equal(exp_bmap, bmap, nbits)) { |
46 | pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n", |
47 | srcfile, line, |
48 | exp_nbits, exp_bmap, nbits, bmap); |
49 | return false; |
50 | } |
51 | return true; |
52 | } |
53 | |
54 | static bool __init |
55 | __check_eq_pbl(const char *srcfile, unsigned int line, |
56 | const char *expected_pbl, |
57 | const unsigned long *bitmap, unsigned int nbits) |
58 | { |
59 | snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap); |
60 | if (strcmp(expected_pbl, pbl_buffer)) { |
61 | pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n", |
62 | srcfile, line, |
63 | expected_pbl, pbl_buffer); |
64 | return false; |
65 | } |
66 | return true; |
67 | } |
68 | |
69 | static bool __init |
70 | __check_eq_u32_array(const char *srcfile, unsigned int line, |
71 | const u32 *exp_arr, unsigned int exp_len, |
72 | const u32 *arr, unsigned int len) |
73 | { |
74 | if (exp_len != len) { |
75 | pr_warn("[%s:%u] array length differ: expected %u, got %u\n", |
76 | srcfile, line, |
77 | exp_len, len); |
78 | return false; |
79 | } |
80 | |
81 | if (memcmp(exp_arr, arr, len*sizeof(*arr))) { |
82 | pr_warn("[%s:%u] array contents differ\n", srcfile, line); |
83 | print_hex_dump(KERN_WARNING, " exp: ", DUMP_PREFIX_OFFSET, |
84 | 32, 4, exp_arr, exp_len*sizeof(*exp_arr), false); |
85 | print_hex_dump(KERN_WARNING, " got: ", DUMP_PREFIX_OFFSET, |
86 | 32, 4, arr, len*sizeof(*arr), false); |
87 | return false; |
88 | } |
89 | |
90 | return true; |
91 | } |
92 | |
93 | #define __expect_eq(suffix, ...) \ |
94 | ({ \ |
95 | int result = 0; \ |
96 | total_tests++; \ |
97 | if (!__check_eq_ ## suffix(__FILE__, __LINE__, \ |
98 | ##__VA_ARGS__)) { \ |
99 | failed_tests++; \ |
100 | result = 1; \ |
101 | } \ |
102 | result; \ |
103 | }) |
104 | |
105 | #define expect_eq_uint(...) __expect_eq(uint, ##__VA_ARGS__) |
106 | #define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__) |
107 | #define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__) |
108 | #define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__) |
109 | |
110 | static void __init test_zero_fill_copy(void) |
111 | { |
112 | DECLARE_BITMAP(bmap1, 1024); |
113 | DECLARE_BITMAP(bmap2, 1024); |
114 | |
115 | bitmap_zero(bmap1, 1024); |
116 | bitmap_zero(bmap2, 1024); |
117 | |
118 | /* single-word bitmaps */ |
119 | expect_eq_pbl("", bmap1, 23); |
120 | |
121 | bitmap_fill(bmap1, 19); |
122 | expect_eq_pbl("0-18", bmap1, 1024); |
123 | |
124 | bitmap_copy(bmap2, bmap1, 23); |
125 | expect_eq_pbl("0-18", bmap2, 1024); |
126 | |
127 | bitmap_fill(bmap2, 23); |
128 | expect_eq_pbl("0-22", bmap2, 1024); |
129 | |
130 | bitmap_copy(bmap2, bmap1, 23); |
131 | expect_eq_pbl("0-18", bmap2, 1024); |
132 | |
133 | bitmap_zero(bmap1, 23); |
134 | expect_eq_pbl("", bmap1, 1024); |
135 | |
136 | /* multi-word bitmaps */ |
137 | bitmap_zero(bmap1, 1024); |
138 | expect_eq_pbl("", bmap1, 1024); |
139 | |
140 | bitmap_fill(bmap1, 109); |
141 | expect_eq_pbl("0-108", bmap1, 1024); |
142 | |
143 | bitmap_copy(bmap2, bmap1, 1024); |
144 | expect_eq_pbl("0-108", bmap2, 1024); |
145 | |
146 | bitmap_fill(bmap2, 1024); |
147 | expect_eq_pbl("0-1023", bmap2, 1024); |
148 | |
149 | bitmap_copy(bmap2, bmap1, 1024); |
150 | expect_eq_pbl("0-108", bmap2, 1024); |
151 | |
152 | /* the following tests assume a 32- or 64-bit arch (even 128b |
153 | * if we care) |
154 | */ |
155 | |
156 | bitmap_fill(bmap2, 1024); |
157 | bitmap_copy(bmap2, bmap1, 109); /* ... but 0-padded til word length */ |
158 | expect_eq_pbl("0-108,128-1023", bmap2, 1024); |
159 | |
160 | bitmap_fill(bmap2, 1024); |
161 | bitmap_copy(bmap2, bmap1, 97); /* ... but aligned on word length */ |
162 | expect_eq_pbl("0-108,128-1023", bmap2, 1024); |
163 | |
164 | bitmap_zero(bmap2, 97); /* ... but 0-padded til word length */ |
165 | expect_eq_pbl("128-1023", bmap2, 1024); |
166 | } |
167 | |
168 | static void __init test_bitmap_u32_array_conversions(void) |
169 | { |
170 | DECLARE_BITMAP(bmap1, 1024); |
171 | DECLARE_BITMAP(bmap2, 1024); |
172 | u32 exp_arr[32], arr[32]; |
173 | unsigned nbits; |
174 | |
175 | for (nbits = 0 ; nbits < 257 ; ++nbits) { |
176 | const unsigned int used_u32s = DIV_ROUND_UP(nbits, 32); |
177 | unsigned int i, rv; |
178 | |
179 | bitmap_zero(bmap1, nbits); |
180 | bitmap_set(bmap1, nbits, 1024 - nbits); /* garbage */ |
181 | |
182 | memset(arr, 0xff, sizeof(arr)); |
183 | rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits); |
184 | expect_eq_uint(nbits, rv); |
185 | |
186 | memset(exp_arr, 0xff, sizeof(exp_arr)); |
187 | memset(exp_arr, 0, used_u32s*sizeof(*exp_arr)); |
188 | expect_eq_u32_array(exp_arr, 32, arr, 32); |
189 | |
190 | bitmap_fill(bmap2, 1024); |
191 | rv = bitmap_from_u32array(bmap2, nbits, arr, used_u32s); |
192 | expect_eq_uint(nbits, rv); |
193 | expect_eq_bitmap(bmap1, 1024, bmap2, 1024); |
194 | |
195 | for (i = 0 ; i < nbits ; ++i) { |
196 | /* |
197 | * test conversion bitmap -> u32[] |
198 | */ |
199 | |
200 | bitmap_zero(bmap1, 1024); |
201 | __set_bit(i, bmap1); |
202 | bitmap_set(bmap1, nbits, 1024 - nbits); /* garbage */ |
203 | |
204 | memset(arr, 0xff, sizeof(arr)); |
205 | rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits); |
206 | expect_eq_uint(nbits, rv); |
207 | |
208 | /* 1st used u32 words contain expected bit set, the |
209 | * remaining words are left unchanged (0xff) |
210 | */ |
211 | memset(exp_arr, 0xff, sizeof(exp_arr)); |
212 | memset(exp_arr, 0, used_u32s*sizeof(*exp_arr)); |
213 | exp_arr[i/32] = (1U<<(i%32)); |
214 | expect_eq_u32_array(exp_arr, 32, arr, 32); |
215 | |
216 | |
217 | /* same, with longer array to fill |
218 | */ |
219 | memset(arr, 0xff, sizeof(arr)); |
220 | rv = bitmap_to_u32array(arr, 32, bmap1, nbits); |
221 | expect_eq_uint(nbits, rv); |
222 | |
223 | /* 1st used u32 words contain expected bit set, the |
224 | * remaining words are all 0s |
225 | */ |
226 | memset(exp_arr, 0, sizeof(exp_arr)); |
227 | exp_arr[i/32] = (1U<<(i%32)); |
228 | expect_eq_u32_array(exp_arr, 32, arr, 32); |
229 | |
230 | /* |
231 | * test conversion u32[] -> bitmap |
232 | */ |
233 | |
234 | /* the 1st nbits of bmap2 are identical to |
235 | * bmap1, the remaining bits of bmap2 are left |
236 | * unchanged (all 1s) |
237 | */ |
238 | bitmap_fill(bmap2, 1024); |
239 | rv = bitmap_from_u32array(bmap2, nbits, |
240 | exp_arr, used_u32s); |
241 | expect_eq_uint(nbits, rv); |
242 | |
243 | expect_eq_bitmap(bmap1, 1024, bmap2, 1024); |
244 | |
245 | /* same, with more bits to fill |
246 | */ |
247 | memset(arr, 0xff, sizeof(arr)); /* garbage */ |
248 | memset(arr, 0, used_u32s*sizeof(u32)); |
249 | arr[i/32] = (1U<<(i%32)); |
250 | |
251 | bitmap_fill(bmap2, 1024); |
252 | rv = bitmap_from_u32array(bmap2, 1024, arr, used_u32s); |
253 | expect_eq_uint(used_u32s*32, rv); |
254 | |
255 | /* the 1st nbits of bmap2 are identical to |
256 | * bmap1, the remaining bits of bmap2 are cleared |
257 | */ |
258 | bitmap_zero(bmap1, 1024); |
259 | __set_bit(i, bmap1); |
260 | expect_eq_bitmap(bmap1, 1024, bmap2, 1024); |
261 | |
262 | |
263 | /* |
264 | * test short conversion bitmap -> u32[] (1 |
265 | * word too short) |
266 | */ |
267 | if (used_u32s > 1) { |
268 | bitmap_zero(bmap1, 1024); |
269 | __set_bit(i, bmap1); |
270 | bitmap_set(bmap1, nbits, |
271 | 1024 - nbits); /* garbage */ |
272 | memset(arr, 0xff, sizeof(arr)); |
273 | |
274 | rv = bitmap_to_u32array(arr, used_u32s - 1, |
275 | bmap1, nbits); |
276 | expect_eq_uint((used_u32s - 1)*32, rv); |
277 | |
278 | /* 1st used u32 words contain expected |
279 | * bit set, the remaining words are |
280 | * left unchanged (0xff) |
281 | */ |
282 | memset(exp_arr, 0xff, sizeof(exp_arr)); |
283 | memset(exp_arr, 0, |
284 | (used_u32s-1)*sizeof(*exp_arr)); |
285 | if ((i/32) < (used_u32s - 1)) |
286 | exp_arr[i/32] = (1U<<(i%32)); |
287 | expect_eq_u32_array(exp_arr, 32, arr, 32); |
288 | } |
289 | |
290 | /* |
291 | * test short conversion u32[] -> bitmap (3 |
292 | * bits too short) |
293 | */ |
294 | if (nbits > 3) { |
295 | memset(arr, 0xff, sizeof(arr)); /* garbage */ |
296 | memset(arr, 0, used_u32s*sizeof(*arr)); |
297 | arr[i/32] = (1U<<(i%32)); |
298 | |
299 | bitmap_zero(bmap1, 1024); |
300 | rv = bitmap_from_u32array(bmap1, nbits - 3, |
301 | arr, used_u32s); |
302 | expect_eq_uint(nbits - 3, rv); |
303 | |
304 | /* we are expecting the bit < nbits - |
305 | * 3 (none otherwise), and the rest of |
306 | * bmap1 unchanged (0-filled) |
307 | */ |
308 | bitmap_zero(bmap2, 1024); |
309 | if (i < nbits - 3) |
310 | __set_bit(i, bmap2); |
311 | expect_eq_bitmap(bmap2, 1024, bmap1, 1024); |
312 | |
313 | /* do the same with bmap1 initially |
314 | * 1-filled |
315 | */ |
316 | |
317 | bitmap_fill(bmap1, 1024); |
318 | rv = bitmap_from_u32array(bmap1, nbits - 3, |
319 | arr, used_u32s); |
320 | expect_eq_uint(nbits - 3, rv); |
321 | |
322 | /* we are expecting the bit < nbits - |
323 | * 3 (none otherwise), and the rest of |
324 | * bmap1 unchanged (1-filled) |
325 | */ |
326 | bitmap_zero(bmap2, 1024); |
327 | if (i < nbits - 3) |
328 | __set_bit(i, bmap2); |
329 | bitmap_set(bmap2, nbits-3, 1024 - nbits + 3); |
330 | expect_eq_bitmap(bmap2, 1024, bmap1, 1024); |
331 | } |
332 | } |
333 | } |
334 | } |
335 | |
336 | static int __init test_bitmap_init(void) |
337 | { |
338 | test_zero_fill_copy(); |
339 | test_bitmap_u32_array_conversions(); |
340 | |
341 | if (failed_tests == 0) |
342 | pr_info("all %u tests passed\n", total_tests); |
343 | else |
344 | pr_warn("failed %u out of %u tests\n", |
345 | failed_tests, total_tests); |
346 | |
347 | return failed_tests ? -EINVAL : 0; |
348 | } |
349 | |
350 | static void __exit test_bitmap_cleanup(void) |
351 | { |
352 | } |
353 | |
354 | module_init(test_bitmap_init); |
355 | module_exit(test_bitmap_cleanup); |
356 | |
357 | MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>"); |
358 | MODULE_LICENSE("GPL"); |
359 |