From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: devel@edk2.groups.io
Cc: Bret Barkelew <brbarkel@microsoft.com>,
Sean Brogan <sean.brogan@microsoft.com>,
Bret Barkelew <Bret.Barkelew@microsoft.com>,
Liming Gao <liming.gao@intel.com>
Subject: [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class
Date: Thu, 23 Jan 2020 18:10:24 -0800 [thread overview]
Message-ID: <20200124021032.13808-4-michael.d.kinney@intel.com> (raw)
In-Reply-To: <20200124021032.13808-1-michael.d.kinney@intel.com>
From: Bret Barkelew <brbarkel@microsoft.com>
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 <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
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 logic
+ and the framework to focus on runnings, reporting, statistics, etc.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ 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 >= 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.
StandaloneMmDriverEntryPoint|Include/Library/StandaloneMmDriverEntryPoint.h
+ ## @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
next prev parent reply other threads:[~2020-01-24 2:10 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-24 2:10 [Patch 00/11] Add Unit Test Framework Michael D Kinney
2020-01-24 2:10 ` [Patch 01/11] .pytool: Add CI support for host based unit tests with results Michael D Kinney
2020-01-27 23:28 ` [edk2-devel] " brbarkel
2020-01-24 2:10 ` [Patch 02/11] BaseTools/Plugin: Add HostBasedUnitTestRunner plugin Michael D Kinney
2020-01-27 23:29 ` [edk2-devel] " brbarkel
2020-02-07 2:32 ` Bob Feng
2020-01-24 2:10 ` Michael D Kinney [this message]
2020-01-27 23:42 ` [edk2-devel] [Patch 03/11] MdePkg/Include/Library: Add UnitTestLib class brbarkel
2020-02-07 0:49 ` Michael D Kinney
2020-02-07 1:22 ` Wu, Hao A
2020-02-07 5:43 ` Bret Barkelew
2020-01-24 2:10 ` [Patch 04/11] UnitTestFrameworkPkg: Add public and private interfaces Michael D Kinney
2020-01-27 23:42 ` [edk2-devel] " brbarkel
2020-01-24 2:10 ` [Patch 05/11] UnitTestFrameworkPkg/Library: Add library instances Michael D Kinney
2020-01-27 23:43 ` [edk2-devel] " brbarkel
2020-01-24 2:10 ` [Patch 06/11] UnitTestFrameworkPkg/Test: Add unit test samples Michael D Kinney
2020-01-27 23:43 ` [edk2-devel] " brbarkel
2020-01-24 2:10 ` [Patch 07/11] UnitTestFrameworkPkg: Add DSC, DSC INC, and YAML files Michael D Kinney
2020-01-27 23:43 ` [edk2-devel] " brbarkel
2020-01-24 2:10 ` [Patch 08/11] MdePkg/Test: Add SafeIntLib and BaseLib Base64 unit tests Michael D Kinney
2020-01-27 23:43 ` [edk2-devel] " brbarkel
2020-02-07 1:27 ` Wu, Hao A
2020-02-07 7:56 ` Liming Gao
2020-02-07 16:05 ` Michael D Kinney
2020-01-24 2:10 ` [Patch 09/11] MdeModulePkg: Add DxeResetSystemLib unit test Michael D Kinney
2020-01-27 23:43 ` [edk2-devel] " brbarkel
2020-02-07 1:25 ` Wu, Hao A
2020-01-24 2:10 ` [Patch 10/11] .azurepipelines: Enable CI for UnitTestFrameworkPkg and host tests Michael D Kinney
2020-01-27 23:44 ` [edk2-devel] " brbarkel
2020-01-24 2:10 ` [Patch 11/11] Maintainers.txt: Add UnitTestFrameworkPkg Michael D Kinney
2020-01-24 10:22 ` Laszlo Ersek
2020-01-27 23:44 ` [edk2-devel] " brbarkel
2020-01-27 23:28 ` [edk2-devel] [Patch 00/11] Add Unit Test Framework brbarkel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200124021032.13808-4-michael.d.kinney@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox