public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@microsoft.com>,
	Bret Barkelew <Bret.Barkelew@microsoft.com>,
	Jiewen Yao <jiewen.yao@intel.com>
Subject: [Patch v2 12/16] UnitTestFrameworkPkg/UnitTestLib: Add checks for ASSERT()
Date: Wed,  8 Jul 2020 21:05:17 -0700	[thread overview]
Message-ID: <20200709040521.3748-13-michael.d.kinney@intel.com> (raw)
In-Reply-To: <20200709040521.3748-1-michael.d.kinney@intel.com>

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

Add UnitTestDebugAssertLib that provides the UnitTestDebugAssert()
service and the gUnitTestExpectAssertFailureJumpBuffer global
variable.  This NULL library is linked against all host and target
unit test builds.  This guarantees that the UnitTestDebugAssert()
service is available to link against all libraries and modules that
use the DebugLib class.

EDKII_UNIT_TEST_FRAMEWORK_ENABLED must always be defined when
building unit tests so the behavior of the DebugLib ASSERT()
macros can be adjusted to allow the unit test framework to
catch an ASSERT() if it is triggered by a function under test.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../UnitTestDebugAssertLib.c                  |  49 +++++
 .../UnitTestDebugAssertLib.inf                |  31 +++
 .../UnitTestDebugAssertLib.uni                |  11 +
 .../Library/UnitTestLib/Assert.c              | 203 ++++++++++++------
 .../Library/UnitTestLib/AssertCmocka.c        |  68 ++++++
 .../Library/UnitTestLib/RunTests.c            |  23 +-
 .../UnitTestResultReportLib.c                 |   3 +-
 .../PrivateInclude/UnitTestFrameworkTypes.h   |   1 +
 .../Test/UnitTestFrameworkPkgHostTest.dsc     |   2 +-
 UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc |   1 +
 .../UnitTestFrameworkPkgTarget.dsc.inc        |   6 +-
 11 files changed, 328 insertions(+), 70 deletions(-)
 create mode 100644 UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c
 create mode 100644 UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
 create mode 100644 UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni

diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c
new file mode 100644
index 0000000000..0a4001e182
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c
@@ -0,0 +1,49 @@
+/** @file
+  Unit Test Debug Assert Library
+
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UnitTestLib.h>
+
+///
+/// Point to jump buffer used with SetJump()/LongJump() to test if a function
+/// under test generates an expected ASSERT() condition.
+///
+BASE_LIBRARY_JUMP_BUFFER  *gUnitTestExpectAssertFailureJumpBuffer = NULL;
+
+/**
+  Unit test library replacement for DebugAssert() in DebugLib.
+
+  If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+  If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+  @param  FileName     The pointer to the name of the source file that generated the assert condition.
+  @param  LineNumber   The line number in the source file that generated the assert condition
+  @param  Description  The pointer to the description of the assert condition.
+
+**/
+VOID
+EFIAPI
+UnitTestDebugAssert (
+  IN CONST CHAR8  *FileName,
+  IN UINTN        LineNumber,
+  IN CONST CHAR8  *Description
+  )
+{
+  CHAR8  Message[256];
+
+  if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
+    UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
+    LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
+  } else {
+    AsciiStrCpyS (Message, sizeof(Message), "Detected unexpected ASSERT(");
+    AsciiStrCatS (Message, sizeof(Message), Description);
+    AsciiStrCatS (Message, sizeof(Message), ")");
+    UnitTestAssertTrue (FALSE, "", LineNumber, FileName, Message);
+  }
+}
diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
new file mode 100644
index 0000000000..e6ccab0dd9
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
@@ -0,0 +1,31 @@
+## @file
+#  Unit Test Debug Assert Library
+#
+#  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UnitTestDebugAssertLib
+  MODULE_UNI_FILE                = UnitTestDebugAssertLib.uni
+  FILE_GUID                      = 9D53AD0D-5416-451F-A5BF-E5420051A99B
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+
+#
+#  VALID_ARCHITECTURES           = ARM AARCH64
+#
+
+[Sources]
+  UnitTestDebugAssertLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UnitTestLib
diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni
new file mode 100644
index 0000000000..9b794aa205
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni
@@ -0,0 +1,11 @@
+// /** @file
+// Unit Test Debug Assert Library
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "Unit Test Debug Assert Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Unit Test Debug Assert Library"
diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c b/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c
index 8a131fab2b..3669d63701 100644
--- a/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c
+++ b/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c
@@ -13,6 +13,8 @@
 #include <Library/DebugLib.h>
 #include <Library/PrintLib.h>
 
