1 /*
2  * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "test_framework.h"
9 
10 #include <assert.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
test_failed(const struct test_result_t * ret,const char * name)15 static void test_failed(const struct test_result_t *ret, const char *name)
16 {
17     printf_set_color(RED);
18     if (ret->info_msg != 0) {
19         TEST_LOG("  %s", ret->info_msg);
20         if (ret->filename != 0) {
21             TEST_LOG(" (Failed at %s:%d)\r\n", ret->filename, ret->line);
22         }
23     } else {
24         if (ret->filename != 0) {
25             TEST_LOG("  Failed at %s:%d\r\n", ret->filename, ret->line);
26         }
27     }
28 
29     TEST_LOG("  TEST: %s - FAILED!\r\n", name);
30 }
31 
print_error(const char * err_msg)32 static void print_error(const char *err_msg)
33 {
34     printf_set_color(RED);
35     TEST_LOG("Error ( %s )\r\n", err_msg);
36 }
37 
test_err_to_str(enum test_suite_err_t err)38 const char *test_err_to_str(enum test_suite_err_t err)
39 {
40     switch (err) {
41     case TEST_SUITE_ERR_NO_ERROR:
42         return "TEST_SUITE_ERR_NO_ERROR";
43     case TEST_SUITE_ERR_INVALID_DATA:
44         return "TEST_SUITE_ERR_INVALID_DATA";
45     case TEST_SUITE_ERR_INVALID_TEST_DATA:
46         return "TEST_SUITE_ERR_INVALID_TEST_DATA";
47     case TEST_SUITE_ERR_TEST_FAILED:
48         return "TEST_SUITE_ERR_TEST_FAILED";
49     /* default:  The default is not defined intentionally to force the
50      *           compiler to check that all the enumeration values are
51      *           covered in the switch.
52      */
53     }
54 }
55 
set_testsuite(const char * name,struct test_t * test_list,uint32_t size,struct test_suite_t * p_ts)56 enum test_suite_err_t set_testsuite(const char *name,
57                                     struct test_t *test_list, uint32_t size,
58                                     struct test_suite_t *p_ts)
59 {
60     if (p_ts == 0) {
61         print_error("TEST_SUITE_ERR_INVALID_DATA!");
62         return TEST_SUITE_ERR_INVALID_DATA;
63     }
64 
65     p_ts->name = name;
66     p_ts->test_list = test_list;
67     p_ts->list_size = size;
68 
69     return TEST_SUITE_ERR_NO_ERROR;
70 }
71 
set_test_failed(const char * info_msg,const char * filename,uint32_t line,struct test_result_t * ret)72 void set_test_failed(const char *info_msg, const char *filename, uint32_t line,
73                      struct test_result_t *ret)
74 {
75     if (ret == 0) {
76         print_error("TEST_SUITE_ERR_INVALID_TEST_DATA!");
77         return;
78     }
79 
80     ret->val = TEST_FAILED;
81     ret->info_msg = info_msg;
82     ret->filename = filename;
83     ret->line = line;
84 }
85 
run_testsuite(struct test_suite_t * test_suite)86 enum test_suite_err_t run_testsuite(struct test_suite_t *test_suite)
87 {
88     uint32_t failed_tests = 0;
89     uint32_t skipped_tests = 0;
90     uint32_t i;
91     struct test_t *p_test;
92     struct test_result_t ret = {0};
93 
94     if (test_suite == 0 || test_suite->freg == 0) {
95         print_error("TEST_SUITE_ERR_INVALID_DATA!");
96         return TEST_SUITE_ERR_INVALID_DATA;
97     }
98 
99     /* Sets test suite parameters */
100     test_suite->freg(test_suite);
101     if (test_suite->name == 0 || test_suite->list_size == 0) {
102         print_error("TEST_SUITE_ERR_INVALID_DATA!");
103         return TEST_SUITE_ERR_INVALID_DATA;
104     }
105 
106     printf_set_color(YELLOW);
107     TEST_LOG("Running Test Suite %s...\r\n", test_suite->name);
108 
109     /* Sets pointer to the first test */
110     p_test = test_suite->test_list;
111 
112     for (i = 0; i < test_suite->list_size; i++) {
113 
114         if (p_test->test == 0 || p_test->name == 0) {
115             print_error("TEST_SUITE_ERR_INVALID_TEST_DATA!");
116             return TEST_SUITE_ERR_INVALID_TEST_DATA;
117         }
118 
119         printf_set_color(DEFAULT);
120         TEST_LOG("> Executing '%s' \r\n  Description: '%s'\r\n",
121                  p_test->name, p_test->desc);
122 
123         /* Sets the default value before the test */
124         ret.val = TEST_PASSED;
125 
126         /* Executes the test */
127         p_test->test(&ret);
128         if (ret.val == TEST_FAILED) {
129             test_failed(&ret, p_test->name);
130             failed_tests++;
131         } else if (ret.val == TEST_SKIPPED) {
132             printf_set_color(DEFAULT);
133             TEST_LOG("  TEST: %s - SKIPPED!\r\n", p_test->name);
134             skipped_tests++;
135         } else {
136             printf_set_color(GREEN);
137             TEST_LOG("  TEST: %s - PASSED!\r\n", p_test->name);
138         }
139 
140         /* Sets pointer to the next test */
141         p_test++;
142     }
143 
144     if (failed_tests != 0) {
145         printf_set_color(DEFAULT);
146         TEST_LOG("Number of failed tests: %d of %d\r\n",
147                  failed_tests, test_suite->list_size);
148     }
149     if (skipped_tests != 0) {
150         printf_set_color(DEFAULT);
151         TEST_LOG("Number of skipped tests: %d of %d\r\n",
152                  skipped_tests, test_suite->list_size);
153     }
154 
155     if (failed_tests == 0) {
156         printf_set_color(GREEN);
157         TEST_LOG("TESTSUITE PASSED!\r\n");
158         test_suite->val = TEST_PASSED;
159     } else {
160         printf_set_color(RED);
161         TEST_LOG("TESTSUITE FAILED!\r\n");
162         test_suite->val = TEST_FAILED;
163     }
164 
165     return TEST_SUITE_ERR_NO_ERROR;
166 }
167