mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
REF: REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2801 Add UnitTestDebugAssertLib that provides the UnitTestDebugAssert() service and the gUnitTestExpectAssertFailureJumpBuffer global variable. This NULL library is linked against all host and target unit test builds. This guarantees that the UnitTestDebugAssert() service is available to link against all libraries and modules that use the DebugLib class. EDKII_UNIT_TEST_FRAMEWORK_ENABLED must always be defined when building unit tests so the behavior of the DebugLib ASSERT() macros can be adjusted to allow the unit test framework to catch an ASSERT() if it is triggered by a function under test. Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
218 lines
6.9 KiB
C
218 lines
6.9 KiB
C
/** @file
|
|
Implement UnitTestResultReportLib doing plain txt out to console
|
|
|
|
Copyright (c) Microsoft Corporation.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
#include <Library/UnitTestResultReportLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
|
|
VOID
|
|
ReportPrint (
|
|
IN CONST CHAR8 *Format,
|
|
...
|
|
);
|
|
|
|
VOID
|
|
ReportOutput (
|
|
IN CONST CHAR8 *Output
|
|
);
|
|
|
|
struct _UNIT_TEST_STATUS_STRING {
|
|
UNIT_TEST_STATUS Status;
|
|
CHAR8 *String;
|
|
};
|
|
|
|
struct _UNIT_TEST_FAILURE_TYPE_STRING {
|
|
FAILURE_TYPE Type;
|
|
CHAR8 *String;
|
|
};
|
|
|
|
struct _UNIT_TEST_STATUS_STRING mStatusStrings[] = {
|
|
{ UNIT_TEST_PASSED, "PASSED"},
|
|
{ UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, "NOT RUN - PREREQUISITE FAILED"},
|
|
{ UNIT_TEST_ERROR_TEST_FAILED, "FAILED"},
|
|
{ UNIT_TEST_RUNNING, "RUNNING"},
|
|
{ UNIT_TEST_PENDING, "PENDING"},
|
|
{ 0, "**UNKNOWN**"}
|
|
};
|
|
|
|
struct _UNIT_TEST_FAILURE_TYPE_STRING mFailureTypeStrings[] = {
|
|
{ FAILURETYPE_NOFAILURE, "NO FAILURE"},
|
|
{ FAILURETYPE_OTHER, "OTHER FAILURE"},
|
|
{ FAILURETYPE_ASSERTTRUE, "ASSERT_TRUE FAILURE"},
|
|
{ FAILURETYPE_ASSERTFALSE, "ASSERT_FALSE FAILURE"},
|
|
{ FAILURETYPE_ASSERTEQUAL, "ASSERT_EQUAL FAILURE"},
|
|
{ FAILURETYPE_ASSERTNOTEQUAL, "ASSERT_NOTEQUAL FAILURE"},
|
|
{ FAILURETYPE_ASSERTNOTEFIERROR, "ASSERT_NOTEFIERROR FAILURE"},
|
|
{ FAILURETYPE_ASSERTSTATUSEQUAL, "ASSERT_STATUSEQUAL FAILURE"},
|
|
{ FAILURETYPE_ASSERTNOTNULL, "ASSERT_NOTNULL FAILURE"},
|
|
{ FAILURETYPE_EXPECTASSERT, "EXPECT_ASSERT FAILURE"},
|
|
{ 0, "*UNKNOWN* Failure"}
|
|
};
|
|
|
|
//
|
|
// TEST REPORTING FUNCTIONS
|
|
//
|
|
|
|
STATIC
|
|
CONST CHAR8*
|
|
GetStringForUnitTestStatus (
|
|
IN UNIT_TEST_STATUS Status
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < ARRAY_SIZE (mStatusStrings) - 1; Index++) {
|
|
if (mStatusStrings[Index].Status == Status) {
|
|
//
|
|
// Return string from matching entry
|
|
//
|
|
return mStatusStrings[Index].String;
|
|
}
|
|
}
|
|
//
|
|
// Return last entry if no match found.
|
|
//
|
|
return mStatusStrings[Index].String;
|
|
}
|
|
|
|
STATIC
|
|
CONST CHAR8*
|
|
GetStringForFailureType (
|
|
IN FAILURE_TYPE Failure
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < ARRAY_SIZE (mFailureTypeStrings) - 1; Index++) {
|
|
if (mFailureTypeStrings[Index].Type == Failure) {
|
|
//
|
|
// Return string from matching entry
|
|
//
|
|
return mFailureTypeStrings[Index].String;
|
|
}
|
|
}
|
|
//
|
|
// Return last entry if no match found.
|
|
//
|
|
DEBUG((DEBUG_INFO, "%a Failure Type does not have string defined 0x%X\n", __FUNCTION__, (UINT32)Failure));
|
|
return mFailureTypeStrings[Index].String;
|
|
}
|
|
|
|
/*
|
|
Method to print the Unit Test run results
|
|
|
|
@retval Success
|
|
*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OutputUnitTestFrameworkReport (
|
|
IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
|
|
)
|
|
{
|
|
UNIT_TEST_FRAMEWORK *Framework;
|
|
INTN Passed;
|
|
INTN Failed;
|
|
INTN NotRun;
|
|
UNIT_TEST_SUITE_LIST_ENTRY *Suite;
|
|
UNIT_TEST_LIST_ENTRY *Test;
|
|
INTN SPassed;
|
|
INTN SFailed;
|
|
INTN SNotRun;
|
|
|
|
Passed = 0;
|
|
Failed = 0;
|
|
NotRun = 0;
|
|
Suite = NULL;
|
|
|
|
Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
|
|
if (Framework == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ReportPrint ("---------------------------------------------------------\n");
|
|
ReportPrint ("------------- UNIT TEST FRAMEWORK RESULTS ---------------\n");
|
|
ReportPrint ("---------------------------------------------------------\n");
|
|
|
|
//print the version and time
|
|
|
|
//
|
|
// Iterate all suites
|
|
//
|
|
for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY*)GetFirstNode(&Framework->TestSuiteList);
|
|
(LIST_ENTRY*)Suite != &Framework->TestSuiteList;
|
|
Suite = (UNIT_TEST_SUITE_LIST_ENTRY*)GetNextNode(&Framework->TestSuiteList, (LIST_ENTRY*)Suite)) {
|
|
|
|
Test = NULL;
|
|
SPassed = 0;
|
|
SFailed = 0;
|
|
SNotRun = 0;
|
|
|
|
ReportPrint ("/////////////////////////////////////////////////////////\n");
|
|
ReportPrint (" SUITE: %a\n", Suite->UTS.Title);
|
|
ReportPrint (" PACKAGE: %a\n", Suite->UTS.Name);
|
|
ReportPrint ("/////////////////////////////////////////////////////////\n");
|
|
|
|
//
|
|
// Iterate all tests within the suite
|
|
//
|
|
for (Test = (UNIT_TEST_LIST_ENTRY*)GetFirstNode(&(Suite->UTS.TestCaseList));
|
|
(LIST_ENTRY*)Test != &(Suite->UTS.TestCaseList);
|
|
Test = (UNIT_TEST_LIST_ENTRY*)GetNextNode(&(Suite->UTS.TestCaseList), (LIST_ENTRY*)Test)) {
|
|
|
|
ReportPrint ("*********************************************************\n");
|
|
ReportPrint (" CLASS NAME: %a\n", Test->UT.Name);
|
|
ReportPrint (" TEST: %a\n", Test->UT.Description);
|
|
ReportPrint (" STATUS: %a\n", GetStringForUnitTestStatus (Test->UT.Result));
|
|
ReportPrint (" FAILURE: %a\n", GetStringForFailureType (Test->UT.FailureType));
|
|
ReportPrint (" FAILURE MESSAGE:\n%a\n", Test->UT.FailureMessage);
|
|
|
|
if (Test->UT.Log != NULL) {
|
|
ReportPrint (" LOG:\n");
|
|
ReportOutput (Test->UT.Log);
|
|
}
|
|
|
|
switch (Test->UT.Result) {
|
|
case UNIT_TEST_PASSED:
|
|
SPassed++;
|
|
break;
|
|
case UNIT_TEST_ERROR_TEST_FAILED:
|
|
SFailed++;
|
|
break;
|
|
case UNIT_TEST_PENDING: // Fall through...
|
|
case UNIT_TEST_RUNNING: // Fall through...
|
|
case UNIT_TEST_ERROR_PREREQUISITE_NOT_MET:
|
|
SNotRun++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
ReportPrint ("**********************************************************\n");
|
|
} //End Test iteration
|
|
|
|
ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
|
|
ReportPrint ("Suite Stats\n");
|
|
ReportPrint (" Passed: %d (%d%%)\n", SPassed, (SPassed * 100)/(SPassed+SFailed+SNotRun));
|
|
ReportPrint (" Failed: %d (%d%%)\n", SFailed, (SFailed * 100) / (SPassed + SFailed + SNotRun));
|
|
ReportPrint (" Not Run: %d (%d%%)\n", SNotRun, (SNotRun * 100) / (SPassed + SFailed + SNotRun));
|
|
ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" );
|
|
|
|
Passed += SPassed; //add to global counters
|
|
Failed += SFailed; //add to global counters
|
|
NotRun += SNotRun; //add to global counters
|
|
}//End Suite iteration
|
|
|
|
ReportPrint ("=========================================================\n");
|
|
ReportPrint ("Total Stats\n");
|
|
ReportPrint (" Passed: %d (%d%%)\n", Passed, (Passed * 100) / (Passed + Failed + NotRun));
|
|
ReportPrint (" Failed: %d (%d%%)\n", Failed, (Failed * 100) / (Passed + Failed + NotRun));
|
|
ReportPrint (" Not Run: %d (%d%%)\n", NotRun, (NotRun * 100) / (Passed + Failed + NotRun));
|
|
ReportPrint ("=========================================================\n" );
|
|
|
|
return EFI_SUCCESS;
|
|
}
|