1 /*-----------------------------------------------------------------------------
3 * Purpose: Report statistics and layout implementation
4 *-----------------------------------------------------------------------------
5 * Copyright (c) 2017 - 2018 Arm Limited. All rights reserved.
6 *----------------------------------------------------------------------------*/
11 TEST_REPORT test_report;
12 static AS_STAT current_assertions; /* Current test case assertions statistics */
13 #define TAS (&test_report.assertions) /* Total assertions */
14 #define CAS (¤t_assertions) /* Current assertions */
16 #ifdef DISABLE_SEMIHOSTING
17 #if defined (__CC_ARM)
18 #pragma import __use_no_semihosting
19 #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
20 __ASM(".global __use_no_semihosting");
24 void _sys_exit(int return_code) {}
26 #define PRINT(x) MsgPrint x
27 #define FLUSH() MsgFlush()
28 #endif // DISABLE_SEMIHOSTING
30 static uint8_t Passed[] = "PASSED";
31 static uint8_t Warning[] = "WARNING";
32 static uint8_t Failed[] = "FAILED";
33 static uint8_t NotExe[] = "NOT EXECUTED";
36 /*-----------------------------------------------------------------------------
37 * Test report function prototypes
38 *----------------------------------------------------------------------------*/
39 static BOOL tr_Init (void);
40 static BOOL tc_Init (void);
41 static uint8_t *tr_Eval (void);
42 static uint8_t *tc_Eval (void);
43 static BOOL StatCount (TC_RES res);
45 /*-----------------------------------------------------------------------------
46 * Printer function prototypes
47 *----------------------------------------------------------------------------*/
48 static void MsgPrint (const char *msg, ...);
49 static void MsgFlush (void);
52 /*-----------------------------------------------------------------------------
53 * Assert interface function prototypes
54 *----------------------------------------------------------------------------*/
55 static BOOL As_File_Result (TC_RES res);
56 static BOOL As_File_Dbgi (TC_RES res, const char *fn, uint32_t ln, char *desc);
64 /*-----------------------------------------------------------------------------
65 * Test report interface function prototypes
66 *----------------------------------------------------------------------------*/
67 BOOL tr_File_Init (void);
68 BOOL tr_File_Open (const char *title, const char *date, const char *time, const char *fn);
69 BOOL tr_File_Close (void);
70 BOOL tc_File_Open (uint32_t num, const char *fn);
71 BOOL tc_File_Close (void);
82 /*-----------------------------------------------------------------------------
84 *----------------------------------------------------------------------------*/
85 BOOL tr_File_Init (void) {
90 /*-----------------------------------------------------------------------------
92 *----------------------------------------------------------------------------*/
93 #if (PRINT_XML_REPORT==1)
94 BOOL tr_File_Open (const char *title, const char *date, const char *time, const char *fn) {
95 PRINT(("<?xml version=\"1.0\"?>\n"));
96 PRINT(("<?xml-stylesheet href=\"TR_Style.xsl\" type=\"text/xsl\" ?>\n"));
97 PRINT(("<report>\n"));
99 PRINT(("<title>%s</title>\n", title));
100 PRINT(("<date>%s</date>\n", date));
101 PRINT(("<time>%s</time>\n", time));
102 PRINT(("<file>%s</file>\n", fn));
103 PRINT(("<test_cases>\n"));
105 BOOL tr_File_Open (const char *title, const char *date, const char *time, const char __attribute__((unused)) *fn) {
106 PRINT(("%s %s %s \n\n", title, date, time));
112 /*-----------------------------------------------------------------------------
114 *----------------------------------------------------------------------------*/
115 BOOL tc_File_Open (uint32_t num, const char *fn) {
117 #if (PRINT_XML_REPORT==1)
119 PRINT(("<no>%d</no>\n", num));
120 PRINT(("<func>%s</func>\n", fn));
121 PRINT(("<req></req>"));
122 PRINT(("<meth></meth>"));
125 PRINT(("TEST %02d: %-42s ", num, fn));
131 /*-----------------------------------------------------------------------------
133 *----------------------------------------------------------------------------*/
134 BOOL tc_File_Close (void) {
135 uint8_t *res = tc_Eval();
136 #if (PRINT_XML_REPORT==1)
137 PRINT(("</dbgi>\n"));
138 PRINT(("<res>%s</res>\n", res));
141 if ((res==Passed)||(res==NotExe)) {
142 PRINT(("%s\n", res));
152 /*-----------------------------------------------------------------------------
154 *----------------------------------------------------------------------------*/
155 BOOL tr_File_Close (void) {
156 #if (PRINT_XML_REPORT==1)
157 PRINT(("</test_cases>\n"));
158 PRINT(("<summary>\n"));
159 PRINT(("<tcnt>%d</tcnt>\n", test_report.tests));
160 PRINT(("<exec>%d</exec>\n", test_report.executed));
161 PRINT(("<pass>%d</pass>\n", test_report.passed));
162 PRINT(("<fail>%d</fail>\n", test_report.failed));
163 PRINT(("<warn>%d</warn>\n", test_report.warnings));
164 PRINT(("<tres>%s</tres>\n", tr_Eval()));
165 PRINT(("</summary>\n"));
166 PRINT(("</test>\n"));
167 PRINT(("</report>\n"));
169 PRINT(("\nTest Summary: %d Tests, %d Executed, %d Passed, %d Failed, %d Warnings.\n",
171 test_report.executed,
174 test_report.warnings));
175 PRINT(("Test Result: %s\n", tr_Eval()));
182 /*-----------------------------------------------------------------------------
183 * Assertion result counter
184 *----------------------------------------------------------------------------*/
185 static BOOL As_File_Result (TC_RES res) {
186 return (StatCount (res));
190 /*-----------------------------------------------------------------------------
191 * Set debug information state
192 *----------------------------------------------------------------------------*/
193 #if (PRINT_XML_REPORT==1)
194 static BOOL As_File_Dbgi (TC_RES __attribute__((unused)) res, const char *fn, uint32_t ln, char *desc) {
195 PRINT(("<detail>\n"));
196 if (desc!=NULL) PRINT(("<desc>%s</desc>\n", desc));
197 PRINT(("<module>%s</module>\n", fn));
198 PRINT(("<line>%d</line>\n", ln));
199 PRINT(("</detail>\n"));
201 static BOOL As_File_Dbgi (TC_RES res, const char *fn, uint32_t ln, char *desc) {
202 PRINT(("\n %s (%d)", fn, ln));
203 if (res==WARNING){ PRINT((" [WARNING]")); }
204 if (res==FAILED) { PRINT((" [FAILED]")); }
205 if (desc!=NULL) { PRINT((" %s", desc)); }
211 /*-----------------------------------------------------------------------------
213 *----------------------------------------------------------------------------*/
214 static BOOL tr_Init (void) {
222 /*-----------------------------------------------------------------------------
224 *----------------------------------------------------------------------------*/
225 static BOOL tc_Init (void) {
233 /*-----------------------------------------------------------------------------
234 * Evaluate test report results
235 *----------------------------------------------------------------------------*/
236 static uint8_t *tr_Eval (void) {
237 if (test_report.failed > 0U) {
238 /* Test fails if any test case failed */
241 else if (test_report.warnings > 0U) {
242 /* Test warns if any test case warnings */
245 else if (test_report.passed > 0U) {
246 /* Test passes if at least one test case passed */
250 /* No test cases were executed */
256 /*-----------------------------------------------------------------------------
257 * Evaluate test case results
258 *----------------------------------------------------------------------------*/
259 static uint8_t *tc_Eval (void) {
261 test_report.executed++;
263 if (CAS->failed > 0U) {
264 /* Test case fails if any failed assertion recorded */
265 test_report.failed++;
268 else if (CAS->warnings > 0U) {
269 /* Test case warns if any warnings assertion recorded */
270 test_report.warnings++;
273 else if (CAS->passed > 0U) {
274 /* Test case passes if at least one assertion passed */
275 test_report.passed++;
279 /* Assert was not invoked - nothing to evaluate */
280 test_report.executed--;
286 /*-----------------------------------------------------------------------------
287 * Statistics result counter
288 *----------------------------------------------------------------------------*/
289 static BOOL StatCount (TC_RES res) {
316 /*-----------------------------------------------------------------------------
318 *----------------------------------------------------------------------------*/
319 TC_RES __set_result (const char *fn, uint32_t ln, TC_RES res, char* desc) {
321 // save assertion result
324 if (TAS->passed < BUFFER_ASSERTIONS) {
325 test_report.assertions.info.passed[TAS->passed].module = fn;
326 test_report.assertions.info.passed[TAS->passed].line = ln;
330 if (TAS->failed < BUFFER_ASSERTIONS) {
331 test_report.assertions.info.failed[TAS->failed].module = fn;
332 test_report.assertions.info.failed[TAS->failed].line = ln;
336 if (TAS->warnings < BUFFER_ASSERTIONS) {
337 test_report.assertions.info.warnings[TAS->warnings].module = fn;
338 test_report.assertions.info.warnings[TAS->warnings].line = ln;
348 // set debug info (if the test case didn't pass)
349 if (res != PASSED) { (void)tcitf.Dbgi (res, fn, ln, desc); }
351 (void)tcitf.Result (res);
355 /*-----------------------------------------------------------------------------
357 *----------------------------------------------------------------------------*/
358 TC_RES __assert_true (const char *fn, uint32_t ln, uint32_t cond) {
360 if (cond != 0U) { res = PASSED; }
361 (void)__set_result(fn, ln, res, NULL);
365 #ifndef DISABLE_SEMIHOSTING
366 /*-----------------------------------------------------------------------------
367 * MsgFlush: Flush the standard output
368 *----------------------------------------------------------------------------*/
369 static void MsgFlush(void) {
370 (void)fflush(stdout);
373 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
374 #pragma clang diagnostic push
375 #pragma clang diagnostic ignored "-Wformat-nonliteral"
377 /*-----------------------------------------------------------------------------
378 * MsgPrint: Print a message to the standard output
379 *----------------------------------------------------------------------------*/
380 static void MsgPrint (const char *msg, ...) {
386 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
387 #pragma clang diagnostic pop
389 #endif // DISABLE_SEMIHOSTING
391 /*-----------------------------------------------------------------------------
393 *----------------------------------------------------------------------------*/