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);
|