net/netvsc: fix crash during Tx
[dpdk.git] / app / test / test_fbarray.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdbool.h>
6 #include <stdio.h>
7 #include <stdint.h>
8 #include <limits.h>
9
10 #include <rte_common.h>
11 #include <rte_debug.h>
12 #include <rte_errno.h>
13 #include <rte_fbarray.h>
14
15 #include "test.h"
16
17 struct fbarray_testsuite_params {
18         struct rte_fbarray arr;
19         int start;
20         int end;
21 };
22
23 static struct fbarray_testsuite_params param;
24
25 #define FBARRAY_TEST_ARR_NAME "fbarray_autotest"
26 #define FBARRAY_TEST_LEN 256
27 #define FBARRAY_TEST_ELT_SZ (sizeof(int))
28
29 static int autotest_setup(void)
30 {
31         return rte_fbarray_init(&param.arr, FBARRAY_TEST_ARR_NAME,
32                         FBARRAY_TEST_LEN, FBARRAY_TEST_ELT_SZ);
33 }
34
35 static void autotest_teardown(void)
36 {
37         rte_fbarray_destroy(&param.arr);
38 }
39
40 static int init_array(void)
41 {
42         int i;
43         for (i = param.start; i <= param.end; i++) {
44                 if (rte_fbarray_set_used(&param.arr, i))
45                         return -1;
46         }
47         return 0;
48 }
49
50 static void reset_array(void)
51 {
52         int i;
53         for (i = 0; i < FBARRAY_TEST_LEN; i++)
54                 rte_fbarray_set_free(&param.arr, i);
55 }
56
57 static int first_msk_test_setup(void)
58 {
59         /* put all within first mask */
60         param.start = 3;
61         param.end = 10;
62         return init_array();
63 }
64
65 static int cross_msk_test_setup(void)
66 {
67         /* put all within second and third mask */
68         param.start = 70;
69         param.end = 160;
70         return init_array();
71 }
72
73 static int multi_msk_test_setup(void)
74 {
75         /* put all within first and last mask */
76         param.start = 3;
77         param.end = FBARRAY_TEST_LEN - 20;
78         return init_array();
79 }
80
81 static int last_msk_test_setup(void)
82 {
83         /* put all within last mask */
84         param.start = FBARRAY_TEST_LEN - 20;
85         param.end = FBARRAY_TEST_LEN - 1;
86         return init_array();
87 }
88
89 static int full_msk_test_setup(void)
90 {
91         /* fill entire mask */
92         param.start = 0;
93         param.end = FBARRAY_TEST_LEN - 1;
94         return init_array();
95 }
96
97 static int empty_msk_test_setup(void)
98 {
99         /* do not fill anything in */
100         reset_array();
101         param.start = -1;
102         param.end = -1;
103         return 0;
104 }
105
106 static int test_invalid(void)
107 {
108         struct rte_fbarray dummy;
109
110         /* invalid parameters */
111         TEST_ASSERT_FAIL(rte_fbarray_attach(NULL),
112                         "Call succeeded with invalid parameters\n");
113         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
114         TEST_ASSERT_FAIL(rte_fbarray_detach(NULL),
115                         "Call succeeded with invalid parameters\n");
116         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
117
118         TEST_ASSERT_FAIL(rte_fbarray_destroy(NULL),
119                         "Call succeeded with invalid parameters\n");
120         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno valuey\n");
121         TEST_ASSERT_FAIL(rte_fbarray_init(NULL, "fail", 16, 16),
122                         "Call succeeded with invalid parameters\n");
123         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
124         TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, NULL, 16, 16),
125                         "Call succeeded with invalid parameters\n");
126         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
127         TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 0, 16),
128                         "Call succeeded with invalid parameters\n");
129         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
130         TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 16, 0),
131                         "Call succeeded with invalid parameters\n");
132         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
133         /* len must not be greater than INT_MAX */
134         TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", INT_MAX + 1U, 16),
135                         "Call succeeded with invalid parameters\n");
136         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
137
138         TEST_ASSERT_NULL(rte_fbarray_get(NULL, 0),
139                         "Call succeeded with invalid parameters\n");
140         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
141         TEST_ASSERT(rte_fbarray_find_idx(NULL, 0) < 0,
142                         "Call succeeded with invalid parameters\n");
143         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
144         TEST_ASSERT(rte_fbarray_set_free(NULL, 0),
145                         "Call succeeded with invalid parameters\n");
146         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
147         TEST_ASSERT(rte_fbarray_set_used(NULL, 0),
148                         "Call succeeded with invalid parameters\n");
149         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
150         TEST_ASSERT(rte_fbarray_find_contig_free(NULL, 0) < 0,
151                         "Call succeeded with invalid parameters\n");
152         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
153         TEST_ASSERT(rte_fbarray_find_contig_used(NULL, 0) < 0,
154                         "Call succeeded with invalid parameters\n");
155         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
156         TEST_ASSERT(rte_fbarray_find_rev_contig_free(NULL, 0) < 0,
157                         "Call succeeded with invalid parameters\n");
158         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
159         TEST_ASSERT(rte_fbarray_find_rev_contig_used(NULL, 0) < 0,
160                         "Call succeeded with invalid parameters\n");
161         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
162         TEST_ASSERT(rte_fbarray_find_next_free(NULL, 0) < 0,
163                         "Call succeeded with invalid parameters\n");
164         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
165         TEST_ASSERT(rte_fbarray_find_next_used(NULL, 0) < 0,
166                         "Call succeeded with invalid parameters\n");
167         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
168         TEST_ASSERT(rte_fbarray_find_prev_free(NULL, 0) < 0,
169                         "Call succeeded with invalid parameters\n");
170         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
171         TEST_ASSERT(rte_fbarray_find_prev_used(NULL, 0) < 0,
172                         "Call succeeded with invalid parameters\n");
173         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
174         TEST_ASSERT(rte_fbarray_find_next_n_free(NULL, 0, 0) < 0,
175                         "Call succeeded with invalid parameters\n");
176         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
177         TEST_ASSERT(rte_fbarray_find_next_n_used(NULL, 0, 0) < 0,
178                         "Call succeeded with invalid parameters\n");
179         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
180         TEST_ASSERT(rte_fbarray_find_prev_n_free(NULL, 0, 0) < 0,
181                         "Call succeeded with invalid parameters\n");
182         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
183         TEST_ASSERT(rte_fbarray_find_prev_n_used(NULL, 0, 0) < 0,
184                         "Call succeeded with invalid parameters\n");
185         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
186         TEST_ASSERT(rte_fbarray_is_used(NULL, 0) < 0,
187                         "Call succeeded with invalid parameters\n");
188         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
189
190         TEST_ASSERT_SUCCESS(rte_fbarray_init(&dummy, "success",
191                         FBARRAY_TEST_LEN, 8),
192                         "Failed to initialize valid fbarray\n");
193
194         /* test API for handling invalid parameters with a valid fbarray */
195         TEST_ASSERT_NULL(rte_fbarray_get(&dummy, FBARRAY_TEST_LEN),
196                         "Call succeeded with invalid parameters\n");
197         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
198
199         TEST_ASSERT(rte_fbarray_find_idx(&dummy, NULL) < 0,
200                         "Call succeeded with invalid parameters\n");
201         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
202
203         TEST_ASSERT(rte_fbarray_set_free(&dummy, FBARRAY_TEST_LEN),
204                         "Call succeeded with invalid parameters\n");
205         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
206
207         TEST_ASSERT(rte_fbarray_set_used(&dummy, FBARRAY_TEST_LEN),
208                         "Call succeeded with invalid parameters\n");
209         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
210
211         TEST_ASSERT(rte_fbarray_find_contig_free(&dummy, FBARRAY_TEST_LEN) < 0,
212                         "Call succeeded with invalid parameters\n");
213         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
214
215         TEST_ASSERT(rte_fbarray_find_contig_used(&dummy, FBARRAY_TEST_LEN) < 0,
216                         "Call succeeded with invalid parameters\n");
217         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
218
219         TEST_ASSERT(rte_fbarray_find_rev_contig_free(&dummy,
220                         FBARRAY_TEST_LEN) < 0,
221                         "Call succeeded with invalid parameters\n");
222         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
223
224         TEST_ASSERT(rte_fbarray_find_rev_contig_used(&dummy,
225                         FBARRAY_TEST_LEN) < 0,
226                         "Call succeeded with invalid parameters\n");
227         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
228
229         TEST_ASSERT(rte_fbarray_find_next_free(&dummy, FBARRAY_TEST_LEN) < 0,
230                         "Call succeeded with invalid parameters\n");
231         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
232
233         TEST_ASSERT(rte_fbarray_find_next_used(&dummy, FBARRAY_TEST_LEN) < 0,
234                         "Call succeeded with invalid parameters\n");
235         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
236
237         TEST_ASSERT(rte_fbarray_find_prev_free(&dummy, FBARRAY_TEST_LEN) < 0,
238                         "Call succeeded with invalid parameters\n");
239         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
240
241         TEST_ASSERT(rte_fbarray_find_prev_used(&dummy, FBARRAY_TEST_LEN) < 0,
242                         "Call succeeded with invalid parameters\n");
243         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
244
245         TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy,
246                         FBARRAY_TEST_LEN, 1) < 0,
247                         "Call succeeded with invalid parameters\n");
248         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
249         TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0,
250                         FBARRAY_TEST_LEN + 1) < 0,
251                         "Call succeeded with invalid parameters\n");
252         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
253         TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, 0) < 0,
254                         "Call succeeded with invalid parameters\n");
255         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
256
257         TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy,
258                         FBARRAY_TEST_LEN, 1) < 0,
259                         "Call succeeded with invalid parameters\n");
260         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
261         TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0,
262                         FBARRAY_TEST_LEN + 1) < 0,
263                         "Call succeeded with invalid parameters\n");
264         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
265         TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, 0) < 0,
266                         "Call succeeded with invalid parameters\n");
267         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
268
269         TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy,
270                         FBARRAY_TEST_LEN, 1) < 0,
271                         "Call succeeded with invalid parameters\n");
272         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
273         TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0,
274                         FBARRAY_TEST_LEN + 1) < 0,
275                         "Call succeeded with invalid parameters\n");
276         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
277         TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, 0) < 0,
278                         "Call succeeded with invalid parameters\n");
279         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
280
281         TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy,
282                         FBARRAY_TEST_LEN, 1) < 0,
283                         "Call succeeded with invalid parameters\n");
284         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
285         TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0,
286                         FBARRAY_TEST_LEN + 1) < 0,
287                         "Call succeeded with invalid parameters\n");
288         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
289         TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, 0) < 0,
290                         "Call succeeded with invalid parameters\n");
291         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
292
293         TEST_ASSERT(rte_fbarray_is_used(&dummy, FBARRAY_TEST_LEN) < 0,
294                         "Call succeeded with invalid parameters\n");
295         TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n");
296
297         TEST_ASSERT_SUCCESS(rte_fbarray_destroy(&dummy),
298                         "Failed to destroy valid fbarray\n");
299
300         return TEST_SUCCESS;
301 }
302
303 static int check_free(void)
304 {
305         const int idx = 0;
306         const int last_idx = FBARRAY_TEST_LEN - 1;
307
308         /* ensure we can find a free spot */
309         TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(&param.arr, idx), idx,
310                         "Free space not found where expected\n");
311         TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(&param.arr, idx, 1), idx,
312                         "Free space not found where expected\n");
313         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(&param.arr, idx),
314                         FBARRAY_TEST_LEN,
315                         "Free space not found where expected\n");
316
317         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(&param.arr, idx), idx,
318                         "Free space not found where expected\n");
319         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(&param.arr, idx, 1), idx,
320                         "Free space not found where expected\n");
321         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(&param.arr, idx), 1,
322                         "Free space not found where expected\n");
323
324         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(&param.arr, last_idx),
325                         last_idx, "Free space not found where expected\n");
326         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(&param.arr, last_idx, 1),
327                         last_idx, "Free space not found where expected\n");
328         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(&param.arr,
329                         last_idx), FBARRAY_TEST_LEN,
330                         "Free space not found where expected\n");
331
332         /* ensure we can't find any used spots */
333         TEST_ASSERT(rte_fbarray_find_next_used(&param.arr, idx) < 0,
334                         "Used space found where none was expected\n");
335         TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n");
336         TEST_ASSERT(rte_fbarray_find_next_n_used(&param.arr, idx, 1) < 0,
337                         "Used space found where none was expected\n");
338         TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n");
339         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(&param.arr, idx), 0,
340                         "Used space found where none was expected\n");
341
342         TEST_ASSERT(rte_fbarray_find_prev_used(&param.arr, last_idx) < 0,
343                         "Used space found where none was expected\n");
344         TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n");
345         TEST_ASSERT(rte_fbarray_find_prev_n_used(&param.arr, last_idx, 1) < 0,
346                         "Used space found where none was expected\n");
347         TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n");
348         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(&param.arr,
349                         last_idx), 0,
350                         "Used space found where none was expected\n");
351
352         return 0;
353 }
354
355 static int check_used_one(void)
356 {
357         const int idx = 0;
358         const int last_idx = FBARRAY_TEST_LEN - 1;
359
360         /* check that we can find used spots now */
361         TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(&param.arr, idx), idx,
362                         "Used space not found where expected\n");
363         TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(&param.arr, idx, 1), idx,
364                         "Used space not found where expected\n");
365         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(&param.arr, idx), 1,
366                         "Used space not found where expected\n");
367
368         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(&param.arr, last_idx), idx,
369                         "Used space not found where expected\n");
370         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(&param.arr, last_idx, 1),
371                         idx, "Used space not found where expected\n");
372         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(&param.arr, idx), 1,
373                         "Used space not found where expected\n");
374         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(&param.arr,
375                         last_idx), idx,
376                         "Used space not found where expected\n");
377
378         /* check if further indices are still free */
379         TEST_ASSERT(rte_fbarray_find_next_used(&param.arr, idx + 1) < 0,
380                         "Used space not found where none was expected\n");
381         TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n");
382         TEST_ASSERT(rte_fbarray_find_next_n_used(&param.arr, idx + 1, 1) < 0,
383                         "Used space not found where none was expected\n");
384         TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n");
385         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(&param.arr, idx + 1), 0,
386                         "Used space not found where none was expected\n");
387         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(&param.arr, idx + 1),
388                         FBARRAY_TEST_LEN - 1,
389                         "Used space not found where none was expected\n");
390
391         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(&param.arr, last_idx), 0,
392                         "Used space not found where none was expected\n");
393         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(&param.arr, last_idx, 1),
394                         0, "Used space not found where none was expected\n");
395         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(&param.arr,
396                         last_idx), 0,
397                         "Used space not found where none was expected\n");
398         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(&param.arr,
399                         last_idx), FBARRAY_TEST_LEN - 1,
400                         "Used space not found where none was expected\n");
401
402         return 0;
403 }
404
405 static int test_basic(void)
406 {
407         const int idx = 0;
408         int i;
409
410         /* check array count */
411         TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n");
412
413         /* ensure we can find a free spot */
414         if (check_free())
415                 return TEST_FAILED;
416
417         /* check if used */
418         TEST_ASSERT_EQUAL(rte_fbarray_is_used(&param.arr, idx), 0,
419                         "Used space found where not expected\n");
420
421         /* mark as used */
422         TEST_ASSERT_SUCCESS(rte_fbarray_set_used(&param.arr, idx),
423                         "Failed to set as used\n");
424
425         /* check if used again */
426         TEST_ASSERT_NOT_EQUAL(rte_fbarray_is_used(&param.arr, idx), 0,
427                         "Used space not found where expected\n");
428
429         if (check_used_one())
430                 return TEST_FAILED;
431
432         /* check array count */
433         TEST_ASSERT_EQUAL(param.arr.count, 1, "Wrong element count\n");
434
435         /* check if getting pointers works for every element */
436         for (i = 0; i < FBARRAY_TEST_LEN; i++) {
437                 void *td = rte_fbarray_get(&param.arr, i);
438                 TEST_ASSERT_NOT_NULL(td, "Invalid pointer returned\n");
439                 TEST_ASSERT_EQUAL(rte_fbarray_find_idx(&param.arr, td), i,
440                                 "Wrong index returned\n");
441         }
442
443         /* mark as free */
444         TEST_ASSERT_SUCCESS(rte_fbarray_set_free(&param.arr, idx),
445                         "Failed to set as free\n");
446
447         /* check array count */
448         TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n");
449
450         /* check if used */
451         TEST_ASSERT_EQUAL(rte_fbarray_is_used(&param.arr, idx), 0,
452                         "Used space found where not expected\n");
453
454         if (check_free())
455                 return TEST_FAILED;
456
457         reset_array();
458
459         return TEST_SUCCESS;
460 }
461
462 static int test_biggest(struct rte_fbarray *arr, int first, int last)
463 {
464         int lo_free_space_first, lo_free_space_last, lo_free_space_len;
465         int hi_free_space_first, hi_free_space_last, hi_free_space_len;
466         int max_free_space_first, max_free_space_last, max_free_space_len;
467         int len = last - first + 1;
468
469         /* first and last must either be both -1, or both not -1 */
470         TEST_ASSERT((first == -1) == (last == -1),
471                         "Invalid arguments provided\n");
472
473         /* figure out what we expect from the low chunk of free space */
474         if (first == -1) {
475                 /* special case: if there are no occupied elements at all,
476                  * consider both free spaces to consume the entire array.
477                  */
478                 lo_free_space_first = 0;
479                 lo_free_space_last = arr->len - 1;
480                 lo_free_space_len = arr->len;
481                 /* if there's no used space, length should be invalid */
482                 len = -1;
483         } else if (first == 0) {
484                 /* if occupied items start at 0, there's no free space */
485                 lo_free_space_first = -1;
486                 lo_free_space_last = -1;
487                 lo_free_space_len = 0;
488         } else {
489                 lo_free_space_first = 0;
490                 lo_free_space_last = first - 1;
491                 lo_free_space_len = lo_free_space_last -
492                                 lo_free_space_first + 1;
493         }
494
495         /* figure out what we expect from the high chunk of free space */
496         if (last == -1) {
497                 /* special case: if there are no occupied elements at all,
498                  * consider both free spaces to consume the entire array.
499                  */
500                 hi_free_space_first = 0;
501                 hi_free_space_last = arr->len - 1;
502                 hi_free_space_len = arr->len;
503                 /* if there's no used space, length should be invalid */
504                 len = -1;
505         } else if (last == ((int)arr->len - 1)) {
506                 /* if occupied items end at array len, there's no free space */
507                 hi_free_space_first = -1;
508                 hi_free_space_last = -1;
509                 hi_free_space_len = 0;
510         } else {
511                 hi_free_space_first = last + 1;
512                 hi_free_space_last = arr->len - 1;
513                 hi_free_space_len = hi_free_space_last -
514                                 hi_free_space_first + 1;
515         }
516
517         /* find which one will be biggest */
518         if (lo_free_space_len > hi_free_space_len) {
519                 max_free_space_first = lo_free_space_first;
520                 max_free_space_last = lo_free_space_last;
521                 max_free_space_len = lo_free_space_len;
522         } else {
523                 /* if they are equal, we'll just use the high chunk */
524                 max_free_space_first = hi_free_space_first;
525                 max_free_space_last = hi_free_space_last;
526                 max_free_space_len = hi_free_space_len;
527         }
528
529         /* check used regions - these should produce identical results */
530         TEST_ASSERT_EQUAL(rte_fbarray_find_biggest_used(arr, 0), first,
531                         "Used space index is wrong\n");
532         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_biggest_used(arr, arr->len - 1),
533                         first,
534                         "Used space index is wrong\n");
535         /* len may be -1, but function will return error anyway */
536         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(arr, first), len,
537                         "Used space length is wrong\n");
538
539         /* check if biggest free region is the one we expect to find. It can be
540          * -1 if there's no free space - we've made sure we use one or the
541          * other, even if both are invalid.
542          */
543         TEST_ASSERT_EQUAL(rte_fbarray_find_biggest_free(arr, 0),
544                         max_free_space_first,
545                         "Biggest free space index is wrong\n");
546         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_biggest_free(arr, arr->len - 1),
547                         max_free_space_first,
548                         "Biggest free space index is wrong\n");
549
550         /* if biggest region exists, check its length */
551         if (max_free_space_first != -1) {
552                 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr,
553                                         max_free_space_first),
554                                 max_free_space_len,
555                                 "Biggest free space length is wrong\n");
556                 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr,
557                                         max_free_space_last),
558                                 max_free_space_len,
559                                 "Biggest free space length is wrong\n");
560         }
561
562         /* find if we see what we expect to see in the low region. if there is
563          * no free space, the function should still match expected value, as
564          * we've set it to -1. we're scanning backwards to avoid accidentally
565          * hitting the high free space region. if there is no occupied space,
566          * there's nothing to do.
567          */
568         if (last != -1) {
569                 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_biggest_free(arr, last),
570                                 lo_free_space_first,
571                                 "Low free space index is wrong\n");
572         }
573
574         if (lo_free_space_first != -1) {
575                 /* if low free region exists, check its length */
576                 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr,
577                                         lo_free_space_first),
578                                 lo_free_space_len,
579                                 "Low free space length is wrong\n");
580                 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr,
581                                         lo_free_space_last),
582                                 lo_free_space_len,
583                                 "Low free space length is wrong\n");
584         }
585
586         /* find if we see what we expect to see in the high region. if there is
587          * no free space, the function should still match expected value, as
588          * we've set it to -1. we're scanning forwards to avoid accidentally
589          * hitting the low free space region. if there is no occupied space,
590          * there's nothing to do.
591          */
592         if (first != -1) {
593                 TEST_ASSERT_EQUAL(rte_fbarray_find_biggest_free(arr, first),
594                                 hi_free_space_first,
595                                 "High free space index is wrong\n");
596         }
597
598         /* if high free region exists, check its length */
599         if (hi_free_space_first != -1) {
600                 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr,
601                                         hi_free_space_first),
602                                 hi_free_space_len,
603                                 "High free space length is wrong\n");
604                 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr,
605                                         hi_free_space_last),
606                                 hi_free_space_len,
607                                 "High free space length is wrong\n");
608         }
609
610         return 0;
611 }
612
613 static int ensure_correct(struct rte_fbarray *arr, int first, int last,
614                 bool used)
615 {
616         int i, len = last - first + 1;
617         for (i = 0; i < len; i++) {
618                 int cur = first + i;
619                 int cur_len = len - i;
620
621                 if (used) {
622                         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(arr,
623                                         cur), cur_len,
624                                         "Used space length is wrong\n");
625                         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr,
626                                         last), len,
627                                         "Used space length is wrong\n");
628                         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr,
629                                         cur), i + 1,
630                                         "Used space length is wrong\n");
631
632                         TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(arr, cur),
633                                         cur,
634                                         "Used space not found where expected\n");
635                         TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr,
636                                         cur, 1), cur,
637                                         "Used space not found where expected\n");
638                         TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, cur,
639                                         cur_len), cur,
640                                         "Used space not found where expected\n");
641
642                         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(arr, cur),
643                                         cur,
644                                         "Used space not found where expected\n");
645                         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(arr,
646                                         last, cur_len), cur,
647                                         "Used space not found where expected\n");
648                 } else {
649                         TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr,
650                                         cur), cur_len,
651                                         "Free space length is wrong\n");
652                         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr,
653                                         last), len,
654                                         "Free space length is wrong\n");
655                         TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr,
656                                         cur), i + 1,
657                                         "Free space length is wrong\n");
658
659                         TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(arr, cur),
660                                         cur,
661                                         "Free space not found where expected\n");
662                         TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur,
663                                         1), cur,
664                                         "Free space not found where expected\n");
665                         TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur,
666                                         cur_len), cur,
667                                         "Free space not found where expected\n");
668
669                         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(arr, cur),
670                                         cur,
671                                         "Free space not found where expected\n");
672                         TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(arr,
673                                         last, cur_len), cur,
674                                         "Free space not found where expected\n");
675                 }
676         }
677         return 0;
678 }
679
680 static int test_find(void)
681 {
682         TEST_ASSERT_EQUAL((int)param.arr.count, param.end - param.start + 1,
683                         "Wrong element count\n");
684         /* ensure space is free before start */
685         if (ensure_correct(&param.arr, 0, param.start - 1, false))
686                 return TEST_FAILED;
687         /* ensure space is occupied where it's supposed to be */
688         if (ensure_correct(&param.arr, param.start, param.end, true))
689                 return TEST_FAILED;
690         /* ensure space after end is free as well */
691         if (ensure_correct(&param.arr, param.end + 1, FBARRAY_TEST_LEN - 1,
692                         false))
693                 return TEST_FAILED;
694         /* test if find_biggest API's work correctly */
695         if (test_biggest(&param.arr, param.start, param.end))
696                 return TEST_FAILED;
697         return TEST_SUCCESS;
698 }
699
700 static int test_empty(void)
701 {
702         TEST_ASSERT_EQUAL((int)param.arr.count, 0, "Wrong element count\n");
703         /* ensure space is free */
704         if (ensure_correct(&param.arr, 0, FBARRAY_TEST_LEN - 1, false))
705                 return TEST_FAILED;
706         /* test if find_biggest API's work correctly */
707         if (test_biggest(&param.arr, param.start, param.end))
708                 return TEST_FAILED;
709         return TEST_SUCCESS;
710 }
711
712
713 static struct unit_test_suite fbarray_test_suite = {
714         .suite_name = "fbarray autotest",
715         .setup = autotest_setup,
716         .teardown = autotest_teardown,
717         .unit_test_cases = {
718                 TEST_CASE(test_invalid),
719                 TEST_CASE(test_basic),
720                 TEST_CASE_ST(first_msk_test_setup, reset_array, test_find),
721                 TEST_CASE_ST(cross_msk_test_setup, reset_array, test_find),
722                 TEST_CASE_ST(multi_msk_test_setup, reset_array, test_find),
723                 TEST_CASE_ST(last_msk_test_setup, reset_array, test_find),
724                 TEST_CASE_ST(full_msk_test_setup, reset_array, test_find),
725                 TEST_CASE_ST(empty_msk_test_setup, reset_array, test_empty),
726                 TEST_CASES_END()
727         }
728 };
729
730 static int
731 test_fbarray(void)
732 {
733         return unit_test_suite_runner(&fbarray_test_suite);
734 }
735
736 REGISTER_TEST_COMMAND(fbarray_autotest, test_fbarray);