/* * Copyright (c) 2015-2021 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ----------------------------------------------------------------------------- * * Project: CMSIS-Driver Validation * Title: Report statistics and layout implementation * * ----------------------------------------------------------------------------- */ #include "DV_Report.h" /* Local macros */ #define PRINT(x) MsgPrint x #define FLUSH() MsgFlush() /* Local functions */ static void tr_Init (void); static void tr_Uninit (void); static void tg_Init (const char *title, const char *date, const char *time, const char *fn); static void tg_Info (const char *info); static void tg_InfoDone(void); static void tg_Uninit (void); static void tc_Init (uint32_t num, const char *fn); static void tc_Detail (const char *module, uint32_t line, const char *message); static void tc_Uninit (void); static void as_Result (TC_RES res); static void MsgPrint (const char *msg, ...); static void MsgFlush (void); /* Global variables */ REPORT_ITF ritf = { /* Structure for report interface */ tr_Init, tr_Uninit, tg_Init, tg_Info, tg_InfoDone, tg_Uninit, tc_Init, tc_Detail, tc_Uninit, as_Result, }; /* Local variables */ static TEST_GROUP_RESULTS test_group_result; /* Test group results */ static uint32_t as_passed = 0U; /* Assertions passed */ static uint32_t as_failed = 0U; /* Assertions failed */ static uint32_t as_detail = 0U; /* Assertions details available */ static const char Passed[] = "PASSED"; static const char Failed[] = "FAILED"; static const char NotExe[] = "NOT EXECUTED"; /*----------------------------------------------------------------------------- * No path - helper function *----------------------------------------------------------------------------*/ static const char *no_path (const char *fn) { const char *cp; #if defined(__CC_ARM) cp = strrchr(fn, (int32_t)'\\'); #else cp = strrchr(fn, (int32_t)'/'); #endif if (cp != NULL) { cp = &cp[1]; } else { cp = fn; } return (cp); } /*----------------------------------------------------------------------------- * Init test report *----------------------------------------------------------------------------*/ static void tr_Init (void) { test_group_result.idx = 0; #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("\n")); PRINT(("\n")); #else PRINT((" \n\n")); #endif } /*----------------------------------------------------------------------------- * Uninit test report *----------------------------------------------------------------------------*/ static void tr_Uninit (void) { #if (PRINT_XML_REPORT==1) PRINT(("\n")); #endif } /*----------------------------------------------------------------------------- * Init test group *----------------------------------------------------------------------------*/ static void tg_Init (const char *title, const char *date, const char *time, const char *fn) { test_group_result.idx++; test_group_result.tests = 0U; test_group_result.passed = 0U; test_group_result.failed = 0U; #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("%s\n", title)); PRINT(("%s\n", date)); PRINT(("\n", time)); PRINT(("%s\n", fn)); PRINT(("%i\n", test_group_result.idx)); PRINT(("\n")); #else (void) fn; PRINT(("%s %s %s \n\n", title, date, time)); #endif } /*----------------------------------------------------------------------------- * Write test group info *----------------------------------------------------------------------------*/ static void tg_Info (const char *info) { PRINT(("%s", info)); PRINT(("\n")); #if (PRINT_XML_REPORT==0) PRINT(("\n")); #endif } /*----------------------------------------------------------------------------- * Test group info done *----------------------------------------------------------------------------*/ static void tg_InfoDone (void) { #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("\n")); #endif } /*----------------------------------------------------------------------------- * Uninit test group *----------------------------------------------------------------------------*/ static void tg_Uninit (void) { const char *tres; if (test_group_result.failed > 0U) { /* If any test failed => Failed */ tres = Failed; } else if (test_group_result.passed > 0U) { /* If 1 passed => Passed */ tres = Passed; } else { /* If no tests exec => Not-executed */ tres = NotExe; } #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("\n")); PRINT(("%d\n", test_group_result.tests)); PRINT(("%d\n", test_group_result.passed)); PRINT(("%d\n", test_group_result.failed)); PRINT(("%s\n", tres)); PRINT(("\n")); PRINT(("\n")); #else PRINT(("\nTest Summary: %d Tests, %d Passed, %d Failed.\n", test_group_result.tests, test_group_result.passed, test_group_result.failed)); PRINT(("Test Result: %s\n\n\n", tres)); #endif FLUSH(); } /*----------------------------------------------------------------------------- * Init test *----------------------------------------------------------------------------*/ static void tc_Init (uint32_t num, const char *fn) { as_passed = 0U; as_failed = 0U; as_detail = 0U; #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("%d\n", num)); PRINT(("%s\n", fn)); PRINT(("\n")); #else PRINT(("TEST %02d: %-32s ", num, fn)); #endif } /*----------------------------------------------------------------------------- * Write test detail *----------------------------------------------------------------------------*/ static void tc_Detail (const char *module, uint32_t line, const char *message) { const char *module_no_path; module_no_path = no_path (module); as_detail = 1U; #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("%s\n", module_no_path)); PRINT(("%d\n", line)); if (message != NULL) { PRINT(("%s\n", message)); } PRINT(("\n")); #else PRINT(("\n %s (%d)", module_no_path, line)); if (message != NULL) { PRINT((": %s", message)); } #endif } /*----------------------------------------------------------------------------- * Uninit test *----------------------------------------------------------------------------*/ static void tc_Uninit (void) { const char *res; test_group_result.tests++; if (as_failed > 0U) { /* If any assertion failed => Failed */ test_group_result.failed++; res = Failed; } else if (as_passed > 0U) { /* If 1 assertion passed => Passed */ test_group_result.passed++; res = Passed; } else { /* If no assertions => Not-executed */ res = NotExe; } #if (PRINT_XML_REPORT==1) PRINT(("\n")); PRINT(("%s\n", res)); PRINT(("\n")); (void)as_detail; #else if (as_detail != 0U) { PRINT(("\n ")); } PRINT(("%s\n", res)); #endif } /*----------------------------------------------------------------------------- * Assertion result registering *----------------------------------------------------------------------------*/ static void as_Result (TC_RES res) { if (res == PASSED) { as_passed++; } else if (res == FAILED) { as_failed++; } else { // Do nothing } } /*----------------------------------------------------------------------------- * Add info line to group info *----------------------------------------------------------------------------*/ void __tg_info (const char *info) { if (info != NULL) { tg_Info(info); } } /*----------------------------------------------------------------------------- * Set result *----------------------------------------------------------------------------*/ void __set_result (const char *module, uint32_t line, const char *message, TC_RES res) { // Set debug info if (message != NULL) { tc_Detail(module, line, message); } // Set result as_Result(res); } /*----------------------------------------------------------------------------- * Set message *----------------------------------------------------------------------------*/ void __set_message (const char *module, uint32_t line, const char *message) { if (message != NULL) { tc_Detail(module, line, message); } } #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-nonliteral" #endif /*----------------------------------------------------------------------------- * MsgPrint: Print a message to the standard output *----------------------------------------------------------------------------*/ static void MsgPrint (const char *msg, ...) { va_list args; va_start(args, msg); (void)vprintf(msg, args); va_end(args); } #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #pragma clang diagnostic pop #endif /*----------------------------------------------------------------------------- * SER_MsgFlush: Flush the standard output *----------------------------------------------------------------------------*/ static void MsgFlush(void) { (void)fflush(stdout); } /*----------------------------------------------------------------------------- * End of file *----------------------------------------------------------------------------*/