]> begriffs open source - cmsis-driver-validation/blob - Source/DV_Report.c
Merge branch 'develop'
[cmsis-driver-validation] / Source / DV_Report.c
1 /*
2  * Copyright (c) 2015-2020 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * -----------------------------------------------------------------------------
19  *
20  * Project:     CMSIS-Driver Validation
21  * Title:       Report statistics and layout implementation
22  *
23  * -----------------------------------------------------------------------------
24  */
25
26
27 #include "DV_Report.h"
28
29
30 /* Local macros */
31 #define PRINT(x) MsgPrint x
32 #define FLUSH()  MsgFlush()
33
34 /* Local functions */
35 static void tr_Init  (void);
36 static void tr_Uninit(void);
37 static void tg_Init  (const char *title, const char *date, const char *time, const char *fn);
38 static void tg_Uninit(void);
39 static void tc_Init  (uint32_t num, const char *fn);
40 static void tc_Uninit(void);
41 static void tc_Detail(const char *module, uint32_t line, const char *message);
42 static void as_Result(TC_RES res);
43
44 static void MsgPrint (const char *msg, ...);
45 static void MsgFlush (void);
46
47 /* Global variables */
48 REPORT_ITF ritf = {                     /* Structure for report interface     */
49   tr_Init,
50   tr_Uninit,
51   tg_Init,
52   tg_Uninit,
53   tc_Init,
54   tc_Uninit,
55   tc_Detail,
56   as_Result
57 };
58
59 /* Local variables */
60 static TEST_GROUP_RESULTS test_group_result;    /* Test group results         */
61
62 static uint32_t   as_passed = 0U;       /* Assertions passed                  */
63 static uint32_t   as_failed = 0U;       /* Assertions failed                  */
64 static uint32_t   as_detail = 0U;       /* Assertions details available       */
65 static const char Passed[] = "PASSED";
66 static const char Failed[] = "FAILED";
67 static const char NotExe[] = "NOT EXECUTED";
68
69
70 /*-----------------------------------------------------------------------------
71  * No path - helper function
72  *----------------------------------------------------------------------------*/
73 static const char *no_path (const char *fn) {
74   const char *cp;
75 #if defined(__CC_ARM)
76   cp = strrchr(fn, (int32_t)'\\');
77 #else
78   cp = strrchr(fn, (int32_t)'/');
79 #endif
80   if (cp != NULL) {
81     cp = &cp[1];
82   } else {
83     cp = fn;
84   }
85   return (cp);
86 }
87
88 /*-----------------------------------------------------------------------------
89  * Init test report
90  *----------------------------------------------------------------------------*/
91 static void tr_Init (void) {
92
93   test_group_result.idx = 0;
94
95 #if (PRINT_XML_REPORT==1)
96   PRINT(("<?xml version=\"1.0\"?>\n"));
97   PRINT(("<?xml-stylesheet href=\"TR_Style.xsl\" type=\"text/xsl\" ?>\n"));
98   PRINT(("<report>\n"));
99 #else
100   PRINT(("                                \n\n"));
101 #endif  
102 }
103
104 /*-----------------------------------------------------------------------------
105  * Uninit test report
106  *----------------------------------------------------------------------------*/
107 static void tr_Uninit (void) {
108 #if (PRINT_XML_REPORT==1)
109   PRINT(("</report>\n"));
110 #endif
111 }
112
113 /*-----------------------------------------------------------------------------
114  * Init test group
115  *----------------------------------------------------------------------------*/
116 static void tg_Init (const char *title, const char *date, const char *time, const char *fn) {
117
118   test_group_result.idx++;
119   test_group_result.tests  = 0U;
120   test_group_result.passed = 0U;
121   test_group_result.failed = 0U;
122
123 #if (PRINT_XML_REPORT==1)
124   PRINT(("<test>\n"));
125   PRINT(("<title>%s</title>\n", title));
126   PRINT(("<date>%s</date>\n",   date));
127   PRINT(("<time>%s</time>\n",   time));
128   PRINT(("<file>%s</file>\n",   fn));
129   PRINT(("<group>%i</group>\n", test_group_result.idx));
130   PRINT(("<test_cases>\n"));
131 #else
132   (void) fn;
133   PRINT(("%s   %s   %s \n\n", title, date, time));
134 #endif  
135 }
136
137 /*-----------------------------------------------------------------------------
138  * Uninit test group
139  *----------------------------------------------------------------------------*/
140 static void tg_Uninit (void) {
141   const char *tres;
142
143   if (test_group_result.failed > 0U) {  /* If any test failed => Failed       */
144     tres = Failed;
145   } else if (test_group_result.passed > 0U) {   /* If 1 passed => Passed      */
146     tres = Passed;
147   } else {                              /* If no tests exec => Not-executed   */
148     tres = NotExe;
149   }
150
151 #if (PRINT_XML_REPORT==1) 
152   PRINT(("</test_cases>\n"));
153   PRINT(("<summary>\n"));
154   PRINT(("<tcnt>%d</tcnt>\n", test_group_result.tests));
155   PRINT(("<pass>%d</pass>\n", test_group_result.passed));
156   PRINT(("<fail>%d</fail>\n", test_group_result.failed));
157   PRINT(("<tres>%s</tres>\n", tres));
158   PRINT(("</summary>\n"));
159   PRINT(("</test>\n"));
160 #else
161   PRINT(("\nTest Summary: %d Tests, %d Passed, %d Failed.\n", 
162          test_group_result.tests, 
163          test_group_result.passed, 
164          test_group_result.failed));
165   PRINT(("Test Result: %s\n\n\n", tres));
166 #endif 
167   FLUSH();
168 }
169
170 /*-----------------------------------------------------------------------------
171  * Init test
172  *----------------------------------------------------------------------------*/
173 static void tc_Init (uint32_t num, const char *fn) {
174
175   as_passed = 0U;
176   as_failed = 0U;
177   as_detail = 0U;
178
179 #if (PRINT_XML_REPORT==1)   
180   PRINT(("<tc>\n"));
181   PRINT(("<no>%d</no>\n",     num));
182   PRINT(("<func>%s</func>\n", fn));
183   PRINT(("<dbgi>\n"));
184 #else
185   PRINT(("TEST %02d: %-32s ", num, fn));
186 #endif 
187 }
188
189 /*-----------------------------------------------------------------------------
190  * Uninit test
191  *----------------------------------------------------------------------------*/
192 static void tc_Uninit (void) {
193   const char *res;
194
195   test_group_result.tests++;
196
197   if (as_failed > 0U) {                 /* If any assertion failed => Failed  */
198     test_group_result.failed++;
199     res = Failed;
200   } else if (as_passed > 0U) {          /* If 1 assertion passed => Passed    */
201     test_group_result.passed++;
202     res = Passed;
203   } else {                              /* If no assertions => Not-executed   */
204     res = NotExe;
205   }
206
207 #if (PRINT_XML_REPORT==1) 
208   PRINT(("</dbgi>\n"));
209   PRINT(("<res>%s</res>\n", res));
210   PRINT(("</tc>\n"));
211   (void)as_detail;
212 #else
213   if (as_detail != 0U) {
214     PRINT(("\n                                          "));
215   }
216   PRINT(("%s\n", res));
217 #endif 
218 }
219
220 /*-----------------------------------------------------------------------------
221  * Write test detail
222  *----------------------------------------------------------------------------*/
223 static void tc_Detail (const char *module, uint32_t line, const char *message) {
224   const char *module_no_path;
225
226   module_no_path = no_path (module);
227
228   as_detail = 1U;
229
230 #if (PRINT_XML_REPORT==1) 
231   PRINT(("<detail>\n"));
232   PRINT(("<module>%s</module>\n", module_no_path));
233   PRINT(("<line>%d</line>\n",     line));
234   if (message != NULL) {
235     PRINT(("<message>%s</message>\n", message));
236   }
237   PRINT(("</detail>\n"));
238 #else
239   PRINT(("\n  %s (%d)", module_no_path, line));
240   if (message != NULL) {
241     PRINT((": %s", message));
242   }
243 #endif
244 }
245
246 /*-----------------------------------------------------------------------------
247  * Assertion result registering
248  *----------------------------------------------------------------------------*/
249 static void as_Result (TC_RES res) {
250
251   if (res == PASSED) {
252     as_passed++;
253   } else if (res == FAILED) {
254     as_failed++;
255   } else {
256     // Do nothing
257   }
258 }
259
260 /*-----------------------------------------------------------------------------
261  * Set result
262  *----------------------------------------------------------------------------*/
263 void __set_result (const char *module, uint32_t line, const char *message, TC_RES res) {
264
265   // Set debug info
266   if (message != NULL) {
267     tc_Detail(module, line, message);
268   }
269
270   // Set result
271   as_Result(res);
272 }
273
274 /*-----------------------------------------------------------------------------
275  * Set message
276  *----------------------------------------------------------------------------*/
277 void __set_message (const char *module, uint32_t line, const char *message) {
278   if (message != NULL) {
279     tc_Detail(module, line, message);
280   }
281 }
282
283
284 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
285 #pragma clang diagnostic push
286 #pragma clang diagnostic ignored "-Wformat-nonliteral"
287 #endif
288 /*-----------------------------------------------------------------------------
289  *       MsgPrint:  Print a message to the standard output
290  *----------------------------------------------------------------------------*/
291 static void MsgPrint (const char *msg, ...) {
292   va_list args;
293   va_start(args, msg);
294   (void)vprintf(msg, args);
295   va_end(args);
296 }
297 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
298 #pragma clang diagnostic pop
299 #endif
300
301 /*-----------------------------------------------------------------------------
302  *       SER_MsgFlush:  Flush the standard output
303  *----------------------------------------------------------------------------*/
304 static void MsgFlush(void) {
305   (void)fflush(stdout);
306 }
307
308 /*-----------------------------------------------------------------------------
309  * End of file
310  *----------------------------------------------------------------------------*/