xref: /nrf52832-nimble/rt-thread/components/utilities/utest/utest.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-11-19     MurphyZhao   the first version
9  */
10 
11 #include <rtthread.h>
12 #include <string.h>
13 #include "utest.h"
14 #include <utest_log.h>
15 
16 #undef DBG_SECTION_NAME
17 #undef DBG_LEVEL
18 #undef DBG_COLOR
19 #undef DBG_ENABLE
20 
21 #define DBG_ENABLE
22 #define DBG_SECTION_NAME          "utest"
23 #ifdef UTEST_DEBUG
24 #define DBG_LEVEL                 DBG_LOG
25 #else
26 #define DBG_LEVEL                 DBG_INFO
27 #endif
28 #define DBG_COLOR
29 #include <rtdbg.h>
30 
31 #if RT_CONSOLEBUF_SIZE < 256
32 #error "RT_CONSOLEBUF_SIZE is less than 256!"
33 #endif
34 
35 static rt_uint8_t utest_log_lv = UTEST_LOG_ALL;
36 static utest_tc_export_t tc_table = RT_NULL;
37 static rt_size_t tc_num;
38 static struct utest local_utest = {UTEST_PASSED, 0, 0};
39 
40 #if defined(__ICCARM__) || defined(__ICCRX__)         /* for IAR compiler */
41 #pragma section="UtestTcTab"
42 #endif
43 
utest_log_lv_set(rt_uint8_t lv)44 void utest_log_lv_set(rt_uint8_t lv)
45 {
46     if (lv == UTEST_LOG_ALL || lv == UTEST_LOG_ASSERT)
47     {
48         utest_log_lv = lv;
49     }
50 }
51 
utest_init(void)52 int utest_init(void)
53 {
54     /* initialize the utest commands table.*/
55 #if defined(__CC_ARM)                                 /* ARM C Compiler */
56     extern const int UtestTcTab$$Base;
57     extern const int UtestTcTab$$Limit;
58     tc_table = (utest_tc_export_t)&UtestTcTab$$Base;
59     tc_num = (utest_tc_export_t)&UtestTcTab$$Limit - tc_table;
60 #elif defined (__ICCARM__) || defined(__ICCRX__)      /* for IAR Compiler */
61     tc_table = (utest_tc_export_t)__section_begin("UtestTcTab");
62     tc_num = (utest_tc_export_t)__section_end("UtestTcTab") - tc_table;
63 #elif defined (__GNUC__)                              /* for GCC Compiler */
64     extern const int __rt_utest_tc_tab_start;
65     extern const int __rt_utest_tc_tab_end;
66     tc_table = (utest_tc_export_t)&__rt_utest_tc_tab_start;
67     tc_num = (utest_tc_export_t) &__rt_utest_tc_tab_end - tc_table;
68 #endif /* defined(__CC_ARM) */
69 
70     LOG_I("utest is initialize success.");
71     LOG_I("total utest testcase num: (%d)", tc_num);
72     return tc_num;
73 }
74 INIT_COMPONENT_EXPORT(utest_init);
75 
utest_tc_list(void)76 static void utest_tc_list(void)
77 {
78     rt_size_t i = 0;
79 
80     LOG_I("Commands list : ");
81 
82     for (i = 0; i < tc_num; i++)
83     {
84         LOG_I("[testcase name]:%s; [run timeout]:%d", tc_table[i].name, tc_table[i].run_timeout);
85     }
86 }
87 MSH_CMD_EXPORT_ALIAS(utest_tc_list, utest_list, output all utest testcase);
88 
file_basename(const char * file)89 static const char *file_basename(const char *file)
90 {
91     char *end_ptr = RT_NULL;
92     char *rst = RT_NULL;
93 
94     if (!((end_ptr = strrchr(file, '\\')) != RT_NULL || \
95         (end_ptr = strrchr(file, '/')) != RT_NULL) || \
96         (rt_strlen(file) < 2))
97     {
98         rst = (char *)file;
99     }
100     else
101     {
102         rst = (char *)(end_ptr + 1);
103     }
104     return (const char *)rst;
105 }
106 
utest_run(const char * utest_name)107 static void utest_run(const char *utest_name)
108 {
109     rt_size_t i = 0;
110 
111     LOG_I("[==========] [ utest    ] started");
112     while(i < tc_num)
113     {
114         if (utest_name && rt_strcmp(utest_name, tc_table[i].name))
115         {
116             i++;
117             continue;
118         }
119 
120         LOG_I("[----------] [ testcase ] (%s) started", tc_table[i].name);
121         if (tc_table[i].init != RT_NULL)
122         {
123             if (tc_table[i].init() != RT_EOK)
124             {
125                 LOG_E("[  FAILED  ] [ result   ] testcase (%s)", tc_table[i].name);
126                 goto __tc_continue;
127             }
128         }
129 
130         if (tc_table[i].tc != RT_NULL)
131         {
132             tc_table[i].tc();
133             if (local_utest.failed_num == 0)
134             {
135                 LOG_I("[  PASSED  ] [ result   ] testcase (%s)", tc_table[i].name);
136             }
137             else
138             {
139                 LOG_E("[  FAILED  ] [ result   ] testcase (%s)", tc_table[i].name);
140             }
141         }
142         else
143         {
144             LOG_E("[  FAILED  ] [ result   ] testcase (%s)", tc_table[i].name);
145         }
146 
147         if (tc_table[i].cleanup != RT_NULL)
148         {
149             if (tc_table[i].cleanup() != RT_EOK)
150             {
151                 LOG_E("[  FAILED  ] [ result   ] testcase (%s)", tc_table[i].name);
152                 goto __tc_continue;
153             }
154         }
155 
156 __tc_continue:
157         LOG_I("[----------] [ testcase ] (%s) finished", tc_table[i].name);
158 
159         i++;
160     }
161     LOG_I("[==========] [ utest    ] finished");
162 }
163 
utest_testcase_run(int argc,char ** argv)164 static void utest_testcase_run(int argc, char** argv)
165 {
166     char utest_name[UTEST_NAME_MAX_LEN];
167 
168     if (argc == 1)
169     {
170         utest_run(RT_NULL);
171     }
172     else if (argc == 2)
173     {
174         rt_memset(utest_name, 0x0, sizeof(utest_name));
175         rt_strncpy(utest_name, argv[1], sizeof(utest_name) -1);
176         utest_run(utest_name);
177     }
178     else
179     {
180         LOG_E("[  error   ] at (%s:%d), in param error.", __func__, __LINE__);
181     }
182 }
183 MSH_CMD_EXPORT_ALIAS(utest_testcase_run, utest_run, utest_run [testcase name]);
184 
utest_handle_get(void)185 utest_t utest_handle_get(void)
186 {
187     return (utest_t)&local_utest;
188 }
189 
utest_unit_run(test_unit_func func,const char * unit_func_name)190 void utest_unit_run(test_unit_func func, const char *unit_func_name)
191 {
192     // LOG_I("[==========] utest unit name: (%s)", unit_func_name);
193     local_utest.error = UTEST_PASSED;
194     local_utest.passed_num = 0;
195     local_utest.failed_num = 0;
196 
197     if (func != RT_NULL)
198     {
199         func();
200     }
201 }
202 
utest_assert(int value,const char * file,int line,const char * func,const char * msg)203 void utest_assert(int value, const char *file, int line, const char *func, const char *msg)
204 {
205     if (!(value))
206     {
207         local_utest.error = UTEST_FAILED;
208         local_utest.failed_num ++;
209         LOG_E("[  ASSERT  ] [ unit     ] at (%s); func: (%s:%d); msg: (%s)", file_basename(file), func, line, msg);
210     }
211     else
212     {
213         if (utest_log_lv == UTEST_LOG_ALL)
214         {
215             LOG_D("[    OK    ] [ unit     ] (%s:%d) is passed", func, line);
216         }
217         local_utest.error = UTEST_PASSED;
218         local_utest.passed_num ++;
219     }
220 }
221 
utest_assert_string(const char * a,const char * b,rt_bool_t equal,const char * file,int line,const char * func,const char * msg)222 void utest_assert_string(const char *a, const char *b, rt_bool_t equal, const char *file, int line, const char *func, const char *msg)
223 {
224     if (a == RT_NULL || b == RT_NULL)
225     {
226         utest_assert(0, file, line, func, msg);
227     }
228 
229     if (equal)
230     {
231         if (rt_strcmp(a, b) == 0)
232         {
233             utest_assert(1, file, line, func, msg);
234         }
235         else
236         {
237             utest_assert(0, file, line, func, msg);
238         }
239     }
240     else
241     {
242         if (rt_strcmp(a, b) == 0)
243         {
244             utest_assert(0, file, line, func, msg);
245         }
246         else
247         {
248             utest_assert(1, file, line, func, msg);
249         }
250     }
251 }
252 
utest_assert_buf(const char * a,const char * b,rt_size_t sz,rt_bool_t equal,const char * file,int line,const char * func,const char * msg)253 void utest_assert_buf(const char *a, const char *b, rt_size_t sz, rt_bool_t equal, const char *file, int line, const char *func, const char *msg)
254 {
255     if (a == RT_NULL || b == RT_NULL)
256     {
257         utest_assert(0, file, line, func, msg);
258     }
259 
260     if (equal)
261     {
262         if (rt_memcmp(a, b, sz) == 0)
263         {
264             utest_assert(1, file, line, func, msg);
265         }
266         else
267         {
268             utest_assert(0, file, line, func, msg);
269         }
270     }
271     else
272     {
273         if (rt_memcmp(a, b, sz) == 0)
274         {
275             utest_assert(0, file, line, func, msg);
276         }
277         else
278         {
279             utest_assert(1, file, line, func, msg);
280         }
281     }
282 }
283