LCOV - code coverage report
Current view: top level - app/test - test_latencystats.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 76 79 96.2 %
Date: 2026-07-01 18:02:41 Functions: 11 11 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 32 56 57.1 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdio.h>
       6                 :            : #include <stdint.h>
       7                 :            : #include <string.h>
       8                 :            : 
       9                 :            : #include <rte_ethdev.h>
      10                 :            : #include <rte_latencystats.h>
      11                 :            : #include "rte_lcore.h"
      12                 :            : #include "rte_metrics.h"
      13                 :            : 
      14                 :            : #include "sample_packet_forward.h"
      15                 :            : #include "test.h"
      16                 :            : 
      17                 :            : #define NUM_STATS 5
      18                 :            : #define LATENCY_NUM_PACKETS 10
      19                 :            : #define LATENCY_FORWARD_ITERATIONS 10000u
      20                 :            : #define LATENCY_FORWARD_MS 10u
      21                 :            : #define MIN_ITERATIONS  10u
      22                 :            : 
      23                 :            : #define QUEUE_ID 0
      24                 :            : 
      25                 :            : static uint16_t portid;
      26                 :            : static struct rte_ring *ring;
      27                 :            : 
      28                 :            : static struct rte_metric_name lat_stats_strings[NUM_STATS] = {
      29                 :            :         {"min_latency_ns"},
      30                 :            :         {"avg_latency_ns"},
      31                 :            :         {"max_latency_ns"},
      32                 :            :         {"jitter_ns"},
      33                 :            :         {"samples"},
      34                 :            : };
      35                 :            : 
      36                 :            : /* Test case for latency init with metrics init */
      37                 :          1 : static int test_latency_init(void)
      38                 :            : {
      39                 :            :         int ret = 0;
      40                 :            : 
      41                 :            :         /* Metrics Initialization */
      42                 :          1 :         rte_metrics_init(rte_socket_id());
      43                 :            : 
      44                 :          1 :         ret = rte_latencystats_init(1, NULL);
      45         [ -  + ]:          1 :         TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_init failed");
      46                 :            : 
      47                 :            :         return TEST_SUCCESS;
      48                 :            : }
      49                 :            : 
      50                 :            : /* Test case to update the latency stats */
      51                 :          1 : static int test_latency_update(void)
      52                 :            : {
      53                 :            :         int ret = 0;
      54                 :            : 
      55                 :          1 :         ret = rte_latencystats_update();
      56         [ -  + ]:          1 :         TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_update failed");
      57                 :            : 
      58                 :            :         return TEST_SUCCESS;
      59                 :            : }
      60                 :            : 
      61                 :            : /* Test case to uninit latency stats */
      62                 :          1 : static int test_latency_uninit(void)
      63                 :            : {
      64                 :            :         int ret = 0;
      65                 :            : 
      66                 :          1 :         ret = rte_latencystats_uninit();
      67         [ -  + ]:          1 :         TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_uninit failed");
      68                 :            : 
      69                 :          1 :         ret = rte_metrics_deinit();
      70         [ -  + ]:          1 :         TEST_ASSERT(ret >= 0, "Test Failed: rte_metrics_deinit failed");
      71                 :            : 
      72                 :            :         return TEST_SUCCESS;
      73                 :            : }
      74                 :            : 
      75                 :            : /* Test case to get names of latency stats */
      76                 :          1 : static int test_latencystats_get_names(void)
      77                 :            : {
      78                 :            :         int ret, i;
      79                 :            :         uint16_t size;
      80                 :          1 :         struct rte_metric_name names[NUM_STATS] = { };
      81                 :            : 
      82                 :            :         /* Success Test: Valid names and size */
      83                 :            :         size = NUM_STATS;
      84                 :          1 :         ret = rte_latencystats_get_names(names, size);
      85         [ +  + ]:          6 :         for (i = 0; i < NUM_STATS; i++) {
      86         [ +  - ]:          5 :                 if (strcmp(lat_stats_strings[i].name, names[i].name) == 0)
      87                 :            :                         printf(" %s\n", names[i].name);
      88                 :            :                 else
      89                 :            :                         printf("Failed: Names are not matched\n");
      90                 :            :         }
      91         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names");
      92                 :            : 
      93                 :            :         /* Failure Test: Invalid names and valid size */
      94                 :          1 :         ret = rte_latencystats_get_names(NULL, size);
      95         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count,"
      96                 :            :                     "Actual: %d Expected: %d", ret, NUM_STATS);
      97                 :            : 
      98                 :            :         /* Failure Test: Valid names and invalid size */
      99                 :            :         size = 0;
     100                 :          1 :         ret = rte_latencystats_get_names(names, size);
     101         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count,"
     102                 :            :                     "Actual: %d Expected: %d", ret, NUM_STATS);
     103                 :            : 
     104                 :            :         return TEST_SUCCESS;
     105                 :            : }
     106                 :            : 
     107                 :            : /* Test case to get latency stats values */
     108                 :          1 : static int test_latencystats_get(void)
     109                 :            : {
     110                 :            :         int ret;
     111                 :            :         uint16_t size;
     112                 :          1 :         struct rte_metric_value values[NUM_STATS] = { };
     113                 :            : 
     114                 :            :         /* Success Test: Valid values and valid size */
     115                 :            :         size = NUM_STATS;
     116                 :          1 :         ret = rte_latencystats_get(values, size);
     117         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get latency metrics"
     118                 :            :                         " values");
     119                 :            : 
     120                 :            :         /* Failure Test: Invalid values and valid size */
     121                 :          1 :         ret = rte_latencystats_get(NULL, size);
     122         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count,"
     123                 :            :                     "Actual: %d Expected: %d", ret, NUM_STATS);
     124                 :            : 
     125                 :            :         /* Failure Test: Valid values and invalid size */
     126                 :            :         size = 0;
     127                 :          1 :         ret = rte_latencystats_get(values, size);
     128         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count,"
     129                 :            :                     "Actual: %d Expected: %d", ret, NUM_STATS);
     130                 :            : 
     131                 :            :         return TEST_SUCCESS;
     132                 :            : }
     133                 :            : 
     134                 :          1 : static int test_latency_ring_setup(void)
     135                 :            : {
     136                 :          1 :         test_ring_setup(&ring, &portid);
     137                 :            : 
     138                 :          1 :         return TEST_SUCCESS;
     139                 :            : }
     140                 :            : 
     141                 :          1 : static void test_latency_ring_free(void)
     142                 :            : {
     143                 :          1 :         test_ring_free(ring);
     144                 :          1 :         test_vdev_uninit("net_ring_net_ringa");
     145                 :          1 : }
     146                 :            : 
     147                 :          1 : static int test_forward_loop(uint16_t portid, struct rte_mbuf *pbuf[LATENCY_NUM_PACKETS])
     148                 :            : {
     149                 :            :         unsigned int i, iters = 0;
     150                 :            :         uint64_t end_cycles;
     151                 :          1 :         struct rte_metric_value values[NUM_STATS] = { };
     152                 :          1 :         struct rte_metric_name names[NUM_STATS] = { };
     153                 :            :         int ret;
     154                 :            : 
     155                 :          1 :         ret = rte_latencystats_get_names(names, NUM_STATS);
     156         [ -  + ]:          1 :         TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names");
     157                 :            : 
     158                 :          1 :         ret = rte_latencystats_get(values, NUM_STATS);
     159         [ -  + ]:          1 :         TEST_ASSERT(ret == NUM_STATS, "Test failed to get results before forwarding");
     160         [ -  + ]:          1 :         TEST_ASSERT(values[4].value == 0, "Samples not zero at start of test");
     161                 :            : 
     162                 :            :         /* Want test to run long enough to collect sufficient samples */
     163                 :          1 :         end_cycles = rte_rdtsc() + rte_get_tsc_hz() / MS_PER_S * LATENCY_FORWARD_MS;
     164         [ +  + ]:      10001 :         for (i = 0; i < LATENCY_FORWARD_ITERATIONS; i++) {
     165                 :      10000 :                 ret = test_packet_forward(pbuf, portid, QUEUE_ID);
     166         [ -  + ]:      10000 :                 if (ret < 0)
     167                 :            :                         printf("send pkts Failed\n");
     168                 :            : 
     169   [ +  +  +  - ]:      19991 :                 if (++iters >= MIN_ITERATIONS && rte_rdtsc() >= end_cycles)
     170                 :            :                         break;
     171                 :            :         }
     172                 :            : 
     173                 :          1 :         ret = rte_latencystats_get(values, NUM_STATS);
     174         [ -  + ]:          1 :         TEST_ASSERT(ret == NUM_STATS, "Test failed to get results after forwarding");
     175                 :            : 
     176         [ -  + ]:          1 :         if (values[4].value == 0) {
     177                 :            :                 printf("No latency samples collected after %u iterations, skipping\n", iters);
     178                 :          0 :                 return TEST_SKIPPED;
     179                 :            :         }
     180                 :            : 
     181         [ +  + ]:          6 :         for (i = 0; i < NUM_STATS; i++) {
     182                 :          5 :                 uint16_t k = values[i].key;
     183                 :            : 
     184                 :          5 :                 printf("%s = %"PRIu64"\n", names[k].name, values[i].value);
     185                 :            :         }
     186                 :          1 :         fflush(stdout);
     187         [ -  + ]:          1 :         TEST_ASSERT(values[4].value > 0, "No samples taken");
     188                 :            : 
     189         [ -  + ]:          1 :         TEST_ASSERT(values[0].value < values[1].value, "Min latency > Avg latency");
     190         [ -  + ]:          1 :         TEST_ASSERT(values[0].value < values[2].value, "Min latency > Max latency");
     191         [ -  + ]:          1 :         TEST_ASSERT(values[1].value < values[2].value, "Avg latency > Max latency");
     192                 :            :         return TEST_SUCCESS;
     193                 :            : }
     194                 :            : 
     195                 :          1 : static int test_latency_packet_forward(void)
     196                 :            : {
     197                 :          1 :         struct rte_mempool *mp = NULL;
     198                 :          1 :         char poolname[] = "mbuf_pool";
     199                 :          1 :         struct rte_mbuf *pbuf[LATENCY_NUM_PACKETS] = { };
     200                 :            :         int ret;
     201                 :            : 
     202                 :          1 :         ret = test_get_mbuf_from_pool(&mp, pbuf, poolname);
     203         [ -  + ]:          1 :         if (ret < 0) {
     204                 :            :                 printf("allocate mbuf pool Failed\n");
     205                 :          0 :                 return TEST_FAILED;
     206                 :            :         }
     207                 :            : 
     208                 :          1 :         ret = test_dev_start(portid, mp);
     209         [ -  + ]:          1 :         if (ret < 0) {
     210                 :          0 :                 printf("test_dev_start(%hu, %p) failed, error code: %d\n",
     211                 :            :                         portid, mp, ret);
     212                 :            :                 ret = TEST_FAILED;
     213                 :            :         } else {
     214                 :          1 :                 ret = test_forward_loop(portid, pbuf);
     215                 :            :         }
     216                 :            : 
     217                 :          1 :         rte_eth_dev_stop(portid);
     218                 :          1 :         test_put_mbuf_to_pool(mp, pbuf);
     219                 :            : 
     220                 :          1 :         return ret;
     221                 :            : }
     222                 :            : 
     223                 :            : static struct
     224                 :            : unit_test_suite latencystats_testsuite = {
     225                 :            :         .suite_name = "Latency Stats Unit Test Suite",
     226                 :            :         .setup = test_latency_ring_setup,
     227                 :            :         .teardown = test_latency_ring_free,
     228                 :            :         .unit_test_cases = {
     229                 :            : 
     230                 :            :                 /* Test Case 1: To check latency init with
     231                 :            :                  * metrics init
     232                 :            :                  */
     233                 :            :                 TEST_CASE_ST(NULL, NULL, test_latency_init),
     234                 :            : 
     235                 :            :                 /* Test Case 2: To check whether latency stats names
     236                 :            :                  * are retrieved
     237                 :            :                  */
     238                 :            :                 TEST_CASE_ST(NULL, NULL, test_latencystats_get_names),
     239                 :            : 
     240                 :            :                 /* Test Case 3: To check whether latency stats
     241                 :            :                  * values are retrieved
     242                 :            :                  */
     243                 :            :                 TEST_CASE_ST(NULL, NULL, test_latencystats_get),
     244                 :            : 
     245                 :            :                 /* Test Case 4: Do packet forwarding for metrics
     246                 :            :                  * calculation and check the latency metrics values
     247                 :            :                  * are updated
     248                 :            :                  */
     249                 :            :                 TEST_CASE_ST(test_latency_packet_forward, NULL,
     250                 :            :                                 test_latency_update),
     251                 :            : 
     252                 :            :                 /* Test Case 5: To check uninit of latency test */
     253                 :            :                 TEST_CASE_ST(NULL, NULL, test_latency_uninit),
     254                 :            : 
     255                 :            :                 TEST_CASES_END()
     256                 :            :         }
     257                 :            : };
     258                 :            : 
     259                 :          1 : static int test_latencystats(void)
     260                 :            : {
     261                 :          1 :         return unit_test_suite_runner(&latencystats_testsuite);
     262                 :            : }
     263                 :            : 
     264                 :        301 : REGISTER_FAST_TEST(latencystats_autotest, NOHUGE_OK, ASAN_OK, test_latencystats);

Generated by: LCOV version 1.14