From: "Michael Kubacki" <mikuback@linux.microsoft.com>
To: Michael D Kinney <michael.d.kinney@intel.com>, devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@microsoft.com>
Subject: Re: [edk2-devel] [edk2-stable202402][Patch V3 7/7] UnitTestFrameworkPkg: Add DSC and host tests that always fail
Date: Mon, 12 Feb 2024 11:26:45 -0500 [thread overview]
Message-ID: <4340de56-0b6c-43b3-a0ac-0897aa623954@linux.microsoft.com> (raw)
In-Reply-To: <20240209203253.488-8-michael.d.kinney@intel.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
On 2/9/2024 3:32 PM, Michael D Kinney wrote:
> Add sample unit tests that always fail or generate unexpected
> exceptions along with a new DSC file to build the unit tests
> that always fail or generate unexpected exceptions. This can
> be used to verify the log information on failures is accurate
> and provides the correct information to determine the source
> of the unit test failure.
>
> Divide by zero is used to generate unexpected exceptions. The
> compiler warnings for divide by zero are disables for the unit
> tests that generate divide by zero exceptions on purpose.
>
> These tests are not added to CI because CI would always fail.
>
> The UnitTestFrameworkPkg.ci.yaml file is updated to ignore the
> INF files for host-based testing that always fail.
>
> Cc: Michael Kubacki <mikuback@linux.microsoft.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
> ---
> .../SampleGoogleTestExpectFail.cpp | 334 +++++++
> .../SampleGoogleTestHostExpectFail.inf | 36 +
> .../SampleGoogleTestGenerateException.cpp | 54 ++
> .../SampleGoogleTestHostGenerateException.inf | 39 +
> .../SampleUnitTestDxeExpectFail.inf | 41 +
> .../SampleUnitTestExpectFail.c | 861 ++++++++++++++++++
> .../SampleUnitTestHostExpectFail.inf | 35 +
> .../SampleUnitTestPeiExpectFail.inf | 41 +
> .../SampleUnitTestSmmExpectFail.inf | 42 +
> .../SampleUnitTestUefiShellExpectFail.inf | 38 +
> .../SampleUnitTestDxeGenerateException.inf | 43 +
> .../SampleUnitTestGenerateException.c | 204 +++++
> .../SampleUnitTestHostGenerateException.inf | 37 +
> .../SampleUnitTestPeiGenerateException.inf | 43 +
> .../SampleUnitTestSmmGenerateException.inf | 44 +
> ...mpleUnitTestUefiShellGenerateException.inf | 40 +
> ...UnitTestFrameworkPkgHostTestExpectFail.dsc | 44 +
> .../UnitTestFrameworkPkg.ci.yaml | 16 +-
> UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc | 26 +
> 19 files changed, 2017 insertions(+), 1 deletion(-)
> create mode 100644 UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestExpectFail.cpp
> create mode 100644 UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf
> create mode 100644 UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestGenerateException.cpp
> create mode 100644 UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestExpectFail.c
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestGenerateException.c
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf
> create mode 100644 UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc
>
> diff --git a/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestExpectFail.cpp b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestExpectFail.cpp
> new file mode 100644
> index 000000000000..bb0e18330570
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestExpectFail.cpp
> @@ -0,0 +1,334 @@
> +/** @file
> + This is a sample to demonstrates the use of GoogleTest that supports host
> + execution environments for test case that are always expected to fail to
> + demonstrate the format of the log file and reports when failures occur.
> +
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/GoogleTestLib.h>
> +extern "C" {
> + #include <Uefi.h>
> + #include <Library/BaseLib.h>
> + #include <Library/DebugLib.h>
> +}
> +
> +/**
> + Sample unit test that verifies the expected result of an unsigned integer
> + addition operation.
> +**/
> +TEST (SimpleMathTests, OnePlusOneShouldEqualTwo) {
> + UINTN A;
> + UINTN B;
> + UINTN C;
> +
> + A = 1;
> + B = 1;
> + C = A + B;
> +
> + ASSERT_NE (C, (UINTN)2);
> +}
> +
> +/**
> + Sample unit test that verifies that a global BOOLEAN is updatable.
> +**/
> +class GlobalBooleanVarTests : public ::testing::Test {
> +public:
> + BOOLEAN SampleGlobalTestBoolean = FALSE;
> +};
> +
> +TEST_F (GlobalBooleanVarTests, GlobalBooleanShouldBeChangeable) {
> + SampleGlobalTestBoolean = TRUE;
> + EXPECT_FALSE (SampleGlobalTestBoolean);
> +
> + SampleGlobalTestBoolean = FALSE;
> + EXPECT_TRUE (SampleGlobalTestBoolean);
> +}
> +
> +/**
> + Sample unit test that logs a warning message and verifies that a global
> + pointer is updatable.
> +**/
> +class GlobalVarTests : public ::testing::Test {
> +public:
> + VOID *SampleGlobalTestPointer = NULL;
> +
> +protected:
> + void
> + SetUp (
> + ) override
> + {
> + ASSERT_NE ((UINTN)SampleGlobalTestPointer, (UINTN)NULL);
> + }
> +
> + void
> + TearDown (
> + )
> + {
> + SampleGlobalTestPointer = NULL;
> + }
> +};
> +
> +TEST_F (GlobalVarTests, GlobalPointerShouldBeChangeable) {
> + SampleGlobalTestPointer = (VOID *)-1;
> + ASSERT_NE ((UINTN)SampleGlobalTestPointer, (UINTN)((VOID *)-1));
> +}
> +
> +/**
> + Set PcdDebugPropertyMask for each MacroTestsAssertsEnabledDisabled test
> +**/
> +class MacroTestsAssertsEnabledDisabled : public testing::TestWithParam<UINT8> {
> + void
> + SetUp (
> + )
> + {
> + PatchPcdSet8 (PcdDebugPropertyMask, GetParam ());
> + }
> +};
> +
> +/**
> + Sample unit test using the ASSERT_TRUE() macro.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertTrue) {
> + UINT64 Result;
> +
> + //
> + // This test passes because expression always evaluated to TRUE.
> + //
> + EXPECT_FALSE (TRUE);
> +
> + //
> + // This test passes because expression always evaluates to TRUE.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + EXPECT_FALSE (Result == BIT1);
> +}
> +
> +/**
> + Sample unit test using the ASSERT_FALSE() macro.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertFalse) {
> + UINT64 Result;
> +
> + //
> + // This test passes because expression always evaluated to FALSE.
> + //
> + EXPECT_TRUE (FALSE);
> +
> + //
> + // This test passes because expression always evaluates to FALSE.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + EXPECT_TRUE (Result == BIT0);
> +}
> +
> +/**
> + Sample unit test using the ASSERT_EQ() macro.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertEqual) {
> + UINT64 Result;
> +
> + //
> + // This test passes because both values are always equal.
> + //
> + EXPECT_NE (1, 1);
> +
> + //
> + // This test passes because both values are always equal.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + EXPECT_NE (Result, (UINT64)BIT1);
> +}
> +
> +/**
> + Sample unit test using the ASSERT_STREQ() macro.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertMemEqual) {
> + CHAR8 *String1;
> + CHAR8 *String2;
> +
> + //
> + // This test passes because String1 and String2 are the same.
> + //
> + String1 = (CHAR8 *)"Hello";
> + String2 = (CHAR8 *)"Hello";
> + EXPECT_STRNE (String1, String2);
> +}
> +
> +/**
> + Sample unit test using the ASSERT_NE() macro.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertNotEqual) {
> + UINT64 Result;
> +
> + //
> + // This test passes because both values are never equal.
> + //
> + EXPECT_EQ (0, 1);
> +
> + //
> + // This test passes because both values are never equal.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + EXPECT_EQ (Result, (UINT64)BIT0);
> +}
> +
> +/**
> + Sample unit test using the ASSERT_TRUE() and ASSERT(FALSE)
> + and EFI_EFFOR() macros to check status
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertNotEfiError) {
> + //
> + // This test passes because the status is not an EFI error.
> + //
> + EXPECT_TRUE (EFI_ERROR (EFI_SUCCESS));
> +
> + //
> + // This test passes because the status is not an EFI error.
> + //
> + EXPECT_TRUE (EFI_ERROR (EFI_WARN_BUFFER_TOO_SMALL));
> +}
> +
> +/**
> + Sample unit test using the ASSERT_EQ() macro to compare EFI_STATUS values.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertStatusEqual) {
> + //
> + // This test passes because the status value are always equal.
> + //
> + EXPECT_NE (EFI_SUCCESS, EFI_SUCCESS);
> +}
> +
> +/**
> + Sample unit test using ASSERT_NE() macro to make sure a pointer is not NULL.
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertNotNull) {
> + UINT64 Result;
> +
> + //
> + // This test passes because the pointer is never NULL.
> + //
> + EXPECT_EQ (&Result, (UINT64 *)NULL);
> +}
> +
> +/**
> + Sample unit test using that generates an unexpected ASSERT
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroDirectForceAssertExpectTestFail) {
> + //
> + // Skip tests that verify an ASSERT() is triggered if ASSERT()s are disabled.
> + //
> + if ((PcdGet8 (PcdDebugPropertyMask) & BIT0) == 0x00) {
> + EXPECT_TRUE (FALSE);
> + return;
> + }
> +
> + //
> + // This test fails because it directly triggers an ASSERT().
> + //
> + ASSERT (FALSE);
> +}
> +
> +/**
> + Sample unit test using that generates an unexpected ASSERT
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroIndirectForceAssertExpectTestFail) {
> + //
> + // Skip tests that verify an ASSERT() is triggered if ASSERT()s are disabled.
> + //
> + if ((PcdGet8 (PcdDebugPropertyMask) & BIT0) == 0x00) {
> + EXPECT_TRUE (FALSE);
> + return;
> + }
> +
> + //
> + // This test fails because DecimalToBcd() generates an ASSERT() if the
> + // value passed in is >= 100. The unexpected ASSERT() is caught by the unit
> + // test framework and generates a failed test.
> + //
> + DecimalToBcd8 (101);
> +}
> +
> +/**
> + Sample unit test using that do not generate an expected ASSERT()
> +**/
> +TEST_P (MacroTestsAssertsEnabledDisabled, MacroExpectedAssertNotTriggeredExpectTestFail) {
> + //
> + // When ASSERT()s are disabled, all tests for ASSERT()s will fail.
> + //
> + if ((PcdGet8 (PcdDebugPropertyMask) & BIT0) == 0x00) {
> + EXPECT_ANY_THROW (ASSERT (TRUE));
> + EXPECT_ANY_THROW (DecimalToBcd8 (99));
> + EXPECT_ANY_THROW (DecimalToBcd8 (101));
> + EXPECT_THROW (DecimalToBcd8 (99), std::runtime_error);
> + EXPECT_THROW (DecimalToBcd8 (101), std::runtime_error);
> + EXPECT_THROW (DecimalToBcd8 (99), std::overflow_error);
> + EXPECT_THROW (DecimalToBcd8 (101), std::overflow_error);
> + EXPECT_THROW_MESSAGE (DecimalToBcd8 (99), "Value < 999");
> + EXPECT_THROW_MESSAGE (DecimalToBcd8 (101), "Value < 999");
> + return;
> + }
> +
> + //
> + // This test fails because ASSERT(TRUE) never triggers an ASSERT().
> + //
> + EXPECT_ANY_THROW (ASSERT (TRUE));
> +
> + //
> + // This test fails because DecimalToBcd() does not generate an ASSERT() if the
> + // value passed in is < 100.
> + //
> + EXPECT_ANY_THROW (DecimalToBcd8 (99));
> +
> + //
> + // This test fails because DecimalToBcd() does not generate an ASSERT() if the
> + // value passed in is < 100.
> + //
> + EXPECT_THROW (DecimalToBcd8 (99), std::runtime_error);
> +
> + //
> + // This test fails because DecimalToBcd() does generate an ASSERT() if the
> + // value passed in is >= 100, but is generates a C++ exception of type
> + // std::runtime_error
> + //
> + EXPECT_THROW (DecimalToBcd8 (101), std::overflow_error);
> +
> + //
> + // This test fails because DecimalToBcd() generates an ASSERT() if the
> + // value passed in is >= 100. The expected ASSERT() is caught by the unit
> + // test framework and throws the C++ exception of type std::runtime_error with
> + // a message that includes the filename, linenumber, and the expression that
> + // triggered the ASSERT(). The message generated by BcdToDecimal() is
> + // "Value < 100", but the expression tested is not "Value < 100".
> + //
> + EXPECT_THROW_MESSAGE (DecimalToBcd8 (101), "Value < 999");
> +}
> +
> +INSTANTIATE_TEST_SUITE_P (
> + ValidInput,
> + MacroTestsAssertsEnabledDisabled,
> + ::testing::Values (PcdGet8 (PcdDebugPropertyMask) | BIT0, PcdGet8 (PcdDebugPropertyMask) & (~BIT0))
> + );
> +
> +/**
> + Sample unit test using the SCOPED_TRACE() macro for trace messages.
> +**/
> +TEST (MacroTestsMessages, MacroTraceMessage) {
> + //
> + // Example of logging.
> + //
> + SCOPED_TRACE ("SCOPED_TRACE message\n");
> + EXPECT_TRUE (FALSE);
> +}
> +
> +int
> +main (
> + int argc,
> + char *argv[]
> + )
> +{
> + testing::InitGoogleTest (&argc, argv);
> + return RUN_ALL_TESTS ();
> +}
> diff --git a/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf
> new file mode 100644
> index 000000000000..af3d254025c3
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# This is a sample to demonstrates the use of GoogleTest that supports host
> +# execution environments for test case that are always expected to fail to
> +# demonstrate the format of the log file and reports when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SampleGoogleTestHostExpectFail
> + FILE_GUID = 6042ADD2-E024-4FD5-8CD7-B2A146BF88D7
> + MODULE_TYPE = HOST_APPLICATION
> + VERSION_STRING = 1.0
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleGoogleTestExpectFail.cpp
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
> +
> +[LibraryClasses]
> + GoogleTestLib
> + BaseLib
> + DebugLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> diff --git a/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestGenerateException.cpp b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestGenerateException.cpp
> new file mode 100644
> index 000000000000..6e62bd79fffc
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestGenerateException.cpp
> @@ -0,0 +1,54 @@
> +/** @file
> + This is a sample to demonstrates the use of GoogleTest that supports host
> + execution environments for test case that generates an exception. For some
> + host-based environments, this is a fatal condition that terminates the unit
> + tests and no additional test cases are executed. On other environments, this
> + condition may be report a unit test failure and continue with additional unit
> + tests.
> +
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/GoogleTestLib.h>
> +extern "C" {
> + #include <Uefi.h>
> + #include <Library/BaseLib.h>
> + #include <Library/DebugLib.h>
> +}
> +
> +UINTN
> +DivideWithNoParameterChecking (
> + UINTN Dividend,
> + UINTN Divisor
> + )
> +{
> + //
> + // Perform integer division with no check for divide by zero
> + //
> + return (Dividend / Divisor);
> +}
> +
> +/**
> + Sample unit test that generates an unexpected exception
> +**/
> +TEST (ExceptionTest, GenerateExceptionExpectTestFail) {
> + //
> + // Assertion that passes without generating an exception
> + //
> + EXPECT_EQ (DivideWithNoParameterChecking (20, 1), (UINTN)20);
> + //
> + // Assertion that generates divide by zero exception before result evaluated
> + //
> + EXPECT_EQ (DivideWithNoParameterChecking (20, 0), MAX_UINTN);
> +}
> +
> +int
> +main (
> + int argc,
> + char *argv[]
> + )
> +{
> + testing::InitGoogleTest (&argc, argv);
> + return RUN_ALL_TESTS ();
> +}
> diff --git a/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf
> new file mode 100644
> index 000000000000..3ce356c8ce61
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf
> @@ -0,0 +1,39 @@
> +## @file
> +# This is a sample to demonstrates the use of GoogleTest that supports host
> +# execution environments for test case that generates an exception. For some
> +# host-based environments, this is a fatal condition that terminates the unit
> +# tests and no additional test cases are executed. On other environments, this
> +# condition may be report a unit test failure and continue with additional unit
> +# tests.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SampleGoogleTestHostGenerateException
> + FILE_GUID = 037A3C56-44C5-4899-AC4D-911943E6FBA1
> + MODULE_TYPE = HOST_APPLICATION
> + VERSION_STRING = 1.0
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleGoogleTestGenerateException.cpp
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
> +
> +[LibraryClasses]
> + GoogleTestLib
> + BaseLib
> + DebugLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf
> new file mode 100644
> index 000000000000..6757434952ff
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf
> @@ -0,0 +1,41 @@
> +## @file
> +# Sample UnitTest built for execution in DXE.
> +# All test case are always expected to fail to demonstrate the format of the log
> +# file and reports when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestDxeExpectFail
> + FILE_GUID = 7092E907-E817-4D39-877C-64BD0F54C1D4
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestExpectFail.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> +
> +[Depex]
> + TRUE
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestExpectFail.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestExpectFail.c
> new file mode 100644
> index 000000000000..f1f1b596b9b6
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestExpectFail.c
> @@ -0,0 +1,861 @@
> +/** @file
> + This is a sample to demonstrate the usage of the Unit Test Library that
> + supports the PEI, DXE, SMM, UEFI Shell, and host execution environments.
> + All test case are always expected to fail to demonstrate the format of the log
> + file and reports when failures occur.
> +
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <PiPei.h>
> +#include <Uefi.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UnitTestLib.h>
> +#include <Library/PrintLib.h>
> +
> +#define UNIT_TEST_NAME "Sample Unit Test Expect Fail"
> +#define UNIT_TEST_VERSION "0.1"
> +
> +///
> +/// Global variables used in unit tests
> +///
> +BOOLEAN mSampleGlobalTestBoolean = FALSE;
> +VOID *mSampleGlobalTestPointer = NULL;
> +
> +/**
> + Sample Unit-Test Prerequisite Function that checks to make sure the global
> + pointer used in the test is already set to NULL.
> +
> + Functions with this prototype are registered to be dispatched by the unit test
> + framework prior to a given test case. If this prereq function returns
> + UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, the test case will be skipped.
> +
> + @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 Unit test case prerequisites
> + are met.
> + @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped.
> +
> +**/
> +UNIT_TEST_STATUS
> +EFIAPI
> +MakeSureThatPointerIsNull (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + UT_ASSERT_NOT_EQUAL ((UINTN)mSampleGlobalTestPointer, (UINTN)NULL);
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Sample Unit-Test Cleanup (after) function that resets the global pointer to
> + NULL.
> +
> + Functions with this prototype are registered to be dispatched by the
> + unit test framework after a given test case. This will be called even if the
> + test case returns an error, but not if the prerequisite fails and the test is
> + skipped. The purpose of this function is to clean up any global state or
> + test data.
> +
> + @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 Test case cleanup succeeded.
> + @retval UNIT_TEST_ERROR_CLEANUP_FAILED Test case cleanup failed.
> +
> +**/
> +VOID
> +EFIAPI
> +ClearThePointer (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + mSampleGlobalTestPointer = NULL;
> +}
> +
> +/**
> + Sample unit test that verifies the expected result of an unsigned integer
> + addition operation.
> +
> + @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
> +OnePlusOneShouldEqualTwo (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + UINTN A;
> + UINTN B;
> + UINTN C;
> +
> + A = 1;
> + B = 1;
> + C = A + B;
> +
> + UT_ASSERT_NOT_EQUAL (C, 2);
> +
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Sample unit test that verifies that a global BOOLEAN is updatable.
> +
> + @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
> +GlobalBooleanShouldBeChangeable (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + mSampleGlobalTestBoolean = TRUE;
> + UT_ASSERT_FALSE (mSampleGlobalTestBoolean);
> +
> + mSampleGlobalTestBoolean = FALSE;
> + UT_ASSERT_TRUE (mSampleGlobalTestBoolean);
> +
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Sample unit test that logs a warning message and verifies that a global
> + pointer is updatable.
> +
> + @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
> +GlobalPointerShouldBeChangeable (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + //
> + // Example of logging.
> + //
> + UT_LOG_WARNING ("About to change a global pointer! Current value is 0x%X\n", mSampleGlobalTestPointer);
> +
> + mSampleGlobalTestPointer = (VOID *)-1;
> + UT_ASSERT_NOT_EQUAL ((UINTN)mSampleGlobalTestPointer, (UINTN)((VOID *)-1));
> + 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_FALSE (TRUE);
> +
> + //
> + // This test passes because expression always evaluates to TRUE.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + UT_ASSERT_FALSE (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_TRUE (FALSE);
> +
> + //
> + // This test passes because expression always evaluates to FALSE.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + UT_ASSERT_TRUE (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_NOT_EQUAL (1, 1);
> +
> + //
> + // This test passes because both values are always equal.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + UT_ASSERT_NOT_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 = "Hello1";
> + String2 = "Hello2";
> + Length = sizeof ("Hello1");
> + 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_EQUAL (0, 1);
> +
> + //
> + // This test passes because both values are never equal.
> + //
> + Result = LShiftU64 (BIT0, 1);
> + UT_ASSERT_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_INVALID_PARAMETER);
> +
> + //
> + // This test passes because the status is not an EFI error.
> + //
> + UT_ASSERT_NOT_EFI_ERROR (EFI_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_NOT_FOUND);
> +
> + 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
> + )
> +{
> + //
> + // This test passes because the pointer is never NULL.
> + //
> + UT_ASSERT_NOT_NULL (NULL);
> +
> + 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
> + )
> +{
> + //
> + // Skip tests that verify an ASSERT() is triggered if ASSERT()s are disabled.
> + //
> + if ((PcdGet8 (PcdDebugPropertyMask) & BIT0) == 0x00) {
> + UT_ASSERT_TRUE (FALSE);
> + return UNIT_TEST_PASSED;
> + }
> +
> + //
> + // This test passes because it directly triggers an ASSERT().
> + //
> + UT_EXPECT_ASSERT_FAILURE (ASSERT (TRUE), 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 (99), NULL);
> +
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Sample unit test the triggers an unexpected ASSERT()
> +
> + @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
> +GenerateUnexpectedAssert (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + //
> + // Skip tests that verify an ASSERT() is triggered if ASSERT()s are disabled.
> + //
> + if ((PcdGet8 (PcdDebugPropertyMask) & BIT0) == 0x00) {
> + UT_ASSERT_TRUE (FALSE);
> + return UNIT_TEST_PASSED;
> + }
> +
> + //
> + // This test fails because DecimalToBcd() generates an ASSERT() if the
> + // value passed in is >= 100. The unexpected ASSERT() is caught by the unit
> + // test framework and generates a failed test.
> + //
> + DecimalToBcd8 (101);
> +
> + 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");
> +
> + UT_ASSERT_TRUE (FALSE);
> +
> + 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");
> +
> + UT_ASSERT_TRUE (FALSE);
> +
> + 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");
> +
> + UT_ASSERT_TRUE (FALSE);
> +
> + 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");
> +
> + UT_ASSERT_TRUE (FALSE);
> +
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Initialize the unit test framework, suite, and unit tests for the
> + sample unit tests and run the unit tests.
> +
> + @retval EFI_SUCCESS All test cases were dispatched.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
> + initialize the unit tests.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UefiTestMain (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + UNIT_TEST_FRAMEWORK_HANDLE Framework;
> + UNIT_TEST_SUITE_HANDLE SimpleMathTests;
> + UNIT_TEST_SUITE_HANDLE GlobalVarTests;
> + UNIT_TEST_SUITE_HANDLE MacroTestsAssertsEnabled;
> + UNIT_TEST_SUITE_HANDLE MacroTestsAssertsDisabled;
> +
> + Framework = NULL;
> +
> + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
> +
> + //
> + // Start setting up the test framework for running the tests.
> + //
> + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
> + goto EXIT;
> + }
> +
> + //
> + // Populate the SimpleMathTests Unit Test Suite.
> + //
> + Status = CreateUnitTestSuite (&SimpleMathTests, Framework, "Simple Math Tests", "Sample.Math", NULL, NULL);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SimpleMathTests\n"));
> + Status = EFI_OUT_OF_RESOURCES;
> + goto EXIT;
> + }
> +
> + AddTestCase (SimpleMathTests, "Adding 1 to 1 should produce 2", "Addition", OnePlusOneShouldEqualTwo, NULL, NULL, NULL);
> +
> + //
> + // Populate the GlobalVarTests Unit Test Suite.
> + //
> + Status = CreateUnitTestSuite (&GlobalVarTests, Framework, "Global Variable Tests", "Sample.Globals", NULL, NULL);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for GlobalVarTests\n"));
> + Status = EFI_OUT_OF_RESOURCES;
> + goto EXIT;
> + }
> +
> + 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);
> +
> + //
> + // 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 Unexpected ASSERT()", "GenerateUnexpectedAssert", GenerateUnexpectedAssert, 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 Unexpected ASSERT()", "GenerateUnexpectedAssert", GenerateUnexpectedAssert, 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.
> + //
> + Status = RunAllTestSuites (Framework);
> +
> +EXIT:
> + if (Framework) {
> + FreeUnitTestFramework (Framework);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Standard PEIM entry point for target based unit test execution from PEI.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiEntryPoint (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + return UefiTestMain ();
> +}
> +
> +/**
> + Standard UEFI entry point for target based unit test execution from DXE, SMM,
> + UEFI Shell.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + return UefiTestMain ();
> +}
> +
> +/**
> + Standard POSIX C entry point for host based unit test execution.
> +**/
> +int
> +main (
> + int argc,
> + char *argv[]
> + )
> +{
> + return UefiTestMain ();
> +}
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf
> new file mode 100644
> index 000000000000..dcaedbf7e4e8
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf
> @@ -0,0 +1,35 @@
> +## @file
> +# Sample UnitTest built for execution on a Host/Dev machine.
> +# All test case are always expected to fail to demonstrate the format of the log
> +# file and reports when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SampleUnitTestHostExpectFail
> + FILE_GUID = C419E68B-D5C6-4F35-AE99-470946328A1F
> + MODULE_TYPE = HOST_APPLICATION
> + VERSION_STRING = 1.0
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestExpectFail.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + UnitTestLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf
> new file mode 100644
> index 000000000000..763d80e532a2
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf
> @@ -0,0 +1,41 @@
> +## @file
> +# Sample UnitTest built for execution in PEI.
> +# All test case are always expected to fail to demonstrate the format of the log
> +# file and reports when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestPeiExpectFail
> + FILE_GUID = A65EA745-A15E-480A-82E5-6AEED8AE8788
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + ENTRY_POINT = PeiEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestExpectFail.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + PeimEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> +
> +[Depex]
> + gEfiPeiMemoryDiscoveredPpiGuid
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf
> new file mode 100644
> index 000000000000..d4c2f4b70703
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# Sample UnitTest built for execution in SMM.
> +# All test case are always expected to fail to demonstrate the format of the log
> +# file and reports when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestSmmExpectFail
> + FILE_GUID = 031B1FE7-582E-4F43-B50D-5A7E42BCC11C
> + MODULE_TYPE = DXE_SMM_DRIVER
> + VERSION_STRING = 1.0
> + PI_SPECIFICATION_VERSION = 0x0001000A
> + ENTRY_POINT = DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestExpectFail.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> +
> +[Depex]
> + gEfiSmmCpuProtocolGuid
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf
> new file mode 100644
> index 000000000000..324b4ff52e5c
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# Sample UnitTest built for execution in UEFI Shell.
> +# All test case are always expected to fail to demonstrate the format of the log
> +# file and reports when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestUefiShellExpectFail
> + FILE_GUID = 8AF3A9A7-228B-462A-B91A-0591493F8D1F
> + MODULE_TYPE = UEFI_APPLICATION
> + VERSION_STRING = 1.0
> + ENTRY_POINT = DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestExpectFail.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiApplicationEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf
> new file mode 100644
> index 000000000000..b742befe4d4e
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf
> @@ -0,0 +1,43 @@
> +## @file
> +# Sample UnitTest built for execution in DXE.
> +# This test case generates an exception. For some host-based environments, this
> +# is a fatal condition that terminates the unit tests and no additional test
> +# cases are executed. On other environments, this condition may be report a unit
> +# test failure and continue with additional unit tests.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestDxeGenerateException
> + FILE_GUID = 2E8C07AF-FAC7-44F3-9108-7F548D347EE1
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestGenerateException.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> +
> +[Depex]
> + TRUE
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestGenerateException.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestGenerateException.c
> new file mode 100644
> index 000000000000..4576e0c81eb0
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestGenerateException.c
> @@ -0,0 +1,204 @@
> +/** @file
> + This is a sample to demonstrate the usage of the Unit Test Library that
> + supports the PEI, DXE, SMM, UEFI Shell, and host execution environments.
> + This test case generates an exception. For some host-based environments, this
> + is a fatal condition that terminates the unit tests and no additional test
> + cases are executed. On other environments, this condition may be report a unit
> + test failure and continue with additional unit tests.
> +
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <PiPei.h>
> +#include <Uefi.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UnitTestLib.h>
> +#include <Library/PrintLib.h>
> +
> +#define UNIT_TEST_NAME "Sample Unit Test Generate Exception"
> +#define UNIT_TEST_VERSION "0.1"
> +
> +/**
> + 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));
> +}
> +
> +UINTN
> +DivideWithNoParameterChecking (
> + UINTN Dividend,
> + UINTN Divisor
> + )
> +{
> + //
> + // Perform integer division with no check for divide by zero
> + //
> + return (Dividend / Divisor);
> +}
> +
> +/**
> + Sample unit test the triggers an unexpected exception
> +
> + @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
> +GenerateUnexpectedException (
> + IN UNIT_TEST_CONTEXT Context
> + )
> +{
> + //
> + // Assertion that passes without generating an exception
> + //
> + UT_ASSERT_EQUAL (DivideWithNoParameterChecking (20, 1), (UINTN)20);
> + //
> + // Assertion that generates divide by zero exception before result evaluated
> + //
> + UT_ASSERT_EQUAL (DivideWithNoParameterChecking (20, 0), MAX_UINTN);
> +
> + return UNIT_TEST_PASSED;
> +}
> +
> +/**
> + Initialize the unit test framework, suite, and unit tests for the
> + sample unit tests and run the unit tests.
> +
> + @retval EFI_SUCCESS All test cases were dispatched.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
> + initialize the unit tests.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UefiTestMain (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> + UNIT_TEST_FRAMEWORK_HANDLE Framework;
> + UNIT_TEST_SUITE_HANDLE MacroTestsAssertsEnabled;
> + UNIT_TEST_SUITE_HANDLE MacroTestsAssertsDisabled;
> +
> + Framework = NULL;
> +
> + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
> +
> + //
> + // Start setting up the test framework for running the tests.
> + //
> + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
> + goto EXIT;
> + }
> +
> + //
> + // 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 Unexpected Exception", "GenerateUnexpectedException", GenerateUnexpectedException, 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 Unexpected Exception", "GenerateUnexpectedException", GenerateUnexpectedException, NULL, NULL, NULL);
> +
> + //
> + // Execute the tests.
> + //
> + Status = RunAllTestSuites (Framework);
> +
> +EXIT:
> + if (Framework) {
> + FreeUnitTestFramework (Framework);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Standard PEIM entry point for target based unit test execution from PEI.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiEntryPoint (
> + IN EFI_PEI_FILE_HANDLE FileHandle,
> + IN CONST EFI_PEI_SERVICES **PeiServices
> + )
> +{
> + return UefiTestMain ();
> +}
> +
> +/**
> + Standard UEFI entry point for target based unit test execution from DXE, SMM,
> + UEFI Shell.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + return UefiTestMain ();
> +}
> +
> +/**
> + Standard POSIX C entry point for host based unit test execution.
> +**/
> +int
> +main (
> + int argc,
> + char *argv[]
> + )
> +{
> + return UefiTestMain ();
> +}
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf
> new file mode 100644
> index 000000000000..a9f10ff1847e
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf
> @@ -0,0 +1,37 @@
> +## @file
> +# Sample UnitTest built for execution on a Host/Dev machine.
> +# This test case generates an exception. For some host-based environments, this
> +# is a fatal condition that terminates the unit tests and no additional test
> +# cases are executed. On other environments, this condition may be report a unit
> +# test failure and continue with additional unit tests.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = SampleUnitTestHostGenerateException
> + FILE_GUID = 842C65F7-E31A-4E67-85B2-72F2958636DF
> + MODULE_TYPE = HOST_APPLICATION
> + VERSION_STRING = 1.0
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestGenerateException.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + UnitTestLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf
> new file mode 100644
> index 000000000000..cb2696156853
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf
> @@ -0,0 +1,43 @@
> +## @file
> +# Sample UnitTest built for execution in PEI.
> +# This test case generates an exception. For some host-based environments, this
> +# is a fatal condition that terminates the unit tests and no additional test
> +# cases are executed. On other environments, this condition may be report a unit
> +# test failure and continue with additional unit tests.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestPeiGenerateException
> + FILE_GUID = F66B54D6-0EB0-410E-A5A5-C76A739C5F5D
> + MODULE_TYPE = PEIM
> + VERSION_STRING = 1.0
> + ENTRY_POINT = PeiEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestGenerateException.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + PeimEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> +
> +[Depex]
> + gEfiPeiMemoryDiscoveredPpiGuid
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf
> new file mode 100644
> index 000000000000..5aee6a52bdce
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf
> @@ -0,0 +1,44 @@
> +## @file
> +# Sample UnitTest built for execution in SMM.
> +# This test case generates an exception. For some host-based environments, this
> +# is a fatal condition that terminates the unit tests and no additional test
> +# cases are executed. On other environments, this condition may be report a unit
> +# test failure and continue with additional unit tests.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestSmmGenerateException
> + FILE_GUID = C28BCCD6-3B42-4896-9931-62CCC5DF91B8
> + MODULE_TYPE = DXE_SMM_DRIVER
> + VERSION_STRING = 1.0
> + PI_SPECIFICATION_VERSION = 0x0001000A
> + ENTRY_POINT = DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestGenerateException.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> +
> +[Depex]
> + gEfiSmmCpuProtocolGuid
> diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf
> new file mode 100644
> index 000000000000..32d6f4270a4b
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Sample UnitTest built for execution in UEFI Shell.
> +# This test case generates an exception. For some host-based environments, this
> +# is a fatal condition that terminates the unit tests and no additional test
> +# cases are executed. On other environments, this condition may be report a unit
> +# test failure and continue with additional unit tests.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010006
> + BASE_NAME = SampleUnitTestUefiShellGenerateException
> + FILE_GUID = E854F900-6B7A-448D-8689-736EB96875BF
> + MODULE_TYPE = UEFI_APPLICATION
> + VERSION_STRING = 1.0
> + ENTRY_POINT = DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + SampleUnitTestGenerateException.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiApplicationEntryPoint
> + BaseLib
> + DebugLib
> + UnitTestLib
> + PrintLib
> +
> +[Pcd]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
> diff --git a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc
> new file mode 100644
> index 000000000000..d89659882dd7
> --- /dev/null
> +++ b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc
> @@ -0,0 +1,44 @@
> +## @file
> +# UnitTestFrameworkPkg DSC file used to build host-based unit tests that archive
> +# always expected to fail to demonstrate the format of the log file and reports
> +# when failures occur.
> +#
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + PLATFORM_NAME = UnitTestFrameworkPkgHostTest
> + PLATFORM_GUID = C7F97D6D-54AC-45A9-8197-CC99B20CC7EC
> + PLATFORM_VERSION = 0.1
> + DSC_SPECIFICATION = 0x00010005
> + OUTPUT_DIRECTORY = Build/UnitTestFrameworkPkg/HostTestExpectFail
> + SUPPORTED_ARCHITECTURES = IA32|X64
> + BUILD_TARGETS = NOOPT
> + SKUID_IDENTIFIER = DEFAULT
> +
> +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
> +
> +[PcdsPatchableInModule]
> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> +
> +[Components]
> + #
> + # Build HOST_APPLICATIONs that test the SampleUnitTest
> + #
> + UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf
> +
> + #
> + # Disable warning for divide by zero to pass build of unit tests
> + # that generate a divide by zero exception.
> + #
> + UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf {
> + <BuildOptions>
> + MSFT:*_*_*_CC_FLAGS = /wd4723
> + }
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf {
> + <BuildOptions>
> + MSFT:*_*_*_CC_FLAGS = /wd4723
> + }
> diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml
> index b61a6a0b0717..c6a412c96078 100644
> --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml
> +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml
> @@ -62,7 +62,12 @@
> },
> ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
> "HostUnitTestDscCompleteCheck": {
> - "IgnoreInf": [],
> + "IgnoreInf": [
> + "UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf",
> + "UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf",
> + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf",
> + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf"
> + ],
> "DscPath": "Test/UnitTestFrameworkPkgHostTest.dsc"
> },
> ## options defined .pytool/Plugin/GuidCheck
> @@ -110,5 +115,14 @@
> ],
> "IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
> "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
> + },
> +
> + # options defined in .pytool/Plugin/UncrustifyCheck
> + "UncrustifyCheck": {
> + "IgnoreFiles": [
> + "Library/CmockaLib/cmocka/**",
> + "Library/GoogleTestLib/googletest/**",
> + "Library/SubhookLib/subhook/**"
> + ]
> }
> }
> diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc
> index 872d9c0d8c69..75be90a55f7e 100644
> --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc
> +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc
> @@ -41,3 +41,29 @@ [Components]
> UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf
> UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf
> UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf
> +
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf
> +
> + #
> + # Disable warning for divide by zero to pass build of unit tests
> + # that generate a divide by zero exception.
> + #
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf {
> + <BuildOptions>
> + MSFT:*_*_*_CC_FLAGS = /wd4723
> + }
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf {
> + <BuildOptions>
> + MSFT:*_*_*_CC_FLAGS = /wd4723
> + }
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf {
> + <BuildOptions>
> + MSFT:*_*_*_CC_FLAGS = /wd4723
> + }
> + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf {
> + <BuildOptions>
> + MSFT:*_*_*_CC_FLAGS = /wd4723
> + }
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115359): https://edk2.groups.io/g/devel/message/115359
Mute This Topic: https://groups.io/mt/104267262/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
prev parent reply other threads:[~2024-02-12 16:26 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-09 20:32 [edk2-devel] [edk2-stable202402][Patch V3 0/7] EDK II CI misses UnitTestFrameworkPkg failures Michael D Kinney
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 1/7] MdePkg/Include: Rename _DEBUG() to address name collision Michael D Kinney
2024-02-13 11:57 ` Leif Lindholm
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 2/7] UnitTestFrameworkPkg: MSFT CC_FLAGS add /MT to for host builds Michael D Kinney
2024-02-10 2:26 ` Michael Kubacki
2024-02-10 4:03 ` Michael D Kinney
2024-02-12 16:25 ` Michael Kubacki
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 3/7] UnitTestFrameworkPkg: Expand host-based exception handling and gcov Michael D Kinney
2024-02-12 16:25 ` Michael Kubacki
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 4/7] UnitTestFrameworkPkg/UnitTestLib: GetActiveFrameworkHandle() no ASSERT() Michael D Kinney
2024-02-12 16:25 ` Michael Kubacki
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 5/7] UnitTestFrameworkPkg/UnitTestDebugAssertLib: Add GoogleTest support Michael D Kinney
2024-02-12 16:25 ` Michael Kubacki
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 6/7] UnitTestFrameworkPkg/SampleGoogleTest: Use EXPECT_ANY_THROW() Michael D Kinney
2024-02-12 16:25 ` Michael Kubacki
2024-02-09 20:32 ` [edk2-devel] [edk2-stable202402][Patch V3 7/7] UnitTestFrameworkPkg: Add DSC and host tests that always fail Michael D Kinney
2024-02-12 16:26 ` Michael Kubacki [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4340de56-0b6c-43b3-a0ac-0897aa623954@linux.microsoft.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox