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
14a8d0d473SBruce Richardson #ifdef RTE_LIB_CMDLINE
15a9de470cSBruce Richardson #include <cmdline_rdline.h>
16a9de470cSBruce Richardson #include <cmdline_parse.h>
17a9de470cSBruce Richardson #include <cmdline_socket.h>
18a9de470cSBruce Richardson #include <cmdline.h>
19a9de470cSBruce Richardson extern cmdline_parse_ctx_t main_ctx[];
20a9de470cSBruce Richardson #endif
21a9de470cSBruce Richardson
22a9de470cSBruce Richardson #include <rte_memory.h>
23a9de470cSBruce Richardson #include <rte_eal.h>
24a9de470cSBruce Richardson #include <rte_cycles.h>
25a9de470cSBruce Richardson #include <rte_log.h>
26a9de470cSBruce Richardson #include <rte_string_fns.h>
27a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
28a9de470cSBruce Richardson #include <rte_timer.h>
29a9de470cSBruce Richardson #endif
30a9de470cSBruce Richardson
31a9de470cSBruce Richardson #include "test.h"
32a8d0d473SBruce Richardson #ifdef RTE_LIB_PDUMP
33a9de470cSBruce Richardson #include "test_pdump.h"
346d27d8c0SReshma Pattan #endif
35a9de470cSBruce Richardson
36a9de470cSBruce Richardson #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
37a9de470cSBruce Richardson
38caa817f0SCiara Power #define FOR_EACH_SUITE_TESTCASE(iter, suite, case) \
39caa817f0SCiara Power for (iter = 0, case = suite->unit_test_cases[0]; \
40e65da89cSCiara Power suite->unit_test_cases[iter].testcase || \
41e65da89cSCiara Power suite->unit_test_cases[iter].testcase_with_data; \
42caa817f0SCiara Power iter++, case = suite->unit_test_cases[iter])
43caa817f0SCiara Power
44fbc53675SCiara Power #define FOR_EACH_SUITE_TESTSUITE(iter, suite, sub_ts) \
45fbc53675SCiara Power for (iter = 0, sub_ts = suite->unit_test_suites ? \
46fbc53675SCiara Power suite->unit_test_suites[0]:NULL; sub_ts && \
47fbc53675SCiara Power suite->unit_test_suites[iter]->suite_name != NULL; \
48fbc53675SCiara Power iter++, sub_ts = suite->unit_test_suites[iter])
49fbc53675SCiara Power
50a9de470cSBruce Richardson const char *prgname; /* to be set to argv[0] */
51a9de470cSBruce Richardson
52218c4e68SBruce Richardson static const char *recursive_call; /* used in linux for MP and other tests */
53a9de470cSBruce Richardson
54a9de470cSBruce Richardson static int
no_action(void)55a9de470cSBruce Richardson no_action(void){ return 0; }
56a9de470cSBruce Richardson
57a9de470cSBruce Richardson static int
do_recursive_call(void)58a9de470cSBruce Richardson do_recursive_call(void)
59a9de470cSBruce Richardson {
60a9de470cSBruce Richardson unsigned i;
61a9de470cSBruce Richardson struct {
62a9de470cSBruce Richardson const char *env_var;
63a9de470cSBruce Richardson int (*action_fn)(void);
64a9de470cSBruce Richardson } actions[] = {
65*987d40a0SJie Zhou #ifndef RTE_EXEC_ENV_WINDOWS
66a9de470cSBruce Richardson { "run_secondary_instances", test_mp_secondary },
67*987d40a0SJie Zhou #endif
68a8d0d473SBruce Richardson #ifdef RTE_LIB_PDUMP
69a8d0d473SBruce Richardson #ifdef RTE_NET_RING
70a9de470cSBruce Richardson { "run_pdump_server_tests", test_pdump },
716d27d8c0SReshma Pattan #endif
72207b1c81SReshma Pattan #endif
73a9de470cSBruce Richardson { "test_missing_c_flag", no_action },
74cb056611SStephen Hemminger { "test_main_lcore_flag", no_action },
75a9de470cSBruce Richardson { "test_invalid_n_flag", no_action },
76a9de470cSBruce Richardson { "test_no_hpet_flag", no_action },
77db27370bSStephen Hemminger { "test_allow_flag", no_action },
78a9de470cSBruce Richardson { "test_invalid_b_flag", no_action },
79a9de470cSBruce Richardson { "test_invalid_vdev_flag", no_action },
80a9de470cSBruce Richardson { "test_invalid_r_flag", no_action },
81a9de470cSBruce Richardson { "test_misc_flags", no_action },
82a9de470cSBruce Richardson { "test_memory_flags", no_action },
83a9de470cSBruce Richardson { "test_file_prefix", no_action },
84a9de470cSBruce Richardson { "test_no_huge_flag", no_action },
85a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
86*987d40a0SJie Zhou #ifndef RTE_EXEC_ENV_WINDOWS
8750247fe0SErik Gabriel Carrillo { "timer_secondary_spawn_wait", test_timer_secondary },
88d3065379STimothy Redaelli #endif
89*987d40a0SJie Zhou #endif
90a9de470cSBruce Richardson };
91a9de470cSBruce Richardson
92a9de470cSBruce Richardson if (recursive_call == NULL)
93a9de470cSBruce Richardson return -1;
9471bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(actions); i++) {
95a9de470cSBruce Richardson if (strcmp(actions[i].env_var, recursive_call) == 0)
96a9de470cSBruce Richardson return (actions[i].action_fn)();
97a9de470cSBruce Richardson }
98a9de470cSBruce Richardson printf("ERROR - missing action to take for %s\n", recursive_call);
99a9de470cSBruce Richardson return -1;
100a9de470cSBruce Richardson }
101a9de470cSBruce Richardson
102a9de470cSBruce Richardson int last_test_result;
103a9de470cSBruce Richardson
104a9de470cSBruce Richardson #define MAX_EXTRA_ARGS 32
105a9de470cSBruce Richardson
106a9de470cSBruce Richardson int
main(int argc,char ** argv)107a9de470cSBruce Richardson main(int argc, char **argv)
108a9de470cSBruce Richardson {
109a8d0d473SBruce Richardson #ifdef RTE_LIB_CMDLINE
110a9de470cSBruce Richardson struct cmdline *cl;
111ace2f054SBruce Richardson char *tests[argc]; /* store an array of tests to run */
112ace2f054SBruce Richardson int test_count = 0;
113ace2f054SBruce Richardson int i;
114a9de470cSBruce Richardson #endif
115a9de470cSBruce Richardson char *extra_args;
116a9de470cSBruce Richardson int ret;
117a9de470cSBruce Richardson
118a9de470cSBruce Richardson extra_args = getenv("DPDK_TEST_PARAMS");
119a9de470cSBruce Richardson if (extra_args != NULL && strlen(extra_args) > 0) {
120a9de470cSBruce Richardson char **all_argv;
121a9de470cSBruce Richardson char *eargv[MAX_EXTRA_ARGS];
122a9de470cSBruce Richardson int all_argc;
123a9de470cSBruce Richardson int eargc;
124a9de470cSBruce Richardson int i;
125a9de470cSBruce Richardson
126a9de470cSBruce Richardson RTE_LOG(INFO, APP, "Using additional DPDK_TEST_PARAMS: '%s'\n",
127a9de470cSBruce Richardson extra_args);
128a9de470cSBruce Richardson eargc = rte_strsplit(extra_args, strlen(extra_args),
129a9de470cSBruce Richardson eargv, MAX_EXTRA_ARGS, ' ');
130a9de470cSBruce Richardson
131a9de470cSBruce Richardson /* merge argc/argv and the environment args */
132a9de470cSBruce Richardson all_argc = argc + eargc;
133a9de470cSBruce Richardson all_argv = malloc(sizeof(*all_argv) * (all_argc + 1));
134a9de470cSBruce Richardson if (all_argv == NULL) {
135a9de470cSBruce Richardson ret = -1;
136a9de470cSBruce Richardson goto out;
137a9de470cSBruce Richardson }
138a9de470cSBruce Richardson
139a9de470cSBruce Richardson for (i = 0; i < argc; i++)
140a9de470cSBruce Richardson all_argv[i] = argv[i];
141a9de470cSBruce Richardson for (i = 0; i < eargc; i++)
142a9de470cSBruce Richardson all_argv[argc + i] = eargv[i];
143a9de470cSBruce Richardson all_argv[all_argc] = NULL;
144a9de470cSBruce Richardson
145a9de470cSBruce Richardson /* call eal_init with combined args */
146a9de470cSBruce Richardson ret = rte_eal_init(all_argc, all_argv);
147a9de470cSBruce Richardson free(all_argv);
148a9de470cSBruce Richardson } else
149a9de470cSBruce Richardson ret = rte_eal_init(argc, argv);
150a9de470cSBruce Richardson if (ret < 0) {
151a9de470cSBruce Richardson ret = -1;
152a9de470cSBruce Richardson goto out;
153a9de470cSBruce Richardson }
154a9de470cSBruce Richardson
1553dd7d693SStanislaw Kardach argv += ret;
156ace2f054SBruce Richardson argc -= ret;
1573dd7d693SStanislaw Kardach
1583dd7d693SStanislaw Kardach prgname = argv[0];
1593dd7d693SStanislaw Kardach
160a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
1613dd7d693SStanislaw Kardach ret = rte_timer_subsystem_init();
1623dd7d693SStanislaw Kardach if (ret < 0 && ret != -EALREADY) {
16350247fe0SErik Gabriel Carrillo ret = -1;
16450247fe0SErik Gabriel Carrillo goto out;
16550247fe0SErik Gabriel Carrillo }
166a9de470cSBruce Richardson #endif
167a9de470cSBruce Richardson
168a9de470cSBruce Richardson if (commands_init() < 0) {
169a9de470cSBruce Richardson ret = -1;
170a9de470cSBruce Richardson goto out;
171a9de470cSBruce Richardson }
172a9de470cSBruce Richardson
173a9de470cSBruce Richardson recursive_call = getenv(RECURSIVE_ENV_VAR);
174a9de470cSBruce Richardson if (recursive_call != NULL) {
175a9de470cSBruce Richardson ret = do_recursive_call();
176a9de470cSBruce Richardson goto out;
177a9de470cSBruce Richardson }
178a9de470cSBruce Richardson
179a9de470cSBruce Richardson #ifdef RTE_LIBEAL_USE_HPET
180a9de470cSBruce Richardson if (rte_eal_hpet_init(1) < 0)
181a9de470cSBruce Richardson #endif
182a9de470cSBruce Richardson RTE_LOG(INFO, APP,
183a9de470cSBruce Richardson "HPET is not enabled, using TSC as default timer\n");
184a9de470cSBruce Richardson
185a9de470cSBruce Richardson
186a8d0d473SBruce Richardson #ifdef RTE_LIB_CMDLINE
187acdabc45SStephen Hemminger char *dpdk_test = getenv("DPDK_TEST");
188ace2f054SBruce Richardson
189ace2f054SBruce Richardson if (dpdk_test && strlen(dpdk_test) == 0)
190ace2f054SBruce Richardson dpdk_test = NULL;
191ace2f054SBruce Richardson
192ace2f054SBruce Richardson if (dpdk_test && !command_valid(dpdk_test)) {
193ace2f054SBruce Richardson RTE_LOG(WARNING, APP, "Invalid DPDK_TEST value '%s'\n", dpdk_test);
194ace2f054SBruce Richardson dpdk_test = NULL;
195ace2f054SBruce Richardson }
196ace2f054SBruce Richardson
197ace2f054SBruce Richardson if (dpdk_test)
198ace2f054SBruce Richardson tests[test_count++] = dpdk_test;
199ace2f054SBruce Richardson for (i = 1; i < argc; i++) {
200ace2f054SBruce Richardson if (!command_valid(argv[i]))
201ace2f054SBruce Richardson RTE_LOG(WARNING, APP, "Invalid test requested: '%s'\n", argv[i]);
202ace2f054SBruce Richardson else
203ace2f054SBruce Richardson tests[test_count++] = argv[i];
204ace2f054SBruce Richardson }
205ace2f054SBruce Richardson
206ace2f054SBruce Richardson if (test_count > 0) {
207acdabc45SStephen Hemminger char buf[1024];
208acdabc45SStephen Hemminger
209acdabc45SStephen Hemminger cl = cmdline_new(main_ctx, "RTE>>", 0, 1);
210acdabc45SStephen Hemminger if (cl == NULL) {
211acdabc45SStephen Hemminger ret = -1;
212acdabc45SStephen Hemminger goto out;
213acdabc45SStephen Hemminger }
214acdabc45SStephen Hemminger
215ace2f054SBruce Richardson for (i = 0; i < test_count; i++) {
216ace2f054SBruce Richardson snprintf(buf, sizeof(buf), "%s\n", tests[i]);
217acdabc45SStephen Hemminger if (cmdline_in(cl, buf, strlen(buf)) < 0) {
218acdabc45SStephen Hemminger printf("error on cmdline input\n");
219acdabc45SStephen Hemminger
220acdabc45SStephen Hemminger ret = -1;
221ace2f054SBruce Richardson } else
222acdabc45SStephen Hemminger ret = last_test_result;
223ace2f054SBruce Richardson
224ace2f054SBruce Richardson if (ret != 0)
225ace2f054SBruce Richardson break;
226acdabc45SStephen Hemminger }
227acdabc45SStephen Hemminger cmdline_free(cl);
228acdabc45SStephen Hemminger goto out;
229acdabc45SStephen Hemminger } else {
230acdabc45SStephen Hemminger /* if no DPDK_TEST env variable, go interactive */
231a9de470cSBruce Richardson cl = cmdline_stdin_new(main_ctx, "RTE>>");
232a9de470cSBruce Richardson if (cl == NULL) {
233a9de470cSBruce Richardson ret = -1;
234a9de470cSBruce Richardson goto out;
235a9de470cSBruce Richardson }
236a9de470cSBruce Richardson
237a9de470cSBruce Richardson cmdline_interact(cl);
238a9de470cSBruce Richardson cmdline_stdin_exit(cl);
239acdabc45SStephen Hemminger }
240a9de470cSBruce Richardson #endif
241a9de470cSBruce Richardson ret = 0;
242a9de470cSBruce Richardson
243a9de470cSBruce Richardson out:
244a8d0d473SBruce Richardson #ifdef RTE_LIB_TIMER
2458650e935SErik Gabriel Carrillo rte_timer_subsystem_finalize();
2468650e935SErik Gabriel Carrillo #endif
247a9de470cSBruce Richardson rte_eal_cleanup();
248a9de470cSBruce Richardson return ret;
249a9de470cSBruce Richardson }
250a9de470cSBruce Richardson
251caa817f0SCiara 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)252caa817f0SCiara Power unit_test_suite_count_tcs_on_setup_fail(struct unit_test_suite *suite,
253fbc53675SCiara Power int test_success, unsigned int *sub_ts_failed,
254fbc53675SCiara Power unsigned int *sub_ts_skipped, unsigned int *sub_ts_total)
255caa817f0SCiara Power {
256caa817f0SCiara Power struct unit_test_case tc;
257fbc53675SCiara Power struct unit_test_suite *ts;
258caa817f0SCiara Power int i;
259caa817f0SCiara Power
260fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts) {
261fbc53675SCiara Power unit_test_suite_count_tcs_on_setup_fail(
262fbc53675SCiara Power ts, test_success, sub_ts_failed,
263fbc53675SCiara Power sub_ts_skipped, sub_ts_total);
264fbc53675SCiara Power suite->total += ts->total;
265fbc53675SCiara Power suite->failed += ts->failed;
266fbc53675SCiara Power suite->skipped += ts->skipped;
267fbc53675SCiara Power if (ts->failed)
268fbc53675SCiara Power (*sub_ts_failed)++;
269fbc53675SCiara Power else
270fbc53675SCiara Power (*sub_ts_skipped)++;
271fbc53675SCiara Power (*sub_ts_total)++;
272fbc53675SCiara Power }
273caa817f0SCiara Power FOR_EACH_SUITE_TESTCASE(i, suite, tc) {
274caa817f0SCiara Power suite->total++;
275caa817f0SCiara Power if (!tc.enabled || test_success == TEST_SKIPPED)
276caa817f0SCiara Power suite->skipped++;
277caa817f0SCiara Power else
278caa817f0SCiara Power suite->failed++;
279caa817f0SCiara Power }
280caa817f0SCiara Power }
281caa817f0SCiara Power
282caa817f0SCiara Power static void
unit_test_suite_reset_counts(struct unit_test_suite * suite)283caa817f0SCiara Power unit_test_suite_reset_counts(struct unit_test_suite *suite)
284caa817f0SCiara Power {
285fbc53675SCiara Power struct unit_test_suite *ts;
286fbc53675SCiara Power int i;
287fbc53675SCiara Power
288fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts)
289fbc53675SCiara Power unit_test_suite_reset_counts(ts);
290caa817f0SCiara Power suite->total = 0;
291caa817f0SCiara Power suite->executed = 0;
292caa817f0SCiara Power suite->succeeded = 0;
293caa817f0SCiara Power suite->skipped = 0;
294caa817f0SCiara Power suite->failed = 0;
295caa817f0SCiara Power suite->unsupported = 0;
296caa817f0SCiara Power }
297a9de470cSBruce Richardson
298a9de470cSBruce Richardson int
unit_test_suite_runner(struct unit_test_suite * suite)299a9de470cSBruce Richardson unit_test_suite_runner(struct unit_test_suite *suite)
300a9de470cSBruce Richardson {
301fbc53675SCiara Power int test_success, i, ret;
302a9de470cSBruce Richardson const char *status;
303caa817f0SCiara Power struct unit_test_case tc;
304fbc53675SCiara Power struct unit_test_suite *ts;
305fbc53675SCiara Power unsigned int sub_ts_succeeded = 0, sub_ts_failed = 0;
306fbc53675SCiara Power unsigned int sub_ts_skipped = 0, sub_ts_total = 0;
307caa817f0SCiara Power
308caa817f0SCiara Power unit_test_suite_reset_counts(suite);
309a9de470cSBruce Richardson
310a9de470cSBruce Richardson if (suite->suite_name) {
311a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
312a9de470cSBruce Richardson printf(" + Test Suite : %s\n", suite->suite_name);
313a9de470cSBruce Richardson }
314a9de470cSBruce Richardson
315e0f4a0edSDavid Marchand if (suite->setup) {
316e0f4a0edSDavid Marchand test_success = suite->setup();
317e0f4a0edSDavid Marchand if (test_success != 0) {
318a9de470cSBruce Richardson /*
319e0f4a0edSDavid Marchand * setup did not pass, so count all enabled tests and
320e0f4a0edSDavid Marchand * mark them as failed/skipped
321a9de470cSBruce Richardson */
322caa817f0SCiara Power unit_test_suite_count_tcs_on_setup_fail(suite,
323fbc53675SCiara Power test_success, &sub_ts_failed,
324fbc53675SCiara Power &sub_ts_skipped, &sub_ts_total);
325a9de470cSBruce Richardson goto suite_summary;
326a9de470cSBruce Richardson }
327e0f4a0edSDavid Marchand }
328a9de470cSBruce Richardson
329a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
330a9de470cSBruce Richardson
331caa817f0SCiara Power FOR_EACH_SUITE_TESTCASE(suite->total, suite, tc) {
332caa817f0SCiara Power if (!tc.enabled) {
333caa817f0SCiara Power suite->skipped++;
334a9de470cSBruce Richardson continue;
335a9de470cSBruce Richardson } else {
336caa817f0SCiara Power suite->executed++;
337a9de470cSBruce Richardson }
338a9de470cSBruce Richardson
339a9de470cSBruce Richardson /* run test case setup */
340caa817f0SCiara Power if (tc.setup)
341caa817f0SCiara Power test_success = tc.setup();
342a9de470cSBruce Richardson else
343a9de470cSBruce Richardson test_success = TEST_SUCCESS;
344a9de470cSBruce Richardson
345a9de470cSBruce Richardson if (test_success == TEST_SUCCESS) {
346a9de470cSBruce Richardson /* run the test case */
347e65da89cSCiara Power if (tc.testcase)
348caa817f0SCiara Power test_success = tc.testcase();
349e65da89cSCiara Power else if (tc.testcase_with_data)
350e65da89cSCiara Power test_success = tc.testcase_with_data(tc.data);
351e65da89cSCiara Power else
352e65da89cSCiara Power test_success = -ENOTSUP;
353e65da89cSCiara Power
354a9de470cSBruce Richardson if (test_success == TEST_SUCCESS)
355caa817f0SCiara Power suite->succeeded++;
356e0f4a0edSDavid Marchand else if (test_success == TEST_SKIPPED)
357caa817f0SCiara Power suite->skipped++;
358a9de470cSBruce Richardson else if (test_success == -ENOTSUP)
359caa817f0SCiara Power suite->unsupported++;
360a9de470cSBruce Richardson else
361caa817f0SCiara Power suite->failed++;
362a9de470cSBruce Richardson } else if (test_success == -ENOTSUP) {
363caa817f0SCiara Power suite->unsupported++;
364a9de470cSBruce Richardson } else {
365caa817f0SCiara Power suite->failed++;
366a9de470cSBruce Richardson }
367a9de470cSBruce Richardson
368a9de470cSBruce Richardson /* run the test case teardown */
369caa817f0SCiara Power if (tc.teardown)
370caa817f0SCiara Power tc.teardown();
371a9de470cSBruce Richardson
372a9de470cSBruce Richardson if (test_success == TEST_SUCCESS)
373a9de470cSBruce Richardson status = "succeeded";
374e0f4a0edSDavid Marchand else if (test_success == TEST_SKIPPED)
375e0f4a0edSDavid Marchand status = "skipped";
376a9de470cSBruce Richardson else if (test_success == -ENOTSUP)
377a9de470cSBruce Richardson status = "unsupported";
378a9de470cSBruce Richardson else
379a9de470cSBruce Richardson status = "failed";
380a9de470cSBruce Richardson
381caa817f0SCiara Power printf(" + TestCase [%2d] : %s %s\n", suite->total,
382caa817f0SCiara Power tc.name, status);
383a9de470cSBruce Richardson }
384fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts) {
385fbc53675SCiara Power ret = unit_test_suite_runner(ts);
386fbc53675SCiara Power if (ret == TEST_SUCCESS)
387fbc53675SCiara Power sub_ts_succeeded++;
388fbc53675SCiara Power else if (ret == TEST_SKIPPED)
389fbc53675SCiara Power sub_ts_skipped++;
390fbc53675SCiara Power else
391fbc53675SCiara Power sub_ts_failed++;
392fbc53675SCiara Power sub_ts_total++;
393fbc53675SCiara Power
394fbc53675SCiara Power suite->total += ts->total;
395fbc53675SCiara Power suite->succeeded += ts->succeeded;
396fbc53675SCiara Power suite->failed += ts->failed;
397fbc53675SCiara Power suite->skipped += ts->skipped;
398fbc53675SCiara Power suite->unsupported += ts->unsupported;
399fbc53675SCiara Power suite->executed += ts->executed;
400fbc53675SCiara Power }
401a9de470cSBruce Richardson
402a9de470cSBruce Richardson /* Run test suite teardown */
403a9de470cSBruce Richardson if (suite->teardown)
404a9de470cSBruce Richardson suite->teardown();
405a9de470cSBruce Richardson
406a9de470cSBruce Richardson goto suite_summary;
407a9de470cSBruce Richardson
408a9de470cSBruce Richardson suite_summary:
409a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
410caa817f0SCiara Power printf(" + Test Suite Summary : %s\n", suite->suite_name);
411fbc53675SCiara Power printf(" + ------------------------------------------------------- +\n");
412fbc53675SCiara Power
413fbc53675SCiara Power FOR_EACH_SUITE_TESTSUITE(i, suite, ts)
414fbc53675SCiara Power printf(" + %s : %d/%d passed, %d/%d skipped, "
415fbc53675SCiara Power "%d/%d failed, %d/%d unsupported\n", ts->suite_name,
416fbc53675SCiara Power ts->succeeded, ts->total, ts->skipped, ts->total,
417fbc53675SCiara Power ts->failed, ts->total, ts->unsupported, ts->total);
418fbc53675SCiara Power
419fbc53675SCiara Power if (suite->unit_test_suites) {
420fbc53675SCiara Power printf(" + ------------------------------------------------------- +\n");
421fbc53675SCiara Power printf(" + Sub Testsuites Total : %2d\n", sub_ts_total);
422fbc53675SCiara Power printf(" + Sub Testsuites Skipped : %2d\n", sub_ts_skipped);
423fbc53675SCiara Power printf(" + Sub Testsuites Passed : %2d\n", sub_ts_succeeded);
424fbc53675SCiara Power printf(" + Sub Testsuites Failed : %2d\n", sub_ts_failed);
425fbc53675SCiara Power printf(" + ------------------------------------------------------- +\n");
426fbc53675SCiara Power }
427fbc53675SCiara Power
428caa817f0SCiara Power printf(" + Tests Total : %2d\n", suite->total);
429caa817f0SCiara Power printf(" + Tests Skipped : %2d\n", suite->skipped);
430caa817f0SCiara Power printf(" + Tests Executed : %2d\n", suite->executed);
431caa817f0SCiara Power printf(" + Tests Unsupported: %2d\n", suite->unsupported);
432caa817f0SCiara Power printf(" + Tests Passed : %2d\n", suite->succeeded);
433caa817f0SCiara Power printf(" + Tests Failed : %2d\n", suite->failed);
434a9de470cSBruce Richardson printf(" + ------------------------------------------------------- +\n");
435a9de470cSBruce Richardson
436caa817f0SCiara Power last_test_result = suite->failed;
437a9de470cSBruce Richardson
438caa817f0SCiara Power if (suite->failed)
439e0f4a0edSDavid Marchand return TEST_FAILED;
440caa817f0SCiara Power if (suite->total == suite->skipped)
441e0f4a0edSDavid Marchand return TEST_SKIPPED;
442e0f4a0edSDavid Marchand return TEST_SUCCESS;
443a9de470cSBruce Richardson }
444