LCOV - code coverage report
Current view: top level - app/test - test_stack.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 87 125 69.6 %
Date: 2024-12-01 18:57:19 Functions: 12 12 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 56 92 60.9 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2019 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <string.h>
       6                 :            : 
       7                 :            : #include <rte_lcore.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include <rte_random.h>
      10                 :            : #include <rte_stack.h>
      11                 :            : 
      12                 :            : #include "test.h"
      13                 :            : 
      14                 :            : #define STACK_SIZE 4096
      15                 :            : #define MAX_BULK 32
      16                 :            : 
      17                 :            : static int
      18                 :          4 : test_stack_push_pop(struct rte_stack *s, void **obj_table, unsigned int bulk_sz)
      19                 :            : {
      20                 :            :         unsigned int i, ret;
      21                 :            :         void **popped_objs;
      22                 :            : 
      23                 :          4 :         popped_objs = rte_calloc(NULL, STACK_SIZE, sizeof(void *), 0);
      24         [ -  + ]:          4 :         if (popped_objs == NULL) {
      25                 :            :                 printf("[%s():%u] failed to calloc %zu bytes\n",
      26                 :            :                        __func__, __LINE__, STACK_SIZE * sizeof(void *));
      27                 :          0 :                 return -1;
      28                 :            :         }
      29                 :            : 
      30         [ +  + ]:       8452 :         for (i = 0; i < STACK_SIZE; i += bulk_sz) {
      31         [ +  + ]:       8448 :                 ret = rte_stack_push(s, &obj_table[i], bulk_sz);
      32                 :            : 
      33         [ -  + ]:       8448 :                 if (ret != bulk_sz) {
      34                 :            :                         printf("[%s():%u] push returned: %d (expected %u)\n",
      35                 :            :                                __func__, __LINE__, ret, bulk_sz);
      36                 :          0 :                         rte_free(popped_objs);
      37                 :          0 :                         return -1;
      38                 :            :                 }
      39                 :            : 
      40         [ -  + ]:       8448 :                 if (rte_stack_count(s) != i + bulk_sz) {
      41                 :            :                         printf("[%s():%u] stack count: %u (expected %u)\n",
      42                 :            :                                __func__, __LINE__, rte_stack_count(s),
      43                 :            :                                i + bulk_sz);
      44                 :          0 :                         rte_free(popped_objs);
      45                 :          0 :                         return -1;
      46                 :            :                 }
      47                 :            : 
      48         [ -  + ]:       8448 :                 if (rte_stack_free_count(s) != STACK_SIZE - i - bulk_sz) {
      49                 :            :                         printf("[%s():%u] stack free count: %u (expected %u)\n",
      50                 :            :                                __func__, __LINE__, rte_stack_count(s),
      51                 :            :                                STACK_SIZE - i - bulk_sz);
      52                 :          0 :                         rte_free(popped_objs);
      53                 :          0 :                         return -1;
      54                 :            :                 }
      55                 :            :         }
      56                 :            : 
      57         [ +  + ]:       8452 :         for (i = 0; i < STACK_SIZE; i += bulk_sz) {
      58         [ +  + ]:       8448 :                 ret = rte_stack_pop(s, &popped_objs[i], bulk_sz);
      59                 :            : 
      60         [ -  + ]:       8448 :                 if (ret != bulk_sz) {
      61                 :            :                         printf("[%s():%u] pop returned: %d (expected %u)\n",
      62                 :            :                                __func__, __LINE__, ret, bulk_sz);
      63                 :          0 :                         rte_free(popped_objs);
      64                 :          0 :                         return -1;
      65                 :            :                 }
      66                 :            : 
      67         [ -  + ]:       8448 :                 if (rte_stack_count(s) != STACK_SIZE - i - bulk_sz) {
      68                 :            :                         printf("[%s():%u] stack count: %u (expected %u)\n",
      69                 :            :                                __func__, __LINE__, rte_stack_count(s),
      70                 :            :                                STACK_SIZE - i - bulk_sz);
      71                 :          0 :                         rte_free(popped_objs);
      72                 :          0 :                         return -1;
      73                 :            :                 }
      74                 :            : 
      75         [ -  + ]:       8448 :                 if (rte_stack_free_count(s) != i + bulk_sz) {
      76                 :            :                         printf("[%s():%u] stack free count: %u (expected %u)\n",
      77                 :            :                                __func__, __LINE__, rte_stack_count(s),
      78                 :            :                                i + bulk_sz);
      79                 :          0 :                         rte_free(popped_objs);
      80                 :          0 :                         return -1;
      81                 :            :                 }
      82                 :            :         }
      83                 :            : 
      84         [ +  + ]:      16388 :         for (i = 0; i < STACK_SIZE; i++) {
      85         [ -  + ]:      16384 :                 if (obj_table[i] != popped_objs[STACK_SIZE - i - 1]) {
      86                 :            :                         printf("[%s():%u] Incorrect value %p at index 0x%x\n",
      87                 :            :                                __func__, __LINE__,
      88                 :            :                                popped_objs[STACK_SIZE - i - 1], i);
      89                 :          0 :                         rte_free(popped_objs);
      90                 :          0 :                         return -1;
      91                 :            :                 }
      92                 :            :         }
      93                 :            : 
      94                 :          4 :         rte_free(popped_objs);
      95                 :            : 
      96                 :          4 :         return 0;
      97                 :            : }
      98                 :            : 
      99                 :            : static int
     100                 :          2 : test_stack_basic(uint32_t flags)
     101                 :            : {
     102                 :            :         struct rte_stack *s = NULL;
     103                 :            :         void **obj_table = NULL;
     104                 :            :         int i, ret = -1;
     105                 :            : 
     106                 :          2 :         obj_table = rte_calloc(NULL, STACK_SIZE, sizeof(void *), 0);
     107         [ -  + ]:          2 :         if (obj_table == NULL) {
     108                 :            :                 printf("[%s():%u] failed to calloc %zu bytes\n",
     109                 :            :                        __func__, __LINE__, STACK_SIZE * sizeof(void *));
     110                 :          0 :                 goto fail_test;
     111                 :            :         }
     112                 :            : 
     113         [ +  + ]:       8194 :         for (i = 0; i < STACK_SIZE; i++)
     114                 :       8192 :                 obj_table[i] = (void *)(uintptr_t)i;
     115                 :            : 
     116                 :          2 :         s = rte_stack_create(__func__, STACK_SIZE, rte_socket_id(), flags);
     117         [ -  + ]:          2 :         if (s == NULL) {
     118                 :            :                 printf("[%s():%u] failed to create a stack\n",
     119                 :            :                        __func__, __LINE__);
     120                 :          0 :                 goto fail_test;
     121                 :            :         }
     122                 :            : 
     123         [ -  + ]:          2 :         if (rte_stack_lookup(__func__) != s) {
     124                 :            :                 printf("[%s():%u] failed to lookup a stack\n",
     125                 :            :                        __func__, __LINE__);
     126                 :          0 :                 goto fail_test;
     127                 :            :         }
     128                 :            : 
     129         [ -  + ]:          2 :         if (rte_stack_count(s) != 0) {
     130                 :            :                 printf("[%s():%u] stack count: %u (expected 0)\n",
     131                 :            :                        __func__, __LINE__, rte_stack_count(s));
     132                 :          0 :                 goto fail_test;
     133                 :            :         }
     134                 :            : 
     135         [ -  + ]:          2 :         if (rte_stack_free_count(s) != STACK_SIZE) {
     136                 :            :                 printf("[%s():%u] stack free count: %u (expected %u)\n",
     137                 :            :                        __func__, __LINE__, rte_stack_count(s), STACK_SIZE);
     138                 :          0 :                 goto fail_test;
     139                 :            :         }
     140                 :            : 
     141                 :          2 :         ret = test_stack_push_pop(s, obj_table, 1);
     142         [ -  + ]:          2 :         if (ret) {
     143                 :            :                 printf("[%s():%u] Single object push/pop failed\n",
     144                 :            :                        __func__, __LINE__);
     145                 :          0 :                 goto fail_test;
     146                 :            :         }
     147                 :            : 
     148                 :          2 :         ret = test_stack_push_pop(s, obj_table, MAX_BULK);
     149         [ -  + ]:          2 :         if (ret) {
     150                 :            :                 printf("[%s():%u] Bulk object push/pop failed\n",
     151                 :            :                        __func__, __LINE__);
     152                 :          0 :                 goto fail_test;
     153                 :            :         }
     154                 :            : 
     155                 :          2 :         ret = rte_stack_push(s, obj_table, 2 * STACK_SIZE);
     156         [ -  + ]:          2 :         if (ret != 0) {
     157                 :            :                 printf("[%s():%u] Excess objects push succeeded\n",
     158                 :            :                        __func__, __LINE__);
     159                 :          0 :                 goto fail_test;
     160                 :            :         }
     161                 :            : 
     162                 :          2 :         ret = rte_stack_pop(s, obj_table, 1);
     163         [ -  + ]:          2 :         if (ret != 0) {
     164                 :            :                 printf("[%s():%u] Empty stack pop succeeded\n",
     165                 :            :                        __func__, __LINE__);
     166                 :          0 :                 goto fail_test;
     167                 :            :         }
     168                 :            : 
     169                 :            :         ret = 0;
     170                 :            : 
     171                 :          2 : fail_test:
     172                 :          2 :         rte_stack_free(s);
     173                 :            : 
     174                 :          2 :         rte_free(obj_table);
     175                 :            : 
     176                 :          2 :         return ret;
     177                 :            : }
     178                 :            : 
     179                 :            : static int
     180                 :          2 : test_stack_name_reuse(uint32_t flags)
     181                 :            : {
     182                 :            :         struct rte_stack *s[2];
     183                 :            : 
     184                 :          2 :         s[0] = rte_stack_create("test", STACK_SIZE, rte_socket_id(), flags);
     185         [ -  + ]:          2 :         if (s[0] == NULL) {
     186                 :            :                 printf("[%s():%u] Failed to create a stack\n",
     187                 :            :                        __func__, __LINE__);
     188                 :          0 :                 return -1;
     189                 :            :         }
     190                 :            : 
     191                 :          2 :         s[1] = rte_stack_create("test", STACK_SIZE, rte_socket_id(), flags);
     192         [ -  + ]:          2 :         if (s[1] != NULL) {
     193                 :            :                 printf("[%s():%u] Failed to detect re-used name\n",
     194                 :            :                        __func__, __LINE__);
     195                 :          0 :                 return -1;
     196                 :            :         }
     197                 :            : 
     198                 :          2 :         rte_stack_free(s[0]);
     199                 :            : 
     200                 :          2 :         return 0;
     201                 :            : }
     202                 :            : 
     203                 :            : static int
     204                 :          2 : test_stack_name_length(uint32_t flags)
     205                 :            : {
     206                 :            :         char name[RTE_STACK_NAMESIZE + 1];
     207                 :            :         struct rte_stack *s;
     208                 :            : 
     209                 :            :         memset(name, 's', sizeof(name));
     210                 :          2 :         name[RTE_STACK_NAMESIZE] = '\0';
     211                 :            : 
     212                 :          2 :         s = rte_stack_create(name, STACK_SIZE, rte_socket_id(), flags);
     213         [ -  + ]:          2 :         if (s != NULL) {
     214                 :            :                 printf("[%s():%u] Failed to prevent long name\n",
     215                 :            :                        __func__, __LINE__);
     216                 :          0 :                 return -1;
     217                 :            :         }
     218                 :            : 
     219         [ -  + ]:          2 :         if (rte_errno != ENAMETOOLONG) {
     220                 :            :                 printf("[%s():%u] rte_stack failed to set correct errno on failed lookup\n",
     221                 :            :                        __func__, __LINE__);
     222                 :          0 :                 return -1;
     223                 :            :         }
     224                 :            : 
     225                 :            :         return 0;
     226                 :            : }
     227                 :            : 
     228                 :            : static int
     229                 :          2 : test_lookup_null(void)
     230                 :            : {
     231                 :          2 :         struct rte_stack *s = rte_stack_lookup("stack_not_found");
     232                 :            : 
     233         [ -  + ]:          2 :         if (s != NULL) {
     234                 :            :                 printf("[%s():%u] rte_stack found a non-existent stack\n",
     235                 :            :                        __func__, __LINE__);
     236                 :          0 :                 return -1;
     237                 :            :         }
     238                 :            : 
     239         [ -  + ]:          2 :         if (rte_errno != ENOENT) {
     240                 :            :                 printf("[%s():%u] rte_stack failed to set correct errno on failed lookup\n",
     241                 :            :                        __func__, __LINE__);
     242                 :          0 :                 return -1;
     243                 :            :         }
     244                 :            : 
     245                 :          2 :         s = rte_stack_lookup(NULL);
     246                 :            : 
     247         [ -  + ]:          2 :         if (s != NULL) {
     248                 :            :                 printf("[%s():%u] rte_stack found a non-existent stack\n",
     249                 :            :                        __func__, __LINE__);
     250                 :          0 :                 return -1;
     251                 :            :         }
     252                 :            : 
     253         [ -  + ]:          2 :         if (rte_errno != EINVAL) {
     254                 :            :                 printf("[%s():%u] rte_stack failed to set correct errno on failed lookup\n",
     255                 :            :                        __func__, __LINE__);
     256                 :          0 :                 return -1;
     257                 :            :         }
     258                 :            : 
     259                 :            :         return 0;
     260                 :            : }
     261                 :            : 
     262                 :            : static int
     263                 :            : test_free_null(void)
     264                 :            : {
     265                 :            :         /* Check whether the library proper handles a NULL pointer */
     266                 :          2 :         rte_stack_free(NULL);
     267                 :            : 
     268                 :            :         return 0;
     269                 :            : }
     270                 :            : 
     271                 :            : #define NUM_ITERS_PER_THREAD 100000
     272                 :            : 
     273                 :            : struct test_args {
     274                 :            :         struct rte_stack *s;
     275                 :            : };
     276                 :            : 
     277                 :            : static struct test_args thread_test_args;
     278                 :            : 
     279                 :            : static int
     280                 :          4 : stack_thread_push_pop(__rte_unused void *args)
     281                 :            : {
     282                 :            :         void *obj_table[MAX_BULK];
     283                 :            :         int i;
     284                 :            : 
     285         [ +  + ]:     399203 :         for (i = 0; i < NUM_ITERS_PER_THREAD; i++) {
     286                 :            :                 unsigned int num;
     287                 :            : 
     288                 :     399199 :                 num = rte_rand() % MAX_BULK;
     289                 :            : 
     290   [ +  +  -  + ]:     796394 :                 if (rte_stack_push(thread_test_args.s, obj_table, num) != num) {
     291                 :            :                         printf("[%s():%u] Failed to push %u pointers\n",
     292                 :            :                                __func__, __LINE__, num);
     293                 :          0 :                         return -1;
     294                 :            :                 }
     295                 :            : 
     296   [ +  +  -  + ]:     797430 :                 if (rte_stack_pop(thread_test_args.s, obj_table, num) != num) {
     297                 :            :                         printf("[%s():%u] Failed to pop %u pointers\n",
     298                 :            :                                __func__, __LINE__, num);
     299                 :          0 :                         return -1;
     300                 :            :                 }
     301                 :            :         }
     302                 :            : 
     303                 :            :         return 0;
     304                 :            : }
     305                 :            : 
     306                 :            : static int
     307                 :          2 : test_stack_multithreaded(uint32_t flags)
     308                 :            : {
     309                 :            :         unsigned int lcore_id;
     310                 :            :         struct rte_stack *s;
     311                 :            :         int result = 0;
     312                 :            : 
     313         [ -  + ]:          2 :         if (rte_lcore_count() < 2) {
     314                 :            :                 printf("Not enough cores for test_stack_multithreaded, expecting at least 2\n");
     315                 :          0 :                 return TEST_SKIPPED;
     316                 :            :         }
     317                 :            : 
     318                 :          2 :         printf("[%s():%u] Running with %u lcores\n",
     319                 :            :                __func__, __LINE__, rte_lcore_count());
     320                 :            : 
     321                 :          2 :         s = rte_stack_create("test", MAX_BULK * rte_lcore_count(), rte_socket_id(), flags);
     322         [ -  + ]:          2 :         if (s == NULL) {
     323                 :            :                 printf("[%s():%u] Failed to create a stack\n",
     324                 :            :                        __func__, __LINE__);
     325                 :          0 :                 return -1;
     326                 :            :         }
     327                 :            : 
     328                 :          2 :         thread_test_args.s = s;
     329                 :            : 
     330         [ -  + ]:          2 :         if (rte_eal_mp_remote_launch(stack_thread_push_pop, NULL, CALL_MAIN))
     331                 :          0 :                 rte_panic("Failed to launch tests\n");
     332                 :            : 
     333         [ +  + ]:          6 :         RTE_LCORE_FOREACH(lcore_id) {
     334         [ -  + ]:          4 :                 if (rte_eal_wait_lcore(lcore_id) < 0)
     335                 :            :                         result = -1;
     336                 :            :         }
     337                 :            : 
     338                 :          2 :         rte_stack_free(s);
     339                 :          2 :         return result;
     340                 :            : }
     341                 :            : 
     342                 :            : static int
     343                 :          2 : __test_stack(uint32_t flags)
     344                 :            : {
     345         [ +  - ]:          2 :         if (test_stack_basic(flags) < 0)
     346                 :            :                 return -1;
     347                 :            : 
     348         [ +  - ]:          2 :         if (test_lookup_null() < 0)
     349                 :            :                 return -1;
     350                 :            : 
     351                 :            :         if (test_free_null() < 0)
     352                 :            :                 return -1;
     353                 :            : 
     354         [ +  - ]:          2 :         if (test_stack_name_reuse(flags) < 0)
     355                 :            :                 return -1;
     356                 :            : 
     357         [ +  - ]:          2 :         if (test_stack_name_length(flags) < 0)
     358                 :            :                 return -1;
     359                 :            : 
     360         [ -  + ]:          2 :         if (test_stack_multithreaded(flags) < 0)
     361                 :          0 :                 return -1;
     362                 :            : 
     363                 :            :         return 0;
     364                 :            : }
     365                 :            : 
     366                 :            : static int
     367                 :          1 : test_stack(void)
     368                 :            : {
     369                 :          1 :         return __test_stack(0);
     370                 :            : }
     371                 :            : 
     372                 :            : static int
     373                 :          1 : test_lf_stack(void)
     374                 :            : {
     375                 :            : #if defined(RTE_STACK_LF_SUPPORTED)
     376                 :          1 :         return __test_stack(RTE_STACK_F_LF);
     377                 :            : #else
     378                 :            :         return TEST_SKIPPED;
     379                 :            : #endif
     380                 :            : }
     381                 :            : 
     382                 :        251 : REGISTER_FAST_TEST(stack_autotest, false, true, test_stack);
     383                 :        251 : REGISTER_FAST_TEST(stack_lf_autotest, false, true, test_lf_stack);

Generated by: LCOV version 1.14