test mbuf attach
[dpdk.git] / app / test-bbdev / main.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4
5 #include <getopt.h>
6 #include <inttypes.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdbool.h>
10
11 #include <rte_eal.h>
12 #include <rte_common.h>
13 #include <rte_string_fns.h>
14 #include <rte_cycles.h>
15 #include <rte_lcore.h>
16
17 #include "main.h"
18
19
20 /* Defines how many testcases can be specified as cmdline args */
21 #define MAX_CMDLINE_TESTCASES 8
22
23 static const char tc_sep = ',';
24
25 /* Declare structure for command line test parameters and options */
26 static struct test_params {
27         struct test_command *test_to_run[MAX_CMDLINE_TESTCASES];
28         unsigned int num_tests;
29         unsigned int num_ops;
30         unsigned int burst_sz;
31         unsigned int num_lcores;
32         double snr;
33         unsigned int iter_max;
34         char test_vector_filename[PATH_MAX];
35         bool init_device;
36 } test_params;
37
38 static struct test_commands_list commands_list =
39         TAILQ_HEAD_INITIALIZER(commands_list);
40
41 void
42 add_test_command(struct test_command *t)
43 {
44         TAILQ_INSERT_TAIL(&commands_list, t, next);
45 }
46
47 int
48 unit_test_suite_runner(struct unit_test_suite *suite)
49 {
50         int test_result = TEST_SUCCESS;
51         unsigned int total = 0, skipped = 0, succeeded = 0, failed = 0;
52         uint64_t start, end;
53
54         printf("\n===========================================================\n");
55         printf("Starting Test Suite : %s\n", suite->suite_name);
56
57         start = rte_rdtsc_precise();
58
59         if (suite->setup) {
60                 test_result = suite->setup();
61                 if (test_result == TEST_FAILED) {
62                         printf(" + Test suite setup %s failed!\n",
63                                         suite->suite_name);
64                         printf(" + ------------------------------------------------------- +\n");
65                         return 1;
66                 }
67                 if (test_result == TEST_SKIPPED) {
68                         printf(" + Test suite setup %s skipped!\n",
69                                         suite->suite_name);
70                         printf(" + ------------------------------------------------------- +\n");
71                         return 0;
72                 }
73         }
74
75         while (suite->unit_test_cases[total].testcase) {
76                 if (suite->unit_test_cases[total].setup)
77                         test_result = suite->unit_test_cases[total].setup();
78
79                 if (test_result == TEST_SUCCESS)
80                         test_result = suite->unit_test_cases[total].testcase();
81
82                 if (suite->unit_test_cases[total].teardown)
83                         suite->unit_test_cases[total].teardown();
84
85                 if (test_result == TEST_SUCCESS) {
86                         succeeded++;
87                         printf("TestCase [%2d] : %s passed\n", total,
88                                         suite->unit_test_cases[total].name);
89                 } else if (test_result == TEST_SKIPPED) {
90                         skipped++;
91                         printf("TestCase [%2d] : %s skipped\n", total,
92                                         suite->unit_test_cases[total].name);
93                 } else {
94                         failed++;
95                         printf("TestCase [%2d] : %s failed\n", total,
96                                         suite->unit_test_cases[total].name);
97                 }
98
99                 total++;
100         }
101
102         /* Run test suite teardown */
103         if (suite->teardown)
104                 suite->teardown();
105
106         end = rte_rdtsc_precise();
107
108         printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
109         printf(" + Test Suite Summary : %s\n", suite->suite_name);
110         printf(" + Tests Total :       %2d\n", total);
111         printf(" + Tests Skipped :     %2d\n", skipped);
112         printf(" + Tests Passed :      %2d\n", succeeded);
113         printf(" + Tests Failed :      %2d\n", failed);
114         printf(" + Tests Lasted :       %lg ms\n",
115                         ((end - start) * 1000) / (double)rte_get_tsc_hz());
116         printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
117
118         return (failed > 0) ? 1 : 0;
119 }
120
121 const char *
122 get_vector_filename(void)
123 {
124         return test_params.test_vector_filename;
125 }
126
127 unsigned int
128 get_num_ops(void)
129 {
130         return test_params.num_ops;
131 }
132
133 unsigned int
134 get_burst_sz(void)
135 {
136         return test_params.burst_sz;
137 }
138
139 unsigned int
140 get_num_lcores(void)
141 {
142         return test_params.num_lcores;
143 }
144
145 double
146 get_snr(void)
147 {
148         return test_params.snr;
149 }
150
151 unsigned int
152 get_iter_max(void)
153 {
154         return test_params.iter_max;
155 }
156
157 bool
158 get_init_device(void)
159 {
160         return test_params.init_device;
161 }
162
163 static void
164 print_usage(const char *prog_name)
165 {
166         struct test_command *t;
167
168         printf("***Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\n"
169                         "\t[-b/--burst-size BURST_SIZE]\n"
170                         "\t[-v/--test-vector VECTOR_FILE]\n"
171                         "\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\n",
172                         prog_name);
173
174         printf("Available testcases: ");
175         TAILQ_FOREACH(t, &commands_list, next)
176                 printf("%s ", t->command);
177         printf("\n");
178 }
179
180 static int
181 parse_args(int argc, char **argv, struct test_params *tp)
182 {
183         int opt, option_index;
184         unsigned int num_tests = 0;
185         bool test_cases_present = false;
186         bool test_vector_present = false;
187         struct test_command *t;
188         char *tokens[MAX_CMDLINE_TESTCASES];
189         int tc, ret;
190
191         static struct option lgopts[] = {
192                 { "num-ops", 1, 0, 'n' },
193                 { "burst-size", 1, 0, 'b' },
194                 { "test-cases", 1, 0, 'c' },
195                 { "test-vector", 1, 0, 'v' },
196                 { "lcores", 1, 0, 'l' },
197                 { "snr", 1, 0, 's' },
198                 { "iter_max", 6, 0, 't' },
199                 { "init-device", 0, 0, 'i'},
200                 { "help", 0, 0, 'h' },
201                 { NULL,  0, 0, 0 }
202         };
203         tp->iter_max = DEFAULT_ITER;
204
205         while ((opt = getopt_long(argc, argv, "hin:b:c:v:l:s:t:", lgopts,
206                         &option_index)) != EOF)
207                 switch (opt) {
208                 case 'n':
209                         TEST_ASSERT(strlen(optarg) > 0,
210                                         "Num of operations is not provided");
211                         tp->num_ops = strtol(optarg, NULL, 10);
212                         break;
213                 case 'b':
214                         TEST_ASSERT(strlen(optarg) > 0,
215                                         "Burst size is not provided");
216                         tp->burst_sz = strtol(optarg, NULL, 10);
217                         TEST_ASSERT(tp->burst_sz <= MAX_BURST,
218                                         "Burst size mustn't be greater than %u",
219                                         MAX_BURST);
220                         break;
221                 case 'c':
222                         TEST_ASSERT(test_cases_present == false,
223                                         "Test cases provided more than once");
224                         test_cases_present = true;
225
226                         ret = rte_strsplit(optarg, strlen(optarg),
227                                         tokens, MAX_CMDLINE_TESTCASES, tc_sep);
228
229                         TEST_ASSERT(ret <= MAX_CMDLINE_TESTCASES,
230                                         "Too many test cases (max=%d)",
231                                         MAX_CMDLINE_TESTCASES);
232
233                         for (tc = 0; tc < ret; ++tc) {
234                                 /* Find matching test case */
235                                 TAILQ_FOREACH(t, &commands_list, next)
236                                         if (!strcmp(tokens[tc], t->command))
237                                                 tp->test_to_run[num_tests] = t;
238
239                                 TEST_ASSERT(tp->test_to_run[num_tests] != NULL,
240                                                 "Unknown test case: %s",
241                                                 tokens[tc]);
242                                 ++num_tests;
243                         }
244                         break;
245                 case 'v':
246                         TEST_ASSERT(test_vector_present == false,
247                                         "Test vector provided more than once");
248                         test_vector_present = true;
249
250                         TEST_ASSERT(strlen(optarg) > 0,
251                                         "Config file name is null");
252
253                         snprintf(tp->test_vector_filename,
254                                         sizeof(tp->test_vector_filename),
255                                         "%s", optarg);
256                         break;
257                 case 's':
258                         TEST_ASSERT(strlen(optarg) > 0,
259                                         "SNR is not provided");
260                         tp->snr = strtod(optarg, NULL);
261                         break;
262                 case 't':
263                         TEST_ASSERT(strlen(optarg) > 0,
264                                         "Iter_max is not provided");
265                         tp->iter_max = strtol(optarg, NULL, 10);
266                         break;
267                 case 'l':
268                         TEST_ASSERT(strlen(optarg) > 0,
269                                         "Num of lcores is not provided");
270                         tp->num_lcores = strtol(optarg, NULL, 10);
271                         TEST_ASSERT(tp->num_lcores <= RTE_MAX_LCORE,
272                                         "Num of lcores mustn't be greater than %u",
273                                         RTE_MAX_LCORE);
274                         break;
275                 case 'i':
276                         /* indicate fpga fec config required */
277                         tp->init_device = true;
278                         break;
279                 case 'h':
280                         print_usage(argv[0]);
281                         return 0;
282                 default:
283                         printf("ERROR: Unknown option: -%c\n", opt);
284                         return -1;
285                 }
286
287         if (tp->num_ops == 0) {
288                 printf(
289                         "WARNING: Num of operations was not provided or was set 0. Set to default (%u)\n",
290                         DEFAULT_OPS);
291                 tp->num_ops = DEFAULT_OPS;
292         }
293         if (tp->burst_sz == 0) {
294                 printf(
295                         "WARNING: Burst size was not provided or was set 0. Set to default (%u)\n",
296                         DEFAULT_BURST);
297                 tp->burst_sz = DEFAULT_BURST;
298         }
299         if (tp->num_lcores == 0) {
300                 printf(
301                         "WARNING: Num of lcores was not provided or was set 0. Set to value from RTE config (%u)\n",
302                         rte_lcore_count());
303                 tp->num_lcores = rte_lcore_count();
304         }
305
306         TEST_ASSERT(tp->burst_sz <= tp->num_ops,
307                         "Burst size (%u) mustn't be greater than num ops (%u)",
308                         tp->burst_sz, tp->num_ops);
309
310         tp->num_tests = num_tests;
311         return 0;
312 }
313
314 static int
315 run_all_tests(void)
316 {
317         int ret = TEST_SUCCESS;
318         struct test_command *t;
319
320         TAILQ_FOREACH(t, &commands_list, next)
321                 ret |= (int) t->callback();
322
323         return ret;
324 }
325
326 static int
327 run_parsed_tests(struct test_params *tp)
328 {
329         int ret = TEST_SUCCESS;
330         unsigned int i;
331
332         for (i = 0; i < tp->num_tests; ++i)
333                 ret |= (int) tp->test_to_run[i]->callback();
334
335         return ret;
336 }
337
338 int
339 main(int argc, char **argv)
340 {
341         int ret;
342
343         /* Init EAL */
344         ret = rte_eal_init(argc, argv);
345         if (ret < 0)
346                 return 1;
347         argc -= ret;
348         argv += ret;
349
350         /* Parse application arguments (after the EAL ones) */
351         ret = parse_args(argc, argv, &test_params);
352         if (ret < 0) {
353                 print_usage(argv[0]);
354                 return 1;
355         }
356
357         /* If no argument provided - run all tests */
358         if (test_params.num_tests == 0)
359                 return run_all_tests();
360         else
361                 return run_parsed_tests(&test_params);
362 }