From nobody Tue Nov 26 02:18:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+62289+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+62289+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1594267542; cv=none; d=zohomail.com; s=zohoarc; b=gACvC7EAPHUJFqdWr+EWj2BDvlEYRiri2X2mrsbPeTksH7NSnH5JJQy8K1EHkfmLuJlsBgFW3b6XvcRR90fy7KTTBNg1yEb2z86r7weAB9nj7/Kekni7N9DNMmS1W6O2LdufORDMOZu3Igg8h3vsiZ7s+1qs2ZZFUgHAfTGtOZY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1594267542; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=9USO/bIWOWuHso0uuaTDmJ1FCvRizKpczuDFPcS4zUg=; b=JfjGj9/s9X3VtG+F7GCF7KOyHPB5N9Abc260kk7mrfNHjLTj8ZFLY5dmoCYBveFcbaV4WMu3w4uaZR7DF2DiQX81n9WCU+dejNS3HD1eKTy2wsrC/t+sVd0lGmx/bLkt3sOkbFGTM6iijLX5qEYQSGqq7bkoQ2DaLPicr9xNuDI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+62289+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1594267542735136.94817948571279; Wed, 8 Jul 2020 21:05:42 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id LE7XYY1788612xC68dpnocLX; Wed, 08 Jul 2020 21:05:42 -0700 X-Received: from mga07.intel.com (mga07.intel.com []) by mx.groups.io with SMTP id smtpd.web11.4378.1594267536731145998 for ; Wed, 08 Jul 2020 21:05:40 -0700 IronPort-SDR: psN1FvqX/6Gk/SJ8YOXDVLGX2bX2scNfbkSU4KGxheGxVbOBvJ/CvpR4FPOZ1TOjvWlgjKwimt sLck5YJUPq8w== X-IronPort-AV: E=McAfee;i="6000,8403,9676"; a="212851117" X-IronPort-AV: E=Sophos;i="5.75,330,1589266800"; d="scan'208";a="212851117" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jul 2020 21:05:40 -0700 IronPort-SDR: beEp7QyAt4cDS6KiqlQ4cuBKAknb+ta9NMRsNBLyl4PWHbei/PhaHX/nbDd+FxK62SKZ/XxeKa OIxuLB/uKTTQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,330,1589266800"; d="scan'208";a="280163954" X-Received: from mdkinney-mobl2.amr.corp.intel.com ([10.255.230.8]) by orsmga003.jf.intel.com with ESMTP; 08 Jul 2020 21:05:40 -0700 From: "Michael D Kinney" To: devel@edk2.groups.io Cc: Sean Brogan , Bret Barkelew , Jiewen Yao Subject: [edk2-devel] [Patch v2 12/16] UnitTestFrameworkPkg/UnitTestLib: Add checks for ASSERT() Date: Wed, 8 Jul 2020 21:05:17 -0700 Message-Id: <20200709040521.3748-13-michael.d.kinney@intel.com> In-Reply-To: <20200709040521.3748-1-michael.d.kinney@intel.com> References: <20200709040521.3748-1-michael.d.kinney@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,michael.d.kinney@intel.com X-Gm-Message-State: jJO9LWynSzI44SD5QnnDVS3xx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1594267542; bh=Y9jTbSWDeTU5TR5aYWG5cVwrlBNWX/qZ40YgQV17kDM=; h=Cc:Date:From:Reply-To:Subject:To; b=h0uiLFLrZkvg9HdMuWqnwUuy77WZZss5e4VIQ43JJyCQQBfIz9pBglMAJKmRKgpgxOJ yXNXUNBNJrBleB8/ne/Y3cQZA4kPGMWdmg/uVnCqtHw6rPCDz4Xv8gPi4vc6QpJu2vkTw z81RDTQ5cXtp+Fl0HAX6t/BaKoDD+tXpGEQ= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" REF: REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2801 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 Cc: Bret Barkelew Cc: Jiewen Yao Signed-off-by: Michael D Kinney --- .../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/Uni= tTestDebugAssertLib.c create mode 100644 UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/Uni= tTestDebugAssertLib.inf create mode 100644 UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/Uni= tTestDebugAssertLib.uni diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDe= bugAssertLib.c b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTe= stDebugAssertLib.c new file mode 100644 index 0000000000..0a4001e182 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAsse= rtLib.c @@ -0,0 +1,49 @@ +/** @file + Unit Test Debug Assert Library + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/// +/// Point to jump buffer used with SetJump()/LongJump() to test if a funct= ion +/// under test generates an expected ASSERT() condition. +/// +BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer =3D NULL; + +/** + Unit test library replacement for DebugAssert() in DebugLib. + + If FileName is NULL, then a string of "(NULL) Filename" is pr= inted. + If Description is NULL, then a string of "(NULL) Descripti= on" is printed. + + @param FileName The pointer to the name of the source file that gen= erated the assert condition. + @param LineNumber The line number in the source file that generated t= he assert condition + @param Description The pointer to the description of the assert condit= ion. + +**/ +VOID +EFIAPI +UnitTestDebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + CHAR8 Message[256]; + + if (gUnitTestExpectAssertFailureJumpBuffer !=3D NULL) { + UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineN= umber, 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/UnitTestDe= bugAssertLib.inf b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/Unit= TestDebugAssertLib.inf new file mode 100644 index 0000000000..e6ccab0dd9 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAsse= rtLib.inf @@ -0,0 +1,31 @@ +## @file +# Unit Test Debug Assert Library +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UnitTestDebugAssertLib + MODULE_UNI_FILE =3D UnitTestDebugAssertLib.uni + FILE_GUID =3D 9D53AD0D-5416-451F-A5BF-E5420051A99B + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NULL + +# +# VALID_ARCHITECTURES =3D ARM AARCH64 +# + +[Sources] + UnitTestDebugAssertLib.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + UnitTestLib diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDe= bugAssertLib.uni b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/Unit= TestDebugAssertLib.uni new file mode 100644 index 0000000000..9b794aa205 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAsse= rtLib.uni @@ -0,0 +1,11 @@ +// /** @file +// Unit Test Debug Assert Library +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.
+// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Unit Test Debug A= ssert Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Unit Test Debug A= ssert Library" diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c b/UnitTestFr= ameworkPkg/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 #include =20 +extern BASE_LIBRARY_JUMP_BUFFER gUnitTestJumpBuffer; + STATIC EFI_STATUS AddUnitTestFailure ( @@ -71,7 +73,7 @@ UnitTestLogFailure ( FailureType ); =20 - return; + LongJump (&gUnitTestJumpBuffer, 1); } =20 /** @@ -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 !=3D ValueB) { - UnitTestLogFailure ( - FAILURETYPE_ASSERTEQUAL, - "%a:%d: Value %a !=3D %a (%d !=3D %d)!\n", - FileName, - LineNumber, - DescriptionA, - DescriptionB, - ValueA, - ValueB - ); UT_LOG_ERROR ( "[ASSERT FAIL] %a:%d: Value %a !=3D %a (%d !=3D %d)!\n", FileName, @@ -267,6 +259,16 @@ UnitTestAssertEqual ( ValueA, ValueB ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTEQUAL, + "%a:%d: Value %a !=3D %a (%d !=3D %d)!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + ValueA, + ValueB + ); } return (ValueA =3D=3D ValueB); } @@ -310,15 +312,6 @@ UnitTestAssertMemEqual ( ) { if (CompareMem(BufferA, BufferB, Length) !=3D 0) { - UnitTestLogFailure ( - FAILURETYPE_ASSERTEQUAL, - "%a:%d: Memory at %a !=3D %a for length %d bytes!\n", - FileName, - LineNumber, - DescriptionA, - DescriptionB, - Length - ); UT_LOG_ERROR ( "[ASSERT FAIL] %a:%d: Value %a !=3D %a for length %d bytes!\n", FileName, @@ -327,6 +320,15 @@ UnitTestAssertMemEqual ( DescriptionB, Length ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTEQUAL, + "%a:%d: Memory at %a !=3D %a for length %d bytes!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + Length + ); return FALSE; } return TRUE; @@ -366,6 +368,15 @@ UnitTestAssertNotEqual ( ) { if (ValueA =3D=3D ValueB) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Value %a =3D=3D %a (%d =3D=3D %d)!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + ValueA, + ValueB + ); UnitTestLogFailure ( FAILURETYPE_ASSERTNOTEQUAL, "%a:%d: Value %a =3D=3D %a (%d =3D=3D %d)!\n", @@ -376,15 +387,6 @@ UnitTestAssertNotEqual ( ValueA, ValueB ); - UT_LOG_ERROR ( - "[ASSERT FAIL] %a:%d: Value %a =3D=3D %a (%d =3D=3D %d)!\n", - FileName, - LineNumber, - DescriptionA, - DescriptionB, - ValueA, - ValueB - ); } return (ValueA !=3D ValueB); } @@ -421,6 +423,14 @@ UnitTestAssertStatusEqual ( ) { if (Status !=3D 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 =3D=3D Expected); } @@ -473,6 +475,12 @@ UnitTestAssertNotNull ( ) { if (Pointer =3D=3D 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 !=3D NULL); } + +/** + If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and retu= rn + 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 exec= uted, + but no ASSERT() conditions were triggered. The log messages contain + FunctionName, LineNumber, and FileName strings to provide the location o= f the + UT_EXPECT_ASSERT_FAILURE() macro. + + @param[in] UnitTestStatus The status from UT_EXPECT_ASSERT_FAILURE() t= hat + is either pass, skipped, or failed. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the UT_EXPECT_ASSERT_FAILURE() mac= ro. + @param[in] LineNumber The source file line number of the the funct= ion + executing the UT_EXPECT_ASSERT_FAILURE() mac= ro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the UT_EXPECT_ASSERT_FAILURE() mac= ro. + @param[in] FunctionCall Null-terminated ASCII string of the function= call + executed by the UT_EXPECT_ASSERT_FAILURE() m= acro. + @param[out] ResultStatus Used to return the UnitTestStatus value to t= he + 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 !=3D NULL) { + *ResultStatus =3D UnitTestStatus; + } + if (UnitTestStatus =3D=3D UNIT_TEST_PASSED) { + UT_LOG_INFO ( + "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected= assert\n", + FileName, + LineNumber, + FunctionCall + ); + } + if (UnitTestStatus =3D=3D UNIT_TEST_SKIPPED) { + UT_LOG_WARNING ( + "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n", + FileName, + LineNumber, + FunctionCall + ); + } + if (UnitTestStatus =3D=3D 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 !=3D UNIT_TEST_ERROR_TEST_FAILED); +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c b/Unit= TestFrameworkPkg/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 ( =20 return (Pointer !=3D NULL); } + +/** + If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and retu= rn + 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 exec= uted, + but no ASSERT() conditions were triggered. The log messages contain + FunctionName, LineNumber, and FileName strings to provide the location o= f the + UT_EXPECT_ASSERT_FAILURE() macro. + + @param[in] UnitTestStatus The status from UT_EXPECT_ASSERT_FAILURE() t= hat + is either pass, skipped, or failed. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the UT_EXPECT_ASSERT_FAILURE() mac= ro. + @param[in] LineNumber The source file line number of the the funct= ion + executing the UT_EXPECT_ASSERT_FAILURE() mac= ro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the UT_EXPECT_ASSERT_FAILURE() mac= ro. + @param[in] FunctionCall Null-terminated ASCII string of the function= call + executed by the UT_EXPECT_ASSERT_FAILURE() m= acro. + @param[out] ResultStatus Used to return the UnitTestStatus value to t= he + 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 !=3D NULL) { + *ResultStatus =3D UnitTestStatus; + } + if (UnitTestStatus =3D=3D UNIT_TEST_PASSED) { + UT_LOG_INFO ( + "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected= assert\n", + FileName, + LineNumber, + FunctionCall + ); + } + if (UnitTestStatus =3D=3D UNIT_TEST_SKIPPED) { + UT_LOG_WARNING ( + "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n", + FileName, + LineNumber, + FunctionCall + ); + } + if (UnitTestStatus =3D=3D 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 !=3D UNIT_TEST_ERROR_TEST_FAILED); +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c b/UnitTest= FrameworkPkg/Library/UnitTestLib/RunTests.c index 793335fd0f..2dc1d159d5 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c @@ -14,6 +14,8 @@ =20 STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle =3D NULL; =20 +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 =3D=3D UNIT_TEST_PENDING && Test->Prerequisite !=3D N= ULL) { DEBUG ((DEBUG_VERBOSE, "PREREQ\n")); - if (Test->Prerequisite (Test->Context) !=3D UNIT_TEST_PASSED) { + if (SetJump (&gUnitTestJumpBuffer) =3D=3D 0) { + if (Test->Prerequisite (Test->Context) !=3D UNIT_TEST_PASSED) { + DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n")); + Test->Result =3D UNIT_TEST_ERROR_PREREQUISITE_NOT_MET; + ParentFramework->CurrentTest =3D NULL; + continue; + } + } else { DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n")); Test->Result =3D UNIT_TEST_ERROR_PREREQUISITE_NOT_MET; ParentFramework->CurrentTest =3D NULL; @@ -88,14 +97,20 @@ RunTestSuite ( // We set the status to UNIT_TEST_RUNNING in case the test needs to re= boot // or quit. The UNIT_TEST_RUNNING state will allow the test to resume // but will prevent the Prerequisite from being dispatched a second ti= me. - Test->Result =3D UNIT_TEST_RUNNING; - Test->Result =3D Test->RunTest (Test->Context); + if (SetJump (&gUnitTestJumpBuffer) =3D=3D 0) { + Test->Result =3D UNIT_TEST_RUNNING; + Test->Result =3D Test->RunTest (Test->Context); + } else { + Test->Result =3D UNIT_TEST_ERROR_TEST_FAILED; + } =20 // // Finally, clean everything up, if need be. if (Test->CleanUp !=3D NULL) { DEBUG ((DEBUG_VERBOSE, "CLEANUP\n")); - Test->CleanUp (Test->Context); + if (SetJump (&gUnitTestJumpBuffer) =3D=3D 0) { + Test->CleanUp (Test->Context); + } } =20 // diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestR= esultReportLib.c b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/Uni= tTestResultReportLib.c index eba68e330c..66c9db457d 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultRe= portLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultRe= portLib.c @@ -49,7 +49,8 @@ struct _UNIT_TEST_FAILURE_TYPE_STRING mFailureTypeStrings= [] =3D { { 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"} }; =20 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) =20 /// /// Unit Test context structure tracked by the unit test framework. diff --git a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc b/U= nitTestFrameworkPkg/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/SampleUnitTestH= ost.inf =20 # - # Build Libraries + # Build HOST_APPLICATION Libraries # UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc b/UnitTestFramew= orkPkg/UnitTestFrameworkPkg.dsc index 2d84691bf1..0dfd98f2a8 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc @@ -28,6 +28,7 @@ [Components] UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultRepor= tLibConOut.inf UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbC= lass.inf UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/Unit= TestPersistenceLibSimpleFileSystem.inf + UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertL= ib.inf =20 UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestD= xe.inf UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestP= ei.inf diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc b/Unit= TestFrameworkPkg/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/UnitTestPersistenceL= ibNull/UnitTestPersistenceLibNull.inf UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultRepor= tLib/UnitTestResultReportLibDebugLib.inf + NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAs= sertLib.inf =20 [LibraryClasses.ARM, LibraryClasses.AARCH64] # @@ -56,5 +57,6 @@ [PcdsFixedAtBuild] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 =20 [BuildOptions] - MSFT:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES - GCC:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES + MSFT:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_U= NIT_TEST_FRAMEWORK_ENABLED + GCC:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_U= NIT_TEST_FRAMEWORK_ENABLED + XCODE:*_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_U= NIT_TEST_FRAMEWORK_ENABLED --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#62289): https://edk2.groups.io/g/devel/message/62289 Mute This Topic: https://groups.io/mt/75391619/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-