+extern BASE_LIBRARY_JUMP_BUFFER  gUnitTestJumpBuffer;
+
 STATIC
 EFI_STATUS
 AddUnitTestFailure (
@@ -71,7 +73,7 @@ UnitTestLogFailure (
     FailureType
     );
 
-  return;
+  LongJump (&gUnitTestJumpBuffer, 1);
 }
 
 /**
@@ -103,6 +105,12 @@ UnitTestAssertTrue (
   )
 {
   if (!Expression) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Expression (%a) is not TRUE!\n",
+      FileName,
+      LineNumber,
+      Description
+      );
     UnitTestLogFailure (
       FAILURETYPE_ASSERTTRUE,
       "%a:%d: Expression (%a) is not TRUE!\n",
@@ -110,12 +118,6 @@ UnitTestAssertTrue (
       LineNumber,
       Description
       );
-    UT_LOG_ERROR (
-      "[ASSERT FAIL] %a:%d: Expression (%a) is not TRUE!\n",
-      FileName,
-      LineNumber,
-      Description
-      );
   }
   return Expression;
 }
@@ -149,6 +151,12 @@ UnitTestAssertFalse (
   )
 {
   if (Expression) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Expression (%a) is not FALSE!\n",
+      FileName,
+      LineNumber,
+      Description
+      );
     UnitTestLogFailure (
       FAILURETYPE_ASSERTFALSE,
       "%a:%d: Expression(%a) is not FALSE!\n",
@@ -156,12 +164,6 @@ UnitTestAssertFalse (
       LineNumber,
       Description
       );
-    UT_LOG_ERROR (
-      "[ASSERT FAIL] %a:%d: Expression (%a) is not FALSE!\n",
-      FileName,
-      LineNumber,
-      Description
-      );
   }
   return !Expression;
 }
@@ -195,6 +197,13 @@ UnitTestAssertNotEfiError (
   )
 {
   if (EFI_ERROR (Status)) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Status '%a' is EFI_ERROR (%r)!\n",
+      FileName,
+      LineNumber,
+      Description,
+      Status
+      );
     UnitTestLogFailure (
       FAILURETYPE_ASSERTNOTEFIERROR,
       "%a:%d: Status '%a' is EFI_ERROR (%r)!\n",
@@ -203,13 +212,6 @@ UnitTestAssertNotEfiError (
       Description,
       Status
       );
-    UT_LOG_ERROR (
-      "[ASSERT FAIL] %a:%d: Status '%a' is EFI_ERROR (%r)!\n",
-      FileName,
-      LineNumber,
-      Description,
-      Status
-      );
   }
   return !EFI_ERROR( Status );
 }
@@ -248,16 +250,6 @@ UnitTestAssertEqual (
   )
 {
   if (ValueA != ValueB) {
-    UnitTestLogFailure (
-      FAILURETYPE_ASSERTEQUAL,
-      "%a:%d: Value %a != %a (%d != %d)!\n",
-      FileName,
-      LineNumber,
-      DescriptionA,
-      DescriptionB,
-      ValueA,
-      ValueB
-      );
     UT_LOG_ERROR (
       "[ASSERT FAIL] %a:%d: Value %a != %a (%d != %d)!\n",
       FileName,
@@ -267,6 +259,16 @@ UnitTestAssertEqual (
       ValueA,
       ValueB
       );
+    UnitTestLogFailure (
+      FAILURETYPE_ASSERTEQUAL,
+      "%a:%d: Value %a != %a (%d != %d)!\n",
+      FileName,
+      LineNumber,
+      DescriptionA,
+      DescriptionB,
+      ValueA,
+      ValueB
+      );
   }
   return (ValueA == ValueB);
 }
@@ -310,15 +312,6 @@ UnitTestAssertMemEqual (
   )
 {
   if (CompareMem(BufferA, BufferB, Length) != 0) {
-    UnitTestLogFailure (
-      FAILURETYPE_ASSERTEQUAL,
-      "%a:%d: Memory at %a != %a for length %d bytes!\n",
-      FileName,
-      LineNumber,
-      DescriptionA,
-      DescriptionB,
-      Length
-      );
     UT_LOG_ERROR (
       "[ASSERT FAIL] %a:%d: Value %a != %a for length %d bytes!\n",
       FileName,
@@ -327,6 +320,15 @@ UnitTestAssertMemEqual (
       DescriptionB,
       Length
       );
+    UnitTestLogFailure (
+      FAILURETYPE_ASSERTEQUAL,
+      "%a:%d: Memory at %a != %a for length %d bytes!\n",
+      FileName,
+      LineNumber,
+      DescriptionA,
+      DescriptionB,
+      Length
+      );
     return FALSE;
   }
   return TRUE;
@@ -366,6 +368,15 @@ UnitTestAssertNotEqual (
   )
 {
   if (ValueA == ValueB) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Value %a == %a (%d == %d)!\n",
+      FileName,
+      LineNumber,
+      DescriptionA,
+      DescriptionB,
+      ValueA,
+      ValueB
+      );
     UnitTestLogFailure (
       FAILURETYPE_ASSERTNOTEQUAL,
       "%a:%d: Value %a == %a (%d == %d)!\n",
@@ -376,15 +387,6 @@ UnitTestAssertNotEqual (
       ValueA,
       ValueB
       );
-    UT_LOG_ERROR (
-      "[ASSERT FAIL] %a:%d: Value %a == %a (%d == %d)!\n",
-      FileName,
-      LineNumber,
-      DescriptionA,
-      DescriptionB,
-      ValueA,
-      ValueB
-      );
   }
   return (ValueA != ValueB);
 }
@@ -421,6 +423,14 @@ UnitTestAssertStatusEqual (
   )
 {
   if (Status != Expected) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Status '%a' is %r, should be %r!\n",
+      FileName,
+      LineNumber,
+      Description,
+      Status,
+      Expected
+      );
     UnitTestLogFailure (
       FAILURETYPE_ASSERTSTATUSEQUAL,
       "%a:%d: Status '%a' is %r, should be %r!\n",
@@ -430,14 +440,6 @@ UnitTestAssertStatusEqual (
       Status,
       Expected
       );
-    UT_LOG_ERROR (
-      "[ASSERT FAIL] %a:%d: Status '%a' is %r, should be %r!\n",
-      FileName,
-      LineNumber,
-      Description,
-      Status,
-      Expected
-      );
   }
   return (Status == Expected);
 }
@@ -473,6 +475,12 @@ UnitTestAssertNotNull (
   )
 {
   if (Pointer == NULL) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Pointer (%a) is NULL!\n",
+      FileName,
+      LineNumber,
+      PointerName
+      );
     UnitTestLogFailure (
       FAILURETYPE_ASSERTNOTNULL,
       "%a:%d: Pointer (%a) is NULL!\n",
@@ -480,12 +488,83 @@ UnitTestAssertNotNull (
       LineNumber,
       PointerName
       );
-    UT_LOG_ERROR (
-      "[ASSERT FAIL] %a:%d: Pointer (%a) is NULL!\n",
-      FileName,
-      LineNumber,
-      PointerName
-      );
   }
   return (Pointer != NULL);
 }
+
+/**
+  If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return
+  TRUE because an ASSERT() was expected when FunctionCall was executed and an
+  ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a
+  warning message and return TRUE because ASSERT() macros are disabled.  If
+  UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and
+  return FALSE because an ASSERT() was expected when FunctionCall was executed,
+  but no ASSERT() conditions were triggered.  The log messages contain
+  FunctionName, LineNumber, and FileName strings to provide the location of the
+  UT_EXPECT_ASSERT_FAILURE() macro.
+
+  @param[in]  UnitTestStatus  The status from UT_EXPECT_ASSERT_FAILURE() that
+                              is either pass, skipped, or failed.
+  @param[in]  FunctionName    Null-terminated ASCII string of the function
+                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[in]  LineNumber      The source file line number of the the function
+                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[in]  FileName        Null-terminated ASCII string of the filename
+                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[in]  FunctionCall    Null-terminated ASCII string of the function call
+                              executed by the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[out] ResultStatus    Used to return the UnitTestStatus value to the
+                              caller of UT_EXPECT_ASSERT_FAILURE().  This is
+                              optional parameter that may be NULL.
+
+  @retval  TRUE   UnitTestStatus is UNIT_TEST_PASSED.
+  @retval  TRUE   UnitTestStatus is UNIT_TEST_SKIPPED.
+  @retval  FALSE  UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED.
+**/
+BOOLEAN
+EFIAPI
+UnitTestExpectAssertFailure (
+  IN  UNIT_TEST_STATUS  UnitTestStatus,
+  IN  CONST CHAR8       *FunctionName,
+  IN  UINTN             LineNumber,
+  IN  CONST CHAR8       *FileName,
+  IN  CONST CHAR8       *FunctionCall,
+  OUT UNIT_TEST_STATUS  *ResultStatus  OPTIONAL
+  )
+{
+  if (ResultStatus != NULL) {
+    *ResultStatus = UnitTestStatus;
+  }
+  if (UnitTestStatus == UNIT_TEST_PASSED) {
+    UT_LOG_INFO (
+      "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n",
+      FileName,
+      LineNumber,
+      FunctionCall
+      );
+  }
+  if (UnitTestStatus == UNIT_TEST_SKIPPED) {
+    UT_LOG_WARNING (
+      "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n",
+      FileName,
+      LineNumber,
+      FunctionCall
+      );
+  }
+  if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {
+    UT_LOG_ERROR (
+      "[ASSERT FAIL] %a:%d: Function call (%a) did not ASSERT()!\n",
+      FileName,
+      LineNumber,
+      FunctionCall
+      );
+    UnitTestLogFailure (
+      FAILURETYPE_EXPECTASSERT,
+      "%a:%d: Function call (%a) did not ASSERT()!\n",
+      FileName,
+      LineNumber,
+      FunctionCall
+      );
+  }
+  return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED);
+}
diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c b/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c
index e48d614976..687c6243ab 100644
--- a/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c
+++ b/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c
@@ -333,3 +333,71 @@ UnitTestAssertNotNull (
 
   return (Pointer != NULL);
 }
