UnitTestFramewokPkg/SampleUnitTest: Use UT_EXPECT_ASSERT_FAILURE()

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2801

Add samples for all UnitTestLib macros including using
UT_EXPECT_ASSERT_FAILURE() for positive test cases where an
ASSERT() is triggered and detected correctly.

Additional test cases are added that disable ASSERT()s and
verify that UT_EXPECT_ASSERT_FAILURE() macros are skipped.

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>
This commit is contained in:
Michael D Kinney
2020-06-10 18:14:39 -07:00
committed by mergify[bot]
parent 9a6c4ac68e
commit 5d29e2d020
8 changed files with 531 additions and 0 deletions

View File

@ -181,6 +181,466 @@ GlobalPointerShouldBeChangeable (
return UNIT_TEST_PASSED; return UNIT_TEST_PASSED;
} }
/**
Unit-Test Test Suite Setup (before) function that enables ASSERT() macros.
**/
VOID
EFIAPI
TestSuiteEnableAsserts (
VOID
)
{
//
// Set BIT0 (DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED)
//
PatchPcdSet8 (PcdDebugPropertyMask, PcdGet8 (PcdDebugPropertyMask) | BIT0);
}
/**
Unit-Test Test Suite Setup (before) function that disables ASSERT() macros.
**/
VOID
EFIAPI
TestSuiteDisableAsserts (
VOID
)
{
//
// Clear BIT0 (DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED)
//
PatchPcdSet8 (PcdDebugPropertyMask, PcdGet8 (PcdDebugPropertyMask) & (~BIT0));
}
/**
Sample unit test using the UT_ASSERT_TRUE() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertTrue (
IN UNIT_TEST_CONTEXT Context
)
{
UINT64 Result;
//
// This test passes because expression always evaluated to TRUE.
//
UT_ASSERT_TRUE (TRUE);
//
// This test passes because expression always evaluates to TRUE.
//
Result = LShiftU64 (BIT0, 1);
UT_ASSERT_TRUE (Result == BIT1);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_FALSE() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertFalse (
IN UNIT_TEST_CONTEXT Context
)
{
UINT64 Result;
//
// This test passes because expression always evaluated to FALSE.
//
UT_ASSERT_FALSE (FALSE);
//
// This test passes because expression always evaluates to FALSE.
//
Result = LShiftU64 (BIT0, 1);
UT_ASSERT_FALSE (Result == BIT0);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_EQUAL() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertEqual (
IN UNIT_TEST_CONTEXT Context
)
{
UINT64 Result;
//
// This test passes because both values are always equal.
//
UT_ASSERT_EQUAL (1, 1);
//
// This test passes because both values are always equal.
//
Result = LShiftU64 (BIT0, 1);
UT_ASSERT_EQUAL (Result, BIT1);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_MEM_EQUAL() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertMemEqual (
IN UNIT_TEST_CONTEXT Context
)
{
CHAR8 *String1;
CHAR8 *String2;
UINTN Length;
//
// This test passes because String1 and String2 are the same.
//
String1 = "Hello";
String2 = "Hello";
Length = sizeof ("Hello");
UT_ASSERT_MEM_EQUAL (String1, String2, Length);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_NOT_EQUAL() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertNotEqual (
IN UNIT_TEST_CONTEXT Context
)
{
UINT64 Result;
//
// This test passes because both values are never equal.
//
UT_ASSERT_NOT_EQUAL (0, 1);
//
// This test passes because both values are never equal.
//
Result = LShiftU64 (BIT0, 1);
UT_ASSERT_NOT_EQUAL (Result, BIT0);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_NOT_EFI_ERROR() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertNotEfiError (
IN UNIT_TEST_CONTEXT Context
)
{
//
// This test passes because the status is not an EFI error.
//
UT_ASSERT_NOT_EFI_ERROR (EFI_SUCCESS);
//
// This test passes because the status is not an EFI error.
//
UT_ASSERT_NOT_EFI_ERROR (EFI_WARN_BUFFER_TOO_SMALL);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_STATUS_EQUAL() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertStatusEqual (
IN UNIT_TEST_CONTEXT Context
)
{
//
// This test passes because the status value are always equal.
//
UT_ASSERT_STATUS_EQUAL (EFI_SUCCESS, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_ASSERT_NOT_NULL() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtAssertNotNull (
IN UNIT_TEST_CONTEXT Context
)
{
UINT64 Result;
//
// This test passes because the pointer is never NULL.
//
UT_ASSERT_NOT_NULL (&Result);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_EXPECT_ASSERT_FAILURE() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtExpectAssertFailure (
IN UNIT_TEST_CONTEXT Context
)
{
//
// This test passes because it directly triggers an ASSERT().
//
UT_EXPECT_ASSERT_FAILURE (ASSERT (FALSE), NULL);
//
// This test passes because DecimalToBcd() generates an ASSERT() if the
// value passed in is >= 100. The expected ASSERT() is caught by the unit
// test framework and UT_EXPECT_ASSERT_FAILURE() returns without an error.
//
UT_EXPECT_ASSERT_FAILURE (DecimalToBcd8 (101), NULL);
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_LOG_ERROR() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtLogError (
IN UNIT_TEST_CONTEXT Context
)
{
//
// Example of logging.
//
UT_LOG_ERROR ("UT_LOG_ERROR() message\n");
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_LOG_WARNING() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtLogWarning (
IN UNIT_TEST_CONTEXT Context
)
{
//
// Example of logging.
//
UT_LOG_WARNING ("UT_LOG_WARNING() message\n");
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_LOG_INFO() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtLogInfo (
IN UNIT_TEST_CONTEXT Context
)
{
//
// Example of logging.
//
UT_LOG_INFO ("UT_LOG_INFO() message\n");
return UNIT_TEST_PASSED;
}
/**
Sample unit test using the UT_LOG_VERBOSE() macro.
@param[in] Context [Optional] An optional parameter that enables:
1) test-case reuse with varied parameters and
2) test-case re-entry for Target tests that need a
reboot. This parameter is a VOID* and it is the
responsibility of the test author to ensure that the
contents are well understood by all test cases that may
consume it.
@retval UNIT_TEST_PASSED The Unit test has completed and the test
case was successful.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
MacroUtLogVerbose (
IN UNIT_TEST_CONTEXT Context
)
{
//
// Example of logging.
//
UT_LOG_VERBOSE ("UT_LOG_VERBOSE() message\n");
return UNIT_TEST_PASSED;
}
/** /**
Initialize the unit test framework, suite, and unit tests for the Initialize the unit test framework, suite, and unit tests for the
sample unit tests and run the unit tests. sample unit tests and run the unit tests.
@ -199,6 +659,8 @@ UefiTestMain (
UNIT_TEST_FRAMEWORK_HANDLE Framework; UNIT_TEST_FRAMEWORK_HANDLE Framework;
UNIT_TEST_SUITE_HANDLE SimpleMathTests; UNIT_TEST_SUITE_HANDLE SimpleMathTests;
UNIT_TEST_SUITE_HANDLE GlobalVarTests; UNIT_TEST_SUITE_HANDLE GlobalVarTests;
UNIT_TEST_SUITE_HANDLE MacroTestsAssertsEnabled;
UNIT_TEST_SUITE_HANDLE MacroTestsAssertsDisabled;
Framework = NULL; Framework = NULL;
@ -236,6 +698,54 @@ UefiTestMain (
AddTestCase (GlobalVarTests, "You should be able to change a global BOOLEAN", "Boolean", GlobalBooleanShouldBeChangeable, NULL, NULL, NULL); AddTestCase (GlobalVarTests, "You should be able to change a global BOOLEAN", "Boolean", GlobalBooleanShouldBeChangeable, NULL, NULL, NULL);
AddTestCase (GlobalVarTests, "You should be able to change a global pointer", "Pointer", GlobalPointerShouldBeChangeable, MakeSureThatPointerIsNull, ClearThePointer, NULL); AddTestCase (GlobalVarTests, "You should be able to change a global pointer", "Pointer", GlobalPointerShouldBeChangeable, MakeSureThatPointerIsNull, ClearThePointer, NULL);
//
// Populate the Macro Tests with ASSERT() enabled
//
Status = CreateUnitTestSuite (&MacroTestsAssertsEnabled, Framework, "Macro Tests with ASSERT() enabled", "Sample.MacroAssertsEnabled", TestSuiteEnableAsserts, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MacroTestsAssertsEnabled\n"));
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_TRUE() macro", "MacroUtAssertTrue", MacroUtAssertTrue, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_FALSE() macro", "MacroUtAssertFalse", MacroUtAssertFalse, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_EQUAL() macro", "MacroUtAssertEqual", MacroUtAssertEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_MEM_EQUAL() macro", "MacroUtAssertMemEqual", MacroUtAssertMemEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_NOT_EQUAL() macro", "MacroUtAssertNotEqual", MacroUtAssertNotEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_NOT_EFI_ERROR() macro", "MacroUtAssertNotEfiError", MacroUtAssertNotEfiError, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_STATUS_EQUAL() macro", "MacroUtAssertStatusEqual", MacroUtAssertStatusEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_ASSERT_NOT_NULL() macro", "MacroUtAssertNotNull", MacroUtAssertNotNull, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_EXPECT_ASSERT_FAILURE() macro", "MacroUtExpectAssertFailure", MacroUtExpectAssertFailure, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_LOG_ERROR() macro", "MacroUtLogError", MacroUtLogError, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_LOG_WARNING() macro", "MacroUtLogWarning", MacroUtLogWarning, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_LOG_INFO() macro", "MacroUtLogInfo", MacroUtLogInfo, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsEnabled, "Test UT_LOG_VERBOSE() macro", "MacroUtLogVerbose", MacroUtLogVerbose, NULL, NULL, NULL);
//
// Populate the Macro Tests with ASSERT() disabled
//
Status = CreateUnitTestSuite (&MacroTestsAssertsDisabled, Framework, "Macro Tests with ASSERT() disabled", "Sample.MacroAssertsDisables", TestSuiteDisableAsserts, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MacroTestsAssertsDisabled\n"));
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_TRUE() macro", "MacroUtAssertTrue", MacroUtAssertTrue, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_FALSE() macro", "MacroUtAssertFalse", MacroUtAssertFalse, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_EQUAL() macro", "MacroUtAssertEqual", MacroUtAssertEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_MEM_EQUAL() macro", "MacroUtAssertMemEqual", MacroUtAssertMemEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_NOT_EQUAL() macro", "MacroUtAssertNotEqual", MacroUtAssertNotEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_NOT_EFI_ERROR() macro", "MacroUtAssertNotEfiError", MacroUtAssertNotEfiError, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_STATUS_EQUAL() macro", "MacroUtAssertStatusEqual", MacroUtAssertStatusEqual, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_ASSERT_NOT_NULL() macro", "MacroUtAssertNotNull", MacroUtAssertNotNull, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_EXPECT_ASSERT_FAILURE() macro", "MacroUtExpectAssertFailure", MacroUtExpectAssertFailure, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_LOG_ERROR() macro", "MacroUtLogError", MacroUtLogError, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_LOG_WARNING() macro", "MacroUtLogWarning", MacroUtLogWarning, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_LOG_INFO() macro", "MacroUtLogInfo", MacroUtLogInfo, NULL, NULL, NULL);
AddTestCase (MacroTestsAssertsDisabled, "Test UT_LOG_VERBOSE() macro", "MacroUtLogVerbose", MacroUtLogVerbose, NULL, NULL, NULL);
// //
// Execute the tests. // Execute the tests.
// //

View File

@ -32,5 +32,8 @@
UnitTestLib UnitTestLib
PrintLib PrintLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
[Depex] [Depex]
TRUE TRUE

View File

@ -28,3 +28,6 @@
BaseLib BaseLib
DebugLib DebugLib
UnitTestLib UnitTestLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask

View File

@ -32,5 +32,8 @@
UnitTestLib UnitTestLib
PrintLib PrintLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
[Depex] [Depex]
gEfiPeiMemoryDiscoveredPpiGuid gEfiPeiMemoryDiscoveredPpiGuid

View File

@ -33,5 +33,8 @@
UnitTestLib UnitTestLib
PrintLib PrintLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
[Depex] [Depex]
gEfiSmmCpuProtocolGuid gEfiSmmCpuProtocolGuid

View File

@ -31,3 +31,6 @@
DebugLib DebugLib
UnitTestLib UnitTestLib
PrintLib PrintLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask

View File

@ -18,6 +18,9 @@
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
[PcdsPatchableInModule]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
[Components] [Components]
# #
# Build HOST_APPLICATION that tests the SampleUnitTest # Build HOST_APPLICATION that tests the SampleUnitTest

View File

@ -20,6 +20,9 @@
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc !include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
[PcdsPatchableInModule]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
[Components] [Components]
UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf
UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf