1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
12 #include <rte_common.h>
13 #include <rte_string_fns.h>
14 #include <rte_cycles.h>
15 #include <rte_lcore.h>
20 /* Defines how many testcases can be specified as cmdline args */
21 #define MAX_CMDLINE_TESTCASES 8
23 static const char tc_sep = ',';
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;
30 unsigned int burst_sz;
31 unsigned int num_lcores;
32 char test_vector_filename[PATH_MAX];
36 static struct test_commands_list commands_list =
37 TAILQ_HEAD_INITIALIZER(commands_list);
40 add_test_command(struct test_command *t)
42 TAILQ_INSERT_TAIL(&commands_list, t, next);
46 unit_test_suite_runner(struct unit_test_suite *suite)
48 int test_result = TEST_SUCCESS;
49 unsigned int total = 0, skipped = 0, succeeded = 0, failed = 0;
52 printf("\n===========================================================\n");
53 printf("Starting Test Suite : %s\n", suite->suite_name);
55 start = rte_rdtsc_precise();
58 test_result = suite->setup();
59 if (test_result == TEST_FAILED) {
60 printf(" + Test suite setup %s failed!\n",
62 printf(" + ------------------------------------------------------- +\n");
65 if (test_result == TEST_SKIPPED) {
66 printf(" + Test suite setup %s skipped!\n",
68 printf(" + ------------------------------------------------------- +\n");
73 while (suite->unit_test_cases[total].testcase) {
74 if (suite->unit_test_cases[total].setup)
75 test_result = suite->unit_test_cases[total].setup();
77 if (test_result == TEST_SUCCESS)
78 test_result = suite->unit_test_cases[total].testcase();
80 if (suite->unit_test_cases[total].teardown)
81 suite->unit_test_cases[total].teardown();
83 if (test_result == TEST_SUCCESS) {
85 printf("TestCase [%2d] : %s passed\n", total,
86 suite->unit_test_cases[total].name);
87 } else if (test_result == TEST_SKIPPED) {
89 printf("TestCase [%2d] : %s skipped\n", total,
90 suite->unit_test_cases[total].name);
93 printf("TestCase [%2d] : %s failed\n", total,
94 suite->unit_test_cases[total].name);
100 /* Run test suite teardown */
104 end = rte_rdtsc_precise();
106 printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
107 printf(" + Test Suite Summary : %s\n", suite->suite_name);
108 printf(" + Tests Total : %2d\n", total);
109 printf(" + Tests Skipped : %2d\n", skipped);
110 printf(" + Tests Passed : %2d\n", succeeded);
111 printf(" + Tests Failed : %2d\n", failed);
112 printf(" + Tests Lasted : %lg ms\n",
113 ((end - start) * 1000) / (double)rte_get_tsc_hz());
114 printf(" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\n");
116 return (failed > 0) ? 1 : 0;
120 get_vector_filename(void)
122 return test_params.test_vector_filename;
128 return test_params.num_ops;
134 return test_params.burst_sz;
140 return test_params.num_lcores;
144 get_init_device(void)
146 return test_params.init_device;
150 print_usage(const char *prog_name)
152 struct test_command *t;
154 printf("***Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\n"
155 "\t[-b/--burst-size BURST_SIZE]\n"
156 "\t[-v/--test-vector VECTOR_FILE]\n"
157 "\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\n",
160 printf("Available testcases: ");
161 TAILQ_FOREACH(t, &commands_list, next)
162 printf("%s ", t->command);
167 parse_args(int argc, char **argv, struct test_params *tp)
169 int opt, option_index;
170 unsigned int num_tests = 0;
171 bool test_cases_present = false;
172 bool test_vector_present = false;
173 struct test_command *t;
174 char *tokens[MAX_CMDLINE_TESTCASES];
177 static struct option lgopts[] = {
178 { "num-ops", 1, 0, 'n' },
179 { "burst-size", 1, 0, 'b' },
180 { "test-cases", 1, 0, 'c' },
181 { "test-vector", 1, 0, 'v' },
182 { "lcores", 1, 0, 'l' },
183 { "init-device", 0, 0, 'i'},
184 { "help", 0, 0, 'h' },
188 while ((opt = getopt_long(argc, argv, "hin:b:c:v:l:", lgopts,
189 &option_index)) != EOF)
192 TEST_ASSERT(strlen(optarg) > 0,
193 "Num of operations is not provided");
194 tp->num_ops = strtol(optarg, NULL, 10);
197 TEST_ASSERT(strlen(optarg) > 0,
198 "Burst size is not provided");
199 tp->burst_sz = strtol(optarg, NULL, 10);
200 TEST_ASSERT(tp->burst_sz <= MAX_BURST,
201 "Burst size mustn't be greater than %u",
205 TEST_ASSERT(test_cases_present == false,
206 "Test cases provided more than once");
207 test_cases_present = true;
209 ret = rte_strsplit(optarg, strlen(optarg),
210 tokens, MAX_CMDLINE_TESTCASES, tc_sep);
212 TEST_ASSERT(ret <= MAX_CMDLINE_TESTCASES,
213 "Too many test cases (max=%d)",
214 MAX_CMDLINE_TESTCASES);
216 for (tc = 0; tc < ret; ++tc) {
217 /* Find matching test case */
218 TAILQ_FOREACH(t, &commands_list, next)
219 if (!strcmp(tokens[tc], t->command))
220 tp->test_to_run[num_tests] = t;
222 TEST_ASSERT(tp->test_to_run[num_tests] != NULL,
223 "Unknown test case: %s",
229 TEST_ASSERT(test_vector_present == false,
230 "Test vector provided more than once");
231 test_vector_present = true;
233 TEST_ASSERT(strlen(optarg) > 0,
234 "Config file name is null");
236 snprintf(tp->test_vector_filename,
237 sizeof(tp->test_vector_filename),
241 TEST_ASSERT(strlen(optarg) > 0,
242 "Num of lcores is not provided");
243 tp->num_lcores = strtol(optarg, NULL, 10);
244 TEST_ASSERT(tp->num_lcores <= RTE_MAX_LCORE,
245 "Num of lcores mustn't be greater than %u",
249 /* indicate fpga fec config required */
250 tp->init_device = true;
253 print_usage(argv[0]);
256 printf("ERROR: Unknown option: -%c\n", opt);
260 if (tp->num_ops == 0) {
262 "WARNING: Num of operations was not provided or was set 0. Set to default (%u)\n",
264 tp->num_ops = DEFAULT_OPS;
266 if (tp->burst_sz == 0) {
268 "WARNING: Burst size was not provided or was set 0. Set to default (%u)\n",
270 tp->burst_sz = DEFAULT_BURST;
272 if (tp->num_lcores == 0) {
274 "WARNING: Num of lcores was not provided or was set 0. Set to value from RTE config (%u)\n",
276 tp->num_lcores = rte_lcore_count();
279 TEST_ASSERT(tp->burst_sz <= tp->num_ops,
280 "Burst size (%u) mustn't be greater than num ops (%u)",
281 tp->burst_sz, tp->num_ops);
283 tp->num_tests = num_tests;
290 int ret = TEST_SUCCESS;
291 struct test_command *t;
293 TAILQ_FOREACH(t, &commands_list, next)
294 ret |= (int) t->callback();
300 run_parsed_tests(struct test_params *tp)
302 int ret = TEST_SUCCESS;
305 for (i = 0; i < tp->num_tests; ++i)
306 ret |= (int) tp->test_to_run[i]->callback();
312 main(int argc, char **argv)
317 ret = rte_eal_init(argc, argv);
323 /* Parse application arguments (after the EAL ones) */
324 ret = parse_args(argc, argv, &test_params);
326 print_usage(argv[0]);
330 /* If no argument provided - run all tests */
331 if (test_params.num_tests == 0)
332 return run_all_tests();
334 return run_parsed_tests(&test_params);