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 4 18 #define LATENCY_NUM_PACKETS 10 19 #define QUEUE_ID 0 20 21 static uint16_t portid; 22 static struct rte_ring *ring; 23 24 static struct rte_metric_name lat_stats_strings[] = { 25 {"min_latency_ns"}, 26 {"avg_latency_ns"}, 27 {"max_latency_ns"}, 28 {"jitter_ns"}, 29 }; 30 31 /* Test case for latency init with metrics init */ 32 static int test_latency_init(void) 33 { 34 int ret = 0; 35 36 /* Metrics Initialization */ 37 rte_metrics_init(rte_socket_id()); 38 39 ret = rte_latencystats_init(1, NULL); 40 TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_init failed"); 41 42 return TEST_SUCCESS; 43 } 44 45 /* Test case to update the latency stats */ 46 static int test_latency_update(void) 47 { 48 int ret = 0; 49 50 ret = rte_latencystats_update(); 51 TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_update failed"); 52 53 return TEST_SUCCESS; 54 } 55 56 /* Test case to uninit latency stats */ 57 static int test_latency_uninit(void) 58 { 59 int ret = 0; 60 61 ret = rte_latencystats_uninit(); 62 TEST_ASSERT(ret >= 0, "Test Failed: rte_latencystats_uninit failed"); 63 64 ret = rte_metrics_deinit(); 65 TEST_ASSERT(ret >= 0, "Test Failed: rte_metrics_deinit failed"); 66 67 return TEST_SUCCESS; 68 } 69 70 /* Test case to get names of latency stats */ 71 static int test_latencystats_get_names(void) 72 { 73 int ret = 0, i = 0; 74 int size = 0; 75 struct rte_metric_name names[NUM_STATS]; 76 77 size_t m_size = sizeof(struct rte_metric_name); 78 for (i = 0; i < NUM_STATS; i++) 79 memset(&names[i], 0, m_size); 80 81 /* Success Test: Valid names and size */ 82 size = NUM_STATS; 83 ret = rte_latencystats_get_names(names, size); 84 for (i = 0; i < NUM_STATS; i++) { 85 if (strcmp(lat_stats_strings[i].name, names[i].name) == 0) 86 printf(" %s\n", names[i].name); 87 else 88 printf("Failed: Names are not matched\n"); 89 } 90 TEST_ASSERT((ret == NUM_STATS), "Test Failed to get metrics names"); 91 92 /* Failure Test: Invalid names and valid size */ 93 ret = rte_latencystats_get_names(NULL, size); 94 TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count," 95 "Actual: %d Expected: %d", ret, NUM_STATS); 96 97 /* Failure Test: Valid names and invalid size */ 98 size = 0; 99 ret = rte_latencystats_get_names(names, size); 100 TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the metrics count," 101 "Actual: %d Expected: %d", ret, NUM_STATS); 102 103 return TEST_SUCCESS; 104 } 105 106 /* Test case to get latency stats values */ 107 static int test_latencystats_get(void) 108 { 109 int ret = 0, i = 0; 110 int size = 0; 111 struct rte_metric_value values[NUM_STATS]; 112 113 size_t v_size = sizeof(struct rte_metric_value); 114 for (i = 0; i < NUM_STATS; i++) 115 memset(&values[i], 0, v_size); 116 117 /* Success Test: Valid values and valid size */ 118 size = NUM_STATS; 119 ret = rte_latencystats_get(values, size); 120 TEST_ASSERT((ret == NUM_STATS), "Test Failed to get latency metrics" 121 " values"); 122 123 /* Failure Test: Invalid values and valid size */ 124 ret = rte_latencystats_get(NULL, size); 125 TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count," 126 "Actual: %d Expected: %d", ret, NUM_STATS); 127 128 /* Failure Test: Valid values and invalid size */ 129 size = 0; 130 ret = rte_latencystats_get(values, size); 131 TEST_ASSERT((ret == NUM_STATS), "Test Failed to get the stats count," 132 "Actual: %d Expected: %d", ret, NUM_STATS); 133 134 return TEST_SUCCESS; 135 } 136 137 static int test_latency_ring_setup(void) 138 { 139 test_ring_setup(&ring, &portid); 140 141 return TEST_SUCCESS; 142 } 143 144 static void test_latency_ring_free(void) 145 { 146 test_ring_free(ring); 147 test_vdev_uninit("net_ring_net_ringa"); 148 } 149 150 static int test_latency_packet_forward(void) 151 { 152 int ret; 153 struct rte_mbuf *pbuf[LATENCY_NUM_PACKETS] = { }; 154 struct rte_mempool *mp; 155 char poolname[] = "mbuf_pool"; 156 157 ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); 158 if (ret < 0) { 159 printf("allocate mbuf pool Failed\n"); 160 return TEST_FAILED; 161 } 162 ret = test_dev_start(portid, mp); 163 if (ret < 0) { 164 printf("test_dev_start(%hu, %p) failed, error code: %d\n", 165 portid, mp, ret); 166 return TEST_FAILED; 167 } 168 169 ret = test_packet_forward(pbuf, portid, QUEUE_ID); 170 if (ret < 0) 171 printf("send pkts Failed\n"); 172 173 rte_eth_dev_stop(portid); 174 test_put_mbuf_to_pool(mp, pbuf); 175 176 return (ret >= 0) ? TEST_SUCCESS : TEST_FAILED; 177 } 178 179 static struct 180 unit_test_suite latencystats_testsuite = { 181 .suite_name = "Latency Stats Unit Test Suite", 182 .setup = test_latency_ring_setup, 183 .teardown = test_latency_ring_free, 184 .unit_test_cases = { 185 186 /* Test Case 1: To check latency init with 187 * metrics init 188 */ 189 TEST_CASE_ST(NULL, NULL, test_latency_init), 190 191 /* Test Case 2: Do packet forwarding for metrics 192 * calculation and check the latency metrics values 193 * are updated 194 */ 195 TEST_CASE_ST(test_latency_packet_forward, NULL, 196 test_latency_update), 197 /* Test Case 3: To check whether latency stats names 198 * are retrieved 199 */ 200 TEST_CASE_ST(NULL, NULL, test_latencystats_get_names), 201 202 /* Test Case 4: To check whether latency stats 203 * values are retrieved 204 */ 205 TEST_CASE_ST(NULL, NULL, test_latencystats_get), 206 207 /* Test Case 5: To check uninit of latency test */ 208 TEST_CASE_ST(NULL, NULL, test_latency_uninit), 209 210 TEST_CASES_END() 211 } 212 }; 213 214 static int test_latencystats(void) 215 { 216 return unit_test_suite_runner(&latencystats_testsuite); 217 } 218 219 REGISTER_TEST_COMMAND(latencystats_autotest, test_latencystats); 220