+
+/**
+  If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return
+  TRUE because an ASSERT() was expected when FunctionCall was executed and an
+  ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a
+  warning message and return TRUE because ASSERT() macros are disabled.  If
+  UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and
+  return FALSE because an ASSERT() was expected when FunctionCall was executed,
+  but no ASSERT() conditions were triggered.  The log messages contain
+  FunctionName, LineNumber, and FileName strings to provide the location of the
+  UT_EXPECT_ASSERT_FAILURE() macro.
+
+  @param[in]  UnitTestStatus  The status from UT_EXPECT_ASSERT_FAILURE() that
+                              is either pass, skipped, or failed.
+  @param[in]  FunctionName    Null-terminated ASCII string of the function
+                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[in]  LineNumber      The source file line number of the the function
+                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[in]  FileName        Null-terminated ASCII string of the filename
+                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[in]  FunctionCall    Null-terminated ASCII string of the function call
+                              executed by the UT_EXPECT_ASSERT_FAILURE() macro.
+  @param[out] ResultStatus    Used to return the UnitTestStatus value to the
+                              caller of UT_EXPECT_ASSERT_FAILURE().  This is
+                              optional parameter that may be NULL.
+
+  @retval  TRUE   UnitTestStatus is UNIT_TEST_PASSED.
+  @retval  TRUE   UnitTestStatus is UNIT_TEST_SKIPPED.
+  @retval  FALSE  UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED.
+**/
+BOOLEAN
+EFIAPI
+UnitTestExpectAssertFailure (
+  IN  UNIT_TEST_STATUS  UnitTestStatus,
+  IN  CONST CHAR8       *FunctionName,
+  IN  UINTN             LineNumber,
+  IN  CONST CHAR8       *FileName,
+  IN  CONST CHAR8       *FunctionCall,
+  OUT UNIT_TEST_STATUS  *ResultStatus  OPTIONAL
+  )
+{
+  CHAR8  TempStr[MAX_STRING_SIZE];
+
+  if (ResultStatus != NULL) {
+    *ResultStatus = UnitTestStatus;
+  }
+  if (UnitTestStatus == UNIT_TEST_PASSED) {
+    UT_LOG_INFO (
+      "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n",
+      FileName,
+      LineNumber,
+      FunctionCall
+      );
+  }
+  if (UnitTestStatus == UNIT_TEST_SKIPPED) {
+    UT_LOG_WARNING (
+      "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n",
+      FileName,
+      LineNumber,
+      FunctionCall
+      );
+  }
+  if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {
+    snprintf (TempStr, sizeof(TempStr), "UT_EXPECT_ASSERT_FAILURE(%s) did not trigger ASSERT()", FunctionCall);
+    _assert_true (FALSE, TempStr, FileName, (INT32)LineNumber);
+  }
+  return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED);
+}
diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c
index 793335fd0f..2dc1d159d5 100644
--- a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c
+++ b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c
@@ -14,6 +14,8 @@
 
 STATIC UNIT_TEST_FRAMEWORK_HANDLE  mFrameworkHandle = NULL;
 
