From nobody Tue Feb 3 14:51:44 2026 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+53461+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+53461+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1579831838; cv=none; d=zohomail.com; s=zohoarc; b=Jw6QGtAdxRWOhsSX4CZRdvmU2ObBwtlXtI+AsSmqBYcp6cxinY/aDpC9cU1t3GwRFbEEKwHnxHZkvYjjPfDzPMOPPfRhcE4F7QRgVQlnHQdqHeQTHAkJ6+/9UT3xVOB2nSRVwrtHxLYIKB4t4lcLL52SnGr1g9ck+tp3H73UokY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1579831838; 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=aeZhSNsHEA7j4PzYKXsAqNtazWdkPfQnX8/zRNMRrew=; b=VfI09Mto6Vd7umFD/lViMVG2NFTz/tduEkQ3ZYc6uPdwlJ0vDmrG8pASCNIE3RBvNiJHSBnh0RgJUQ561MGpZW4OtPDSgl70yb73pJhZJKL9vJIbmbXLN5iDYIKURy0Y73oMl7ZssJmvCaCjjTTonA0NgBlU7LzywGDhUvDA/D4= 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+53461+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 1579831838553531.1242333584497; Thu, 23 Jan 2020 18:10:38 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 9THKYY1788612xVl7KAJDJEr; Thu, 23 Jan 2020 18:10:37 -0800 X-Received: from mga09.intel.com (mga09.intel.com []) by mx.groups.io with SMTP id smtpd.web11.7301.1579831835785711151 for ; Thu, 23 Jan 2020 18:10:37 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Jan 2020 18:10:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,356,1574150400"; d="scan'208";a="375395293" X-Received: from unknown (HELO mdkinney-MOBL2.amr.corp.intel.com) ([10.241.98.74]) by orsmga004.jf.intel.com with ESMTP; 23 Jan 2020 18:10:35 -0800 From: "Michael D Kinney" To: devel@edk2.groups.io Cc: Bret Barkelew , Sean Brogan , Bret Barkelew , Liming Gao Subject: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class Date: Thu, 23 Jan 2020 18:10:24 -0800 Message-Id: <20200124021032.13808-4-michael.d.kinney@intel.com> In-Reply-To: <20200124021032.13808-1-michael.d.kinney@intel.com> References: <20200124021032.13808-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: DgLJKeJ2DoWGrl8FdckMxIGZx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1579831837; bh=dk8tbHI7FgU0nWQ14SDCD+hSR+WE4G8SHv7WpLAFthM=; h=Cc:Date:From:Reply-To:Subject:To; b=j0ge0zzfBgQIduxQ1BZrxsdIHrLh20/QBtJ0XWzz6co7w+h6mHabQQeEIodpHNf29D1 mgU187l+4RjJrpNcuSqSa+S5ME5fA7P57VRWNgUXcz9jHZZo9czhbKgf2SzffSVezjGjy ukBaN1t0ItADCkvIiUEnUgdIz5N5600Vxt0= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" From: Bret Barkelew Add UnitTestLib class to MdePkg that provides services and macros to implement unit tests. These services and macros support the following features: * Create a Unit Test Framework * Add a Unit Test Suite to a Unit Test Framework + Support optional step that executes before a Unit Test Suite is started. + Support optional step that executes after a Unit Test Suite is finished. * Add a Unit Test to a Unit Test Suite + Support optional step that executes before a Unit Test is started. + Support optional step that executes after a Unit Test is finished. * Run all unit tests added to a Unit Test Framework * Save Unit Test Framework state to persistent storage * Support assertion checks in a unit test for TRUE, FALSE, EQUAL, MEM_EQUAL, NOT_EFI_ERROR, STATUS_EQUAL, and NOT_NULL. * Support generation of log messages at ERROR, WARN, INFO, and VERBOSE levels. Cc: Sean Brogan Cc: Bret Barkelew Cc: Liming Gao Signed-off-by: Michael D Kinney Reviewed-by: Bret Barkelew Reviewed-by: Hao A Wu Reviewed-by: Michael D Kinney --- MdePkg/Include/Library/UnitTestLib.h | 757 +++++++++++++++++++++++++++ MdePkg/MdePkg.dec | 4 + 2 files changed, 761 insertions(+) create mode 100644 MdePkg/Include/Library/UnitTestLib.h diff --git a/MdePkg/Include/Library/UnitTestLib.h b/MdePkg/Include/Library/= UnitTestLib.h new file mode 100644 index 0000000000..757ebaf6ba --- /dev/null +++ b/MdePkg/Include/Library/UnitTestLib.h @@ -0,0 +1,757 @@ +/** @file + Provides a unit test framework. This allows tests to focus on testing l= ogic + and the framework to focus on runnings, reporting, statistics, etc. + + Copyright (c) Microsoft Corporation.
+ Copyright (c) 2020, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __UNIT_TEST_LIB_H__ +#define __UNIT_TEST_LIB_H__ + +/// +/// Unit Test Status +/// +typedef UINT32 UNIT_TEST_STATUS; +#define UNIT_TEST_PASSED (0) +#define UNIT_TEST_ERROR_PREREQUISITE_NOT_MET (1) +#define UNIT_TEST_ERROR_TEST_FAILED (2) +#define UNIT_TEST_ERROR_CLEANUP_FAILED (3) +#define UNIT_TEST_SKIPPED (0xFFFFFFFD) +#define UNIT_TEST_RUNNING (0xFFFFFFFE) +#define UNIT_TEST_PENDING (0xFFFFFFFF) + +/// +/// Declare PcdUnitTestLogLevel bits and UnitTestLog() ErrorLevel paramete= r. +/// +#define UNIT_TEST_LOG_LEVEL_ERROR BIT0 +#define UNIT_TEST_LOG_LEVEL_WARN BIT1 +#define UNIT_TEST_LOG_LEVEL_INFO BIT2 +#define UNIT_TEST_LOG_LEVEL_VERBOSE BIT3 + +/// +/// Unit Test Framework Handle +/// +struct UNIT_TEST_FRAMEWORK_OBJECT; +typedef struct UNIT_TEST_FRAMEWORK_OBJECT *UNIT_TEST_FRAMEWORK_HANDLE; + +/// +/// Unit Test Suite Handle +/// +struct UNIT_TEST_SUITE_OBJECT; +typedef struct UNIT_TEST_SUITE_OBJECT *UNIT_TEST_SUITE_HANDLE; + +/// +/// Unit Test Handle +/// +struct UNIT_TEST_OBJECT; +typedef struct UNIT_TEST_OBJECT *UNIT_TEST_HANDLE; + +/// +/// Unit Test Context +/// +typedef VOID* UNIT_TEST_CONTEXT; + +/** + The prototype for a single UnitTest case function. + + Funtions with this prototype are registered to be dispatched by the + UnitTest framework, and results are recorded as test Pass or Fail. + + @param[in] Context [Optional] An optional paramter 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 th= at may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and th= e test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. + +**/ +typedef +UNIT_TEST_STATUS +(EFIAPI *UNIT_TEST_FUNCTION)( + IN UNIT_TEST_CONTEXT Context + ); + +/** + Unit-Test Prerequisite Function pointer type. + + Funtions 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 paramter 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 th= at may + consume it. + + @retval UNIT_TEST_PASSED Unit test case prerequisi= tes + are met. + @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipp= ed. + +**/ +typedef +UNIT_TEST_STATUS +(EFIAPI *UNIT_TEST_PREREQUISITE)( + IN UNIT_TEST_CONTEXT Context + ); + +/** + Unit-Test Cleanup (after) function pointer type. + + Funtions 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 te= st is + skipped. The purpose of this function is to clean up any global state or + test data. + + @param[in] Context [Optional] An optional paramter 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 th= at may + consume it. + + @retval UNIT_TEST_PASSED Test case cleanup succeeded. + @retval UNIT_TEST_ERROR_CLEANUP_FAILED Test case cleanup failed. + +**/ +typedef +VOID +(EFIAPI *UNIT_TEST_CLEANUP)( + IN UNIT_TEST_CONTEXT Context + ); + +/** + Unit-Test Test Suite Setup (before) function pointer type. Funtions with= this + prototype are registered to be dispatched by the UnitTest framework prio= r to + running any of the test cases in a test suite. It will only be run once= at + the beginning of the suite (not prior to each case). + + The purpose of this function is to set up any global state or test data. +**/ +typedef +VOID +(EFIAPI *UNIT_TEST_SUITE_SETUP)( + VOID + ); + +/** + Unit-Test Test Suite Teardown (after) function pointer type. Funtions w= ith + this prototype are registered to be dispatched by the UnitTest framework= after + running all of the test cases in a test suite. It will only be run once= at + the end of the suite. + + The purpose of this function is to clean up any global state or test dat= a. +**/ +typedef +VOID +(EFIAPI *UNIT_TEST_SUITE_TEARDOWN)( + VOID + ); + +/** + Method to Initialize the Unit Test framework. This function registers t= he + test name and also initializes the internal state of the test framework = to + receive any new suites and tests. + + @param[out] FrameworkHandle Unit test framework to be created. + @param[in] Title Null-terminated ASCII string that is the u= ser + friendly name of the framework. String is + copied. + @param[in] ShortTitle Null-terminaled ASCII short string that is= the + short name of the framework with no spaces. + String is copied. + @param[in] VersionString Null-terminaled ASCII version string for t= he + framework. String is copied. + + @retval EFI_SUCCESS The unit test framework was initialized. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. + @retval EFI_INVALID_PARAMETER Title is NULL. + @retval EFI_INVALID_PARAMETER ShortTitle is NULL. + @retval EFI_INVALID_PARAMETER VersionString is NULL. + @retval EFI_INVALID_PARAMETER ShortTitle is invalid. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available= to + initialize the unit test framework. +**/ +EFI_STATUS +EFIAPI +InitUnitTestFramework ( + OUT UNIT_TEST_FRAMEWORK_HANDLE *FrameworkHandle, + IN CHAR8 *Title, + IN CHAR8 *ShortTitle, + IN CHAR8 *VersionString + ); + +/** + Registers a Unit Test Suite in the Unit Test Framework. + At least one test suite must be registered, because all test cases must = be + within a unit test suite. + + @param[out] SuiteHandle Unit test suite to create + @param[in] FrameworkHandle Unit test framework to add unit test suite= to + @param[in] Title Null-terminated ASCII string that is the u= ser + friendly name of the test suite. String is + copied. + @param[in] Name Null-terminated ASCII string that is the s= hort + name of the test suite with no spaces. St= ring + is copied. + @param[in] Setup Setup function, runs before suite. This i= s an + optional parameter that may be NULL. + @param[in] Teardown Teardown function, runs after suite. This= is an + optional parameter that may be NULL. + + @retval EFI_SUCCESS The unit test suite was created. + @retval EFI_INVALID_PARAMETER SuiteHandle is NULL. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. + @retval EFI_INVALID_PARAMETER Title is NULL. + @retval EFI_INVALID_PARAMETER Name is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available= to + initialize the unit test suite. +**/ +EFI_STATUS +EFIAPI +CreateUnitTestSuite ( + OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle, + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + IN CHAR8 *Title, + IN CHAR8 *Name, + IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL, + IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL + ); + +/** + Adds test case to Suite + + @param[in] SuiteHandle Unit test suite to add test to. + @param[in] Description Null-terminated ASCII string that is the user + friendly description of a test. String is cop= ied. + @param[in] Name Null-terminated ASCII string that is the short= name + of the test with no spaces. String is copied. + @param[in] Function Unit test function. + @param[in] Prerequisite Prerequisite function, runs before test. This= is + an optional parameter that may be NULL. + @param[in] CleanUp Clean up function, runs after test. This is an + optional parameter that may be NULL. + @param[in] Context Pointer to context. This is an optional par= ameter + that may be NULL. + + @retval EFI_SUCCESS The unit test case was added to Suite. + @retval EFI_INVALID_PARAMETER SuiteHandle is NULL. + @retval EFI_INVALID_PARAMETER Description is NULL. + @retval EFI_INVALID_PARAMETER Name is NULL. + @retval EFI_INVALID_PARAMETER Function is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available= to + add the unit test case to Suite. +**/ +EFI_STATUS +EFIAPI +AddTestCase ( + IN UNIT_TEST_SUITE_HANDLE SuiteHandle, + IN CHAR8 *Description, + IN CHAR8 *Name, + IN UNIT_TEST_FUNCTION Function, + IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL, + IN UNIT_TEST_CLEANUP CleanUp OPTIONAL, + IN UNIT_TEST_CONTEXT Context OPTIONAL + ); + +/** + Execute all unit test cases in all unit test suites added to a Framework. + + Once a unit test framework is initialized and all unit test suites and u= nit + test cases are registered, this function will cause the unit test framew= ork to + dispatch all unit test cases in sequence and record the results for repo= rting. + + @param[in] FrameworkHandle A handle to the current running framework t= hat + dispatched the test. Necessary for recordi= ng + certain test events with the framework. + + @retval EFI_SUCCESS All test cases were dispached. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. +**/ +EFI_STATUS +EFIAPI +RunAllTestSuites ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ); + +/** + Cleanup a test framework. + + After tests are run, this will teardown the entire framework and free all + allocated data within. + + @param[in] FrameworkHandle A handle to the current running framework t= hat + dispatched the test. Necessary for recordi= ng + certain test events with the framework. + + @retval EFI_SUCCESS All resources associated with framework = were + freed. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. +**/ +EFI_STATUS +EFIAPI +FreeUnitTestFramework ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ); + +/** + Leverages a framework-specific mechanism (see UnitTestPersistenceLib if = you're + a framework author) to save the state of the executing framework along w= ith + any allocated data so that the test may be resumed upon reentry. A test = case + should pass any needed context (which, to prevent an infinite loop, shou= ld be + at least the current execution count) which will be saved by the framewo= rk and + passed to the test case upon resume. + + Generally called from within a test case prior to quitting or rebooting. + + @param[in] FrameworkHandle A handle to the current running framework= that + dispatched the test. Necessary for recor= ding + certain test events with the framework. + @param[in] ContextToSave A buffer of test case-specific data to be= saved + along with framework state. Will be pass= ed as + "Context" to the test case upon resume. = This + is an optional parameter that may be NULL. + @param[in] ContextToSaveSize Size of the ContextToSave buffer. + + @retval EFI_SUCCESS The framework state and context were sav= ed. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. + @retval EFI_INVALID_PARAMETER ContextToSave is not NULL and + ContextToSaveSize is 0. + @retval EFI_INVALID_PARAMETER ContextToSave is >=3D 4GB. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available= to + save the framework and context state. + @retval EFI_DEVICE_ERROR The framework and context state could no= t be + saved to a persistent storage devide due= to a + device error. +**/ +EFI_STATUS +EFIAPI +SaveFrameworkState ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL, + IN UINTN ContextToSaveSize + ); + +/** + This macro uses the framework assertion logic to check an expression for + "TRUE". If the expression evaluates to TRUE, execution continues. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] Expression Expression to be evaluated for TRUE. +**/ +#define UT_ASSERT_TRUE(Expression) = \ + if(!UnitTestAssertTrue ((Expression), __FUNCTION__, __LINE__, __FILE__, = #Expression)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check an expression for + "FALSE". If the expression evaluates to FALSE, execution continues. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] Expression Expression to be evaluated for FALSE. +**/ +#define UT_ASSERT_FALSE(Expression) = \ + if(!UnitTestAssertFalse ((Expression), __FUNCTION__, __LINE__, __FILE__,= #Expression)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check whether two simple + values are equal. If the values are equal, execution continues. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] ValueA Value to be compared for equality (64-bit comparison= ). + @param[in] ValueB Value to be compared for equality (64-bit comparison= ). +**/ +#define UT_ASSERT_EQUAL(ValueA, ValueB) = \ + if(!UnitTestAssertEqual ((UINT64)(ValueA), (UINT64)(ValueB), __FUNCTION_= _, __LINE__, __FILE__, #ValueA, #ValueB)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check whether two memory + buffers are equal. If the buffers are equal, execution continues. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] BufferA Pointer to a buffer for comparison. + @param[in] BufferB Pointer to a buffer for comparison. + @param[in] Length Number of bytes to compare in BufferA and BufferB. +**/ +#define UT_ASSERT_MEM_EQUAL(BufferA, BufferB, Length) = \ + if(!UnitTestAssertMemEqual ((VOID *)(UINTN)(BufferA), (VOID *)(UINTN)(Bu= fferB), (UINTN)Length, __FUNCTION__, __LINE__, __FILE__, #BufferA, #BufferB= )) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check whether two simple + values are non-equal. If the values are non-equal, execution continues. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] ValueA Value to be compared for inequality (64-bit comparis= on). + @param[in] ValueB Value to be compared for inequality (64-bit comparis= on). +**/ +#define UT_ASSERT_NOT_EQUAL(ValueA, ValueB) = \ + if(!UnitTestAssertNotEqual ((UINT64)(ValueA), (UINT64)(ValueB), __FUNCTI= ON__, __LINE__, __FILE__, #ValueA, #ValueB)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check whether an EFI_ST= ATUS + value is !EFI_ERROR(). If the status is !EFI_ERROR(), execution continu= es. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] Status EFI_STATUS value to check. +**/ +#define UT_ASSERT_NOT_EFI_ERROR(Status) = \ + if(!UnitTestAssertNotEfiError ((Status), __FUNCTION__, __LINE__, __FILE_= _, #Status)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check whether two EFI_S= TATUS + values are equal. If the values are equal, execution continues. + Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] Status EFI_STATUS values to compare for equality. + @param[in] Expected EFI_STATUS values to compare for equality. +**/ +#define UT_ASSERT_STATUS_EQUAL(Status, Expected) = \ + if(!UnitTestAssertStatusEqual ((Status), (Expected), __FUNCTION__, __LIN= E__, __FILE__, #Status)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + This macro uses the framework assertion logic to check whether a pointer= is + not NULL. If the pointer is not NULL, execution continues. Otherwise, t= he + test case immediately returns UNIT_TEST_ERROR_TEST_FAILED. + + @param[in] Pointer Pointer to be checked against NULL. +**/ +#define UT_ASSERT_NOT_NULL(Pointer) = \ + if(!UnitTestAssertNotNull ((Pointer), __FUNCTION__, __LINE__, __FILE__, = #Pointer)) { \ + return UNIT_TEST_ERROR_TEST_FAILED; = \ + } + +/** + If Expression is TRUE, then TRUE is returned. + If Expression is FALSE, then an assert is triggered and the location of = the + assert provided by FunctionName, LineNumber, FileName, and Description a= re + recorded and FALSE is returned. + + @param[in] Expression The BOOLEAN result of the expression evaluatio= n. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the expression= being + evaluated. + + @retval TRUE Expression is TRUE. + @retval FALSE Expression is FALSE. +**/ +BOOLEAN +EFIAPI +UnitTestAssertTrue ( + IN BOOLEAN Expression, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ); + +/** + If Expression is FALSE, then TRUE is returned. + If Expression is TRUE, then an assert is triggered and the location of t= he + assert provided by FunctionName, LineNumber, FileName, and Description a= re + recorded and FALSE is returned. + + @param[in] Expression The BOOLEAN result of the expression evaluatio= n. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the expression= being + evaluated. + + @retval TRUE Expression is FALSE. + @retval FALSE Expression is TRUE. +**/ +BOOLEAN +EFIAPI +UnitTestAssertFalse ( + IN BOOLEAN Expression, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ); + +/** + If Status is not an EFI_ERROR(), then TRUE is returned. + If Status is an EFI_ERROR(), then an assert is triggered and the locatio= n of + the assert provided by FunctionName, LineNumber, FileName, and Descripti= on are + recorded and FALSE is returned. + + @param[in] Status The EFI_STATUS value to evaluate. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the status + expression being evaluated. + + @retval TRUE Status is not an EFI_ERROR(). + @retval FALSE Status is an EFI_ERROR(). +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotEfiError ( + IN EFI_STATUS Status, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ); + +/** + If ValueA is equal ValueB, then TRUE is returned. + If ValueA is not equal to ValueB, then an assert is triggered and the lo= cation + of the assert provided by FunctionName, LineNumber, FileName, Descriptio= nA, + and DescriptionB are recorded and FALSE is returned. + + @param[in] ValueA 64-bit value. + @param[in] ValueB 64-bit value. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a descrip= tion + of ValueA. + @param[in] DescriptionB Null-terminated ASCII string that is a descrip= tion + of ValueB. + + @retval TRUE ValueA is equal to ValueB. + @retval FALSE ValueA is not equal to ValueB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertEqual ( + IN UINT64 ValueA, + IN UINT64 ValueB, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ); + +/** + If the contents of BufferA are identical to the contents of BufferB, the= n TRUE + is returned. If the contents of BufferA are not identical to the conten= ts of + BufferB, then an assert is triggered and the location of the assert prov= ided + by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are + recorded and FALSE is returned. + + @param[in] BufferA Pointer to a buffer for comparison. + @param[in] BufferB Pointer to a buffer for comparison. + @param[in] Length Number of bytes to compare in BufferA and Buff= erB. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a descrip= tion + of BufferA. + @param[in] DescriptionB Null-terminated ASCII string that is a descrip= tion + of BufferB. + + @retval TRUE The contents of BufferA are identical to the contents of + BufferB. + @retval FALSE The contents of BufferA are not identical to the content= s of + BufferB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertMemEqual ( + IN VOID *BufferA, + IN VOID *BufferB, + IN UINTN Length, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ); + +/** + If ValueA is not equal ValueB, then TRUE is returned. + If ValueA is equal to ValueB, then an assert is triggered and the locati= on + of the assert provided by FunctionName, LineNumber, FileName, Descriptio= nA + and DescriptionB are recorded and FALSE is returned. + + @param[in] ValueA 64-bit value. + @param[in] ValueB 64-bit value. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a descrip= tion + of ValueA. + @param[in] DescriptionB Null-terminated ASCII string that is a descrip= tion + of ValueB. + + @retval TRUE ValueA is not equal to ValueB. + @retval FALSE ValueA is equal to ValueB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotEqual ( + IN UINT64 ValueA, + IN UINT64 ValueB, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ); + +/** + If Status is equal to Expected, then TRUE is returned. + If Status is not equal to Expected, then an assert is triggered and the + location of the assert provided by FunctionName, LineNumber, FileName, a= nd + Description are recorded and FALSE is returned. + + @param[in] Status EFI_STATUS value returned from an API under te= st. + @param[in] Expected The expected EFI_STATUS return value from an A= PI + under test. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string that is a descrip= tion + of Status. + + @retval TRUE Status is equal to Expected. + @retval FALSE Status is not equal to Expected. +**/ +BOOLEAN +EFIAPI +UnitTestAssertStatusEqual ( + IN EFI_STATUS Status, + IN EFI_STATUS Expected, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ); + +/** + If Pointer is not equal to NULL, then TRUE is returned. + If Pointer is equal to NULL, then an assert is triggered and the locatio= n of + the assert provided by FunctionName, LineNumber, FileName, and PointerNa= me + are recorded and FALSE is returned. + + @param[in] Pointer Pointer value to be checked against NULL. + @param[in] Expected The expected EFI_STATUS return value from a fu= nction + under test. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macr= o. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] PointerName Null-terminated ASCII string that is a descrip= tion + of Pointer. + + @retval TRUE Pointer is not equal to NULL. + @retval FALSE Pointer is equal to NULL. +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotNull ( + IN VOID *Pointer, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *PointerName + ); + +/** + Test logging macro that records an ERROR message in the test framework l= og. + Record is associated with the currently executing test case. + + @param[in] Format Formatting string following the format defined in + MdePkg/Include/Library/PrintLib.h. + @param[in] ... Print args. +**/ +#define UT_LOG_ERROR(Format, ...) \ + UnitTestLog (UNIT_TEST_LOG_LEVEL_ERROR, Format, ##__VA_ARGS__) + +/** + Test logging macro that records a WARNING message in the test framework = log. + Record is associated with the currently executing test case. + + @param[in] Format Formatting string following the format defined in + MdePkg/Include/Library/PrintLib.h. + @param[in] ... Print args. +**/ +#define UT_LOG_WARNING(Format, ...) \ + UnitTestLog (UNIT_TEST_LOG_LEVEL_WARN, Format, ##__VA_ARGS__) + +/** + Test logging macro that records an INFO message in the test framework lo= g. + Record is associated with the currently executing test case. + + @param[in] Format Formatting string following the format defined in + MdePkg/Include/Library/PrintLib.h. + @param[in] ... Print args. +**/ +#define UT_LOG_INFO(Format, ...) \ + UnitTestLog (UNIT_TEST_LOG_LEVEL_INFO, Format, ##__VA_ARGS__) + +/** + Test logging macro that records a VERBOSE message in the test framework = log. + Record is associated with the currently executing test case. + + @param[in] Format Formatting string following the format defined in + MdePkg/Include/Library/PrintLib.h. + @param[in] ... Print args. +**/ +#define UT_LOG_VERBOSE(Format, ...) \ + UnitTestLog (UNIT_TEST_LOG_LEVEL_VERBOSE, Format, ##__VA_ARGS__) + +/** + Test logging function that records a messages in the test framework log. + Record is associated with the currently executing test case. + + @param[in] ErrorLevel The error level of the unit test log message. + @param[in] Format Formatting string following the format defined i= n the + MdePkg/Include/Library/PrintLib.h. + @param[in] ... Print args. +**/ +VOID +EFIAPI +UnitTestLog ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ); + +#endif diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index d022cc5e3e..ac1f5339af 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -244,6 +244,10 @@ [LibraryClasses] ## @libraryclass Module entry point library for standalone MM drivers. StandaloneMmDriverEntryPoint|Include/Library/StandaloneMmDriverEntryPoin= t.h =20 + ## @libraryclass Provides a unit test framework + # + UnitTestLib|Include/Library/UnitTestLib.h + [LibraryClasses.IA32, LibraryClasses.X64] ## @libraryclass Abstracts both S/W SMI generation and detection. ## --=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 (#53461): https://edk2.groups.io/g/devel/message/53461 Mute This Topic: https://groups.io/mt/70061162/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-