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>
19 /* Defines how many testcases can be specified as cmdline args */
20 #define MAX_CMDLINE_TESTCASES 8
22 static const char tc_sep
= ',';
24 static struct test_params
{
25 struct test_command
*test_to_run
[MAX_CMDLINE_TESTCASES
];
26 unsigned int num_tests
;
28 unsigned int burst_sz
;
29 unsigned int num_lcores
;
30 char test_vector_filename
[PATH_MAX
];
33 static struct test_commands_list commands_list
=
34 TAILQ_HEAD_INITIALIZER(commands_list
);
37 add_test_command(struct test_command
*t
)
39 TAILQ_INSERT_TAIL(&commands_list
, t
, next
);
43 unit_test_suite_runner(struct unit_test_suite
*suite
)
45 int test_result
= TEST_SUCCESS
;
46 unsigned int total
= 0, skipped
= 0, succeeded
= 0, failed
= 0;
50 "\n + ------------------------------------------------------- +\n");
51 printf(" + Starting Test Suite : %s\n", suite
->suite_name
);
53 start
= rte_rdtsc_precise();
56 test_result
= suite
->setup();
57 if (test_result
== TEST_FAILED
) {
58 printf(" + Test suite setup %s failed!\n",
61 " + ------------------------------------------------------- +\n");
64 if (test_result
== TEST_SKIPPED
) {
65 printf(" + Test suite setup %s skipped!\n",
68 " + ------------------------------------------------------- +\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 print_usage(const char *prog_name
)
146 struct test_command
*t
;
148 printf("Usage: %s [EAL params] [-- [-n/--num-ops NUM_OPS]\n"
149 "\t[-b/--burst-size BURST_SIZE]\n"
150 "\t[-v/--test-vector VECTOR_FILE]\n"
151 "\t[-c/--test-cases TEST_CASE[,TEST_CASE,...]]]\n",
154 printf("Available testcases: ");
155 TAILQ_FOREACH(t
, &commands_list
, next
)
156 printf("%s ", t
->command
);
161 parse_args(int argc
, char **argv
, struct test_params
*tp
)
163 int opt
, option_index
;
164 unsigned int num_tests
= 0;
165 bool test_cases_present
= false;
166 bool test_vector_present
= false;
167 struct test_command
*t
;
168 char *tokens
[MAX_CMDLINE_TESTCASES
];
171 static struct option lgopts
[] = {
172 { "num-ops", 1, 0, 'n' },
173 { "burst-size", 1, 0, 'b' },
174 { "test-cases", 1, 0, 'c' },
175 { "test-vector", 1, 0, 'v' },
176 { "lcores", 1, 0, 'l' },
177 { "help", 0, 0, 'h' },
181 while ((opt
= getopt_long(argc
, argv
, "hn:b:c:v:l:", lgopts
,
182 &option_index
)) != EOF
)
185 TEST_ASSERT(strlen(optarg
) > 0,
186 "Num of operations is not provided");
187 tp
->num_ops
= strtol(optarg
, NULL
, 10);
190 TEST_ASSERT(strlen(optarg
) > 0,
191 "Burst size is not provided");
192 tp
->burst_sz
= strtol(optarg
, NULL
, 10);
193 TEST_ASSERT(tp
->burst_sz
<= MAX_BURST
,
194 "Burst size mustn't be greater than %u",
198 TEST_ASSERT(test_cases_present
== false,
199 "Test cases provided more than once");
200 test_cases_present
= true;
202 ret
= rte_strsplit(optarg
, strlen(optarg
),
203 tokens
, MAX_CMDLINE_TESTCASES
, tc_sep
);
205 TEST_ASSERT(ret
<= MAX_CMDLINE_TESTCASES
,
206 "Too many test cases (max=%d)",
207 MAX_CMDLINE_TESTCASES
);
209 for (tc
= 0; tc
< ret
; ++tc
) {
210 /* Find matching test case */
211 TAILQ_FOREACH(t
, &commands_list
, next
)
212 if (!strcmp(tokens
[tc
], t
->command
))
213 tp
->test_to_run
[num_tests
] = t
;
215 TEST_ASSERT(tp
->test_to_run
[num_tests
] != NULL
,
216 "Unknown test case: %s",
222 TEST_ASSERT(test_vector_present
== false,
223 "Test vector provided more than once");
224 test_vector_present
= true;
226 TEST_ASSERT(strlen(optarg
) > 0,
227 "Config file name is null");
229 strlcpy(tp
->test_vector_filename
, optarg
,
230 sizeof(tp
->test_vector_filename
));
233 TEST_ASSERT(strlen(optarg
) > 0,
234 "Num of lcores is not provided");
235 tp
->num_lcores
= strtol(optarg
, NULL
, 10);
236 TEST_ASSERT(tp
->num_lcores
<= RTE_MAX_LCORE
,
237 "Num of lcores mustn't be greater than %u",
241 print_usage(argv
[0]);
244 printf("ERROR: Unknown option: -%c\n", opt
);
248 if (tp
->num_ops
== 0) {
250 "WARNING: Num of operations was not provided or was set 0. Set to default (%u)\n",
252 tp
->num_ops
= DEFAULT_OPS
;
254 if (tp
->burst_sz
== 0) {
256 "WARNING: Burst size was not provided or was set 0. Set to default (%u)\n",
258 tp
->burst_sz
= DEFAULT_BURST
;
260 if (tp
->num_lcores
== 0) {
262 "WARNING: Num of lcores was not provided or was set 0. Set to value from RTE config (%u)\n",
264 tp
->num_lcores
= rte_lcore_count();
267 TEST_ASSERT(tp
->burst_sz
<= tp
->num_ops
,
268 "Burst size (%u) mustn't be greater than num ops (%u)",
269 tp
->burst_sz
, tp
->num_ops
);
271 tp
->num_tests
= num_tests
;
278 int ret
= TEST_SUCCESS
;
279 struct test_command
*t
;
281 TAILQ_FOREACH(t
, &commands_list
, next
)
282 ret
|= t
->callback();
288 run_parsed_tests(struct test_params
*tp
)
290 int ret
= TEST_SUCCESS
;
293 for (i
= 0; i
< tp
->num_tests
; ++i
)
294 ret
|= tp
->test_to_run
[i
]->callback();
300 main(int argc
, char **argv
)
305 ret
= rte_eal_init(argc
, argv
);
311 /* Parse application arguments (after the EAL ones) */
312 ret
= parse_args(argc
, argv
, &test_params
);
314 print_usage(argv
[0]);
318 /* If no argument provided - run all tests */
319 if (test_params
.num_tests
== 0)
320 return run_all_tests();
322 return run_parsed_tests(&test_params
);