1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson */
4a9de470cSBruce Richardson
5a9de470cSBruce Richardson #include <string.h>
6a9de470cSBruce Richardson #include <stdio.h>
7a9de470cSBruce Richardson #include <stdint.h>
8a9de470cSBruce Richardson #include <stdarg.h>
9a9de470cSBruce Richardson #include <stdlib.h>
10a9de470cSBruce Richardson #include <errno.h>
11a9de470cSBruce Richardson #include <ctype.h>
12a9de470cSBruce Richardson #include <sys/queue.h>
13a9de470cSBruce Richardson
14a9de470cSBruce Richardson #include <cmdline_rdline.h>
15a9de470cSBruce Richardson #include <cmdline_parse.h>
16a9de470cSBruce Richardson #include <cmdline_socket.h>
17a9de470cSBruce Richardson #include <cmdline.h>
18a9de470cSBruce Richardson extern cmdline_parse_ctx_t main_ctx[];
19a9de470cSBruce Richardson
20a9de470cSBruce Richardson #include <rte_memory.h>
21a9de470cSBruce Richardson #include <rte_eal.h>
22a9de470cSBruce Richardson #include <rte_cycles.h>
23a9de470cSBruce Richardson #include <rte_log.h>
24a9de470cSBruce Richardson #include <rte_string_fns.h>
25a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
26a9de470cSBruce Richardson #include <rte_timer.h>
27a9de470cSBruce Richardson #endif
28a9de470cSBruce Richardson
29a9de470cSBruce Richardson #include "test.h"
30a8d0d473SBruce Richardson #ifdef RTE_LIB_PDUMP
31a9de470cSBruce Richardson #include "test_pdump.h"
326d27d8c0SReshma Pattan #endif
33a9de470cSBruce Richardson
34a9de470cSBruce Richardson #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
35a9de470cSBruce Richardson
36caa817f0SCiara Power #define FOR_EACH_SUITE_TESTCASE(iter, suite, case) \
37caa817f0SCiara Power for (iter = 0, case = suite->unit_test_cases[0]; \
38e65da89cSCiara Power suite->unit_test_cases[iter].testcase || \
39e65da89cSCiara Power suite->unit_test_cases[iter].testcase_with_data; \
40caa817f0SCiara Power iter++, case = suite->unit_test_cases[iter])
41caa817f0SCiara Power
42fbc53675SCiara Power #define FOR_EACH_SUITE_TESTSUITE(iter, suite, sub_ts) \
43fbc53675SCiara Power for (iter = 0, sub_ts = suite->unit_test_suites ? \
44fbc53675SCiara Power suite->unit_test_suites[0]:NULL; sub_ts && \
45fbc53675SCiara Power suite->unit_test_suites[iter]->suite_name != NULL; \
46fbc53675SCiara Power iter++, sub_ts = suite->unit_test_suites[iter])
47fbc53675SCiara Power
48a9de470cSBruce Richardson const char *prgname; /* to be set to argv[0] */
49a9de470cSBruce Richardson
50218c4e68SBruce Richardson static const char *recursive_call; /* used in linux for MP and other tests */
51a9de470cSBruce Richardson
52a9de470cSBruce Richardson static int
no_action(void)53a9de470cSBruce Richardson no_action(void){ return 0; }
54a9de470cSBruce Richardson
55a9de470cSBruce Richardson static int
do_recursive_call(void)56a9de470cSBruce Richardson do_recursive_call(void)
57a9de470cSBruce Richardson {
58a9de470cSBruce Richardson unsigned i;
59a9de470cSBruce Richardson struct {
60a9de470cSBruce Richardson const char *env_var;
61a9de470cSBruce Richardson int (*action_fn)(void);
62a9de470cSBruce Richardson } actions[] = {
63987d40a0SJie Zhou #ifndef RTE_EXEC_ENV_WINDOWS
64a9de470cSBruce Richardson { "run_secondary_instances", test_mp_secondary },
65987d40a0SJie Zhou #endif
66a8d0d473SBruce Richardson #ifdef RTE_LIB_PDUMP
67a8d0d473SBruce Richardson #ifdef RTE_NET_RING
68a9de470cSBruce Richardson { "run_pdump_server_tests", test_pdump },
696d27d8c0SReshma Pattan #endif
70207b1c81SReshma Pattan #endif
71a9de470cSBruce Richardson { "test_missing_c_flag", no_action },
72cb056611SStephen Hemminger { "test_main_lcore_flag", no_action },
73a9de470cSBruce Richardson { "test_invalid_n_flag", no_action },
74a9de470cSBruce Richardson { "test_no_hpet_flag", no_action },
75db27370bSStephen Hemminger { "test_allow_flag", no_action },
76a9de470cSBruce Richardson { "test_invalid_b_flag", no_action },
77a9de470cSBruce Richardson { "test_invalid_vdev_flag", no_action },
78a9de470cSBruce Richardson { "test_invalid_r_flag", no_action },
79a9de470cSBruce Richardson { "test_misc_flags", no_action },
80a9de470cSBruce Richardson { "test_memory_flags", no_action },
81a9de470cSBruce Richardson { "test_file_prefix", no_action },
82a9de470cSBruce Richardson { "test_no_huge_flag", no_action },
83a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
84987d40a0SJie Zhou #ifndef RTE_EXEC_ENV_WINDOWS
8550247fe0SErik Gabriel Carrillo { "timer_secondary_spawn_wait", test_timer_secondary },
86d3065379STimothy Redaelli #endif
87987d40a0SJie Zhou #endif
88a9de470cSBruce Richardson };
89a9de470cSBruce Richardson
90a9de470cSBruce Richardson if (recursive_call == NULL)
91a9de470cSBruce Richardson return -1;
9271bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(actions); i++) {
93a9de470cSBruce Richardson if (strcmp(actions[i].env_var, recursive_call) == 0)
94a9de470cSBruce Richardson return (actions[i].action_fn)();
95a9de470cSBruce Richardson }
96a9de470cSBruce Richardson printf("ERROR - missing action to take for %s\n", recursive_call);
97a9de470cSBruce Richardson return -1;
98a9de470cSBruce Richardson }
99a9de470cSBruce Richardson
100a9de470cSBruce Richardson int last_test_result;
101a9de470cSBruce Richardson
102a9de470cSBruce Richardson #define MAX_EXTRA_ARGS 32
103a9de470cSBruce Richardson
104a9de470cSBruce Richardson int
main(int argc,char ** argv)105a9de470cSBruce Richardson main(int argc, char **argv)
106a9de470cSBruce Richardson {
107a9de470cSBruce Richardson struct cmdline *cl;
108ace2f054SBruce Richardson char *tests[argc]; /* store an array of tests to run */
109ace2f054SBruce Richardson int test_count = 0;
110ace2f054SBruce Richardson int i;
111a9de470cSBruce Richardson char *extra_args;
112a9de470cSBruce Richardson int ret;
113a9de470cSBruce Richardson
114a9de470cSBruce Richardson extra_args = getenv("DPDK_TEST_PARAMS");
115a9de470cSBruce Richardson if (extra_args != NULL && strlen(extra_args) > 0) {
116a9de470cSBruce Richardson char **all_argv;
117a9de470cSBruce Richardson char *eargv[MAX_EXTRA_ARGS];
118a9de470cSBruce Richardson int all_argc;
119a9de470cSBruce Richardson int eargc;
120a9de470cSBruce Richardson int i;
121a9de470cSBruce Richardson
122a9de470cSBruce Richardson RTE_LOG(INFO, APP, "Using additional DPDK_TEST_PARAMS: '%s'\n",
123a9de470cSBruce Richardson extra_args);
124a9de470cSBruce Richardson eargc = rte_strsplit(extra_args, strlen(extra_args),
125a9de470cSBruce Richardson eargv, MAX_EXTRA_ARGS, ' ');
126a9de470cSBruce Richardson
127a9de470cSBruce Richardson /* merge argc/argv and the environment args */
128a9de470cSBruce Richardson all_argc = argc + eargc;
129a9de470cSBruce Richardson all_argv = malloc(sizeof(*all_argv) * (all_argc + 1));
130a9de470cSBruce Richardson if (all_argv == NULL) {
131a9de470cSBruce Richardson ret = -1;
132a9de470cSBruce Richardson goto out;
133a9de470cSBruce Richardson }
134a9de470cSBruce Richardson
135a9de470cSBruce Richardson for (i = 0; i < argc; i++)
136a9de470cSBruce Richardson all_argv[i] = argv[i];
137a9de470cSBruce Richardson for (i = 0; i < eargc; i++)
138a9de470cSBruce Richardson all_argv[argc + i] = eargv[i];
139a9de470cSBruce Richardson all_argv[all_argc] = NULL;
140a9de470cSBruce Richardson
141a9de470cSBruce Richardson /* call eal_init with combined args */
142a9de470cSBruce Richardson ret = rte_eal_init(all_argc, all_argv);
143a9de470cSBruce Richardson free(all_argv);
144a9de470cSBruce Richardson } else
145a9de470cSBruce Richardson ret = rte_eal_init(argc, argv);
146a9de470cSBruce Richardson if (ret < 0) {
147a9de470cSBruce Richardson ret = -1;
148a9de470cSBruce Richardson goto out;
149a9de470cSBruce Richardson }
150a9de470cSBruce Richardson
1513dd7d693SStanislaw Kardach argv += ret;
152ace2f054SBruce Richardson argc -= ret;
1533dd7d693SStanislaw Kardach
1543dd7d693SStanislaw Kardach prgname = argv[0];
1553dd7d693SStanislaw Kardach
156a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
1573dd7d693SStanislaw Kardach ret = rte_timer_subsystem_init();
1583dd7d693SStanislaw Kardach if (ret < 0 && ret != -EALREADY) {
15950247fe0SErik Gabriel Carrillo ret = -1;
16050247fe0SErik Gabriel Carrillo goto out;
16150247fe0SErik Gabriel Carrillo }
162a9de470cSBruce Richardson #endif
163a9de470cSBruce Richardson
164a9de470cSBruce Richardson if (commands_init() < 0) {
165a9de470cSBruce Richardson ret = -1;
166a9de470cSBruce Richardson goto out;
167a9de470cSBruce Richardson }
168a9de470cSBruce Richardson
169a9de470cSBruce Richardson recursive_call = getenv(RECURSIVE_ENV_VAR);
170a9de470cSBruce Richardson if (recursive_call != NULL) {
171a9de470cSBruce Richardson ret = do_recursive_call();
172a9de470cSBruce Richardson goto out;
173a9de470cSBruce Richardson }
174a9de470cSBruce Richardson
175a9de470cSBruce Richardson #ifdef RTE_LIBEAL_USE_HPET
176a9de470cSBruce Richardson if (rte_eal_hpet_init(1) < 0)
177a9de470cSBruce Richardson #endif
178a9de470cSBruce Richardson RTE_LOG(INFO, APP,
179a9de470cSBruce Richardson "HPET is not enabled, using TSC as default timer\n");
180a9de470cSBruce Richardson
181a9de470cSBruce Richardson
182acdabc45SStephen Hemminger char *dpdk_test = getenv("DPDK_TEST");
183ace2f054SBruce Richardson
184f940a2e3SBruce Richardson if (dpdk_test && strlen(dpdk_test) > 0)
185ace2f054SBruce Richardson tests[test_count++] = dpdk_test;
186f940a2e3SBruce Richardson for (i = 1; i < argc; i++)
187ace2f054SBruce Richardson tests[test_count++] = argv[i];
188ace2f054SBruce Richardson
189ace2f054SBruce Richardson if (test_count > 0) {
190acdabc45SStephen Hemminger char buf[1024];
1911f48a7d2SBruce Richardson char *dpdk_test_skip = getenv("DPDK_TEST_SKIP");
1921f48a7d2SBruce Richardson char *skip_tests[128] = {0};
1931f48a7d2SBruce Richardson size_t n_skip_tests = 0;
1941f48a7d2SBruce Richardson
1951f48a7d2SBruce Richardson if (dpdk_test_skip != NULL && strlen(dpdk_test_skip) > 0) {
1961f48a7d2SBruce Richardson int split_ret;
1971f48a7d2SBruce Richardson char *dpdk_test_skip_cp = strdup(dpdk_test_skip);
1981f48a7d2SBruce Richardson if (dpdk_test_skip_cp == NULL) {
1991f48a7d2SBruce Richardson ret = -1;
2001f48a7d2SBruce Richardson goto out;
2011f48a7d2SBruce Richardson }
2021f48a7d2SBruce Richardson dpdk_test_skip = dpdk_test_skip_cp;
2031f48a7d2SBruce Richardson split_ret = rte_strsplit(dpdk_test_skip, strlen(dpdk_test_skip),
2041f48a7d2SBruce Richardson skip_tests, RTE_DIM(skip_tests), ',');
2051f48a7d2SBruce Richardson if (split_ret > 0)
2061f48a7d2SBruce Richardson n_skip_tests = split_ret;
2071f48a7d2SBruce Richardson else
2081f48a7d2SBruce Richardson free(dpdk_test_skip);
2091f48a7d2SBruce Richardson }
210acdabc45SStephen Hemminger
211acdabc45SStephen Hemminger cl = cmdline_new(main_ctx, "RTE>>", 0, 1);
212acdabc45SStephen Hemminger if (cl == NULL) {
213acdabc45SStephen Hemminger ret = -1;
214acdabc45SStephen Hemminger goto out;
215acdabc45SStephen Hemminger }
216acdabc45SStephen Hemminger
217ace2f054SBruce Richardson for (i = 0; i < test_count; i++) {
2181f48a7d2SBruce Richardson /* check if test is to be skipped */
2191f48a7d2SBruce Richardson for (size_t j = 0; j < n_skip_tests; j++) {
2201f48a7d2SBruce Richardson if (strcmp(tests[i], skip_tests[j]) == 0) {
2211f48a7d2SBruce Richardson fprintf(stderr, "Skipping %s [DPDK_TEST_SKIP]\n", tests[i]);
2221f48a7d2SBruce Richardson ret = TEST_SKIPPED;
2231f48a7d2SBruce Richardson goto end_of_cmd;
2241f48a7d2SBruce Richardson }
2251f48a7d2SBruce Richardson }
2261f48a7d2SBruce Richardson
227ace2f054SBruce Richardson snprintf(buf, sizeof(buf), "%s\n", tests[i]);
228f940a2e3SBruce Richardson if (cmdline_parse_check(cl, buf) < 0) {
229f940a2e3SBruce Richardson printf("Error: invalid test command: '%s'\n", tests[i]);
230f940a2e3SBruce Richardson ret = -1;
231f940a2e3SBruce Richardson } else if (cmdline_in(cl, buf, strlen(buf)) < 0) {
232acdabc45SStephen Hemminger printf("error on cmdline input\n");
233acdabc45SStephen Hemminger ret = -1;
234ace2f054SBruce Richardson } else
235acdabc45SStephen Hemminger ret = last_test_result;
236ace2f054SBruce Richardson
2371f48a7d2SBruce Richardson end_of_cmd:
238db01e7e8SBruce Richardson if (ret != 0 && ret != TEST_SKIPPED)
239ace2f054SBruce Richardson break;
240acdabc45SStephen Hemminger }
2411f48a7d2SBruce Richardson if (n_skip_tests > 0)
2421f48a7d2SBruce Richardson free(dpdk_test_skip);
2431f48a7d2SBruce Richardson
244acdabc45SStephen Hemminger cmdline_free(cl);
245acdabc45SStephen Hemminger goto out;
246acdabc45SStephen Hemminger } else {
247acdabc45SStephen Hemminger /* if no DPDK_TEST env variable, go interactive */
248a9de470cSBruce Richardson cl = cmdline_stdin_new(main_ctx, "RTE>>");
249a9de470cSBruce Richardson if (cl == NULL) {
250a9de470cSBruce Richardson ret = -1;
251a9de470cSBruce Richardson goto out;
252a9de470cSBruce Richardson }
253a9de470cSBruce Richardson
254a9de470cSBruce Richardson cmdline_interact(cl);
255a9de470cSBruce Richardson cmdline_stdin_exit(cl);
256acdabc45SStephen Hemminger }
257a9de470cSBruce Richardson ret = 0;
258a9de470cSBruce Richardson
259a9de470cSBruce Richardson out:
260a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
2618650e935SErik Gabriel Carrillo rte_timer_subsystem_finalize();
2628650e935SErik Gabriel Carrillo #endif
263a9de470cSBruce Richardson rte_eal_cleanup();
264a9de470cSBruce Richardson return ret;
265a9de470cSBruce Richardson }
266a9de470cSBruce Richardson
267caa817f0SCiara Power static void
unit_test_suite_count_tcs_on_setup_fail(struct unit_test_suite * suite,int test_success,unsigned int * sub_ts_failed,unsigned int * sub_ts_skipped,unsigned int * sub_ts_total)268caa817f0SCiara Power unit_test_suite_count_tcs_on_setup_fail(struct unit_test_suite *suite,
269fbc53675SCiara Power int test_success, unsigned int *sub_ts_failed,
270fbc53675SCiara Power unsigned int *sub_ts_skipped, unsigned int *sub_ts_total)
271caa817f0SCiara Power {
272caa817f0SCiara Power struct unit_test_case tc;
273fbc53675SCiara Power struct unit_test_suite *ts;
274caa817f0SCiara Power int i;
275caa817f0SCiara Power
276fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts) {
277fbc53675SCiara Power unit_test_suite_count_tcs_on_setup_fail(
278fbc53675SCiara Power ts, test_success, sub_ts_failed,
279fbc53675SCiara Power sub_ts_skipped, sub_ts_total);
280fbc53675SCiara Power suite->total += ts->total;
281fbc53675SCiara Power suite->failed += ts->failed;
282fbc53675SCiara Power suite->skipped += ts->skipped;
283fbc53675SCiara Power if (ts->failed)
284fbc53675SCiara Power (*sub_ts_failed)++;
285fbc53675SCiara Power else
286fbc53675SCiara Power (*sub_ts_skipped)++;
287fbc53675SCiara Power (*sub_ts_total)++;
288fbc53675SCiara Power }
289caa817f0SCiara Power FOR_EACH_SUITE_TESTCASE(i, suite, tc) {
290caa817f0SCiara Power suite->total++;
291caa817f0SCiara Power if (!tc.enabled || test_success == TEST_SKIPPED)
292caa817f0SCiara Power suite->skipped++;
293caa817f0SCiara Power else
294caa817f0SCiara Power suite->failed++;
295caa817f0SCiara Power }
296caa817f0SCiara Power }
297caa817f0SCiara Power
298caa817f0SCiara Power static void
unit_test_suite_reset_counts(struct unit_test_suite * suite)299caa817f0SCiara Power unit_test_suite_reset_counts(struct unit_test_suite *suite)
300caa817f0SCiara Power {
301fbc53675SCiara Power struct unit_test_suite *ts;
302fbc53675SCiara Power int i;
303fbc53675SCiara Power
304fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts)
305fbc53675SCiara Power unit_test_suite_reset_counts(ts);
306caa817f0SCiara Power suite->total = 0;
307caa817f0SCiara Power suite->executed = 0;
308caa817f0SCiara Power suite->succeeded = 0;
309caa817f0SCiara Power suite->skipped = 0;
310caa817f0SCiara Power suite->failed = 0;
311caa817f0SCiara Power suite->unsupported = 0;
312caa817f0SCiara Power }
313a9de470cSBruce Richardson
314a9de470cSBruce Richardson int
unit_test_suite_runner(struct unit_test_suite * suite)315a9de470cSBruce Richardson unit_test_suite_runner(struct unit_test_suite *suite)
316a9de470cSBruce Richardson {
317fbc53675SCiara Power int test_success, i, ret;
318a9de470cSBruce Richardson const char *status;
319caa817f0SCiara Power struct unit_test_case tc;
320fbc53675SCiara Power struct unit_test_suite *ts;
321fbc53675SCiara Power unsigned int sub_ts_succeeded = 0, sub_ts_failed = 0;
322fbc53675SCiara Power unsigned int sub_ts_skipped = 0, sub_ts_total = 0;
323caa817f0SCiara Power
324caa817f0SCiara Power unit_test_suite_reset_counts(suite);
325a9de470cSBruce Richardson
326a9de470cSBruce Richardson if (suite->suite_name) {
327a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
328a9de470cSBruce Richardson printf(" + Test Suite : %s\n", suite->suite_name);
329a9de470cSBruce Richardson }
330a9de470cSBruce Richardson
331e0f4a0edSDavid Marchand if (suite->setup) {
332e0f4a0edSDavid Marchand test_success = suite->setup();
333e0f4a0edSDavid Marchand if (test_success != 0) {
334a9de470cSBruce Richardson /*
335e0f4a0edSDavid Marchand * setup did not pass, so count all enabled tests and
336e0f4a0edSDavid Marchand * mark them as failed/skipped
337a9de470cSBruce Richardson */
338caa817f0SCiara Power unit_test_suite_count_tcs_on_setup_fail(suite,
339fbc53675SCiara Power test_success, &sub_ts_failed,
340fbc53675SCiara Power &sub_ts_skipped, &sub_ts_total);
341a9de470cSBruce Richardson goto suite_summary;
342a9de470cSBruce Richardson }
343e0f4a0edSDavid Marchand }
344a9de470cSBruce Richardson
345a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
346a9de470cSBruce Richardson
347caa817f0SCiara Power FOR_EACH_SUITE_TESTCASE(suite->total, suite, tc) {
348caa817f0SCiara Power if (!tc.enabled) {
349caa817f0SCiara Power suite->skipped++;
350a9de470cSBruce Richardson continue;
351a9de470cSBruce Richardson } else {
352caa817f0SCiara Power suite->executed++;
353a9de470cSBruce Richardson }
354a9de470cSBruce Richardson
355a9de470cSBruce Richardson /* run test case setup */
356caa817f0SCiara Power if (tc.setup)
357caa817f0SCiara Power test_success = tc.setup();
358a9de470cSBruce Richardson else
359a9de470cSBruce Richardson test_success = TEST_SUCCESS;
360a9de470cSBruce Richardson
361a9de470cSBruce Richardson if (test_success == TEST_SUCCESS) {
362a9de470cSBruce Richardson /* run the test case */
363e65da89cSCiara Power if (tc.testcase)
364caa817f0SCiara Power test_success = tc.testcase();
365e65da89cSCiara Power else if (tc.testcase_with_data)
366e65da89cSCiara Power test_success = tc.testcase_with_data(tc.data);
367e65da89cSCiara Power else
368e65da89cSCiara Power test_success = -ENOTSUP;
369e65da89cSCiara Power
370a9de470cSBruce Richardson if (test_success == TEST_SUCCESS)
371caa817f0SCiara Power suite->succeeded++;
372*a620df6dSBruce Richardson else if (test_success == TEST_SKIPPED) {
373caa817f0SCiara Power suite->skipped++;
374*a620df6dSBruce Richardson suite->executed--;
375*a620df6dSBruce Richardson } else if (test_success == -ENOTSUP) {
376caa817f0SCiara Power suite->unsupported++;
377*a620df6dSBruce Richardson suite->executed--;
378*a620df6dSBruce Richardson } else
379caa817f0SCiara Power suite->failed++;
380a9de470cSBruce Richardson } else if (test_success == -ENOTSUP) {
381caa817f0SCiara Power suite->unsupported++;
38296b5d4f9SAnoob Joseph } else if (test_success == TEST_SKIPPED) {
38396b5d4f9SAnoob Joseph suite->skipped++;
384a9de470cSBruce Richardson } else {
385caa817f0SCiara Power suite->failed++;
386a9de470cSBruce Richardson }
387a9de470cSBruce Richardson
388a9de470cSBruce Richardson /* run the test case teardown */
389caa817f0SCiara Power if (tc.teardown)
390caa817f0SCiara Power tc.teardown();
391a9de470cSBruce Richardson
392a9de470cSBruce Richardson if (test_success == TEST_SUCCESS)
393a9de470cSBruce Richardson status = "succeeded";
394e0f4a0edSDavid Marchand else if (test_success == TEST_SKIPPED)
395e0f4a0edSDavid Marchand status = "skipped";
396a9de470cSBruce Richardson else if (test_success == -ENOTSUP)
397a9de470cSBruce Richardson status = "unsupported";
398a9de470cSBruce Richardson else
399a9de470cSBruce Richardson status = "failed";
400a9de470cSBruce Richardson
401caa817f0SCiara Power printf(" + TestCase [%2d] : %s %s\n", suite->total,
402caa817f0SCiara Power tc.name, status);
403a9de470cSBruce Richardson }
404fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts) {
405fbc53675SCiara Power ret = unit_test_suite_runner(ts);
406fbc53675SCiara Power if (ret == TEST_SUCCESS)
407fbc53675SCiara Power sub_ts_succeeded++;
408fbc53675SCiara Power else if (ret == TEST_SKIPPED)
409fbc53675SCiara Power sub_ts_skipped++;
410fbc53675SCiara Power else
411fbc53675SCiara Power sub_ts_failed++;
412fbc53675SCiara Power sub_ts_total++;
413fbc53675SCiara Power
414fbc53675SCiara Power suite->total += ts->total;
415fbc53675SCiara Power suite->succeeded += ts->succeeded;
416fbc53675SCiara Power suite->failed += ts->failed;
417fbc53675SCiara Power suite->skipped += ts->skipped;
418fbc53675SCiara Power suite->unsupported += ts->unsupported;
419fbc53675SCiara Power suite->executed += ts->executed;
420fbc53675SCiara Power }
421a9de470cSBruce Richardson
422a9de470cSBruce Richardson /* Run test suite teardown */
423a9de470cSBruce Richardson if (suite->teardown)
424a9de470cSBruce Richardson suite->teardown();
425a9de470cSBruce Richardson
426a9de470cSBruce Richardson goto suite_summary;
427a9de470cSBruce Richardson
428a9de470cSBruce Richardson suite_summary:
429a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
430caa817f0SCiara Power printf(" + Test Suite Summary : %s\n", suite->suite_name);
431fbc53675SCiara Power printf(" + ------------------------------------------------------- +\n");
432fbc53675SCiara Power
433fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts)
434fbc53675SCiara Power printf(" + %s : %d/%d passed, %d/%d skipped, "
435fbc53675SCiara Power "%d/%d failed, %d/%d unsupported\n", ts->suite_name,
436fbc53675SCiara Power ts->succeeded, ts->total, ts->skipped, ts->total,
437fbc53675SCiara Power ts->failed, ts->total, ts->unsupported, ts->total);
438fbc53675SCiara Power
439fbc53675SCiara Power if (suite->unit_test_suites) {
440fbc53675SCiara Power printf(" + ------------------------------------------------------- +\n");
441fbc53675SCiara Power printf(" + Sub Testsuites Total : %2d\n", sub_ts_total);
442fbc53675SCiara Power printf(" + Sub Testsuites Skipped : %2d\n", sub_ts_skipped);
443fbc53675SCiara Power printf(" + Sub Testsuites Passed : %2d\n", sub_ts_succeeded);
444fbc53675SCiara Power printf(" + Sub Testsuites Failed : %2d\n", sub_ts_failed);
445fbc53675SCiara Power printf(" + ------------------------------------------------------- +\n");
446fbc53675SCiara Power }
447fbc53675SCiara Power
448caa817f0SCiara Power printf(" + Tests Total : %2d\n", suite->total);
449caa817f0SCiara Power printf(" + Tests Skipped : %2d\n", suite->skipped);
450caa817f0SCiara Power printf(" + Tests Executed : %2d\n", suite->executed);
451caa817f0SCiara Power printf(" + Tests Unsupported: %2d\n", suite->unsupported);
452caa817f0SCiara Power printf(" + Tests Passed : %2d\n", suite->succeeded);
453caa817f0SCiara Power printf(" + Tests Failed : %2d\n", suite->failed);
454a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
455a9de470cSBruce Richardson
456caa817f0SCiara Power last_test_result = suite->failed;
457a9de470cSBruce Richardson
458caa817f0SCiara Power if (suite->failed)
459e0f4a0edSDavid Marchand return TEST_FAILED;
460caa817f0SCiara Power if (suite->total == suite->skipped)
461e0f4a0edSDavid Marchand return TEST_SKIPPED;
462e0f4a0edSDavid Marchand return TEST_SUCCESS;
463a9de470cSBruce Richardson }
464