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 static struct fbarray_testsuite_params unaligned; 25 26 #define FBARRAY_TEST_ARR_NAME "fbarray_autotest" 27 #define FBARRAY_TEST_LEN 256 28 #define FBARRAY_UNALIGNED_TEST_ARR_NAME "fbarray_unaligned_autotest" 29 #define FBARRAY_UNALIGNED_TEST_LEN 60 30 #define FBARRAY_TEST_ELT_SZ (sizeof(int)) 31 32 static int autotest_setup(void) 33 { 34 int ret; 35 36 ret = rte_fbarray_init(¶m.arr, FBARRAY_TEST_ARR_NAME, 37 FBARRAY_TEST_LEN, FBARRAY_TEST_ELT_SZ); 38 if (ret) { 39 printf("Failed to initialize test array\n"); 40 return -1; 41 } 42 ret = rte_fbarray_init(&unaligned.arr, FBARRAY_UNALIGNED_TEST_ARR_NAME, 43 FBARRAY_UNALIGNED_TEST_LEN, FBARRAY_TEST_ELT_SZ); 44 if (ret) { 45 printf("Failed to initialize unaligned test array\n"); 46 rte_fbarray_destroy(¶m.arr); 47 return -1; 48 } 49 return 0; 50 } 51 52 static void autotest_teardown(void) 53 { 54 rte_fbarray_destroy(¶m.arr); 55 rte_fbarray_destroy(&unaligned.arr); 56 } 57 58 static int init_aligned(void) 59 { 60 int i; 61 for (i = param.start; i <= param.end; i++) { 62 if (rte_fbarray_set_used(¶m.arr, i)) 63 return -1; 64 } 65 return 0; 66 } 67 68 static int init_unaligned(void) 69 { 70 int i; 71 for (i = unaligned.start; i <= unaligned.end; i++) { 72 if (rte_fbarray_set_used(&unaligned.arr, i)) 73 return -1; 74 } 75 return 0; 76 } 77 78 static void reset_aligned(void) 79 { 80 int i; 81 for (i = 0; i < FBARRAY_TEST_LEN; i++) 82 rte_fbarray_set_free(¶m.arr, i); 83 /* reset param as well */ 84 param.start = -1; 85 param.end = -1; 86 } 87 88 static void reset_unaligned(void) 89 { 90 int i; 91 for (i = 0; i < FBARRAY_UNALIGNED_TEST_LEN; i++) 92 rte_fbarray_set_free(&unaligned.arr, i); 93 /* reset param as well */ 94 unaligned.start = -1; 95 unaligned.end = -1; 96 97 } 98 99 static int first_msk_test_setup(void) 100 { 101 /* put all within first mask */ 102 param.start = 3; 103 param.end = 10; 104 return init_aligned(); 105 } 106 107 static int cross_msk_test_setup(void) 108 { 109 /* put all within second and third mask */ 110 param.start = 70; 111 param.end = 160; 112 return init_aligned(); 113 } 114 115 static int multi_msk_test_setup(void) 116 { 117 /* put all within first and last mask */ 118 param.start = 3; 119 param.end = FBARRAY_TEST_LEN - 20; 120 return init_aligned(); 121 } 122 123 static int last_msk_test_setup(void) 124 { 125 /* put all within last mask */ 126 param.start = FBARRAY_TEST_LEN - 20; 127 param.end = FBARRAY_TEST_LEN - 1; 128 return init_aligned(); 129 } 130 131 static int full_msk_test_setup(void) 132 { 133 /* fill entire mask */ 134 param.start = 0; 135 param.end = FBARRAY_TEST_LEN - 1; 136 return init_aligned(); 137 } 138 139 static int lookahead_test_setup(void) 140 { 141 /* set index 64 as used */ 142 param.start = 64; 143 param.end = 64; 144 return init_aligned(); 145 } 146 147 static int lookbehind_test_setup(void) 148 { 149 /* set index 63 as used */ 150 param.start = 63; 151 param.end = 63; 152 return init_aligned(); 153 } 154 155 static int unaligned_test_setup(void) 156 { 157 unaligned.start = 0; 158 /* leave one free bit at the end */ 159 unaligned.end = FBARRAY_UNALIGNED_TEST_LEN - 2; 160 return init_unaligned(); 161 } 162 163 static int test_invalid(void) 164 { 165 struct rte_fbarray dummy; 166 167 /* invalid parameters */ 168 TEST_ASSERT_FAIL(rte_fbarray_attach(NULL), 169 "Call succeeded with invalid parameters\n"); 170 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 171 TEST_ASSERT_FAIL(rte_fbarray_detach(NULL), 172 "Call succeeded with invalid parameters\n"); 173 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 174 175 TEST_ASSERT_FAIL(rte_fbarray_destroy(NULL), 176 "Call succeeded with invalid parameters\n"); 177 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno valuey\n"); 178 TEST_ASSERT_FAIL(rte_fbarray_init(NULL, "fail", 16, 16), 179 "Call succeeded with invalid parameters\n"); 180 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 181 TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, NULL, 16, 16), 182 "Call succeeded with invalid parameters\n"); 183 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 184 TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 0, 16), 185 "Call succeeded with invalid parameters\n"); 186 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 187 TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", 16, 0), 188 "Call succeeded with invalid parameters\n"); 189 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 190 /* len must not be greater than INT_MAX */ 191 TEST_ASSERT_FAIL(rte_fbarray_init(&dummy, "fail", INT_MAX + 1U, 16), 192 "Call succeeded with invalid parameters\n"); 193 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 194 195 TEST_ASSERT_NULL(rte_fbarray_get(NULL, 0), 196 "Call succeeded with invalid parameters\n"); 197 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 198 TEST_ASSERT(rte_fbarray_find_idx(NULL, 0) < 0, 199 "Call succeeded with invalid parameters\n"); 200 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 201 TEST_ASSERT(rte_fbarray_set_free(NULL, 0), 202 "Call succeeded with invalid parameters\n"); 203 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 204 TEST_ASSERT(rte_fbarray_set_used(NULL, 0), 205 "Call succeeded with invalid parameters\n"); 206 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 207 TEST_ASSERT(rte_fbarray_find_contig_free(NULL, 0) < 0, 208 "Call succeeded with invalid parameters\n"); 209 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 210 TEST_ASSERT(rte_fbarray_find_contig_used(NULL, 0) < 0, 211 "Call succeeded with invalid parameters\n"); 212 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 213 TEST_ASSERT(rte_fbarray_find_rev_contig_free(NULL, 0) < 0, 214 "Call succeeded with invalid parameters\n"); 215 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 216 TEST_ASSERT(rte_fbarray_find_rev_contig_used(NULL, 0) < 0, 217 "Call succeeded with invalid parameters\n"); 218 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 219 TEST_ASSERT(rte_fbarray_find_next_free(NULL, 0) < 0, 220 "Call succeeded with invalid parameters\n"); 221 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 222 TEST_ASSERT(rte_fbarray_find_next_used(NULL, 0) < 0, 223 "Call succeeded with invalid parameters\n"); 224 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 225 TEST_ASSERT(rte_fbarray_find_prev_free(NULL, 0) < 0, 226 "Call succeeded with invalid parameters\n"); 227 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 228 TEST_ASSERT(rte_fbarray_find_prev_used(NULL, 0) < 0, 229 "Call succeeded with invalid parameters\n"); 230 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 231 TEST_ASSERT(rte_fbarray_find_next_n_free(NULL, 0, 0) < 0, 232 "Call succeeded with invalid parameters\n"); 233 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 234 TEST_ASSERT(rte_fbarray_find_next_n_used(NULL, 0, 0) < 0, 235 "Call succeeded with invalid parameters\n"); 236 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 237 TEST_ASSERT(rte_fbarray_find_prev_n_free(NULL, 0, 0) < 0, 238 "Call succeeded with invalid parameters\n"); 239 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 240 TEST_ASSERT(rte_fbarray_find_prev_n_used(NULL, 0, 0) < 0, 241 "Call succeeded with invalid parameters\n"); 242 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 243 TEST_ASSERT(rte_fbarray_is_used(NULL, 0) < 0, 244 "Call succeeded with invalid parameters\n"); 245 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 246 247 TEST_ASSERT_SUCCESS(rte_fbarray_init(&dummy, "success", 248 FBARRAY_TEST_LEN, 8), 249 "Failed to initialize valid fbarray\n"); 250 251 /* test API for handling invalid parameters with a valid fbarray */ 252 TEST_ASSERT_NULL(rte_fbarray_get(&dummy, FBARRAY_TEST_LEN), 253 "Call succeeded with invalid parameters\n"); 254 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 255 256 TEST_ASSERT(rte_fbarray_find_idx(&dummy, NULL) < 0, 257 "Call succeeded with invalid parameters\n"); 258 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 259 260 TEST_ASSERT(rte_fbarray_set_free(&dummy, FBARRAY_TEST_LEN), 261 "Call succeeded with invalid parameters\n"); 262 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 263 264 TEST_ASSERT(rte_fbarray_set_used(&dummy, FBARRAY_TEST_LEN), 265 "Call succeeded with invalid parameters\n"); 266 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 267 268 TEST_ASSERT(rte_fbarray_find_contig_free(&dummy, FBARRAY_TEST_LEN) < 0, 269 "Call succeeded with invalid parameters\n"); 270 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 271 272 TEST_ASSERT(rte_fbarray_find_contig_used(&dummy, FBARRAY_TEST_LEN) < 0, 273 "Call succeeded with invalid parameters\n"); 274 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 275 276 TEST_ASSERT(rte_fbarray_find_rev_contig_free(&dummy, 277 FBARRAY_TEST_LEN) < 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_rev_contig_used(&dummy, 282 FBARRAY_TEST_LEN) < 0, 283 "Call succeeded with invalid parameters\n"); 284 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 285 286 TEST_ASSERT(rte_fbarray_find_next_free(&dummy, FBARRAY_TEST_LEN) < 0, 287 "Call succeeded with invalid parameters\n"); 288 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 289 290 TEST_ASSERT(rte_fbarray_find_next_used(&dummy, FBARRAY_TEST_LEN) < 0, 291 "Call succeeded with invalid parameters\n"); 292 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 293 294 TEST_ASSERT(rte_fbarray_find_prev_free(&dummy, FBARRAY_TEST_LEN) < 0, 295 "Call succeeded with invalid parameters\n"); 296 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 297 298 TEST_ASSERT(rte_fbarray_find_prev_used(&dummy, FBARRAY_TEST_LEN) < 0, 299 "Call succeeded with invalid parameters\n"); 300 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 301 302 TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 303 FBARRAY_TEST_LEN, 1) < 0, 304 "Call succeeded with invalid parameters\n"); 305 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 306 TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, 307 FBARRAY_TEST_LEN + 1) < 0, 308 "Call succeeded with invalid parameters\n"); 309 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 310 TEST_ASSERT(rte_fbarray_find_next_n_free(&dummy, 0, 0) < 0, 311 "Call succeeded with invalid parameters\n"); 312 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 313 314 TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 315 FBARRAY_TEST_LEN, 1) < 0, 316 "Call succeeded with invalid parameters\n"); 317 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 318 TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, 319 FBARRAY_TEST_LEN + 1) < 0, 320 "Call succeeded with invalid parameters\n"); 321 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 322 TEST_ASSERT(rte_fbarray_find_next_n_used(&dummy, 0, 0) < 0, 323 "Call succeeded with invalid parameters\n"); 324 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 325 326 TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 327 FBARRAY_TEST_LEN, 1) < 0, 328 "Call succeeded with invalid parameters\n"); 329 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 330 TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, 331 FBARRAY_TEST_LEN + 1) < 0, 332 "Call succeeded with invalid parameters\n"); 333 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 334 TEST_ASSERT(rte_fbarray_find_prev_n_free(&dummy, 0, 0) < 0, 335 "Call succeeded with invalid parameters\n"); 336 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 337 338 TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 339 FBARRAY_TEST_LEN, 1) < 0, 340 "Call succeeded with invalid parameters\n"); 341 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 342 TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, 343 FBARRAY_TEST_LEN + 1) < 0, 344 "Call succeeded with invalid parameters\n"); 345 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 346 TEST_ASSERT(rte_fbarray_find_prev_n_used(&dummy, 0, 0) < 0, 347 "Call succeeded with invalid parameters\n"); 348 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 349 350 TEST_ASSERT(rte_fbarray_is_used(&dummy, FBARRAY_TEST_LEN) < 0, 351 "Call succeeded with invalid parameters\n"); 352 TEST_ASSERT_EQUAL(rte_errno, EINVAL, "Wrong errno value\n"); 353 354 TEST_ASSERT_SUCCESS(rte_fbarray_destroy(&dummy), 355 "Failed to destroy valid fbarray\n"); 356 357 return TEST_SUCCESS; 358 } 359 360 static int check_free(void) 361 { 362 const int idx = 0; 363 const int last_idx = FBARRAY_TEST_LEN - 1; 364 365 /* ensure we can find a free spot */ 366 TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(¶m.arr, idx), idx, 367 "Free space not found where expected\n"); 368 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(¶m.arr, idx, 1), idx, 369 "Free space not found where expected\n"); 370 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(¶m.arr, idx), 371 FBARRAY_TEST_LEN, 372 "Free space not found where expected\n"); 373 374 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(¶m.arr, idx), idx, 375 "Free space not found where expected\n"); 376 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, idx, 1), idx, 377 "Free space not found where expected\n"); 378 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, idx), 1, 379 "Free space not found where expected\n"); 380 381 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(¶m.arr, last_idx), 382 last_idx, "Free space not found where expected\n"); 383 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, last_idx, 1), 384 last_idx, "Free space not found where expected\n"); 385 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, 386 last_idx), FBARRAY_TEST_LEN, 387 "Free space not found where expected\n"); 388 389 /* ensure we can't find any used spots */ 390 TEST_ASSERT(rte_fbarray_find_next_used(¶m.arr, idx) < 0, 391 "Used space found where none was expected\n"); 392 TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); 393 TEST_ASSERT(rte_fbarray_find_next_n_used(¶m.arr, idx, 1) < 0, 394 "Used space found where none was expected\n"); 395 TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); 396 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx), 0, 397 "Used space found where none was expected\n"); 398 399 TEST_ASSERT(rte_fbarray_find_prev_used(¶m.arr, last_idx) < 0, 400 "Used space found where none was expected\n"); 401 TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); 402 TEST_ASSERT(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1) < 0, 403 "Used space found where none was expected\n"); 404 TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); 405 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, 406 last_idx), 0, 407 "Used space found where none was expected\n"); 408 409 return 0; 410 } 411 412 static int check_used_one(void) 413 { 414 const int idx = 0; 415 const int last_idx = FBARRAY_TEST_LEN - 1; 416 417 /* check that we can find used spots now */ 418 TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(¶m.arr, idx), idx, 419 "Used space not found where expected\n"); 420 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(¶m.arr, idx, 1), idx, 421 "Used space not found where expected\n"); 422 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx), 1, 423 "Used space not found where expected\n"); 424 425 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(¶m.arr, last_idx), idx, 426 "Used space not found where expected\n"); 427 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1), 428 idx, "Used space not found where expected\n"); 429 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, idx), 1, 430 "Used space not found where expected\n"); 431 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, 432 last_idx), idx, 433 "Used space not found where expected\n"); 434 435 /* check if further indices are still free */ 436 TEST_ASSERT(rte_fbarray_find_next_used(¶m.arr, idx + 1) < 0, 437 "Used space not found where none was expected\n"); 438 TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); 439 TEST_ASSERT(rte_fbarray_find_next_n_used(¶m.arr, idx + 1, 1) < 0, 440 "Used space not found where none was expected\n"); 441 TEST_ASSERT_EQUAL(rte_errno, ENOENT, "Wrong errno value\n"); 442 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(¶m.arr, idx + 1), 0, 443 "Used space not found where none was expected\n"); 444 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(¶m.arr, idx + 1), 445 FBARRAY_TEST_LEN - 1, 446 "Used space not found where none was expected\n"); 447 448 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(¶m.arr, last_idx), 0, 449 "Used space not found where none was expected\n"); 450 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(¶m.arr, last_idx, 1), 451 0, "Used space not found where none was expected\n"); 452 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(¶m.arr, 453 last_idx), 0, 454 "Used space not found where none was expected\n"); 455 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(¶m.arr, 456 last_idx), FBARRAY_TEST_LEN - 1, 457 "Used space not found where none was expected\n"); 458 459 return 0; 460 } 461 462 static int test_basic(void) 463 { 464 const int idx = 0; 465 int i; 466 467 /* check array count */ 468 TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n"); 469 470 /* ensure we can find a free spot */ 471 if (check_free()) 472 return TEST_FAILED; 473 474 /* check if used */ 475 TEST_ASSERT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, 476 "Used space found where not expected\n"); 477 478 /* mark as used */ 479 TEST_ASSERT_SUCCESS(rte_fbarray_set_used(¶m.arr, idx), 480 "Failed to set as used\n"); 481 482 /* check if used again */ 483 TEST_ASSERT_NOT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, 484 "Used space not found where expected\n"); 485 486 if (check_used_one()) 487 return TEST_FAILED; 488 489 /* check array count */ 490 TEST_ASSERT_EQUAL(param.arr.count, 1, "Wrong element count\n"); 491 492 /* check if getting pointers works for every element */ 493 for (i = 0; i < FBARRAY_TEST_LEN; i++) { 494 void *td = rte_fbarray_get(¶m.arr, i); 495 TEST_ASSERT_NOT_NULL(td, "Invalid pointer returned\n"); 496 TEST_ASSERT_EQUAL(rte_fbarray_find_idx(¶m.arr, td), i, 497 "Wrong index returned\n"); 498 } 499 500 /* mark as free */ 501 TEST_ASSERT_SUCCESS(rte_fbarray_set_free(¶m.arr, idx), 502 "Failed to set as free\n"); 503 504 /* check array count */ 505 TEST_ASSERT_EQUAL(param.arr.count, 0, "Wrong element count\n"); 506 507 /* check if used */ 508 TEST_ASSERT_EQUAL(rte_fbarray_is_used(¶m.arr, idx), 0, 509 "Used space found where not expected\n"); 510 511 if (check_free()) 512 return TEST_FAILED; 513 514 reset_aligned(); 515 516 return TEST_SUCCESS; 517 } 518 519 static int test_biggest(struct rte_fbarray *arr, int first, int last) 520 { 521 int lo_free_space_first, lo_free_space_last, lo_free_space_len; 522 int hi_free_space_first, hi_free_space_last, hi_free_space_len; 523 int max_free_space_first, max_free_space_last, max_free_space_len; 524 int len = last - first + 1; 525 526 /* first and last must either be both -1, or both not -1 */ 527 TEST_ASSERT((first == -1) == (last == -1), 528 "Invalid arguments provided\n"); 529 530 /* figure out what we expect from the low chunk of free space */ 531 if (first == -1) { 532 /* special case: if there are no occupied elements at all, 533 * consider both free spaces to consume the entire array. 534 */ 535 lo_free_space_first = 0; 536 lo_free_space_last = arr->len - 1; 537 lo_free_space_len = arr->len; 538 /* if there's no used space, length should be invalid */ 539 len = -1; 540 } else if (first == 0) { 541 /* if occupied items start at 0, there's no free space */ 542 lo_free_space_first = -1; 543 lo_free_space_last = -1; 544 lo_free_space_len = 0; 545 } else { 546 lo_free_space_first = 0; 547 lo_free_space_last = first - 1; 548 lo_free_space_len = lo_free_space_last - 549 lo_free_space_first + 1; 550 } 551 552 /* figure out what we expect from the high chunk of free space */ 553 if (last == -1) { 554 /* special case: if there are no occupied elements at all, 555 * consider both free spaces to consume the entire array. 556 */ 557 hi_free_space_first = 0; 558 hi_free_space_last = arr->len - 1; 559 hi_free_space_len = arr->len; 560 /* if there's no used space, length should be invalid */ 561 len = -1; 562 } else if (last == ((int)arr->len - 1)) { 563 /* if occupied items end at array len, there's no free space */ 564 hi_free_space_first = -1; 565 hi_free_space_last = -1; 566 hi_free_space_len = 0; 567 } else { 568 hi_free_space_first = last + 1; 569 hi_free_space_last = arr->len - 1; 570 hi_free_space_len = hi_free_space_last - 571 hi_free_space_first + 1; 572 } 573 574 /* find which one will be biggest */ 575 if (lo_free_space_len > hi_free_space_len) { 576 max_free_space_first = lo_free_space_first; 577 max_free_space_last = lo_free_space_last; 578 max_free_space_len = lo_free_space_len; 579 } else { 580 /* if they are equal, we'll just use the high chunk */ 581 max_free_space_first = hi_free_space_first; 582 max_free_space_last = hi_free_space_last; 583 max_free_space_len = hi_free_space_len; 584 } 585 586 /* check used regions - these should produce identical results */ 587 TEST_ASSERT_EQUAL(rte_fbarray_find_biggest_used(arr, 0), first, 588 "Used space index is wrong\n"); 589 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_biggest_used(arr, arr->len - 1), 590 first, 591 "Used space index is wrong\n"); 592 /* len may be -1, but function will return error anyway */ 593 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(arr, first), len, 594 "Used space length is wrong\n"); 595 596 /* check if biggest free region is the one we expect to find. It can be 597 * -1 if there's no free space - we've made sure we use one or the 598 * other, even if both are invalid. 599 */ 600 TEST_ASSERT_EQUAL(rte_fbarray_find_biggest_free(arr, 0), 601 max_free_space_first, 602 "Biggest free space index is wrong\n"); 603 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_biggest_free(arr, arr->len - 1), 604 max_free_space_first, 605 "Biggest free space index is wrong\n"); 606 607 /* if biggest region exists, check its length */ 608 if (max_free_space_first != -1) { 609 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr, 610 max_free_space_first), 611 max_free_space_len, 612 "Biggest free space length is wrong\n"); 613 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, 614 max_free_space_last), 615 max_free_space_len, 616 "Biggest free space length is wrong\n"); 617 } 618 619 /* find if we see what we expect to see in the low region. if there is 620 * no free space, the function should still match expected value, as 621 * we've set it to -1. we're scanning backwards to avoid accidentally 622 * hitting the high free space region. if there is no occupied space, 623 * there's nothing to do. 624 */ 625 if (last != -1) { 626 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_biggest_free(arr, last), 627 lo_free_space_first, 628 "Low free space index is wrong\n"); 629 } 630 631 if (lo_free_space_first != -1) { 632 /* if low free region exists, check its length */ 633 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr, 634 lo_free_space_first), 635 lo_free_space_len, 636 "Low free space length is wrong\n"); 637 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, 638 lo_free_space_last), 639 lo_free_space_len, 640 "Low free space length is wrong\n"); 641 } 642 643 /* find if we see what we expect to see in the high region. if there is 644 * no free space, the function should still match expected value, as 645 * we've set it to -1. we're scanning forwards to avoid accidentally 646 * hitting the low free space region. if there is no occupied space, 647 * there's nothing to do. 648 */ 649 if (first != -1) { 650 TEST_ASSERT_EQUAL(rte_fbarray_find_biggest_free(arr, first), 651 hi_free_space_first, 652 "High free space index is wrong\n"); 653 } 654 655 /* if high free region exists, check its length */ 656 if (hi_free_space_first != -1) { 657 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr, 658 hi_free_space_first), 659 hi_free_space_len, 660 "High free space length is wrong\n"); 661 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, 662 hi_free_space_last), 663 hi_free_space_len, 664 "High free space length is wrong\n"); 665 } 666 667 return 0; 668 } 669 670 static int ensure_correct(struct rte_fbarray *arr, int first, int last, 671 bool used) 672 { 673 int i, len = last - first + 1; 674 for (i = 0; i < len; i++) { 675 int cur = first + i; 676 int cur_len = len - i; 677 678 if (used) { 679 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_used(arr, 680 cur), cur_len, 681 "Used space length is wrong\n"); 682 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr, 683 last), len, 684 "Used space length is wrong\n"); 685 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_used(arr, 686 cur), i + 1, 687 "Used space length is wrong\n"); 688 689 TEST_ASSERT_EQUAL(rte_fbarray_find_next_used(arr, cur), 690 cur, 691 "Used space not found where expected\n"); 692 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, 693 cur, 1), cur, 694 "Used space not found where expected\n"); 695 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_used(arr, cur, 696 cur_len), cur, 697 "Used space not found where expected\n"); 698 699 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_used(arr, cur), 700 cur, 701 "Used space not found where expected\n"); 702 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_used(arr, 703 last, cur_len), cur, 704 "Used space not found where expected\n"); 705 } else { 706 TEST_ASSERT_EQUAL(rte_fbarray_find_contig_free(arr, 707 cur), cur_len, 708 "Free space length is wrong\n"); 709 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, 710 last), len, 711 "Free space length is wrong\n"); 712 TEST_ASSERT_EQUAL(rte_fbarray_find_rev_contig_free(arr, 713 cur), i + 1, 714 "Free space length is wrong\n"); 715 716 TEST_ASSERT_EQUAL(rte_fbarray_find_next_free(arr, cur), 717 cur, 718 "Free space not found where expected\n"); 719 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur, 720 1), cur, 721 "Free space not found where expected\n"); 722 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(arr, cur, 723 cur_len), cur, 724 "Free space not found where expected\n"); 725 726 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_free(arr, cur), 727 cur, 728 "Free space not found where expected\n"); 729 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(arr, 730 last, cur_len), cur, 731 "Free space not found where expected\n"); 732 } 733 } 734 return 0; 735 } 736 737 static int test_find(void) 738 { 739 TEST_ASSERT_EQUAL((int)param.arr.count, param.end - param.start + 1, 740 "Wrong element count\n"); 741 /* ensure space is free before start */ 742 if (ensure_correct(¶m.arr, 0, param.start - 1, false)) 743 return TEST_FAILED; 744 /* ensure space is occupied where it's supposed to be */ 745 if (ensure_correct(¶m.arr, param.start, param.end, true)) 746 return TEST_FAILED; 747 /* ensure space after end is free as well */ 748 if (ensure_correct(¶m.arr, param.end + 1, FBARRAY_TEST_LEN - 1, 749 false)) 750 return TEST_FAILED; 751 /* test if find_biggest API's work correctly */ 752 if (test_biggest(¶m.arr, param.start, param.end)) 753 return TEST_FAILED; 754 return TEST_SUCCESS; 755 } 756 757 static int test_find_unaligned(void) 758 { 759 TEST_ASSERT_EQUAL((int)unaligned.arr.count, unaligned.end - unaligned.start + 1, 760 "Wrong element count\n"); 761 /* ensure space is free before start */ 762 if (ensure_correct(&unaligned.arr, 0, unaligned.start - 1, false)) 763 return TEST_FAILED; 764 /* ensure space is occupied where it's supposed to be */ 765 if (ensure_correct(&unaligned.arr, unaligned.start, unaligned.end, true)) 766 return TEST_FAILED; 767 /* ensure space after end is free as well */ 768 if (ensure_correct(&unaligned.arr, unaligned.end + 1, FBARRAY_UNALIGNED_TEST_LEN - 1, 769 false)) 770 return TEST_FAILED; 771 /* test if find_biggest API's work correctly */ 772 if (test_biggest(&unaligned.arr, unaligned.start, unaligned.end)) 773 return TEST_FAILED; 774 return TEST_SUCCESS; 775 } 776 777 static int test_empty(void) 778 { 779 TEST_ASSERT_EQUAL((int)param.arr.count, 0, "Wrong element count\n"); 780 /* ensure space is free */ 781 if (ensure_correct(¶m.arr, 0, FBARRAY_TEST_LEN - 1, false)) 782 return TEST_FAILED; 783 /* test if find_biggest API's work correctly */ 784 if (test_biggest(¶m.arr, param.start, param.end)) 785 return TEST_FAILED; 786 return TEST_SUCCESS; 787 } 788 789 static int test_lookahead(void) 790 { 791 int ret; 792 793 /* run regular test first */ 794 ret = test_find(); 795 if (ret != TEST_SUCCESS) 796 return ret; 797 798 /* test if we can find free chunk while not starting with 0 */ 799 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(¶m.arr, 1, param.start), 800 param.start + 1, "Free chunk index is wrong\n"); 801 return TEST_SUCCESS; 802 } 803 804 static int test_lookbehind(void) 805 { 806 int ret, free_len = 2; 807 808 /* run regular test first */ 809 ret = test_find(); 810 if (ret != TEST_SUCCESS) 811 return ret; 812 813 /* test if we can find free chunk while crossing mask boundary */ 814 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, param.start + 1, free_len), 815 param.start - free_len, "Free chunk index is wrong\n"); 816 return TEST_SUCCESS; 817 } 818 819 static int test_lookahead_mask(void) 820 { 821 /* 822 * There is a certain type of lookahead behavior we want to test here, 823 * namely masking of bits that were scanned with lookahead but that we 824 * know do not match our criteria. This is achieved in following steps: 825 * 826 * 0. Look for a big enough chunk of free space (say, 62 elements) 827 * 1. Trigger lookahead by breaking a run somewhere inside mask 0 828 * (indices 0-63) 829 * 2. Fail lookahead by breaking the run somewhere inside mask 1 830 * (indices 64-127) 831 * 3. Ensure that we can still find free space in mask 1 afterwards 832 */ 833 834 /* break run on first mask */ 835 rte_fbarray_set_used(¶m.arr, 61); 836 /* break run on second mask */ 837 rte_fbarray_set_used(¶m.arr, 70); 838 839 /* we expect to find free space at 71 */ 840 TEST_ASSERT_EQUAL(rte_fbarray_find_next_n_free(¶m.arr, 0, 62), 841 71, "Free chunk index is wrong\n"); 842 return TEST_SUCCESS; 843 } 844 845 static int test_lookbehind_mask(void) 846 { 847 /* 848 * There is a certain type of lookbehind behavior we want to test here, 849 * namely masking of bits that were scanned with lookbehind but that we 850 * know do not match our criteria. This is achieved in two steps: 851 * 852 * 0. Look for a big enough chunk of free space (say, 62 elements) 853 * 1. Trigger lookbehind by breaking a run somewhere inside mask 2 854 * (indices 128-191) 855 * 2. Fail lookbehind by breaking the run somewhere inside mask 1 856 * (indices 64-127) 857 * 3. Ensure that we can still find free space in mask 1 afterwards 858 */ 859 860 /* break run on mask 2 */ 861 rte_fbarray_set_used(¶m.arr, 130); 862 /* break run on mask 1 */ 863 rte_fbarray_set_used(¶m.arr, 70); 864 865 /* start from 190, we expect to find free space at 8 */ 866 TEST_ASSERT_EQUAL(rte_fbarray_find_prev_n_free(¶m.arr, 190, 62), 867 8, "Free chunk index is wrong\n"); 868 return TEST_SUCCESS; 869 } 870 871 static struct unit_test_suite fbarray_test_suite = { 872 .suite_name = "fbarray autotest", 873 .setup = autotest_setup, 874 .teardown = autotest_teardown, 875 .unit_test_cases = { 876 TEST_CASE(test_invalid), 877 TEST_CASE(test_basic), 878 TEST_CASE_ST(first_msk_test_setup, reset_aligned, test_find), 879 TEST_CASE_ST(cross_msk_test_setup, reset_aligned, test_find), 880 TEST_CASE_ST(multi_msk_test_setup, reset_aligned, test_find), 881 TEST_CASE_ST(last_msk_test_setup, reset_aligned, test_find), 882 TEST_CASE_ST(full_msk_test_setup, reset_aligned, test_find), 883 /* empty test does not need setup */ 884 TEST_CASE_ST(NULL, reset_aligned, test_empty), 885 TEST_CASE_ST(lookahead_test_setup, reset_aligned, test_lookahead), 886 TEST_CASE_ST(lookbehind_test_setup, reset_aligned, test_lookbehind), 887 /* setup for these tests is more complex so do it in test func */ 888 TEST_CASE_ST(NULL, reset_aligned, test_lookahead_mask), 889 TEST_CASE_ST(NULL, reset_aligned, test_lookbehind_mask), 890 TEST_CASE_ST(unaligned_test_setup, reset_unaligned, test_find_unaligned), 891 TEST_CASES_END() 892 } 893 }; 894 895 static int 896 test_fbarray(void) 897 { 898 return unit_test_suite_runner(&fbarray_test_suite); 899 } 900 901 REGISTER_FAST_TEST(fbarray_autotest, true, true, test_fbarray); 902