From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mx.groups.io with SMTP id smtpd.web09.6247.1581036570441070681 for ; Thu, 06 Feb 2020 16:49:30 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.43, mailfrom: michael.d.kinney@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Feb 2020 16:49:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,411,1574150400"; d="scan'208";a="236170899" Received: from orsmsx104.amr.corp.intel.com ([10.22.225.131]) by orsmga006.jf.intel.com with ESMTP; 06 Feb 2020 16:49:29 -0800 Received: from orsmsx113.amr.corp.intel.com ([169.254.9.57]) by ORSMSX104.amr.corp.intel.com ([169.254.4.176]) with mapi id 14.03.0439.000; Thu, 6 Feb 2020 16:49:28 -0800 From: "Michael D Kinney" To: "devel@edk2.groups.io" , "Kinney, Michael D" Subject: Re: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class Thread-Topic: [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class Thread-Index: AQHV0lvkbIPPwX+HIkOj3Cy75SY9uagO/Alg Date: Fri, 7 Feb 2020 00:49:28 +0000 Message-ID: References: <20200124021032.13808-1-michael.d.kinney@intel.com> <20200124021032.13808-4-michael.d.kinney@intel.com> In-Reply-To: <20200124021032.13808-4-michael.d.kinney@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.22.254.139] MIME-Version: 1.0 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Michael D Kinney > -----Original Message----- > From: devel@edk2.groups.io On > Behalf Of Michael D Kinney > Sent: Thursday, January 23, 2020 6:10 PM > To: devel@edk2.groups.io > Cc: Bret Barkelew ; Sean Brogan > ; Bret Barkelew > ; Gao, Liming > > Subject: [edk2-devel] [Patch 03/11] > MdePkg/Include/Library: Add UnitTestLib class >=20 > From: Bret Barkelew >=20 > Add UnitTestLib class to MdePkg that provides services > and macros to implement unit tests. These services and > macros support the following features: >=20 > * 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. >=20 > Cc: Sean Brogan > Cc: Bret Barkelew > Cc: Liming Gao > Signed-off-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 >=20 > 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 logic > + 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 parameter. > +/// > +#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 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. > + > +**/ > +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 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. > + > +**/ > +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 test 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 that 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 prior 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 with > + 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 data. > +**/ > +typedef > +VOID > +(EFIAPI *UNIT_TEST_SUITE_TEARDOWN)( > + VOID > + ); > + > +/** > + Method to Initialize the Unit Test framework. This > function registers the > + 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 user > + 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 the > + 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 user > + friendly name of the > test suite. String is > + copied. > + @param[in] Name Null-terminated ASCII > string that is the short > + name of the test suite > with no spaces. String > + is copied. > + @param[in] Setup Setup function, runs > before suite. This is 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 copied. > + @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 parameter > + 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 unit > + test cases are registered, this function will cause > the unit test framework to > + dispatch all unit test cases in sequence and record > the results for reporting. > + > + @param[in] FrameworkHandle A handle to the current > running framework that > + dispatched the test. > Necessary for recording > + 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 that > + dispatched the test. > Necessary for recording > + 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 with > + 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, should be > + at least the current execution count) which will be > saved by the framework 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 recording > + 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 passed 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 saved. > + @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 not 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)(BufferB), > (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 comparison). > + @param[in] ValueB Value to be compared for > inequality (64-bit comparison). > +**/ > +#define UT_ASSERT_NOT_EQUAL(ValueA, ValueB) > \ > + if(!UnitTestAssertNotEqual ((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 an EFI_STATUS > + value is !EFI_ERROR(). If the status is > !EFI_ERROR(), execution continues. > + 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_STATUS > + 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__, __LINE__, __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, the > + 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 are > + recorded and FALSE is returned. > + > + @param[in] Expression The BOOLEAN result of the > expression evaluation. > + @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 macro. > + @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 the > + assert provided by FunctionName, LineNumber, > FileName, and Description are > + recorded and FALSE is returned. > + > + @param[in] Expression The BOOLEAN result of the > expression evaluation. > + @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 macro. > + @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 location of > + the assert provided by FunctionName, LineNumber, > FileName, and Description 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 macro. > + @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 location > + of the assert provided by FunctionName, LineNumber, > FileName, DescriptionA, > + 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 macro. > + @param[in] FileName Null-terminated ASCII > string of the filename > + executing the assert > macro. > + @param[in] DescriptionA Null-terminated ASCII > string that is a description > + of ValueA. > + @param[in] DescriptionB Null-terminated ASCII > string that is a description > + 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, then TRUE > + is returned. If the contents of BufferA are not > identical to the contents of > + BufferB, then an assert is triggered and the > location of the assert provided > + 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 BufferB. > + @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 macro. > + @param[in] FileName Null-terminated ASCII > string of the filename > + executing the assert > macro. > + @param[in] DescriptionA Null-terminated ASCII > string that is a description > + of BufferA. > + @param[in] DescriptionB Null-terminated ASCII > string that is a description > + 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 contents 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 location > + of the assert provided by FunctionName, LineNumber, > FileName, DescriptionA > + 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 macro. > + @param[in] FileName Null-terminated ASCII > string of the filename > + executing the assert > macro. > + @param[in] DescriptionA Null-terminated ASCII > string that is a description > + of ValueA. > + @param[in] DescriptionB Null-terminated ASCII > string that is a description > + 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, and > + Description are recorded and FALSE is returned. > + > + @param[in] Status EFI_STATUS value returned > from an API under test. > + @param[in] Expected The expected EFI_STATUS > return value from an API > + 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 macro. > + @param[in] FileName Null-terminated ASCII > string of the filename > + executing the assert > macro. > + @param[in] Description Null-terminated ASCII > string that is a description > + 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 location of > + the assert provided by FunctionName, LineNumber, > FileName, and PointerName > + 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 function > + 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 macro. > + @param[in] FileName Null-terminated ASCII > string of the filename > + executing the assert > macro. > + @param[in] PointerName Null-terminated ASCII > string that is a description > + 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 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_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 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_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 in 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. >=20 > StandaloneMmDriverEntryPoint|Include/Library/Standalone > MmDriverEntryPoint.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. > ## > -- > 2.21.0.windows.1 >=20 >=20 >=20