]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg/Include/Library: Add UnitTestLib class
authorBret Barkelew <brbarkel@microsoft.com>
Mon, 11 Nov 2019 07:10:55 +0000 (23:10 -0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 7 Feb 2020 19:18:53 +0000 (19:18 +0000)
https://bugzilla.tianocore.org/show_bug.cgi?id=2505

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>
Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
MdePkg/Include/Library/UnitTestLib.h [new file with mode: 0644]
MdePkg/MdePkg.dec

diff --git a/MdePkg/Include/Library/UnitTestLib.h b/MdePkg/Include/Library/UnitTestLib.h
new file mode 100644 (file)
index 0000000..c06c36b
--- /dev/null
@@ -0,0 +1,757 @@
+/** @file\r
+  Provides a unit test framework.  This allows tests to focus on testing logic\r
+  and the framework to focus on runnings, reporting, statistics, etc.\r
+\r
+  Copyright (c) Microsoft Corporation.<BR>\r
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#ifndef __UNIT_TEST_LIB_H__\r
+#define __UNIT_TEST_LIB_H__\r
+\r
+///\r
+/// Unit Test Status\r
+///\r
+typedef UINT32  UNIT_TEST_STATUS;\r
+#define UNIT_TEST_PASSED                      (0)\r
+#define UNIT_TEST_ERROR_PREREQUISITE_NOT_MET  (1)\r
+#define UNIT_TEST_ERROR_TEST_FAILED           (2)\r
+#define UNIT_TEST_ERROR_CLEANUP_FAILED        (3)\r
+#define UNIT_TEST_SKIPPED                     (0xFFFFFFFD)\r
+#define UNIT_TEST_RUNNING                     (0xFFFFFFFE)\r
+#define UNIT_TEST_PENDING                     (0xFFFFFFFF)\r
+\r
+///\r
+/// Declare PcdUnitTestLogLevel bits and UnitTestLog() ErrorLevel parameter.\r
+///\r
+#define UNIT_TEST_LOG_LEVEL_ERROR    BIT0\r
+#define UNIT_TEST_LOG_LEVEL_WARN     BIT1\r
+#define UNIT_TEST_LOG_LEVEL_INFO     BIT2\r
+#define UNIT_TEST_LOG_LEVEL_VERBOSE  BIT3\r
+\r
+///\r
+/// Unit Test Framework Handle\r
+///\r
+struct UNIT_TEST_FRAMEWORK_OBJECT;\r
+typedef struct UNIT_TEST_FRAMEWORK_OBJECT  *UNIT_TEST_FRAMEWORK_HANDLE;\r
+\r
+///\r
+/// Unit Test Suite Handle\r
+///\r
+struct UNIT_TEST_SUITE_OBJECT;\r
+typedef struct UNIT_TEST_SUITE_OBJECT  *UNIT_TEST_SUITE_HANDLE;\r
+\r
+///\r
+/// Unit Test Handle\r
+///\r
+struct UNIT_TEST_OBJECT;\r
+typedef struct UNIT_TEST_OBJECT  *UNIT_TEST_HANDLE;\r
+\r
+///\r
+/// Unit Test Context\r
+///\r
+typedef VOID*  UNIT_TEST_CONTEXT;\r
+\r
+/**\r
+  The prototype for a single UnitTest case function.\r
+\r
+  Functions with this prototype are registered to be dispatched by the\r
+  UnitTest framework, and results are recorded as test Pass or Fail.\r
+\r
+  @param[in]  Context    [Optional] An optional parameter that enables:\r
+                         1) test-case reuse with varied parameters and\r
+                         2) test-case re-entry for Target tests that need a\r
+                         reboot.  This parameter is a VOID* and it is the\r
+                         responsibility of the test author to ensure that the\r
+                         contents are well understood by all test cases that may\r
+                         consume it.\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+typedef\r
+UNIT_TEST_STATUS\r
+(EFIAPI *UNIT_TEST_FUNCTION)(\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  );\r
+\r
+/**\r
+  Unit-Test Prerequisite Function pointer type.\r
+\r
+  Functions with this prototype are registered to be dispatched by the unit test\r
+  framework prior to a given test case. If this prereq function returns\r
+  UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, the test case will be skipped.\r
+\r
+  @param[in]  Context    [Optional] An optional parameter that enables:\r
+                         1) test-case reuse with varied parameters and\r
+                         2) test-case re-entry for Target tests that need a\r
+                         reboot.  This parameter is a VOID* and it is the\r
+                         responsibility of the test author to ensure that the\r
+                         contents are well understood by all test cases that may\r
+                         consume it.\r
+\r
+  @retval  UNIT_TEST_PASSED                      Unit test case prerequisites\r
+                                                 are met.\r
+  @retval  UNIT_TEST_ERROR_PREREQUISITE_NOT_MET  Test case should be skipped.\r
+\r
+**/\r
+typedef\r
+UNIT_TEST_STATUS\r
+(EFIAPI *UNIT_TEST_PREREQUISITE)(\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  );\r
+\r
+/**\r
+  Unit-Test Cleanup (after) function pointer type.\r
+\r
+  Functions with this prototype are registered to be dispatched by the\r
+  unit test framework after a given test case. This will be called even if the\r
+  test case returns an error, but not if the prerequisite fails and the test is\r
+  skipped.  The purpose of this function is to clean up any global state or\r
+  test data.\r
+\r
+  @param[in]  Context    [Optional] An optional parameter that enables:\r
+                         1) test-case reuse with varied parameters and\r
+                         2) test-case re-entry for Target tests that need a\r
+                         reboot.  This parameter is a VOID* and it is the\r
+                         responsibility of the test author to ensure that the\r
+                         contents are well understood by all test cases that may\r
+                         consume it.\r
+\r
+  @retval  UNIT_TEST_PASSED                Test case cleanup succeeded.\r
+  @retval  UNIT_TEST_ERROR_CLEANUP_FAILED  Test case cleanup failed.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_CLEANUP)(\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  );\r
+\r
+/**\r
+  Unit-Test Test Suite Setup (before) function pointer type. Functions with this\r
+  prototype are registered to be dispatched by the UnitTest framework prior to\r
+  running any of the test cases in a test suite.  It will only be run once at\r
+  the beginning of the suite (not prior to each case).\r
+\r
+  The purpose of this function is to set up any global state or test data.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_SUITE_SETUP)(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Unit-Test Test Suite Teardown (after) function pointer type.  Functions with\r
+  this prototype are registered to be dispatched by the UnitTest framework after\r
+  running all of the test cases in a test suite.  It will only be run once at\r
+  the end of the suite.\r
+\r
+  The purpose of this function is to clean up any global state or test data.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_SUITE_TEARDOWN)(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Method to Initialize the Unit Test framework.  This function registers the\r
+  test name and also initializes the internal state of the test framework to\r
+  receive any new suites and tests.\r
+\r
+  @param[out]  FrameworkHandle  Unit test framework to be created.\r
+  @param[in]   Title            Null-terminated ASCII string that is the user\r
+                                friendly name of the framework. String is\r
+                                copied.\r
+  @param[in]   ShortTitle       Null-terminated ASCII short string that is the\r
+                                short name of the framework with no spaces.\r
+                                String is copied.\r
+  @param[in]   VersionString    Null-terminated ASCII version string for the\r
+                                framework. String is copied.\r
+\r
+  @retval  EFI_SUCCESS            The unit test framework was initialized.\r
+  @retval  EFI_INVALID_PARAMETER  FrameworkHandle is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Title is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  ShortTitle is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  VersionString is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  ShortTitle is invalid.\r
+  @retval  EFI_OUT_OF_RESOURCES   There are not enough resources available to\r
+                                  initialize the unit test framework.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitUnitTestFramework (\r
+  OUT UNIT_TEST_FRAMEWORK_HANDLE  *FrameworkHandle,\r
+  IN  CHAR8                       *Title,\r
+  IN  CHAR8                       *ShortTitle,\r
+  IN  CHAR8                       *VersionString\r
+  );\r
+\r
+/**\r
+  Registers a Unit Test Suite in the Unit Test Framework.\r
+  At least one test suite must be registered, because all test cases must be\r
+  within a unit test suite.\r
+\r
+  @param[out]  SuiteHandle      Unit test suite to create\r
+  @param[in]   FrameworkHandle  Unit test framework to add unit test suite to\r
+  @param[in]   Title            Null-terminated ASCII string that is the user\r
+                                friendly name of the test suite.  String is\r
+                                copied.\r
+  @param[in]   Name             Null-terminated ASCII string that is the short\r
+                                name of the test suite with no spaces.  String\r
+                                is copied.\r
+  @param[in]   Setup            Setup function, runs before suite.  This is an\r
+                                optional parameter that may be NULL.\r
+  @param[in]   Teardown         Teardown function, runs after suite.  This is an\r
+                                optional parameter that may be NULL.\r
+\r
+  @retval  EFI_SUCCESS            The unit test suite was created.\r
+  @retval  EFI_INVALID_PARAMETER  SuiteHandle is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  FrameworkHandle is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Title is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Name is NULL.\r
+  @retval  EFI_OUT_OF_RESOURCES   There are not enough resources available to\r
+                                  initialize the unit test suite.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateUnitTestSuite (\r
+  OUT UNIT_TEST_SUITE_HANDLE      *SuiteHandle,\r
+  IN  UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle,\r
+  IN  CHAR8                       *Title,\r
+  IN  CHAR8                       *Name,\r
+  IN  UNIT_TEST_SUITE_SETUP       Setup     OPTIONAL,\r
+  IN  UNIT_TEST_SUITE_TEARDOWN    Teardown  OPTIONAL\r
+  );\r
+\r
+/**\r
+  Adds test case to Suite\r
+\r
+  @param[in]  SuiteHandle   Unit test suite to add test to.\r
+  @param[in]  Description   Null-terminated ASCII string that is the user\r
+                            friendly description of a test.  String is copied.\r
+  @param[in]  Name          Null-terminated ASCII string that is the short name\r
+                            of the test with no spaces.  String is copied.\r
+  @param[in]  Function      Unit test function.\r
+  @param[in]  Prerequisite  Prerequisite function, runs before test.  This is\r
+                            an optional parameter that may be NULL.\r
+  @param[in]  CleanUp       Clean up function, runs after test.  This is an\r
+                            optional parameter that may be NULL.\r
+  @param[in]  Context       Pointer to context.    This is an optional parameter\r
+                            that may be NULL.\r
+\r
+  @retval  EFI_SUCCESS            The unit test case was added to Suite.\r
+  @retval  EFI_INVALID_PARAMETER  SuiteHandle is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Description is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Name is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  Function is NULL.\r
+  @retval  EFI_OUT_OF_RESOURCES   There are not enough resources available to\r
+                                  add the unit test case to Suite.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AddTestCase (\r
+  IN UNIT_TEST_SUITE_HANDLE  SuiteHandle,\r
+  IN CHAR8                   *Description,\r
+  IN CHAR8                   *Name,\r
+  IN UNIT_TEST_FUNCTION      Function,\r
+  IN UNIT_TEST_PREREQUISITE  Prerequisite  OPTIONAL,\r
+  IN UNIT_TEST_CLEANUP       CleanUp       OPTIONAL,\r
+  IN UNIT_TEST_CONTEXT       Context       OPTIONAL\r
+  );\r
+\r
+/**\r
+  Execute all unit test cases in all unit test suites added to a Framework.\r
+\r
+  Once a unit test framework is initialized and all unit test suites and unit\r
+  test cases are registered, this function will cause the unit test framework to\r
+  dispatch all unit test cases in sequence and record the results for reporting.\r
+\r
+  @param[in]  FrameworkHandle  A handle to the current running framework that\r
+                               dispatched the test.  Necessary for recording\r
+                               certain test events with the framework.\r
+\r
+  @retval  EFI_SUCCESS            All test cases were dispatched.\r
+  @retval  EFI_INVALID_PARAMETER  FrameworkHandle is NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RunAllTestSuites (\r
+  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle\r
+  );\r
+\r
+/**\r
+  Cleanup a test framework.\r
+\r
+  After tests are run, this will teardown the entire framework and free all\r
+  allocated data within.\r
+\r
+  @param[in]  FrameworkHandle  A handle to the current running framework that\r
+                               dispatched the test.  Necessary for recording\r
+                               certain test events with the framework.\r
+\r
+  @retval  EFI_SUCCESS            All resources associated with framework were\r
+                                  freed.\r
+  @retval  EFI_INVALID_PARAMETER  FrameworkHandle is NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FreeUnitTestFramework (\r
+  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle\r
+  );\r
+\r
+/**\r
+  Leverages a framework-specific mechanism (see UnitTestPersistenceLib if you're\r
+  a framework author) to save the state of the executing framework along with\r
+  any allocated data so that the test may be resumed upon reentry. A test case\r
+  should pass any needed context (which, to prevent an infinite loop, should be\r
+  at least the current execution count) which will be saved by the framework and\r
+  passed to the test case upon resume.\r
+\r
+  Generally called from within a test case prior to quitting or rebooting.\r
+\r
+  @param[in]  FrameworkHandle    A handle to the current running framework that\r
+                                 dispatched the test.  Necessary for recording\r
+                                 certain test events with the framework.\r
+  @param[in]  ContextToSave      A buffer of test case-specific data to be saved\r
+                                 along with framework state.  Will be passed as\r
+                                 "Context" to the test case upon resume.  This\r
+                                 is an optional parameter that may be NULL.\r
+  @param[in]  ContextToSaveSize  Size of the ContextToSave buffer.\r
+\r
+  @retval  EFI_SUCCESS            The framework state and context were saved.\r
+  @retval  EFI_INVALID_PARAMETER  FrameworkHandle is NULL.\r
+  @retval  EFI_INVALID_PARAMETER  ContextToSave is not NULL and\r
+                                  ContextToSaveSize is 0.\r
+  @retval  EFI_INVALID_PARAMETER  ContextToSave is >= 4GB.\r
+  @retval  EFI_OUT_OF_RESOURCES   There are not enough resources available to\r
+                                  save the framework and context state.\r
+  @retval  EFI_DEVICE_ERROR       The framework and context state could not be\r
+                                  saved to a persistent storage device due to a\r
+                                  device error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SaveFrameworkState (\r
+  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle,\r
+  IN UNIT_TEST_CONTEXT           ContextToSave     OPTIONAL,\r
+  IN UINTN                       ContextToSaveSize\r
+  );\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check an expression for\r
+  "TRUE". If the expression evaluates to TRUE, execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  Expression  Expression to be evaluated for TRUE.\r
+**/\r
+#define UT_ASSERT_TRUE(Expression)                                                        \\r
+  if(!UnitTestAssertTrue ((Expression), __FUNCTION__, __LINE__, __FILE__, #Expression)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                   \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check an expression for\r
+  "FALSE". If the expression evaluates to FALSE, execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  Expression  Expression to be evaluated for FALSE.\r
+**/\r
+#define UT_ASSERT_FALSE(Expression)                                                        \\r
+  if(!UnitTestAssertFalse ((Expression), __FUNCTION__, __LINE__, __FILE__, #Expression)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                    \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check whether two simple\r
+  values are equal.  If the values are equal, execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  ValueA  Value to be compared for equality (64-bit comparison).\r
+  @param[in]  ValueB  Value to be compared for equality (64-bit comparison).\r
+**/\r
+#define UT_ASSERT_EQUAL(ValueA, ValueB)                                                                           \\r
+  if(!UnitTestAssertEqual ((UINT64)(ValueA), (UINT64)(ValueB), __FUNCTION__, __LINE__, __FILE__, #ValueA, #ValueB)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                                           \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check whether two memory\r
+  buffers are equal.  If the buffers are equal, execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  BufferA  Pointer to a buffer for comparison.\r
+  @param[in]  BufferB  Pointer to a buffer for comparison.\r
+  @param[in]  Length   Number of bytes to compare in BufferA and BufferB.\r
+**/\r
+#define UT_ASSERT_MEM_EQUAL(BufferA, BufferB, Length)                                                                               \\r
+  if(!UnitTestAssertMemEqual ((VOID *)(UINTN)(BufferA), (VOID *)(UINTN)(BufferB), (UINTN)Length, __FUNCTION__, __LINE__, __FILE__, #BufferA, #BufferB)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                                                           \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check whether two simple\r
+  values are non-equal.  If the values are non-equal, execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  ValueA  Value to be compared for inequality (64-bit comparison).\r
+  @param[in]  ValueB  Value to be compared for inequality (64-bit comparison).\r
+**/\r
+#define UT_ASSERT_NOT_EQUAL(ValueA, ValueB)                                                                          \\r
+  if(!UnitTestAssertNotEqual ((UINT64)(ValueA), (UINT64)(ValueB), __FUNCTION__, __LINE__, __FILE__, #ValueA, #ValueB)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                                              \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check whether an EFI_STATUS\r
+  value is !EFI_ERROR().  If the status is !EFI_ERROR(), execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  Status  EFI_STATUS value to check.\r
+**/\r
+#define UT_ASSERT_NOT_EFI_ERROR(Status)                                                \\r
+  if(!UnitTestAssertNotEfiError ((Status), __FUNCTION__, __LINE__, __FILE__, #Status)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check whether two EFI_STATUS\r
+  values are equal.  If the values are equal, execution continues.\r
+  Otherwise, the test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  Status    EFI_STATUS values to compare for equality.\r
+  @param[in]  Expected  EFI_STATUS values to compare for equality.\r
+**/\r
+#define UT_ASSERT_STATUS_EQUAL(Status, Expected)                                                 \\r
+  if(!UnitTestAssertStatusEqual ((Status), (Expected), __FUNCTION__, __LINE__, __FILE__, #Status)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                                          \\r
+  }\r
+\r
+/**\r
+  This macro uses the framework assertion logic to check whether a pointer is\r
+  not NULL.  If the pointer is not NULL, execution continues. Otherwise, the\r
+  test case immediately returns UNIT_TEST_ERROR_TEST_FAILED.\r
+\r
+  @param[in]  Pointer  Pointer to be checked against NULL.\r
+**/\r
+#define UT_ASSERT_NOT_NULL(Pointer)                                                  \\r
+  if(!UnitTestAssertNotNull ((Pointer), __FUNCTION__, __LINE__, __FILE__, #Pointer)) { \\r
+    return UNIT_TEST_ERROR_TEST_FAILED;                                              \\r
+  }\r
+\r
+/**\r
+  If Expression is TRUE, then TRUE is returned.\r
+  If Expression is FALSE, then an assert is triggered and the location of the\r
+  assert provided by FunctionName, LineNumber, FileName, and Description are\r
+  recorded and FALSE is returned.\r
+\r
+  @param[in]  Expression    The BOOLEAN result of the expression evaluation.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  Description   Null-terminated ASCII string of the expression being\r
+                            evaluated.\r
+\r
+  @retval  TRUE   Expression is TRUE.\r
+  @retval  FALSE  Expression is FALSE.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertTrue (\r
+  IN BOOLEAN      Expression,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *Description\r
+  );\r
+\r
+/**\r
+  If Expression is FALSE, then TRUE is returned.\r
+  If Expression is TRUE, then an assert is triggered and the location of the\r
+  assert provided by FunctionName, LineNumber, FileName, and Description are\r
+  recorded and FALSE is returned.\r
+\r
+  @param[in]  Expression    The BOOLEAN result of the expression evaluation.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  Description   Null-terminated ASCII string of the expression being\r
+                            evaluated.\r
+\r
+  @retval  TRUE   Expression is FALSE.\r
+  @retval  FALSE  Expression is TRUE.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertFalse (\r
+  IN BOOLEAN      Expression,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *Description\r
+  );\r
+\r
+/**\r
+  If Status is not an EFI_ERROR(), then TRUE is returned.\r
+  If Status is an EFI_ERROR(), then an assert is triggered and the location of\r
+  the assert provided by FunctionName, LineNumber, FileName, and Description are\r
+  recorded and FALSE is returned.\r
+\r
+  @param[in]  Status        The EFI_STATUS value to evaluate.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  Description   Null-terminated ASCII string of the status\r
+                            expression being evaluated.\r
+\r
+  @retval  TRUE   Status is not an EFI_ERROR().\r
+  @retval  FALSE  Status is an EFI_ERROR().\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertNotEfiError (\r
+  IN EFI_STATUS   Status,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *Description\r
+  );\r
+\r
+/**\r
+  If ValueA is equal ValueB, then TRUE is returned.\r
+  If ValueA is not equal to ValueB, then an assert is triggered and the location\r
+  of the assert provided by FunctionName, LineNumber, FileName, DescriptionA,\r
+  and DescriptionB are recorded and FALSE is returned.\r
+\r
+  @param[in]  ValueA        64-bit value.\r
+  @param[in]  ValueB        64-bit value.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  DescriptionA  Null-terminated ASCII string that is a description\r
+                            of ValueA.\r
+  @param[in]  DescriptionB  Null-terminated ASCII string that is a description\r
+                            of ValueB.\r
+\r
+  @retval  TRUE   ValueA is equal to ValueB.\r
+  @retval  FALSE  ValueA is not equal to ValueB.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertEqual (\r
+  IN UINT64       ValueA,\r
+  IN UINT64       ValueB,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *DescriptionA,\r
+  IN CONST CHAR8  *DescriptionB\r
+  );\r
+\r
+/**\r
+  If the contents of BufferA are identical to the contents of BufferB, then TRUE\r
+  is returned.  If the contents of BufferA are not identical to the contents of\r
+  BufferB, then an assert is triggered and the location of the assert provided\r
+  by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are\r
+  recorded and FALSE is returned.\r
+\r
+  @param[in]  BufferA       Pointer to a buffer for comparison.\r
+  @param[in]  BufferB       Pointer to a buffer for comparison.\r
+  @param[in]  Length        Number of bytes to compare in BufferA and BufferB.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  DescriptionA  Null-terminated ASCII string that is a description\r
+                            of BufferA.\r
+  @param[in]  DescriptionB  Null-terminated ASCII string that is a description\r
+                            of BufferB.\r
+\r
+  @retval  TRUE   The contents of BufferA are identical to the contents of\r
+                  BufferB.\r
+  @retval  FALSE  The contents of BufferA are not identical to the contents of\r
+                  BufferB.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertMemEqual (\r
+  IN VOID         *BufferA,\r
+  IN VOID         *BufferB,\r
+  IN UINTN        Length,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *DescriptionA,\r
+  IN CONST CHAR8  *DescriptionB\r
+  );\r
+\r
+/**\r
+  If ValueA is not equal ValueB, then TRUE is returned.\r
+  If ValueA is equal to ValueB, then an assert is triggered and the location\r
+  of the assert provided by FunctionName, LineNumber, FileName, DescriptionA\r
+  and DescriptionB are recorded and FALSE is returned.\r
+\r
+  @param[in]  ValueA        64-bit value.\r
+  @param[in]  ValueB        64-bit value.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  DescriptionA  Null-terminated ASCII string that is a description\r
+                            of ValueA.\r
+  @param[in]  DescriptionB  Null-terminated ASCII string that is a description\r
+                            of ValueB.\r
+\r
+  @retval  TRUE   ValueA is not equal to ValueB.\r
+  @retval  FALSE  ValueA is equal to ValueB.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertNotEqual (\r
+  IN UINT64       ValueA,\r
+  IN UINT64       ValueB,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *DescriptionA,\r
+  IN CONST CHAR8  *DescriptionB\r
+  );\r
+\r
+/**\r
+  If Status is equal to Expected, then TRUE is returned.\r
+  If Status is not equal to Expected, then an assert is triggered and the\r
+  location of the assert provided by FunctionName, LineNumber, FileName, and\r
+  Description are recorded and FALSE is returned.\r
+\r
+  @param[in]  Status        EFI_STATUS value returned from an API under test.\r
+  @param[in]  Expected      The expected EFI_STATUS return value from an API\r
+                            under test.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  Description   Null-terminated ASCII string that is a description\r
+                            of Status.\r
+\r
+  @retval  TRUE   Status is equal to Expected.\r
+  @retval  FALSE  Status is not equal to Expected.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertStatusEqual (\r
+  IN EFI_STATUS   Status,\r
+  IN EFI_STATUS   Expected,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *Description\r
+  );\r
+\r
+/**\r
+  If Pointer is not equal to NULL, then TRUE is returned.\r
+  If Pointer is equal to NULL, then an assert is triggered and the location of\r
+  the assert provided by FunctionName, LineNumber, FileName, and PointerName\r
+  are recorded and FALSE is returned.\r
+\r
+  @param[in]  Pointer       Pointer value to be checked against NULL.\r
+  @param[in]  Expected      The expected EFI_STATUS return value from a function\r
+                            under test.\r
+  @param[in]  FunctionName  Null-terminated ASCII string of the function\r
+                            executing the assert macro.\r
+  @param[in]  LineNumber    The source file line number of the assert macro.\r
+  @param[in]  FileName      Null-terminated ASCII string of the filename\r
+                            executing the assert macro.\r
+  @param[in]  PointerName   Null-terminated ASCII string that is a description\r
+                            of Pointer.\r
+\r
+  @retval  TRUE   Pointer is not equal to NULL.\r
+  @retval  FALSE  Pointer is equal to NULL.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UnitTestAssertNotNull (\r
+  IN VOID         *Pointer,\r
+  IN CONST CHAR8  *FunctionName,\r
+  IN UINTN        LineNumber,\r
+  IN CONST CHAR8  *FileName,\r
+  IN CONST CHAR8  *PointerName\r
+  );\r
+\r
+/**\r
+  Test logging macro that records an ERROR message in the test framework log.\r
+  Record is associated with the currently executing test case.\r
+\r
+  @param[in]  Format  Formatting string following the format defined in\r
+                      MdePkg/Include/Library/PrintLib.h.\r
+  @param[in]  ...     Print args.\r
+**/\r
+#define UT_LOG_ERROR(Format, ...)  \\r
+  UnitTestLog (UNIT_TEST_LOG_LEVEL_ERROR, Format, ##__VA_ARGS__)\r
+\r
+/**\r
+  Test logging macro that records a WARNING message in the test framework log.\r
+  Record is associated with the currently executing test case.\r
+\r
+  @param[in]  Format  Formatting string following the format defined in\r
+                      MdePkg/Include/Library/PrintLib.h.\r
+  @param[in]  ...     Print args.\r
+**/\r
+#define UT_LOG_WARNING(Format, ...)  \\r
+  UnitTestLog (UNIT_TEST_LOG_LEVEL_WARN, Format, ##__VA_ARGS__)\r
+\r
+/**\r
+  Test logging macro that records an INFO message in the test framework log.\r
+  Record is associated with the currently executing test case.\r
+\r
+  @param[in]  Format  Formatting string following the format defined in\r
+                      MdePkg/Include/Library/PrintLib.h.\r
+  @param[in]  ...     Print args.\r
+**/\r
+#define UT_LOG_INFO(Format, ...)  \\r
+  UnitTestLog (UNIT_TEST_LOG_LEVEL_INFO, Format, ##__VA_ARGS__)\r
+\r
+/**\r
+  Test logging macro that records a VERBOSE message in the test framework log.\r
+  Record is associated with the currently executing test case.\r
+\r
+  @param[in]  Format  Formatting string following the format defined in\r
+                      MdePkg/Include/Library/PrintLib.h.\r
+  @param[in]  ...     Print args.\r
+**/\r
+#define UT_LOG_VERBOSE(Format, ...)  \\r
+  UnitTestLog (UNIT_TEST_LOG_LEVEL_VERBOSE, Format, ##__VA_ARGS__)\r
+\r
+/**\r
+  Test logging function that records a messages in the test framework log.\r
+  Record is associated with the currently executing test case.\r
+\r
+  @param[in]  ErrorLevel  The error level of the unit test log message.\r
+  @param[in]  Format      Formatting string following the format defined in the\r
+                          MdePkg/Include/Library/PrintLib.h.\r
+  @param[in]  ...         Print args.\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestLog (\r
+  IN  UINTN        ErrorLevel,\r
+  IN  CONST CHAR8  *Format,\r
+  ...\r
+  );\r
+\r
+#endif\r
index d022cc5e3ef2176af64329093ecd111122996817..ac1f5339af0697d7da170a171ef90750a6630bf6 100644 (file)
   ##  @libraryclass  Module entry point library for standalone MM drivers.\r
   StandaloneMmDriverEntryPoint|Include/Library/StandaloneMmDriverEntryPoint.h\r
 \r
+  ## @libraryclass Provides a unit test framework\r
+  #\r
+  UnitTestLib|Include/Library/UnitTestLib.h\r
+\r
 [LibraryClasses.IA32, LibraryClasses.X64]\r
   ##  @libraryclass  Abstracts both S/W SMI generation and detection.\r
   ##\r