+BASE_LIBRARY_JUMP_BUFFER  gUnitTestJumpBuffer;
+
 UNIT_TEST_FRAMEWORK_HANDLE
 GetActiveFrameworkHandle (
   VOID
@@ -75,7 +77,14 @@ RunTestSuite (
     // Next, if we're still running, make sure that our test prerequisites are in place.
     if (Test->Result == UNIT_TEST_PENDING && Test->Prerequisite != NULL) {
       DEBUG ((DEBUG_VERBOSE, "PREREQ\n"));
-      if (Test->Prerequisite (Test->Context) != UNIT_TEST_PASSED) {
+      if (SetJump (&gUnitTestJumpBuffer) == 0) {
+        if (Test->Prerequisite (Test->Context) != UNIT_TEST_PASSED) {
+          DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n"));
+          Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
+          ParentFramework->CurrentTest  = NULL;
+          continue;
+        }
+      } else {
         DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n"));
         Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
         ParentFramework->CurrentTest  = NULL;
@@ -88,14 +97,20 @@ RunTestSuite (
     // We set the status to UNIT_TEST_RUNNING in case the test needs to reboot
     // or quit. The UNIT_TEST_RUNNING state will allow the test to resume
     // but will prevent the Prerequisite from being dispatched a second time.
-    Test->Result = UNIT_TEST_RUNNING;
-    Test->Result = Test->RunTest (Test->Context);
+    if (SetJump (&gUnitTestJumpBuffer) == 0) {
+      Test->Result = UNIT_TEST_RUNNING;
+      Test->Result = Test->RunTest (Test->Context);
+    } else {
+      Test->Result = UNIT_TEST_ERROR_TEST_FAILED;
+    }
 
     //
     // Finally, clean everything up, if need be.
     if (Test->CleanUp != NULL) {
       DEBUG ((DEBUG_VERBOSE, "CLEANUP\n"));
-      Test->CleanUp (Test->Context);
+      if (SetJump (&gUnitTestJumpBuffer) == 0) {
+        Test->CleanUp (Test->Context);
+      }
     }
 
     //
diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c
index eba68e330c..66c9db457d 100644
--- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c
+++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c
@@ -49,7 +49,8 @@ struct _UNIT_TEST_FAILURE_TYPE_STRING mFailureTypeStrings[] = {
   { FAILURETYPE_ASSERTNOTEQUAL,    "ASSERT_NOTEQUAL FAILURE"},
   { FAILURETYPE_ASSERTNOTEFIERROR, "ASSERT_NOTEFIERROR FAILURE"},
   { FAILURETYPE_ASSERTSTATUSEQUAL, "ASSERT_STATUSEQUAL FAILURE"},
-  { FAILURETYPE_ASSERTNOTNULL ,    "ASSERT_NOTNULL FAILURE"},
+  { FAILURETYPE_ASSERTNOTNULL,     "ASSERT_NOTNULL FAILURE"},
+  { FAILURETYPE_EXPECTASSERT,      "EXPECT_ASSERT FAILURE"},
   { 0,                             "*UNKNOWN* Failure"}
 };
 
diff --git a/UnitTestFrameworkPkg/PrivateInclude/UnitTestFrameworkTypes.h b/UnitTestFrameworkPkg/PrivateInclude/UnitTestFrameworkTypes.h
index e58b30093e..b0e2f61bbf 100644
--- a/UnitTestFrameworkPkg/PrivateInclude/UnitTestFrameworkTypes.h
+++ b/UnitTestFrameworkPkg/PrivateInclude/UnitTestFrameworkTypes.h
@@ -44,6 +44,7 @@ typedef UINT32 FAILURE_TYPE;
 #define FAILURETYPE_ASSERTNOTEFIERROR    (6)
 #define FAILURETYPE_ASSERTSTATUSEQUAL    (7)
 #define FAILURETYPE_ASSERTNOTNULL        (8)
+#define FAILURETYPE_EXPECTASSERT         (9)
 
 ///
 /// Unit Test context structure tracked by the unit test framework.
diff --git a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
index 701e7299d7..70affddead 100644
--- a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
+++ b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
@@ -25,7 +25,7 @@ [Components]
   UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestHost.inf
 
   #
-  # Build Libraries
+  # Build HOST_APPLICATION Libraries
   #
   UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
   UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc
index 2d84691bf1..0dfd98f2a8 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc
@@ -28,6 +28,7 @@ [Components]
   UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf
   UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.inf
   UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.inf
+  UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
 
   UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf
   UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
index 0881278ab0..8adf690098 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
@@ -29,6 +29,7 @@ [LibraryClasses]
   UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf
   UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
   UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
+  NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
 
 [LibraryClasses.ARM, LibraryClasses.AARCH64]
   #
@@ -56,5 +57,6 @@ [PcdsFixedAtBuild]
   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
 
 [BuildOptions]
-  MSFT:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
-  GCC:*_*_*_CC_FLAGS  = -D DISABLE_NEW_DEPRECATED_INTERFACES
+  MSFT:*_*_*_CC_FLAGS  = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
+  GCC:*_*_*_CC_FLAGS   = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
+  XCODE:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
-- 
2.21.0.windows.1


  parent reply	other threads:[~2020-07-09  4:05 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-09  4:05 [Patch v2 00/16] UnitTestFrameworkPkg: Enhancements and bug fixes Michael D Kinney
2020-07-09  4:05 ` [Patch v2 01/16] BaseTools/Python: Allow HOST_APPLICATION to use NULL libraries Michael D Kinney
2020-07-09 11:44   ` Bob Feng
2020-07-09 23:50   ` [edk2-devel] " Sean
2020-07-09  4:05 ` [Patch v2 02/16] MdePkg/BaseCpuLibNull: Add Null version of CpuLib for host testing Michael D Kinney
2020-07-09 23:51   ` [edk2-devel] " Sean
2020-07-09  4:05 ` [Patch v2 03/16] MdePkg/BaseCacheMaintenanceLibNull: Add Null instance " Michael D Kinney
2020-07-09  4:05 ` [Patch v2 04/16] MdePkg/BaseLib: Break out IA32/X64 GCC inline privileged functions Michael D Kinney
2020-07-09  4:05 ` [Patch v2 05/16] MdePkg/Library/BaseLib: Add BaseLib instance for host based unit tests Michael D Kinney
2020-07-09 14:13   ` Liming Gao
2020-07-09 17:05     ` Michael D Kinney
2020-07-10  7:54       ` Liming Gao
2020-07-10 16:38         ` Michael D Kinney
2020-07-09  4:05 ` [Patch v2 06/16] UnitTestFrameworkPkg: Use host libraries from MdePkg Michael D Kinney
2020-07-09  4:05 ` [Patch v2 07/16] UnitTestFrameworkPkg: Enable source level debug for host tests Michael D Kinney
2020-07-09  4:05 ` [Patch v2 08/16] UnitTestFrameworkPkg: Set host application stack size to 256KB Michael D Kinney
2020-07-09  4:05 ` [Patch v2 09/16] UnitTestFrameworkPkg: Change target mode DebugLib mapping Michael D Kinney
2020-07-09  4:05 ` [Patch v2 10/16] UnitTestFrameworkPkg/UnitTestLib: Move print log into cleanup Michael D Kinney
2020-07-09  4:05 ` [Patch v2 11/16] UnitTestFrameworkPkg/UnitTestLib: Fix target mode log messages Michael D Kinney
2020-07-09  4:05 ` Michael D Kinney [this message]
2020-07-09  4:05 ` [Patch v2 13/16] MdePkg/Include: Hook DebugLib _ASSERT() for unit tests Michael D Kinney
2020-07-09  4:05 ` [Patch v2 14/16] MdePkg/Include: Add UT_EXPECT_ASSERT_FAILURE() to UnitTestLib Michael D Kinney
2020-07-09  4:05 ` [Patch v2 15/16] MdePkg/Library/BaseStackCheckLib: Fix PCD type in INF Michael D Kinney
2020-07-09 12:45   ` Liming Gao
2020-07-09  4:05 ` [Patch v2 16/16] UnitTestFramewokPkg/SampleUnitTest: Use UT_EXPECT_ASSERT_FAILURE() Michael D Kinney

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=20200709040521.3748-13-michael.d.kinney@intel.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