]> begriffs open source - cmsis-driver-validation/blob - Source/DV_Report.c
- Added example for Inventek ISM43362 WiFi Driver testing on STMicroelectronics B...
[cmsis-driver-validation] / Source / DV_Report.c
1 /*-----------------------------------------------------------------------------
2  *      Name:         report.c 
3  *      Purpose:      Report statistics and layout implementation
4  *-----------------------------------------------------------------------------
5  *      Copyright(c) KEIL - An ARM Company
6  *----------------------------------------------------------------------------*/
7 #include "DV_Report.h"
8
9 TEST_REPORT test_report;
10 static AS_STAT current_assertions;   /* Current test case statistics         */
11 #define TAS (&test_report.assertions) /* Total assertions                     */
12 #define CAS (&current_assertions)     /* Current assertions                   */
13
14 #define PRINT(x) MsgPrint x
15 #define FLUSH()  MsgFlush()
16
17 static uint8_t Passed[] = "PASSED";
18 static uint8_t Warning[] = "WARNING";
19 static uint8_t Failed[] = "FAILED";
20 static uint8_t NotExe[] = "NOT EXECUTED";
21
22
23 /*-----------------------------------------------------------------------------
24  * Test report function prototypes
25  *----------------------------------------------------------------------------*/
26 static BOOL     tr_Init   (void);
27 static BOOL     tc_Init   (void);
28 static uint8_t *tr_Eval   (void);
29 static uint8_t *tc_Eval   (void);
30 static BOOL     StatCount (TC_RES res);
31
32 /*-----------------------------------------------------------------------------
33  * Printer function prototypes
34  *----------------------------------------------------------------------------*/
35 static void MsgPrint (const char *msg, ...);
36 static void MsgFlush (void);
37
38
39 /*-----------------------------------------------------------------------------
40  * Assert interface function prototypes
41  *----------------------------------------------------------------------------*/
42 static BOOL As_File_Result (TC_RES res);
43 static BOOL As_File_Dbgi   (TC_RES res, const char *fn, uint32_t ln, char *desc);
44
45 TC_ITF tcitf = {
46   As_File_Result,
47   As_File_Dbgi,
48 };
49
50
51 /*-----------------------------------------------------------------------------
52  * Test report interface function prototypes
53  *----------------------------------------------------------------------------*/
54 BOOL tr_File_Init  (void);
55 BOOL tr_File_Open  (const char *title, const char *date, const char *time, const char *fn);
56 BOOL tr_File_Close (void);
57 BOOL tc_File_Open  (uint32_t num, const char *fn);
58 BOOL tc_File_Close (void);
59
60 REPORT_ITF ritf = {
61   tr_File_Init,
62   tr_File_Open,
63   tr_File_Close,
64   tc_File_Open,
65   tc_File_Close
66 };
67
68
69 /*-----------------------------------------------------------------------------
70  * Init test report
71  *----------------------------------------------------------------------------*/
72 BOOL tr_File_Init (void) {
73   return (tr_Init());
74 }
75
76
77 /*-----------------------------------------------------------------------------
78  * Open test report
79  *----------------------------------------------------------------------------*/
80 BOOL tr_File_Open (const char *title, const char *date, const char *time, const char *fn) {
81 #if (PRINT_XML_REPORT==1)  
82   PRINT(("<?xml version=\"1.0\"?>\n"));
83   PRINT(("<?xml-stylesheet href=\"TR_Style.xsl\" type=\"text/xsl\" ?>\n"));
84   PRINT(("<report>\n"));  
85   PRINT(("<test>\n"));
86   PRINT(("<title>%s</title>\n", title));
87   PRINT(("<date>%s</date>\n",   date));
88   PRINT(("<time>%s</time>\n",   time));
89   PRINT(("<file>%s</file>\n",   fn));
90   PRINT(("<test_cases>\n"));
91 #else
92   (void) fn;
93   PRINT(("%s   %s   %s \n\n", title, date, time));
94 #endif  
95   return (__TRUE);
96 }
97
98
99 /*-----------------------------------------------------------------------------
100  * Open test case
101  *----------------------------------------------------------------------------*/
102 BOOL tc_File_Open (uint32_t num, const char *fn) {
103   tc_Init ();
104 #if (PRINT_XML_REPORT==1)   
105   PRINT(("<tc>\n"));
106   PRINT(("<no>%d</no>\n",     num));
107   PRINT(("<func>%s</func>\n", fn));
108   PRINT(("<req></req>"));
109   PRINT(("<meth></meth>"));
110   PRINT(("<dbgi>\n"));
111 #else
112   PRINT(("TEST %02d: %-32s ", num, fn));
113 #endif 
114   return (__TRUE);
115 }
116
117
118 /*-----------------------------------------------------------------------------
119  * Close test case
120  *----------------------------------------------------------------------------*/
121 BOOL tc_File_Close (void) {
122   uint8_t *res = tc_Eval();
123 #if (PRINT_XML_REPORT==1) 
124   PRINT(("</dbgi>\n"));
125   PRINT(("<res>%s</res>\n", res));
126   PRINT(("</tc>\n"));
127 #else
128   if ((res==Passed)||(res==NotExe))  
129     PRINT(("%s\n", res));
130   else
131     PRINT(("\n"));
132 #endif 
133   FLUSH();
134   return (__TRUE);
135 }
136
137
138 /*-----------------------------------------------------------------------------
139  * Close test report
140  *----------------------------------------------------------------------------*/
141 BOOL tr_File_Close (void) {
142 #if (PRINT_XML_REPORT==1) 
143   PRINT(("</test_cases>\n"));
144   PRINT(("<summary>\n"));
145   PRINT(("<tcnt>%d</tcnt>\n", test_report.tests));
146   PRINT(("<exec>%d</exec>\n", test_report.executed));
147   PRINT(("<pass>%d</pass>\n", test_report.passed));
148   PRINT(("<fail>%d</fail>\n", test_report.failed));
149   PRINT(("<warn>%d</warn>\n", test_report.warnings));
150   PRINT(("<tres>%s</tres>\n", tr_Eval()));
151   PRINT(("</summary>\n"));
152   PRINT(("</test>\n"));
153   PRINT(("</report>\n"));
154 #else
155   PRINT(("\nTest Summary: %d Tests, %d Executed, %d Passed, %d Failed, %d Warnings.\n", 
156          test_report.tests, 
157          test_report.executed, 
158          test_report.passed, 
159          test_report.failed, 
160          test_report.warnings)); 
161   PRINT(("Test Result: %s\n", tr_Eval()));
162 #endif 
163   FLUSH();
164   return (__TRUE);
165 }
166
167
168 /*-----------------------------------------------------------------------------
169  * Assertion result counter 
170  *----------------------------------------------------------------------------*/
171 BOOL As_File_Result (TC_RES res) {
172   return (StatCount (res));
173 }
174
175
176 /*-----------------------------------------------------------------------------
177  * Set debug information state 
178  *----------------------------------------------------------------------------*/
179 BOOL As_File_Dbgi (TC_RES res, const char *fn, uint32_t ln, char *desc) {
180   /* Write debug information block */
181 #if (PRINT_XML_REPORT==1) 
182   PRINT(("<detail>\n"));
183   if (desc!=NULL) PRINT(("<desc>%s</desc>\n", desc));
184   PRINT(("<module>%s</module>\n", fn));
185   PRINT(("<line>%d</line>\n", ln));
186   PRINT(("</detail>\n"));
187 #else
188   PRINT(("\n  %s (%d)", fn, ln));
189   if (res==WARNING) PRINT((" [WARNING]"));
190   if (res==FAILED) PRINT((" [FAILED]"));
191   if (desc!=NULL) PRINT((" %s", desc));
192 #endif 
193   return (__TRUE);
194 }
195
196
197 /*-----------------------------------------------------------------------------
198  * Init test report
199  *----------------------------------------------------------------------------*/
200 BOOL tr_Init (void) {
201   TAS->passed = 0;
202   TAS->failed = 0;
203   TAS->warnings = 0;
204   return (__TRUE);
205 }
206
207
208 /*-----------------------------------------------------------------------------
209  * Init test case
210  *----------------------------------------------------------------------------*/
211 BOOL tc_Init (void) {
212   CAS->passed = 0;
213   CAS->failed = 0;
214   CAS->warnings = 0;
215   return (__TRUE);
216 }
217
218
219 /*-----------------------------------------------------------------------------
220  * Evaluate test report results
221  *----------------------------------------------------------------------------*/
222 uint8_t *tr_Eval (void) {
223   if (test_report.failed > 0) {
224     /* Test fails if any test case failed */
225     return (Failed);
226   }
227   else if (test_report.warnings > 0) {
228     /* Test warns if any test case warnings */
229     return (Warning);
230   }
231   else if (test_report.passed > 0) {
232     /* Test passes if at least one test case passed */
233     return (Passed);
234   }
235   else {
236     /* No test cases were executed */
237     return (NotExe);
238   }
239 }
240
241
242 /*-----------------------------------------------------------------------------
243  * Evaluate test case results
244  *----------------------------------------------------------------------------*/
245 uint8_t *tc_Eval (void) {
246   test_report.tests++;
247   test_report.executed++;
248
249   if (CAS->failed > 0) {
250     /* Test case fails if any failed assertion recorded */
251     test_report.failed++;
252     return Failed;
253   }
254   else if (CAS->warnings > 0) {
255     /* Test case warns if any warnings assertion recorded */
256     test_report.warnings++;
257     return Warning;
258   }
259   else if (CAS->passed > 0) {
260     /* Test case passes if at least one assertion passed */
261     test_report.passed++;
262     return Passed;
263   }
264   else {
265     /* Assert was not invoked - nothing to evaluate */
266     test_report.executed--;
267     return NotExe;
268   }
269 }
270
271
272 /*-----------------------------------------------------------------------------
273  * Statistics result counter
274  *----------------------------------------------------------------------------*/
275 BOOL StatCount (TC_RES res) {
276   switch (res) {
277     case PASSED:
278       CAS->passed++;
279       TAS->passed++;
280       break;
281
282     case WARNING:
283       CAS->warnings++;
284       TAS->warnings++;
285       break;
286
287     case FAILED:
288       CAS->failed++;
289       TAS->failed++;
290       break;
291
292     case NOT_EXECUTED:
293       return (__FALSE);
294   }
295   return (__TRUE);
296 }
297
298 /*-----------------------------------------------------------------------------
299  * No path
300  *----------------------------------------------------------------------------*/
301 static const char *no_path (const char *fn) {
302   const char *cp;
303 #if defined(__CC_ARM)
304   cp = strrchr(fn, '\\');
305 #else
306   cp = strrchr(fn, '/');
307 #endif
308   if (cp) return (cp + 1);
309   return (fn);
310 }
311
312 /*-----------------------------------------------------------------------------
313  * Set result
314  *----------------------------------------------------------------------------*/
315 uint32_t __set_result (const char *fn, uint32_t ln, TC_RES res, char* desc) {
316
317   fn = no_path (fn);
318
319   // save assertion result
320   switch (res) {
321     case PASSED:     
322       if (TAS->passed < BUFFER_ASSERTIONS) {
323         test_report.assertions.info.passed[TAS->passed].module = fn;
324         test_report.assertions.info.passed[TAS->passed].line = ln;
325       }
326       break;
327     case FAILED:
328       if (TAS->failed < BUFFER_ASSERTIONS) {
329         test_report.assertions.info.failed[TAS->failed].module = fn;
330         test_report.assertions.info.failed[TAS->failed].line = ln;
331       }
332       break;
333     case WARNING:
334       if (TAS->warnings < BUFFER_ASSERTIONS) {
335         test_report.assertions.info.warnings[TAS->warnings].module = fn;
336         test_report.assertions.info.warnings[TAS->warnings].line = ln;
337       }
338       break;
339     case NOT_EXECUTED:
340       break;
341   }  
342   
343   // set debug info (if the test case didn't pass)
344   if (res != PASSED) tcitf.Dbgi (res, fn, ln, desc);
345   // set result
346   tcitf.Result (res);
347   return (res);
348 }
349
350 /*-----------------------------------------------------------------------------
351  * Assert true 
352  *----------------------------------------------------------------------------*/
353 uint32_t __assert_true (const char *fn, uint32_t ln, uint32_t cond) {
354   TC_RES res = FAILED;
355   if (cond!=0) res = PASSED; 
356   __set_result(fn, ln, res, NULL);
357   return (res);
358 }
359
360 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
361 #pragma clang diagnostic push
362 #pragma clang diagnostic ignored "-Wformat-nonliteral"
363 #endif
364 /*-----------------------------------------------------------------------------
365  *       MsgPrint:  Print a message to the standard output
366  *----------------------------------------------------------------------------*/
367 void MsgPrint (const char *msg, ...) {
368   va_list args;
369   va_start(args, msg);
370   vprintf(msg, args);
371   va_end(args);
372 }
373 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
374 #pragma clang diagnostic pop
375 #endif
376
377 /*-----------------------------------------------------------------------------
378  *       SER_MsgFlush:  Flush the standard output
379  *----------------------------------------------------------------------------*/
380 void MsgFlush(void) {
381   fflush(stdout);
382 }
383
384 /*-----------------------------------------------------------------------------
385  * End of file
386  *----------------------------------------------------------------------------*/