From 9687d1e12b13b741efef0fb194050c0fae8f4bb6 Mon Sep 17 00:00:00 2001 From: Houkes Date: Fri, 16 Mar 2018 11:53:29 +0100 Subject: [PATCH 01/10] JUNIT compliant for Jenkins --- CUnit/Headers/Automated.h | 7 ++ CUnit/Sources/Automated/Automated.c | 107 ++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/CUnit/Headers/Automated.h b/CUnit/Headers/Automated.h index 0ddfcde..12a53fb 100644 --- a/CUnit/Headers/Automated.h +++ b/CUnit/Headers/Automated.h @@ -66,6 +66,13 @@ CU_EXPORT CU_ErrorCode CU_list_tests_to_file(void); * @return An error code indicating the error status. */ +CU_EXPORT CU_ErrorCode CU_list_tests_to_junit_file(void); +/**< + * Creates a Junit file which is compatible with Jenkins. + * + * @param szFilenameRoot String containing root to use for file names. + */ + CU_EXPORT void CU_set_output_filename(const char* szFilenameRoot); /**< * Sets the root file name for automated test output files. diff --git a/CUnit/Sources/Automated/Automated.c b/CUnit/Sources/Automated/Automated.c index bc1059c..2394fbc 100644 --- a/CUnit/Sources/Automated/Automated.c +++ b/CUnit/Sources/Automated/Automated.c @@ -39,6 +39,8 @@ * 02-May-2006 Added internationalization hooks. (JDS) * * 07-May-2011 Added patch to fix broken xml tags dur to spacial characters in the test name. (AK) + * + * 16-Mar-2018 Add path for JUNIT tests in Jenkins. Also log the faults in XML output. (BHO) */ /** @file @@ -84,6 +86,7 @@ static char _gPackageName[50] = ""; * Static function forward declarations *=================================================================*/ static CU_ErrorCode automated_list_all_tests(CU_pTestRegistry pRegistry, const char* szFilename); +static CU_ErrorCode automated_junit_list_all_tests(CU_pTestRegistry pRegistry, const char* szFilename); static CU_ErrorCode initialize_result_file(const char* szFilename); static CU_ErrorCode uninitialize_result_file(void); @@ -766,4 +769,108 @@ const char *CU_automated_package_name_get() { return _gPackageName; } + +/*------------------------------------------------------------------------*/ +/** Generates an xml junit listing compatible with Jenkins. + */ +CU_ErrorCode CU_list_tests_to_junit_file() +{ + /* if a filename root hasn't been set, use the default one */ + if (0 == strlen(f_szTestListFileName)) { + CU_set_output_filename(f_szDefaultFileRoot); + } + + return automated_junit_list_all_tests(CU_get_registry(), f_szTestListFileName); +} + +/*------------------------------------------------------------------------*/ +/** Generates an xml junit listing of all tests in all suites for the + * specified test registry. The output is directed to a file + * having the specified name. + * @param pRegistry Test registry for which to generate list (non-NULL). + * @param szFilename Non-NULL, non-empty string containing name for + * listing file. + * @return A CU_ErrorCode indicating the error status. + */ +static CU_ErrorCode automated_junit_list_all_tests(CU_pTestRegistry pRegistry, const char* szFilename) +{ + CU_pSuite pSuite = NULL; + CU_pTest pTest = NULL; + FILE* pTestListFile = NULL; + char* szTime; + time_t tTime = 0; + CU_pFailureRecord pFail = NULL; + + CU_set_error(CUE_SUCCESS); + + if (NULL == pRegistry) { + CU_set_error(CUE_NOREGISTRY); + } + else if ((NULL == szFilename) || (0 == strlen(szFilename))) { + CU_set_error(CUE_BAD_FILENAME); + } + else if (NULL == (pTestListFile = fopen(f_szTestListFileName, "w"))) { + CU_set_error(CUE_FOPEN_FAILED); + } + else { + setvbuf(pTestListFile, NULL, _IONBF, 0); + + fprintf(pTestListFile, + "\n" + "\n"); + + pSuite = pRegistry->pSuite; + while (NULL != pSuite) { + assert(NULL != pSuite->pName); + pTest = pSuite->pTest; + + fprintf(pTestListFile, + "\n", + pSuite->pName, + pSuite->uiNumberOfTests); + + while (NULL != pTest) { + assert(NULL != pTest->pName); + + fprintf(pTestListFile, "\n", + pTest->pName); + pFail = CU_get_failure_list(); + while (NULL != pFail) + { + if (pFail->pTest == pTest) + { + fprintf(pTestListFile, "\n", + pFail->strFileName, pFail->uiLineNumber, pFail->strCondition, pFail->type); + } + + pFail = pFail->pNext; + } + + fprintf(pTestListFile, "\n "); + pTest = pTest->pNext; + } + fprintf(pTestListFile, + "\n "); + + pSuite = pSuite->pNext; + } + + fprintf(pTestListFile, "\n "); + + time(&tTime); + szTime = ctime(&tTime); + fprintf(pTestListFile, + " \n", + (NULL != szTime) ? szTime : ""); + + if (0 != fclose(pTestListFile)) { + CU_set_error(CUE_FCLOSE_FAILED); + } + } + + return CU_get_error(); +} + + /** @} */ From df66c78b6640ce01120beb82903e8c3c3f4f1469 Mon Sep 17 00:00:00 2001 From: mensfort Date: Wed, 6 Jun 2018 14:36:29 +0200 Subject: [PATCH 02/10] quotes in Junit output not working, now they are --- CUnit/Sources/Automated/Automated.c | 24 ++++++++++++++++++++---- CUnit/Sources/Framework/Util.c | 4 +++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CUnit/Sources/Automated/Automated.c b/CUnit/Sources/Automated/Automated.c index 2394fbc..a237fbe 100644 --- a/CUnit/Sources/Automated/Automated.c +++ b/CUnit/Sources/Automated/Automated.c @@ -800,6 +800,7 @@ static CU_ErrorCode automated_junit_list_all_tests(CU_pTestRegistry pRegistry, c char* szTime; time_t tTime = 0; CU_pFailureRecord pFail = NULL; + CU_pLoggingRecord pComment = NULL; CU_set_error(CUE_SUCCESS); @@ -833,19 +834,34 @@ static CU_ErrorCode automated_junit_list_all_tests(CU_pTestRegistry pRegistry, c while (NULL != pTest) { assert(NULL != pTest->pName); - fprintf(pTestListFile, "\n", - pTest->pName); + fprintf(pTestListFile, "\n", + pTest->pName, pTest->assertions); pFail = CU_get_failure_list(); while (NULL != pFail) { - if (pFail->pTest == pTest) + if (pFail->pTest == pTest && pFail->strCondition != NULL) { + int szTempName_len; + char *szTempName = (char *)CU_MALLOC((szTempName_len = CU_translated_strlen(pFail->strCondition) + 1)); + CU_translate_special_characters(pFail->strCondition, szTempName, szTempName_len); fprintf(pTestListFile, "\n", - pFail->strFileName, pFail->uiLineNumber, pFail->strCondition, pFail->type); + pFail->strFileName, pFail->uiLineNumber, szTempName, pFail->type); } pFail = pFail->pNext; } + pComment = CU_get_comment_list(); + while (NULL != pComment) + { + if (pComment->pTest == pTest) + { + int szTempName_len; + char *szTempName = (char *)CU_MALLOC((szTempName_len = CU_translated_strlen(pComment->strMessage) + 1)); + CU_translate_special_characters(pComment->strMessage, szTempName, szTempName_len); + fprintf(pTestListFile, "%s", szTempName); + } + pComment = pComment->pNext; + } fprintf(pTestListFile, "\n "); pTest = pTest->pNext; diff --git a/CUnit/Sources/Framework/Util.c b/CUnit/Sources/Framework/Util.c index 2c85c92..e5305d3 100644 --- a/CUnit/Sources/Framework/Util.c +++ b/CUnit/Sources/Framework/Util.c @@ -67,7 +67,9 @@ static const struct bindings { } CU_bindings [] = { {'&', "&"}, {'>', ">"}, - {'<', "<"} + {'<', "<"}, + {'\"', """}, + {'\'', "'"}, }; /*------------------------------------------------------------------------*/ From d9da97d72a6041bfde4ebb9e242c580cc09e87f2 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:24:26 +0200 Subject: [PATCH 03/10] Update CUnit.h CU_LOG to add logging for Cunit. This is put in the comment for JUNIT XML output. --- CUnit/Headers/CUnit.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/CUnit/Headers/CUnit.h b/CUnit/Headers/CUnit.h index 617439a..e2d17c5 100644 --- a/CUnit/Headers/CUnit.h +++ b/CUnit/Headers/CUnit.h @@ -122,6 +122,15 @@ #define CU_ASSERT(value) \ { CU_assertImplementation((value), __LINE__, #value, __FILE__, "", CU_FALSE); } +/** Assert with your own message. + */ +#define CU_LOG CU_log + +/** Assert with your own message. + */ +#define CU_LOG_ASSERT(message, ...) \ + { CU_error_message(__FILE__, __LINE__, message, ##__VA_ARGS__); } + /** Simple assertion. * Reports failure and causes test to abort. */ @@ -200,49 +209,49 @@ * Reports failure with no other action. */ #define CU_ASSERT_PTR_EQUAL(actual, expected) \ - { CU_assertImplementation(((const void*)(actual) == (const void*)(expected)), __LINE__, ("CU_ASSERT_PTR_EQUAL(" #actual "," #expected ")"), __FILE__, "", CU_FALSE); } + { CU_assertImplementation(((void*)(actual) == (void*)(expected)), __LINE__, ("CU_ASSERT_PTR_EQUAL(" #actual "," #expected ")"), __FILE__, "", CU_FALSE); } /** Asserts that pointers actual == expected. * Reports failure and causes test to abort. */ #define CU_ASSERT_PTR_EQUAL_FATAL(actual, expected) \ - { CU_assertImplementation(((const void*)(actual) == (const void*)(expected)), __LINE__, ("CU_ASSERT_PTR_EQUAL_FATAL(" #actual "," #expected ")"), __FILE__, "", CU_TRUE); } + { CU_assertImplementation(((void*)(actual) == (void*)(expected)), __LINE__, ("CU_ASSERT_PTR_EQUAL_FATAL(" #actual "," #expected ")"), __FILE__, "", CU_TRUE); } /** Asserts that pointers actual != expected. * Reports failure with no other action. */ #define CU_ASSERT_PTR_NOT_EQUAL(actual, expected) \ - { CU_assertImplementation(((const void*)(actual) != (const void*)(expected)), __LINE__, ("CU_ASSERT_PTR_NOT_EQUAL(" #actual "," #expected ")"), __FILE__, "", CU_FALSE); } + { CU_assertImplementation(((void*)(actual) != (void*)(expected)), __LINE__, ("CU_ASSERT_PTR_NOT_EQUAL(" #actual "," #expected ")"), __FILE__, "", CU_FALSE); } /** Asserts that pointers actual != expected. * Reports failure and causes test to abort. */ #define CU_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected) \ - { CU_assertImplementation(((const void*)(actual) != (const void*)(expected)), __LINE__, ("CU_ASSERT_PTR_NOT_EQUAL_FATAL(" #actual "," #expected ")"), __FILE__, "", CU_TRUE); } + { CU_assertImplementation(((void*)(actual) != (void*)(expected)), __LINE__, ("CU_ASSERT_PTR_NOT_EQUAL_FATAL(" #actual "," #expected ")"), __FILE__, "", CU_TRUE); } /** Asserts that pointer value is NULL. * Reports failure with no other action. */ #define CU_ASSERT_PTR_NULL(value) \ - { CU_assertImplementation((NULL == (const void*)(value)), __LINE__, ("CU_ASSERT_PTR_NULL(" #value")"), __FILE__, "", CU_FALSE); } + { CU_assertImplementation((NULL == (void*)(value)), __LINE__, ("CU_ASSERT_PTR_NULL(" #value")"), __FILE__, "", CU_FALSE); } /** Asserts that pointer value is NULL. * Reports failure and causes test to abort. */ #define CU_ASSERT_PTR_NULL_FATAL(value) \ - { CU_assertImplementation((NULL == (const void*)(value)), __LINE__, ("CU_ASSERT_PTR_NULL_FATAL(" #value")"), __FILE__, "", CU_TRUE); } + { CU_assertImplementation((NULL == (void*)(value)), __LINE__, ("CU_ASSERT_PTR_NULL_FATAL(" #value")"), __FILE__, "", CU_TRUE); } /** Asserts that pointer value is not NULL. * Reports failure with no other action. */ #define CU_ASSERT_PTR_NOT_NULL(value) \ - { CU_assertImplementation((NULL != (const void*)(value)), __LINE__, ("CU_ASSERT_PTR_NOT_NULL(" #value")"), __FILE__, "", CU_FALSE); } + { CU_assertImplementation((NULL != (void*)(value)), __LINE__, ("CU_ASSERT_PTR_NOT_NULL(" #value")"), __FILE__, "", CU_FALSE); } /** Asserts that pointer value is not NULL. * Reports failure and causes test to abort. */ #define CU_ASSERT_PTR_NOT_NULL_FATAL(value) \ - { CU_assertImplementation((NULL != (const void*)(value)), __LINE__, ("CU_ASSERT_PTR_NOT_NULL_FATAL(" #value")"), __FILE__, "", CU_TRUE); } + { CU_assertImplementation((NULL != (void*)(value)), __LINE__, ("CU_ASSERT_PTR_NOT_NULL_FATAL(" #value")"), __FILE__, "", CU_TRUE); } /** Asserts that string actual == expected. * Reports failure with no other action. From f53c263deeafcd163a5bba8a9946f33493965e18 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:27:43 +0200 Subject: [PATCH 04/10] Update TestRun.h Add normal text logging (CU_LOG) to Junit XML --- CUnit/Headers/TestRun.h | 177 ++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 70 deletions(-) diff --git a/CUnit/Headers/TestRun.h b/CUnit/Headers/TestRun.h index ba93145..3a8699b 100644 --- a/CUnit/Headers/TestRun.h +++ b/CUnit/Headers/TestRun.h @@ -44,6 +44,9 @@ * * 24-May-2006 Added callbacks for suite start and complete events. * Added tracking/reported of elapsed time. (JDS) + * + * 1-May-2018 Added logging structure for normal text logging in Junit files + * (Bart Houkes) */ /** @file @@ -71,6 +74,7 @@ #include "CUError.h" #include "TestDB.h" #include +#include #ifdef __cplusplus extern "C" { @@ -103,6 +107,20 @@ typedef struct CU_FailureRecord } CU_FailureRecord; typedef CU_FailureRecord* CU_pFailureRecord; /**< Pointer to CU_FailureRecord. */ +/* CU_LoggingRecord type definition. */ +/** Data type for holding comments (linked list). */ +typedef struct CU_LoggingRecord +{ + char* strMessage; /**< Test condition which failed. */ + CU_pTest pTest; /**< Test containing failure. */ + CU_pSuite pSuite; /**< Suite containing test having failure. */ + + struct CU_LoggingRecord* pNext; /**< Pointer to next record in linked list. */ + struct CU_LoggingRecord* pPrev; /**< Pointer to previous record in linked list. */ + +} CU_LoggingRecord; +typedef CU_LoggingRecord* CU_pLoggingRecord; /**< Pointer to CU_LoggingRecord. */ + /* CU_RunSummary type definition. */ /** Data type for holding statistics and assertion failures for a test run. */ typedef struct CU_RunSummary @@ -121,7 +139,7 @@ typedef struct CU_RunSummary } CU_RunSummary; typedef CU_RunSummary* CU_pRunSummary; /**< Pointer to CU_RunSummary. */ -/*-------------------------------------------------------------------- +/*-------------------------------------------------------------------- * Type Definitions for Message Handlers. *--------------------------------------------------------------------*/ typedef void (*CU_SuiteStartMessageHandler)(const CU_pSuite pSuite); @@ -129,33 +147,33 @@ typedef void (*CU_SuiteStartMessageHandler)(const CU_pSuite pSuite); typedef void (*CU_TestStartMessageHandler)(const CU_pTest pTest, const CU_pSuite pSuite); /**< Message handler called at the start of a test. - * The parameters are the test and suite being run. The test run is - * considered in progress when the message handler is called. + * The parameters are the test and suite being run. The test run is + * considered in progress when the message handler is called. * Neither pTest nor pSuite may be null. */ typedef void (*CU_TestCompleteMessageHandler)(const CU_pTest pTest, const CU_pSuite pSuite, const CU_pFailureRecord pFailure); /**< Message handler called at the completion of a test. - * The parameters are the test and suite being run, plus a pointer to - * the first failure record applicable to this test. If the test did - * not have any assertion failures, pFailure will be NULL. The test run + * The parameters are the test and suite being run, plus a pointer to + * the first failure record applicable to this test. If the test did + * not have any assertion failures, pFailure will be NULL. The test run * is considered in progress when the message handler is called. */ typedef void (*CU_SuiteCompleteMessageHandler)(const CU_pSuite pSuite, const CU_pFailureRecord pFailure); /**< Message handler called at the completion of a suite. - * The parameters are suite being run, plus a pointer to the first failure - * record applicable to this suite. If the suite and it's tests did not - * have any failures, pFailure will be NULL. The test run is considered + * The parameters are suite being run, plus a pointer to the first failure + * record applicable to this suite. If the suite and it's tests did not + * have any failures, pFailure will be NULL. The test run is considered * in progress when the message handler is called. */ typedef void (*CU_AllTestsCompleteMessageHandler)(const CU_pFailureRecord pFailure); /**< Message handler called at the completion of a test run. - * The parameter is a pointer to the linked list holding the failure - * records for the test run. The test run is considered completed + * The parameter is a pointer to the linked list holding the failure + * records for the test run. The test run is considered completed * when the message handler is called. */ @@ -169,7 +187,7 @@ typedef void (*CU_SuiteCleanupFailureMessageHandler)(const CU_pSuite pSuite); * The test run is considered in progress when the message handler is called. */ -/*-------------------------------------------------------------------- +/*-------------------------------------------------------------------- * Get/Set functions for Message Handlers *--------------------------------------------------------------------*/ CU_EXPORT void CU_set_suite_start_handler(CU_SuiteStartMessageHandler pSuiteStartMessage); @@ -202,21 +220,21 @@ CU_EXPORT CU_SuiteInitFailureMessageHandler CU_get_suite_init_failure_handler CU_EXPORT CU_SuiteCleanupFailureMessageHandler CU_get_suite_cleanup_failure_handler(void); /**< Retrieves the message handler called when a suite cleanup error occurs. */ -/*-------------------------------------------------------------------- +/*-------------------------------------------------------------------- * Functions for running registered tests and suites. *--------------------------------------------------------------------*/ CU_EXPORT CU_ErrorCode CU_run_all_tests(void); -/**< +/**< * Runs all tests in all suites registered in the test registry. * The suites are run in the order registered in the test registry. * For each suite, it is first checked to make sure it is active. - * Any initialization function is then called, the suite is run - * using run_single_suite(), and finally any suite cleanup function - * is called. If an error condition (other than CUE_NOREGISTRY) - * occurs during the run, the action depends on the current error + * Any initialization function is then called, the suite is run + * using run_single_suite(), and finally any suite cleanup function + * is called. If an error condition (other than CUE_NOREGISTRY) + * occurs during the run, the action depends on the current error * action (see CU_set_error_action()). An inactive suite is not * considered an error for this function. Note that the run - * statistics (counts of tests, successes, failures) are cleared + * statistics (counts of tests, successes, failures) are cleared * each time this function is run, even if it is unsuccessful. * * @return A CU_ErrorCode indicating the first error condition @@ -226,33 +244,33 @@ CU_EXPORT CU_ErrorCode CU_run_all_tests(void); */ CU_EXPORT CU_ErrorCode CU_run_suite(CU_pSuite pSuite); -/**< +/**< * Runs all tests in a specified suite. - * The suite need not be registered in the test registry to be - * run. It does, however, need to have its fActive flag set to + * The suite need not be registered in the test registry to be + * run. It does, however, need to have its fActive flag set to * CU_TRUE.

* * Any initialization function for the suite is first called, - * then the suite is run using run_single_suite(), and any suite - * cleanup function is called. Note that the run statistics - * (counts of tests, successes, failures) are initialized each - * time this function is called even if it is unsuccessful. If - * an error condition occurs during the run, the action depends + * then the suite is run using run_single_suite(), and any suite + * cleanup function is called. Note that the run statistics + * (counts of tests, successes, failures) are initialized each + * time this function is called even if it is unsuccessful. If + * an error condition occurs during the run, the action depends * on the current error action (see CU_set_error_action()). * * @param pSuite The suite containing the test (non-NULL) * @return A CU_ErrorCode indicating the first error condition * encountered while running the suite. CU_run_suite() - * sets and returns CUE_NOSUITE if pSuite is NULL, or - * CUE_SUITE_INACTIVE if the requested suite is not - * activated. Other error codes can be set during suite + * sets and returns CUE_NOSUITE if pSuite is NULL, or + * CUE_SUITE_INACTIVE if the requested suite is not + * activated. Other error codes can be set during suite * initialization or cleanup or during test runs. * @see CU_run_all_tests() to run all suites. * @see CU_run_test() to run a single test in a specific suite. */ CU_EXPORT CU_ErrorCode CU_run_test(CU_pSuite pSuite, CU_pTest pTest); -/**< +/**< * Runs a specific test in a specified suite. * The suite need not be registered in the test registry to be run, * although the test must be registered in the specified suite. @@ -274,42 +292,42 @@ CU_EXPORT CU_ErrorCode CU_run_test(CU_pSuite pSuite, CU_pTest pTest); * CUE_NOTEST if pTest is NULL, CUE_SUITE_INACTIVE if * pSuite is not active, CUE_TEST_NOT_IN_SUITE * if pTest is not registered in pSuite, and CU_TEST_INACTIVE - * if pTest is not active. Other error codes can be set during + * if pTest is not active. Other error codes can be set during * suite initialization or cleanup or during the test run. * @see CU_run_all_tests() to run all tests/suites. * @see CU_run_suite() to run all tests in a specific suite. */ -/*-------------------------------------------------------------------- +/*-------------------------------------------------------------------- * Functions for setting runtime behavior. *--------------------------------------------------------------------*/ CU_EXPORT void CU_set_fail_on_inactive(CU_BOOL new_inactive); /**< * Sets whether an inactive suite or test is treated as a failure. - * If CU_TRUE, then failure records will be generated for inactive - * suites or tests encountered during a test run. The default is - * CU_TRUE so that the client is reminded that the framewrork - * contains inactive suites/tests. Set to CU_FALSE to turn off + * If CU_TRUE, then failure records will be generated for inactive + * suites or tests encountered during a test run. The default is + * CU_TRUE so that the client is reminded that the framewrork + * contains inactive suites/tests. Set to CU_FALSE to turn off * this behavior. * * @param new_inactive New setting for whether to treat inactive - * suites and tests as failures during a test + * suites and tests as failures during a test * run (CU_TRUE) or not (CU_FALSE). * @see CU_get_fail_on_failure() */ - + CU_EXPORT CU_BOOL CU_get_fail_on_inactive(void); /**< - * Retrieves the current setting for whether inactive suites/tests - * are treated as failures. If CU_TRUE then failure records will + * Retrieves the current setting for whether inactive suites/tests + * are treated as failures. If CU_TRUE then failure records will * be generated for inactive suites encountered during a test run. * * @return CU_TRUE if inactive suites/tests are failures, CU_FALSE if not. * @see CU_set_fail_on_inactive() */ -/*-------------------------------------------------------------------- - * Functions for getting information about the previous test run. +/*-------------------------------------------------------------------- + * Functions for getting information about the previous test run. *--------------------------------------------------------------------*/ CU_EXPORT unsigned int CU_get_number_of_suites_run(void); /**< Retrieves the number of suites completed during the previous run (reset each run). */ @@ -330,13 +348,13 @@ CU_EXPORT unsigned int CU_get_number_of_successes(void); CU_EXPORT unsigned int CU_get_number_of_failures(void); /**< Retrieves the number of failed assertions during the last run (reset each run). */ CU_EXPORT unsigned int CU_get_number_of_failure_records(void); -/**< - * Retrieves the number failure records created during the previous run (reset each run). - * Note that this may be more than the number of failed assertions, since failure +/**< + * Retrieves the number failure records created during the previous run (reset each run). + * Note that this may be more than the number of failed assertions, since failure * records may also be created for failed suite initialization and cleanup. */ CU_EXPORT double CU_get_elapsed_time(void); -/**< +/**< * Retrieves the elapsed time for the last run in seconds (reset each run). * This function will calculate the current elapsed time if the test run has not * yet completed. This is in contrast to the run summary returned by @@ -344,37 +362,42 @@ CU_EXPORT double CU_get_elapsed_time(void); * end of the run. */ CU_EXPORT CU_pFailureRecord CU_get_failure_list(void); -/**< - * Retrieves the head of the linked list of failures which occurred during the - * last run (reset each run). Note that the pointer returned is invalidated - * when the client initiates a run using CU_run_all_tests(), CU_run_suite(), +/**< + * Retrieves the head of the linked list of failures which occurred during the + * last run (reset each run). Note that the pointer returned is invalidated + * when the client initiates a run using CU_run_all_tests(), CU_run_suite(), * or CU_run_test(). */ -CU_EXPORT CU_pRunSummary CU_get_run_summary(void); +CU_EXPORT CU_pLoggingRecord CU_get_comment_list(void); /**< + * Retrieves the head of the linked list of comments which added during the + * last run (reset each run). + */ +CU_EXPORT CU_pRunSummary CU_get_run_summary(void); +/**< * Retrieves the entire run summary for the last test run (reset each run). - * The run counts and stats contained in the run summary are updated - * throughout a test run. Note, however, that the elapsed time is not - * updated until after all suites/tests are run but before the "all tests - * complete" message handler is called (if any). To get the elapsed + * The run counts and stats contained in the run summary are updated + * throughout a test run. Note, however, that the elapsed time is not + * updated until after all suites/tests are run but before the "all tests + * complete" message handler is called (if any). To get the elapsed * time during a test run, use CU_get_elapsed_time() instead. */ CU_EXPORT char * CU_get_run_results_string(void); /**< * Creates a string and fills it with a summary of the current run results. - * The run summary presents data for the suites, tests, and assertions - * encountered during the run, as well as the elapsed time. The data - * presented include the number of registered, run, passed, failed, and - * inactive entities for each, as well as the elapsed time. This function - * can be called at any time, although the test registry must have been - * initialized (checked by assertion). The returned string is owned by - * the caller and should be deallocated using CU_FREE(). NULL is returned + * The run summary presents data for the suites, tests, and assertions + * encountered during the run, as well as the elapsed time. The data + * presented include the number of registered, run, passed, failed, and + * inactive entities for each, as well as the elapsed time. This function + * can be called at any time, although the test registry must have been + * initialized (checked by assertion). The returned string is owned by + * the caller and should be deallocated using CU_FREE(). NULL is returned * if there is an error allocating the new string. * * @return A new string containing the run summary (owned by caller). */ - + CU_EXPORT void CU_print_run_results(FILE *file); /**< * Prints a summary of the current run results to file. @@ -387,7 +410,21 @@ CU_EXPORT void CU_print_run_results(FILE *file); * @param file Pointer to stream to receive the printed summary (non-NULL). */ -/*-------------------------------------------------------------------- +CU_EXPORT void CU_error_message(const char *strFile, unsigned int uiLine, const char *strMessage, ...); +/**< + * Create an error logging with formatted message. + * + * @param strMessage What message + */ + +CU_EXPORT void CU_log(const char *strMessage, ...); +/**< + * Create a logging with formatted message. Added to the Junit output, not resulting in errors. + * + * @param strMessage What message + */ + +/*-------------------------------------------------------------------- * Functions for internal & testing use. *--------------------------------------------------------------------*/ CU_EXPORT CU_pSuite CU_get_current_suite(void); @@ -400,10 +437,10 @@ CU_EXPORT CU_BOOL CU_is_test_running(void); */ CU_EXPORT void CU_clear_previous_results(void); -/**< - * Initializes the run summary information stored from the previous test run. - * Resets the run counts to zero, and frees any memory associated with - * failure records. Calling this function multiple times, while inefficient, +/**< + * Initializes the run summary information stored from the previous test run. + * Resets the run counts to zero, and frees any memory associated with + * failure records. Calling this function multiple times, while inefficient, * will not cause an error condition. * @see clear_previous_results() */ @@ -414,7 +451,7 @@ CU_EXPORT CU_BOOL CU_assertImplementation(CU_BOOL bValue, const char *strFile, const char *strFunction, CU_BOOL bFatal); -/**< +/**< * Assertion implementation function. * All CUnit assertions reduce to a call to this function. It should only be * called during an active test run (checked by assertion). This means that CUnit From 0bf1fd97b52df39a3b8238696650bc49dfe5b0c0 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:30:52 +0200 Subject: [PATCH 05/10] Update Automated.c Add normal text log to CUNIT --- CUnit/Sources/Automated/Automated.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/CUnit/Sources/Automated/Automated.c b/CUnit/Sources/Automated/Automated.c index a237fbe..978241c 100644 --- a/CUnit/Sources/Automated/Automated.c +++ b/CUnit/Sources/Automated/Automated.c @@ -40,7 +40,10 @@ * * 07-May-2011 Added patch to fix broken xml tags dur to spacial characters in the test name. (AK) * - * 16-Mar-2018 Add path for JUNIT tests in Jenkins. Also log the faults in XML output. (BHO) + * 16-Mar-2018 Add path for JUNIT tests in Jenkins. Also log the faults in XML output. (Bart Houkes) + * + * 1-May-2018 Add Normal comments to JUNIT output (use CU_LOG(...) + * */ /** @file @@ -834,18 +837,15 @@ static CU_ErrorCode automated_junit_list_all_tests(CU_pTestRegistry pRegistry, c while (NULL != pTest) { assert(NULL != pTest->pName); - fprintf(pTestListFile, "\n", - pTest->pName, pTest->assertions); + fprintf(pTestListFile, "\n", + pTest->pName); pFail = CU_get_failure_list(); while (NULL != pFail) { - if (pFail->pTest == pTest && pFail->strCondition != NULL) + if (pFail->pTest == pTest) { - int szTempName_len; - char *szTempName = (char *)CU_MALLOC((szTempName_len = CU_translated_strlen(pFail->strCondition) + 1)); - CU_translate_special_characters(pFail->strCondition, szTempName, szTempName_len); fprintf(pTestListFile, "\n", - pFail->strFileName, pFail->uiLineNumber, szTempName, pFail->type); + pFail->strFileName, pFail->uiLineNumber, pFail->strCondition, pFail->type); } pFail = pFail->pNext; @@ -855,10 +855,7 @@ static CU_ErrorCode automated_junit_list_all_tests(CU_pTestRegistry pRegistry, c { if (pComment->pTest == pTest) { - int szTempName_len; - char *szTempName = (char *)CU_MALLOC((szTempName_len = CU_translated_strlen(pComment->strMessage) + 1)); - CU_translate_special_characters(pComment->strMessage, szTempName, szTempName_len); - fprintf(pTestListFile, "%s", szTempName); + fprintf(pTestListFile, "%s", pComment->strMessage); } pComment = pComment->pNext; } From 1cd560af57f3050201e58818e082edfa9d8673c8 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:34:45 +0200 Subject: [PATCH 06/10] Update TestRun.c Add default logging to XML JUNIT files. Use CU_LOG --- CUnit/Sources/Framework/TestRun.c | 241 +++++++++++++++++++++++------- 1 file changed, 189 insertions(+), 52 deletions(-) diff --git a/CUnit/Sources/Framework/TestRun.c b/CUnit/Sources/Framework/TestRun.c index 781abba..d3c331f 100644 --- a/CUnit/Sources/Framework/TestRun.c +++ b/CUnit/Sources/Framework/TestRun.c @@ -62,6 +62,7 @@ * * 16-Avr-2007 Added setup and teardown functions. (CJN) * + * 1-May-2018 Add normal logging to XML JUNIT test logging (Bart Houkes) */ /** @file @@ -98,9 +99,15 @@ static CU_RunSummary f_run_summary = {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /** CU_pFailureRecord to hold head of failure record list of each test run. */ static CU_pFailureRecord f_failure_list = NULL; +/** CU_pLoggingRecord to hold head of failure record list of each test run. */ +static CU_pLoggingRecord f_logging_list = NULL; + /** CU_pFailureRecord to hold head of failure record list of each test run. */ static CU_pFailureRecord f_last_failure = NULL; +/** CU_pLoggingRecord to hold head of failure record list of each test run. */ +static CU_pLoggingRecord f_last_logging = NULL; + /** Flag for whether inactive suites/tests are treated as failures. */ static CU_BOOL f_failure_on_inactive = CU_TRUE; @@ -132,8 +139,9 @@ static CU_SuiteCleanupFailureMessageHandler f_pSuiteCleanupFailureMessageHandler /*================================================================= * Private function forward declarations *=================================================================*/ -static void clear_previous_results(CU_pRunSummary pRunSummary, CU_pFailureRecord* ppFailure); +static void clear_previous_results(CU_pRunSummary pRunSummary, CU_pFailureRecord* ppFailure, CU_pLoggingRecord *ppComments); static void cleanup_failure_list(CU_pFailureRecord* ppFailure); +static void cleanup_comment_list(CU_pLoggingRecord* ppComment); static CU_ErrorCode run_single_suite(CU_pSuite pSuite, CU_pRunSummary pRunSummary); static CU_ErrorCode run_single_test(CU_pTest pTest, CU_pRunSummary pRunSummary); static void add_failure(CU_pFailureRecord* ppFailure, @@ -144,15 +152,19 @@ static void add_failure(CU_pFailureRecord* ppFailure, const char *szFileName, CU_pSuite pSuite, CU_pTest pTest); +static void add_comment(CU_pLoggingRecord* ppComment, + const char *szComment, + CU_pSuite pSuite, + CU_pTest pTest); /*================================================================= * Public Interface functions *=================================================================*/ -CU_BOOL CU_assertImplementation(CU_BOOL bValue, +CU_BOOL CU_assertImplementation(CU_BOOL bValue, unsigned int uiLine, - const char *strCondition, + const char *strCondition, const char *strFile, - const char *strFunction, + const char *strFunction, CU_BOOL bFatal) { /* not used in current implementation - stop compiler warning */ @@ -176,6 +188,33 @@ CU_BOOL CU_assertImplementation(CU_BOOL bValue, return bValue; } +/*------------------------------------------------------------------------*/ +void CU_log(const char *strMessage, ...) +{ + va_list aptr; + char msg[4096]; + + assert(NULL != strMessage); + va_start(aptr, strMessage); + vsprintf(msg, strMessage, aptr); + ++f_run_summary.nAssertsFailed; + add_comment(&f_logging_list, msg, f_pCurSuite, f_pCurTest); +} + +/*------------------------------------------------------------------------*/ +void CU_error_message(const char *strFile, unsigned int uiLine, const char *strMessage, ...) +{ + va_list aptr; + char msg[4096]; + + assert(NULL != strMessage); + va_start(aptr, strMessage); + vsprintf(msg, strMessage, aptr); + ++f_run_summary.nAssertsFailed; + add_failure(&f_failure_list, &f_run_summary, CUF_AssertFailed, + uiLine, msg, strFile, f_pCurSuite, f_pCurTest); +} + /*------------------------------------------------------------------------*/ void CU_set_suite_start_handler(CU_SuiteStartMessageHandler pSuiteStartHandler) { @@ -337,6 +376,12 @@ CU_pFailureRecord CU_get_failure_list(void) return f_failure_list; } +/*------------------------------------------------------------------------*/ +CU_pLoggingRecord CU_get_comment_list(void) +{ + return f_logging_list; +} + /*------------------------------------------------------------------------*/ CU_pRunSummary CU_get_run_summary(void) { @@ -352,7 +397,7 @@ CU_ErrorCode CU_run_all_tests(void) CU_ErrorCode result2; /* Clear results from the previous run */ - clear_previous_results(&f_run_summary, &f_failure_list); + clear_previous_results(&f_run_summary, &f_failure_list, &f_logging_list); if (NULL == pRegistry) { result = CUE_NOREGISTRY; @@ -388,7 +433,7 @@ CU_ErrorCode CU_run_suite(CU_pSuite pSuite) CU_ErrorCode result = CUE_SUCCESS; /* Clear results from the previous run */ - clear_previous_results(&f_run_summary, &f_failure_list); + clear_previous_results(&f_run_summary, &f_failure_list, &f_logging_list); if (NULL == pSuite) { result = CUE_NOSUITE; @@ -421,7 +466,7 @@ CU_ErrorCode CU_run_test(CU_pSuite pSuite, CU_pTest pTest) CU_ErrorCode result2; /* Clear results from the previous run */ - clear_previous_results(&f_run_summary, &f_failure_list); + clear_previous_results(&f_run_summary, &f_failure_list, &f_logging_list); if (NULL == pSuite) { result = CUE_NOSUITE; @@ -485,7 +530,7 @@ CU_ErrorCode CU_run_test(CU_pSuite pSuite, CU_pTest pTest) result = (CUE_SUCCESS == result) ? CUE_SCLEAN_FAILED : result; } } - + /* run handler for suite completion, if any */ if (NULL != f_pSuiteCompleteMessageHandler) { (*f_pSuiteCompleteMessageHandler)(pSuite, NULL); @@ -510,7 +555,7 @@ CU_ErrorCode CU_run_test(CU_pSuite pSuite, CU_pTest pTest) /*------------------------------------------------------------------------*/ void CU_clear_previous_results(void) { - clear_previous_results(&f_run_summary, &f_failure_list); + clear_previous_results(&f_run_summary, &f_failure_list, &f_logging_list); } /*------------------------------------------------------------------------*/ @@ -536,7 +581,7 @@ CU_EXPORT void CU_set_fail_on_inactive(CU_BOOL new_inactive) { f_failure_on_inactive = new_inactive; } - + /*------------------------------------------------------------------------*/ CU_EXPORT CU_BOOL CU_get_fail_on_inactive(void) { @@ -547,7 +592,7 @@ CU_EXPORT CU_BOOL CU_get_fail_on_inactive(void) CU_EXPORT void CU_print_run_results(FILE *file) { char *summary_string; - + assert(NULL != file); summary_string = CU_get_run_results_string(); if (NULL != summary_string) { @@ -574,42 +619,42 @@ CU_EXPORT char * CU_get_run_results_string(void) width[0] = strlen(_("Run Summary:")); width[1] = CU_MAX(6, - CU_MAX(strlen(_("Type")), - CU_MAX(strlen(_("suites")), - CU_MAX(strlen(_("tests")), + CU_MAX(strlen(_("Type")), + CU_MAX(strlen(_("suites")), + CU_MAX(strlen(_("tests")), strlen(_("asserts")))))) + 1; width[2] = CU_MAX(6, - CU_MAX(strlen(_("Total")), - CU_MAX(CU_number_width(pRegistry->uiNumberOfSuites), - CU_MAX(CU_number_width(pRegistry->uiNumberOfTests), + CU_MAX(strlen(_("Total")), + CU_MAX(CU_number_width(pRegistry->uiNumberOfSuites), + CU_MAX(CU_number_width(pRegistry->uiNumberOfTests), CU_number_width(pRunSummary->nAsserts))))) + 1; width[3] = CU_MAX(6, - CU_MAX(strlen(_("Ran")), - CU_MAX(CU_number_width(pRunSummary->nSuitesRun), - CU_MAX(CU_number_width(pRunSummary->nTestsRun), + CU_MAX(strlen(_("Ran")), + CU_MAX(CU_number_width(pRunSummary->nSuitesRun), + CU_MAX(CU_number_width(pRunSummary->nTestsRun), CU_number_width(pRunSummary->nAsserts))))) + 1; width[4] = CU_MAX(6, - CU_MAX(strlen(_("Passed")), - CU_MAX(strlen(_("n/a")), - CU_MAX(CU_number_width(pRunSummary->nTestsRun - pRunSummary->nTestsFailed), + CU_MAX(strlen(_("Passed")), + CU_MAX(strlen(_("n/a")), + CU_MAX(CU_number_width(pRunSummary->nTestsRun - pRunSummary->nTestsFailed), CU_number_width(pRunSummary->nAsserts - pRunSummary->nAssertsFailed))))) + 1; width[5] = CU_MAX(6, - CU_MAX(strlen(_("Failed")), - CU_MAX(CU_number_width(pRunSummary->nSuitesFailed), - CU_MAX(CU_number_width(pRunSummary->nTestsFailed), + CU_MAX(strlen(_("Failed")), + CU_MAX(CU_number_width(pRunSummary->nSuitesFailed), + CU_MAX(CU_number_width(pRunSummary->nTestsFailed), CU_number_width(pRunSummary->nAssertsFailed))))) + 1; width[6] = CU_MAX(6, - CU_MAX(strlen(_("Inactive")), - CU_MAX(CU_number_width(pRunSummary->nSuitesInactive), - CU_MAX(CU_number_width(pRunSummary->nTestsInactive), + CU_MAX(strlen(_("Inactive")), + CU_MAX(CU_number_width(pRunSummary->nSuitesInactive), + CU_MAX(CU_number_width(pRunSummary->nTestsInactive), strlen(_("n/a")))))) + 1; width[7] = strlen(_("Elapsed time = ")); width[8] = strlen(_(" seconds")); - + len = 13 + 4*(width[0] + width[1] + width[2] + width[3] + width[4] + width[5] + width[6]) + width[7] + width[8] + 1; result = (char *)CU_MALLOC(len); - + if (NULL != result) { snprintf(result, len, "%*s%*s%*s%*s%*s%*s%*s\n" /* if you change this, be sure */ "%*s%*s%*u%*u%*s%*u%*u\n" /* to change the calculation of */ @@ -655,7 +700,7 @@ CU_EXPORT char * CU_get_run_results_string(void) /*================================================================= * Static Function Definitions *=================================================================*/ -/** +/** * Records a runtime failure. * This function is called whenever a runtime failure occurs. * This includes user assertion failures, suite initialization and @@ -744,21 +789,80 @@ static void add_failure(CU_pFailureRecord* ppFailure, f_last_failure = pFailureNew; } +/*================================================================= + * Static Function Definitions + *=================================================================*/ +/** + * Records a runtime comment. + * This function is called whenever the user wants comment in test + * output Junit files. + * + * @param ppComment Pointer to head of linked list of failure + * records to append with new failure record. + * If it points to a NULL pointer, it will be set + * to point to the new failure record. + * @param szComment Comment itself + * @param pSuite The suite being run at time of failure + * @param pTest The test being run at time of failure + */ +static void add_comment(CU_pLoggingRecord* ppComment, + const char *szComment, + CU_pSuite pSuite, + CU_pTest pTest) +{ + CU_pLoggingRecord pCommentNew = NULL; + CU_pLoggingRecord pTemp = NULL; + + assert(NULL != ppComment); + + pCommentNew = (CU_pLoggingRecord)CU_MALLOC(sizeof(CU_LoggingRecord)); + + if (NULL == pCommentNew) { + return; + } + + pCommentNew->strMessage = (char*)CU_MALLOC(strlen(szComment) + 1); + if (NULL == pCommentNew->strMessage) { + CU_FREE(pCommentNew); + return; + } + strcpy(pCommentNew->strMessage, szComment); + + pCommentNew->pTest = pTest; + pCommentNew->pSuite = pSuite; + pCommentNew->pNext = NULL; + pCommentNew->pPrev = NULL; + + pTemp = *ppComment; + if (NULL != pTemp) { + while (NULL != pTemp->pNext) { + pTemp = pTemp->pNext; + } + pTemp->pNext = pCommentNew; + pCommentNew->pPrev = pTemp; + } + else { + *ppComment = pCommentNew; + } + f_last_logging = pCommentNew; +} + /* * Local function for result set initialization/cleanup. */ /*------------------------------------------------------------------------*/ -/** - * Initializes the run summary information in the specified structure. - * Resets the run counts to zero, and calls cleanup_failure_list() if - * failures were recorded by the last test run. Calling this function +/** + * Initializes the run summary information in the specified structure. + * Resets the run counts to zero, and calls cleanup_failure_list() if + * failures were recorded by the last test run. Calling this function * multiple times, while inefficient, will not cause an error condition. * * @param pRunSummary CU_RunSummary to initialize (non-NULL). * @param ppFailure The failure record to clean (non-NULL). + * @param ppComment The comment record to clean (non-NULL). * @see CU_clear_previous_results() */ -static void clear_previous_results(CU_pRunSummary pRunSummary, CU_pFailureRecord* ppFailure) +static void clear_previous_results(CU_pRunSummary pRunSummary, CU_pFailureRecord* ppFailure, CU_pLoggingRecord* ppComment) { assert(NULL != pRunSummary); assert(NULL != ppFailure); @@ -777,13 +881,16 @@ static void clear_previous_results(CU_pRunSummary pRunSummary, CU_pFailureRecord if (NULL != *ppFailure) { cleanup_failure_list(ppFailure); } + if (NULL != *ppComment) { + cleanup_comment_list(ppComment); + } f_last_failure = NULL; } /*------------------------------------------------------------------------*/ -/** - * Frees all memory allocated for the linked list of test failure +/** + * Frees all memory allocated for the linked list of test failure * records. pFailure is reset to NULL after its list is cleaned up. * * @param ppFailure Pointer to head of linked list of @@ -815,13 +922,43 @@ static void cleanup_failure_list(CU_pFailureRecord* ppFailure) *ppFailure = NULL; } +/*------------------------------------------------------------------------*/ +/** + * Frees all memory allocated for the linked list of logging + * records. pComment is reset to NULL after its list is cleaned up. + * + * @param ppComment Pointer to head of linked list of + * CU_pLoggingRecord to clean. + * @see CU_clear_previous_results() + */ +static void cleanup_comment_list(CU_pLoggingRecord* ppComment) +{ + CU_pLoggingRecord pCurLogging = NULL; + CU_pLoggingRecord pNextLogging = NULL; + + pCurLogging = *ppComment; + + while (NULL != pCurLogging) { + + if (NULL != pCurLogging->strMessage) { + CU_FREE(pCurLogging->strMessage); + } + + pNextLogging = pCurLogging->pNext; + CU_FREE(pCurLogging); + pCurLogging = pNextLogging; + } + + *ppComment = NULL; +} + /*------------------------------------------------------------------------*/ /** * Runs all tests in a specified suite. - * Internal function to run all tests in a suite. The suite need + * Internal function to run all tests in a suite. The suite need * not be registered in the test registry to be run. Only * suites having their fActive flags set CU_TRUE will actually be - * run. If the CUnit framework is in an error condition after + * run. If the CUnit framework is in an error condition after * running a test, no additional tests are run. * * @param pSuite The suite containing the test (non-NULL). @@ -863,7 +1000,7 @@ static CU_ErrorCode run_single_suite(CU_pSuite pSuite, CU_pRunSummary pRunSummar } pRunSummary->nSuitesFailed++; add_failure(&f_failure_list, &f_run_summary, CUF_SuiteInitFailed, 0, - _("Suite Initialization failed - Suite Skipped"), + _("Suite Initialization failed - Suite Skipped"), _("CUnit System"), pSuite, NULL); result = CUE_SINIT_FAILED; } @@ -941,11 +1078,11 @@ static CU_ErrorCode run_single_suite(CU_pSuite pSuite, CU_pRunSummary pRunSummar } /*------------------------------------------------------------------------*/ -/** +/** * Runs a specific test. - * Internal function to run a test case. This includes calling - * any handler to be run before executing the test, running the - * test's function (if any), and calling any handler to be run + * Internal function to run a test case. This includes calling + * any handler to be run before executing the test, running the + * test's function (if any), and calling any handler to be run * after executing a test. Suite initialization and cleanup functions * are not called by this function. A current suite must be set and * active (checked by assertion). @@ -1070,7 +1207,7 @@ static void add_test_event(TestEventType type, CU_pSuite psuite, fprintf(stderr, "Memory allocation failed in add_test_event()."); exit(1); } - + pNewEvent->type = type; pNewEvent->pSuite = psuite; pNewEvent->pTest = ptest; @@ -1166,7 +1303,7 @@ static void suite_cleanup_failure_handler(const CU_pSuite pSuite) add_test_event(SUITE_CLEANUP_FAILED, pSuite, NULL, NULL); } -/** +/** * Centralize test result testing - we're going to do it a lot! * This is messy since we want to report the calling location upon failure. * @@ -1756,7 +1893,7 @@ static void test_CU_run_all_tests(void) /* run with no suites or tests registered */ CU_initialize_registry(); - + CU_set_error_action(CUEA_IGNORE); TEST(CUE_SUCCESS == CU_run_all_tests()); test_results(0,0,0,0,0,0,0,0,0,0); @@ -2099,7 +2236,6 @@ static void test_CU_run_all_tests(void) CU_cleanup_registry(); } - /*-------------------------------------------------*/ static void test_CU_run_suite(void) { @@ -2523,7 +2659,7 @@ static void test_CU_run_test(void) TEST(CUE_SUITE_INACTIVE == CU_run_test(pSuite1, pTest1)); test_results(0,0,1,0,0,0,0,0,0,1); CU_set_suite_active(pSuite1, CU_TRUE); - + CU_set_test_active(pTest1, CU_FALSE); CU_set_fail_on_inactive(CU_FALSE); TEST(CUE_TEST_INACTIVE == CU_run_test(pSuite1, pTest1)); /* test inactive */ @@ -2897,7 +3033,7 @@ static void test_add_failure(void) pFailure3 = pFailure1; pFailure4 = pFailure2; - clear_previous_results(&run_summary, &pFailure1); + clear_previous_results(&run_summary, &pFailure1, &f_logging_list); TEST(0 == run_summary.nFailureRecords); TEST(0 != test_cunit_get_n_memevents(pFailure3)); @@ -2923,3 +3059,4 @@ void test_cunit_TestRun(void) } #endif /* CUNIT_BUILD_TESTS */ + From 3c3f0f6dfa8f87c1b7dcf76b28c8c8f98eda86a9 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:37:42 +0200 Subject: [PATCH 07/10] Update AUTHORS Add myself --- AUTHORS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AUTHORS b/AUTHORS index 17f2f9d..8417a8c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,3 +10,7 @@ Special thanks to the following contributors to CUnit: K. Cheung and Aurema Pty Ltd. Shortcut code for efficient registration of CUnit tests and suites. + +Bart Houkes (BHO) +Email : bart@kassaku.nl +Added code since 2018 for private and business. From 0b8021ca8ea98d8d0d3d3af5d3330d85902a0ba2 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:40:22 +0200 Subject: [PATCH 08/10] Update ChangeLog --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 13607fa..7d485bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +* Mar 2018 Bart Houkes +- Add JENKINS compliant JUNIT function to export test results. +- Add number of tests passed/failed inside the XML report. +- Option to add comments inside the XML report. +- Add wildcards to your test output, e.g. CU_LOG("%d %s %f", x,y, z); +- Add wildcards in asserts. + * Tue Oct 14 2010 Martin Gerhardy - release 2.1.1 From 7688fbd61a6fb925b5164f994b4ca661ecae3d7b Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:44:10 +0200 Subject: [PATCH 09/10] Update ExampleTests.c Add example to test --- Examples/ExampleTests.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Examples/ExampleTests.c b/Examples/ExampleTests.c index 5cd2d52..811bbf6 100644 --- a/Examples/ExampleTests.c +++ b/Examples/ExampleTests.c @@ -83,11 +83,14 @@ static void testAssertTrue(void) static void testAssertFalse(void) { + int a=3, b=5; CU_ASSERT_FALSE(CU_FALSE); CU_ASSERT_FALSE(!CU_TRUE); - + CU_LOG("test will assert now"); CU_ASSERT_FALSE(!CU_FALSE); CU_ASSERT_FALSE(CU_TRUE); + if (a!=b) + CU_ASSERT("a is not b %d!=%d", a,b); } static void testAssertEqual(void) From 2c5046f7c87087a51f3c3fab35718f66b9fc3608 Mon Sep 17 00:00:00 2001 From: Bart Houkes Date: Tue, 12 Jun 2018 11:46:59 +0200 Subject: [PATCH 10/10] Update CUnitExample.c Example for Jenkins output test --- Examples/Demo_fprintf/CUnitExample.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/Examples/Demo_fprintf/CUnitExample.c b/Examples/Demo_fprintf/CUnitExample.c index 4b31233..c0c12e7 100644 --- a/Examples/Demo_fprintf/CUnitExample.c +++ b/Examples/Demo_fprintf/CUnitExample.c @@ -106,25 +106,18 @@ int main() /* add a suite to the registry */ pSuite = CU_add_suite("Suite_1", init_suite1, clean_suite1); - if (NULL == pSuite) { - CU_cleanup_registry(); - return CU_get_error(); - } - - /* add the tests to the suite */ - /* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */ - if ((NULL == CU_add_test(pSuite, "test of fprintf()", testFPRINTF)) || - (NULL == CU_add_test(pSuite, "test of fread()", testFREAD))) - { - CU_cleanup_registry(); - return CU_get_error(); - } + CU_add_test(pSuite, "test of fprintf()", testFPRINTF); + CU_add_test(pSuite, "test of fread()", testFREAD); /* Run all tests using the console interface */ - CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_set_mode(CU_BRM_NORMAL); + CU_automated_enable_junit_xml(CU_TRUE); CU_basic_run_tests(); + CU_set_output_filename("BART"); + CU_list_tests_to_junit_file(); CU_cleanup_registry(); - return CU_get_error(); + + return CU_get_number_of_failures(); }