]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2010-2014 Intel Corporation | |
7c673cae FG |
3 | */ |
4 | ||
11fdf7f2 | 5 | #include <stdio.h> |
7c673cae FG |
6 | #include <unistd.h> |
7 | #include <string.h> | |
8 | ||
9 | #include <rte_cycles.h> | |
10 | #include <rte_errno.h> | |
11 | #include <rte_mbuf.h> | |
12 | #include <rte_reorder.h> | |
13 | #include <rte_lcore.h> | |
14 | #include <rte_malloc.h> | |
15 | ||
16 | #include "test.h" | |
17 | ||
18 | #define BURST 32 | |
19 | #define REORDER_BUFFER_SIZE 16384 | |
20 | #define NUM_MBUFS (2*REORDER_BUFFER_SIZE) | |
21 | #define REORDER_BUFFER_SIZE_INVALID 2049 | |
22 | ||
23 | struct reorder_unittest_params { | |
24 | struct rte_mempool *p; | |
25 | struct rte_reorder_buffer *b; | |
26 | }; | |
27 | ||
28 | static struct reorder_unittest_params default_params = { | |
29 | .p = NULL, | |
30 | .b = NULL | |
31 | }; | |
32 | ||
33 | static struct reorder_unittest_params *test_params = &default_params; | |
34 | ||
35 | static int | |
36 | test_reorder_create(void) | |
37 | { | |
38 | struct rte_reorder_buffer *b = NULL; | |
39 | ||
40 | b = rte_reorder_create(NULL, rte_socket_id(), REORDER_BUFFER_SIZE); | |
41 | TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), | |
42 | "No error on create() with NULL name"); | |
43 | ||
44 | b = rte_reorder_create("PKT", rte_socket_id(), REORDER_BUFFER_SIZE_INVALID); | |
45 | TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), | |
46 | "No error on create() with invalid buffer size param."); | |
47 | ||
48 | b = rte_reorder_create("PKT_RO1", rte_socket_id(), REORDER_BUFFER_SIZE); | |
49 | TEST_ASSERT_EQUAL(b, test_params->b, | |
50 | "New reorder instance created with already existing name"); | |
51 | ||
52 | return 0; | |
53 | } | |
54 | ||
55 | static int | |
56 | test_reorder_init(void) | |
57 | { | |
58 | struct rte_reorder_buffer *b = NULL; | |
59 | unsigned int size; | |
60 | /* | |
61 | * The minimum memory area size that should be passed to library is, | |
62 | * sizeof(struct rte_reorder_buffer) + (2 * size * sizeof(struct rte_mbuf *)); | |
63 | * Otherwise error will be thrown | |
64 | */ | |
65 | ||
66 | size = 100; | |
67 | b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE); | |
68 | TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), | |
69 | "No error on init with NULL buffer."); | |
70 | ||
71 | b = rte_malloc(NULL, size, 0); | |
72 | b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE); | |
73 | TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), | |
74 | "No error on init with invalid mem zone size."); | |
75 | rte_free(b); | |
76 | ||
77 | size = 262336; | |
78 | b = rte_malloc(NULL, size, 0); | |
79 | b = rte_reorder_init(b, size, "PKT1", REORDER_BUFFER_SIZE_INVALID); | |
80 | TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), | |
81 | "No error on init with invalid buffer size param."); | |
82 | ||
83 | b = rte_reorder_init(b, size, NULL, REORDER_BUFFER_SIZE); | |
84 | TEST_ASSERT((b == NULL) && (rte_errno == EINVAL), | |
85 | "No error on init with invalid name."); | |
86 | rte_free(b); | |
87 | ||
88 | return 0; | |
89 | } | |
90 | ||
91 | static int | |
92 | test_reorder_find_existing(void) | |
93 | { | |
94 | struct rte_reorder_buffer *b = NULL; | |
95 | ||
96 | /* Try to find existing reorder buffer instance */ | |
97 | b = rte_reorder_find_existing("PKT_RO1"); | |
98 | TEST_ASSERT_EQUAL(b, test_params->b, | |
99 | "existing reorder buffer instance not found"); | |
100 | ||
101 | /* Try to find non existing reorder buffer instance */ | |
102 | b = rte_reorder_find_existing("ro_find_non_existing"); | |
103 | TEST_ASSERT((b == NULL) && (rte_errno == ENOENT), | |
104 | "non existing reorder buffer instance found"); | |
105 | ||
106 | return 0; | |
107 | } | |
108 | ||
109 | static int | |
110 | test_reorder_free(void) | |
111 | { | |
112 | struct rte_reorder_buffer *b1 = NULL, *b2 = NULL; | |
113 | const char *name = "test_free"; | |
114 | ||
115 | b1 = rte_reorder_create(name, rte_socket_id(), 8); | |
116 | TEST_ASSERT_NOT_NULL(b1, "Failed to create reorder buffer."); | |
117 | ||
118 | b2 = rte_reorder_find_existing(name); | |
119 | TEST_ASSERT_EQUAL(b1, b2, "Failed to find existing reorder buffer"); | |
120 | ||
121 | rte_reorder_free(b1); | |
122 | ||
123 | b2 = rte_reorder_find_existing(name); | |
124 | TEST_ASSERT((b2 == NULL) && (rte_errno == ENOENT), | |
125 | "Found previously freed reorder buffer"); | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
130 | static int | |
131 | test_reorder_insert(void) | |
132 | { | |
133 | struct rte_reorder_buffer *b = NULL; | |
134 | struct rte_mempool *p = test_params->p; | |
135 | const unsigned int size = 4; | |
136 | const unsigned int num_bufs = 7; | |
137 | struct rte_mbuf *bufs[num_bufs]; | |
138 | int ret = 0; | |
139 | unsigned i; | |
140 | ||
141 | /* This would create a reorder buffer instance consisting of: | |
142 | * reorder_seq = 0 | |
143 | * ready_buf: RB[size] = {NULL, NULL, NULL, NULL} | |
144 | * order_buf: OB[size] = {NULL, NULL, NULL, NULL} | |
145 | */ | |
146 | b = rte_reorder_create("test_insert", rte_socket_id(), size); | |
147 | TEST_ASSERT_NOT_NULL(b, "Failed to create reorder buffer"); | |
148 | ||
11fdf7f2 TL |
149 | for (i = 0; i < num_bufs; i++) { |
150 | bufs[i] = rte_pktmbuf_alloc(p); | |
151 | TEST_ASSERT_NOT_NULL(bufs[i], "Packet allocation failed\n"); | |
7c673cae | 152 | bufs[i]->seqn = i; |
11fdf7f2 | 153 | } |
7c673cae FG |
154 | |
155 | /* This should fill up order buffer: | |
156 | * reorder_seq = 0 | |
157 | * RB[] = {NULL, NULL, NULL, NULL} | |
158 | * OB[] = {0, 1, 2, 3} | |
159 | */ | |
160 | for (i = 0; i < size; i++) { | |
161 | ret = rte_reorder_insert(b, bufs[i]); | |
162 | if (ret != 0) { | |
163 | printf("%s:%d: Error inserting packet with seqn less than size\n", | |
164 | __func__, __LINE__); | |
165 | ret = -1; | |
166 | goto exit; | |
167 | } | |
11fdf7f2 | 168 | bufs[i] = NULL; |
7c673cae FG |
169 | } |
170 | ||
171 | /* early packet - should move mbufs to ready buf and move sequence window | |
172 | * reorder_seq = 4 | |
173 | * RB[] = {0, 1, 2, 3} | |
174 | * OB[] = {4, NULL, NULL, NULL} | |
175 | */ | |
176 | ret = rte_reorder_insert(b, bufs[4]); | |
177 | if (ret != 0) { | |
178 | printf("%s:%d: Error inserting early packet with seqn: size\n", | |
179 | __func__, __LINE__); | |
180 | ret = -1; | |
181 | goto exit; | |
182 | } | |
11fdf7f2 | 183 | bufs[4] = NULL; |
7c673cae FG |
184 | |
185 | /* early packet from current sequence window - full ready buffer */ | |
186 | bufs[5]->seqn = 2 * size; | |
187 | ret = rte_reorder_insert(b, bufs[5]); | |
188 | if (!((ret == -1) && (rte_errno == ENOSPC))) { | |
189 | printf("%s:%d: No error inserting early packet with full ready buffer\n", | |
190 | __func__, __LINE__); | |
191 | ret = -1; | |
192 | goto exit; | |
193 | } | |
11fdf7f2 | 194 | bufs[5] = NULL; |
7c673cae FG |
195 | |
196 | /* late packet */ | |
197 | bufs[6]->seqn = 3 * size; | |
198 | ret = rte_reorder_insert(b, bufs[6]); | |
199 | if (!((ret == -1) && (rte_errno == ERANGE))) { | |
200 | printf("%s:%d: No error inserting late packet with seqn:" | |
201 | " 3 * size\n", __func__, __LINE__); | |
202 | ret = -1; | |
203 | goto exit; | |
204 | } | |
11fdf7f2 | 205 | bufs[6] = NULL; |
7c673cae FG |
206 | |
207 | ret = 0; | |
208 | exit: | |
7c673cae | 209 | rte_reorder_free(b); |
11fdf7f2 TL |
210 | for (i = 0; i < num_bufs; i++) { |
211 | if (bufs[i] != NULL) | |
212 | rte_pktmbuf_free(bufs[i]); | |
213 | } | |
7c673cae FG |
214 | return ret; |
215 | } | |
216 | ||
217 | static int | |
218 | test_reorder_drain(void) | |
219 | { | |
220 | struct rte_reorder_buffer *b = NULL; | |
221 | struct rte_mempool *p = test_params->p; | |
222 | const unsigned int size = 4; | |
223 | const unsigned int num_bufs = 8; | |
224 | struct rte_mbuf *bufs[num_bufs]; | |
225 | struct rte_mbuf *robufs[num_bufs]; | |
226 | int ret = 0; | |
227 | unsigned i, cnt; | |
228 | ||
11fdf7f2 TL |
229 | /* initialize all robufs to NULL */ |
230 | for (i = 0; i < num_bufs; i++) | |
231 | robufs[i] = NULL; | |
232 | ||
7c673cae FG |
233 | /* This would create a reorder buffer instance consisting of: |
234 | * reorder_seq = 0 | |
235 | * ready_buf: RB[size] = {NULL, NULL, NULL, NULL} | |
236 | * order_buf: OB[size] = {NULL, NULL, NULL, NULL} | |
237 | */ | |
238 | b = rte_reorder_create("test_drain", rte_socket_id(), size); | |
239 | TEST_ASSERT_NOT_NULL(b, "Failed to create reorder buffer"); | |
240 | ||
7c673cae FG |
241 | /* Check no drained packets if reorder is empty */ |
242 | cnt = rte_reorder_drain(b, robufs, 1); | |
243 | if (cnt != 0) { | |
244 | printf("%s:%d: drained packets from empty reorder buffer\n", | |
245 | __func__, __LINE__); | |
246 | ret = -1; | |
247 | goto exit; | |
248 | } | |
249 | ||
11fdf7f2 TL |
250 | for (i = 0; i < num_bufs; i++) { |
251 | bufs[i] = rte_pktmbuf_alloc(p); | |
252 | TEST_ASSERT_NOT_NULL(bufs[i], "Packet allocation failed\n"); | |
7c673cae | 253 | bufs[i]->seqn = i; |
11fdf7f2 | 254 | } |
7c673cae FG |
255 | |
256 | /* Insert packet with seqn 1: | |
257 | * reorder_seq = 0 | |
258 | * RB[] = {NULL, NULL, NULL, NULL} | |
259 | * OB[] = {1, NULL, NULL, NULL} | |
260 | */ | |
261 | rte_reorder_insert(b, bufs[1]); | |
11fdf7f2 | 262 | bufs[1] = NULL; |
7c673cae FG |
263 | |
264 | cnt = rte_reorder_drain(b, robufs, 1); | |
265 | if (cnt != 1) { | |
266 | printf("%s:%d:%d: number of expected packets not drained\n", | |
267 | __func__, __LINE__, cnt); | |
268 | ret = -1; | |
269 | goto exit; | |
270 | } | |
11fdf7f2 TL |
271 | if (robufs[0] != NULL) |
272 | rte_pktmbuf_free(robufs[i]); | |
7c673cae FG |
273 | |
274 | /* Insert more packets | |
275 | * RB[] = {NULL, NULL, NULL, NULL} | |
276 | * OB[] = {NULL, 2, 3, NULL} | |
277 | */ | |
278 | rte_reorder_insert(b, bufs[2]); | |
279 | rte_reorder_insert(b, bufs[3]); | |
11fdf7f2 TL |
280 | bufs[2] = NULL; |
281 | bufs[3] = NULL; | |
7c673cae FG |
282 | |
283 | /* Insert more packets | |
284 | * RB[] = {NULL, NULL, NULL, NULL} | |
285 | * OB[] = {NULL, 2, 3, 4} | |
286 | */ | |
287 | rte_reorder_insert(b, bufs[4]); | |
11fdf7f2 | 288 | bufs[4] = NULL; |
7c673cae FG |
289 | |
290 | /* Insert more packets | |
291 | * RB[] = {2, 3, 4, NULL} | |
292 | * OB[] = {NULL, NULL, 7, NULL} | |
293 | */ | |
294 | rte_reorder_insert(b, bufs[7]); | |
11fdf7f2 | 295 | bufs[7] = NULL; |
7c673cae FG |
296 | |
297 | /* drained expected packets */ | |
298 | cnt = rte_reorder_drain(b, robufs, 4); | |
299 | if (cnt != 3) { | |
300 | printf("%s:%d:%d: number of expected packets not drained\n", | |
301 | __func__, __LINE__, cnt); | |
302 | ret = -1; | |
303 | goto exit; | |
304 | } | |
11fdf7f2 TL |
305 | for (i = 0; i < 3; i++) { |
306 | if (robufs[i] != NULL) | |
307 | rte_pktmbuf_free(robufs[i]); | |
308 | } | |
7c673cae FG |
309 | |
310 | /* | |
311 | * RB[] = {NULL, NULL, NULL, NULL} | |
312 | * OB[] = {NULL, NULL, 7, NULL} | |
313 | */ | |
314 | cnt = rte_reorder_drain(b, robufs, 1); | |
315 | if (cnt != 0) { | |
316 | printf("%s:%d:%d: number of expected packets not drained\n", | |
317 | __func__, __LINE__, cnt); | |
318 | ret = -1; | |
319 | goto exit; | |
320 | } | |
321 | ret = 0; | |
322 | exit: | |
7c673cae | 323 | rte_reorder_free(b); |
11fdf7f2 TL |
324 | for (i = 0; i < num_bufs; i++) { |
325 | if (bufs[i] != NULL) | |
326 | rte_pktmbuf_free(bufs[i]); | |
327 | if (robufs[i] != NULL) | |
328 | rte_pktmbuf_free(robufs[i]); | |
329 | } | |
7c673cae FG |
330 | return ret; |
331 | } | |
332 | ||
333 | static int | |
334 | test_setup(void) | |
335 | { | |
336 | /* reorder buffer instance creation */ | |
337 | if (test_params->b == NULL) { | |
338 | test_params->b = rte_reorder_create("PKT_RO1", rte_socket_id(), | |
339 | REORDER_BUFFER_SIZE); | |
340 | if (test_params->b == NULL) { | |
341 | printf("%s: Error creating reorder buffer instance b\n", | |
342 | __func__); | |
343 | return -1; | |
344 | } | |
345 | } else | |
346 | rte_reorder_reset(test_params->b); | |
347 | ||
348 | /* mempool creation */ | |
349 | if (test_params->p == NULL) { | |
350 | test_params->p = rte_pktmbuf_pool_create("RO_MBUF_POOL", | |
351 | NUM_MBUFS, BURST, 0, RTE_MBUF_DEFAULT_BUF_SIZE, | |
352 | rte_socket_id()); | |
353 | if (test_params->p == NULL) { | |
354 | printf("%s: Error creating mempool\n", __func__); | |
355 | return -1; | |
356 | } | |
357 | } | |
358 | return 0; | |
359 | } | |
360 | ||
11fdf7f2 TL |
361 | static void |
362 | test_teardown(void) | |
363 | { | |
364 | rte_reorder_free(test_params->b); | |
365 | test_params->b = NULL; | |
366 | rte_mempool_free(test_params->p); | |
367 | test_params->p = NULL; | |
368 | } | |
369 | ||
370 | ||
7c673cae FG |
371 | static struct unit_test_suite reorder_test_suite = { |
372 | ||
373 | .setup = test_setup, | |
11fdf7f2 | 374 | .teardown = test_teardown, |
7c673cae FG |
375 | .suite_name = "Reorder Unit Test Suite", |
376 | .unit_test_cases = { | |
377 | TEST_CASE(test_reorder_create), | |
378 | TEST_CASE(test_reorder_init), | |
379 | TEST_CASE(test_reorder_find_existing), | |
380 | TEST_CASE(test_reorder_free), | |
381 | TEST_CASE(test_reorder_insert), | |
382 | TEST_CASE(test_reorder_drain), | |
383 | TEST_CASES_END() | |
384 | } | |
385 | }; | |
386 | ||
387 | static int | |
388 | test_reorder(void) | |
389 | { | |
390 | return unit_test_suite_runner(&reorder_test_suite); | |
391 | } | |
392 | ||
393 | REGISTER_TEST_COMMAND(reorder_autotest, test_reorder); |