--- /dev/null
+/** @file\r
+ Provides a library function that can be customized to set the platform to boot\r
+ from USB on the next boot. This allows the test framework to reboot back to\r
+ USB. Since boot managers are not all the same creating a lib to support\r
+ platform customization will make porting to new code base/platform easier.\r
+\r
+ Copyright (c) Microsoft Corporation.<BR>\r
+ Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __UNIT_TEST_BOOT_LIB_H__\r
+#define __UNIT_TEST_BOOT_LIB_H__\r
+\r
+/**\r
+ Set the boot manager to boot from a specific device on the next boot. This\r
+ should be set only for the next boot and shouldn't require any manual clean up\r
+\r
+ @retval EFI_SUCCESS Boot device for next boot was set.\r
+ @retval EFI_UNSUPPORTED Setting the boot device for the next boot is not\r
+ supportted.\r
+ @retval Other Boot device for next boot can not be set.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetBootNextDevice (\r
+ VOID\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ This header file describes a library that contains functions to save and\r
+ restore unit test internal state, in case the test needs to pause and resume\r
+ (eg. a reboot-based test).\r
+\r
+ Copyright (c) Microsoft Corporation.<BR>\r
+ Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _UNIT_TEST_PERSISTENCE_LIB_H_\r
+#define _UNIT_TEST_PERSISTENCE_LIB_H_\r
+\r
+#include <UnitTestFrameworkTypes.h>\r
+\r
+#define UNIT_TEST_PERSISTENCE_LIB_VERSION 1\r
+\r
+/**\r
+ Determines whether a persistence cache already exists for\r
+ the given framework.\r
+\r
+ @param[in] FrameworkHandle A pointer to the framework that is being persisted.\r
+\r
+ @retval TRUE\r
+ @retval FALSE Cache doesn't exist or an error occurred.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DoesCacheExist (\r
+ IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle\r
+ );\r
+\r
+/**\r
+ Will save the data associated with an internal Unit Test Framework\r
+ state in a manner that can persist a Unit Test Application quit or\r
+ even a system reboot.\r
+\r
+ @param[in] FrameworkHandle A pointer to the framework that is being persisted.\r
+ @param[in] SaveData A pointer to the buffer containing the serialized\r
+ framework internal state.\r
+\r
+ @retval EFI_SUCCESS Data is persisted and the test can be safely quit.\r
+ @retval Others Data is not persisted and test cannot be resumed upon exit.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SaveUnitTestCache (\r
+ IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,\r
+ IN UNIT_TEST_SAVE_HEADER *SaveData\r
+ );\r
+\r
+/**\r
+ Will retrieve any cached state associated with the given framework.\r
+ Will allocate a buffer to hold the loaded data.\r
+\r
+ @param[in] FrameworkHandle A pointer to the framework that is being persisted.\r
+ @param[in] SaveData A pointer pointer that will be updated with the address\r
+ of the loaded data buffer.\r
+\r
+ @retval EFI_SUCCESS Data has been loaded successfully and SaveData is updated\r
+ with a pointer to the buffer.\r
+ @retval Others An error has occurred and no data has been loaded. SaveData\r
+ is set to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LoadUnitTestCache (\r
+ IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,\r
+ OUT UNIT_TEST_SAVE_HEADER **SaveData\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Provides a unit test result report. This allows new result output formats to\r
+ be easily customized.\r
+\r
+ Copyright (c) Microsoft Corporation.<BR>\r
+ Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __UNIT_TEST_RESULT_REPORT_LIB_H__\r
+#define __UNIT_TEST_RESULT_REPORT_LIB_H__\r
+\r
+#include <UnitTestFrameworkTypes.h>\r
+\r
+/**\r
+Method to produce the Unit Test run results\r
+\r
+@retval Success\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OutputUnitTestFrameworkReport (\r
+ IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Provides the basic types and common elements of the unit test framework\r
+\r
+ Copyright (c) Microsoft Corporation.<BR>\r
+ Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __UNIT_TEST_TYPES_H__\r
+#define __UNIT_TEST_TYPES_H__\r
+\r
+#include <Library/UnitTestLib.h>\r
+\r
+///\r
+/// The maximum length of a string stored in the unit test framework\r
+///\r
+#define UNIT_TEST_MAX_STRING_LENGTH (120)\r
+\r
+///\r
+/// The size of a firngerprint used to save/resume execution of a unit test\r
+/// framework. This is the size of a CRC32 value which is 32-bit value.\r
+///\r
+///\r
+#define UNIT_TEST_FINGERPRINT_SIZE (sizeof (UINT32))\r
+\r
+///\r
+/// The maximum length of a test failure message stored in the unit test\r
+/// framework\r
+///\r
+#define UNIT_TEST_TESTFAILUREMSG_LENGTH (120)\r
+\r
+///\r
+/// FAILURE_TYPE used to record the type of assert that was triggered by a unit\r
+/// test.\r
+///\r
+typedef UINT32 FAILURE_TYPE;\r
+#define FAILURETYPE_NOFAILURE (0)\r
+#define FAILURETYPE_OTHER (1)\r
+#define FAILURETYPE_ASSERTTRUE (2)\r
+#define FAILURETYPE_ASSERTFALSE (3)\r
+#define FAILURETYPE_ASSERTEQUAL (4)\r
+#define FAILURETYPE_ASSERTNOTEQUAL (5)\r
+#define FAILURETYPE_ASSERTNOTEFIERROR (6)\r
+#define FAILURETYPE_ASSERTSTATUSEQUAL (7)\r
+#define FAILURETYPE_ASSERTNOTNULL (8)\r
+\r
+///\r
+/// Unit Test context structure tracked by the unit test framework.\r
+///\r
+typedef struct {\r
+ CHAR8 *Description;\r
+ CHAR8 *Name; //can't have spaces and should be short\r
+ CHAR8 *Log;\r
+ FAILURE_TYPE FailureType;\r
+ CHAR8 FailureMessage[UNIT_TEST_TESTFAILUREMSG_LENGTH];\r
+ UINT8 Fingerprint[UNIT_TEST_FINGERPRINT_SIZE];\r
+ UNIT_TEST_STATUS Result;\r
+ UNIT_TEST_FUNCTION RunTest;\r
+ UNIT_TEST_PREREQUISITE Prerequisite;\r
+ UNIT_TEST_CLEANUP CleanUp;\r
+ UNIT_TEST_CONTEXT Context;\r
+ UNIT_TEST_SUITE_HANDLE ParentSuite;\r
+} UNIT_TEST;\r
+\r
+///\r
+/// Structure used to store the set of unit tests in a unit test suite as a list.\r
+///\r
+typedef struct {\r
+ LIST_ENTRY Entry;\r
+ UNIT_TEST UT;\r
+} UNIT_TEST_LIST_ENTRY;\r
+\r
+///\r
+/// Unit Test Suite context structure tracked by the unit test framework.\r
+///\r
+typedef struct {\r
+ UINTN NumTests;\r
+ CHAR8 *Title;\r
+ CHAR8 *Name;\r
+ UINT8 Fingerprint[UNIT_TEST_FINGERPRINT_SIZE];\r
+ UNIT_TEST_SUITE_SETUP Setup;\r
+ UNIT_TEST_SUITE_TEARDOWN Teardown;\r
+ LIST_ENTRY TestCaseList; // UNIT_TEST_LIST_ENTRY\r
+ UNIT_TEST_FRAMEWORK_HANDLE ParentFramework;\r
+} UNIT_TEST_SUITE;\r
+\r
+///\r
+/// Structure used to store the set of unit test suites in a unit test framework\r
+/// as a list.\r
+///\r
+typedef struct {\r
+ LIST_ENTRY Entry;\r
+ UNIT_TEST_SUITE UTS;\r
+} UNIT_TEST_SUITE_LIST_ENTRY;\r
+\r
+///\r
+/// Unit Test Framework context structure tracked by the unit test framework.\r
+///\r
+typedef struct {\r
+ CHAR8 *Title;\r
+ CHAR8 *ShortTitle; // This title should contain NO spaces or non-filename characters. Is used in reporting and serialization.\r
+ CHAR8 *VersionString;\r
+ CHAR8 *Log;\r
+ UINT8 Fingerprint[UNIT_TEST_FINGERPRINT_SIZE];\r
+ LIST_ENTRY TestSuiteList; // UNIT_TEST_SUITE_LIST_ENTRY\r
+ EFI_TIME StartTime;\r
+ EFI_TIME EndTime;\r
+ UNIT_TEST *CurrentTest;\r
+ VOID *SavedState; // This is an instance of UNIT_TEST_SAVE_HEADER*, if present.\r
+} UNIT_TEST_FRAMEWORK;\r
+\r
+///\r
+/// Serialized version of a unit test\r
+///\r
+typedef struct {\r
+ UINT32 Size; // Size of the UNIT_TEST_SAVE_TEST including Log[]\r
+ UINT8 Fingerprint[UNIT_TEST_FINGERPRINT_SIZE]; // Fingerprint of the test itself.\r
+ CHAR8 FailureMessage[UNIT_TEST_TESTFAILUREMSG_LENGTH];\r
+ FAILURE_TYPE FailureType;\r
+ UNIT_TEST_STATUS Result;\r
+ CHAR8 Log[];\r
+} UNIT_TEST_SAVE_TEST;\r
+\r
+///\r
+/// Serialized version of a unit test context\r
+///\r
+typedef struct {\r
+ UINT32 Size; // Size of the UNIT_TEST_SAVE_CONTEXT including Data[]\r
+ UINT8 Fingerprint[UNIT_TEST_FINGERPRINT_SIZE]; // Fingerprint of the corresponding test.\r
+ UINT8 Data[]; // Actual data of the context.\r
+} UNIT_TEST_SAVE_CONTEXT;\r
+\r
+///\r
+/// Serialized version of unit test framework\r
+///\r
+typedef struct {\r
+ UINT8 Version;\r
+ UINT32 SaveStateSize; // Size of the entire serialized buffer.\r
+ UINT8 Fingerprint[UNIT_TEST_FINGERPRINT_SIZE]; // Fingerprint of the framework that has been saved.\r
+ EFI_TIME StartTime;\r
+ UINT32 TestCount;\r
+ BOOLEAN HasSavedContext;\r
+ // UNIT_TEST_SAVE_TEST Tests[]; // Array of structures starts here.\r
+ // UNIT_TEST_SAVE_CONTEXT SavedContext[]; // Saved context for the currently running test.\r
+ // CHAR8 Log[]; // NOTE: Not yet implemented!!\r
+} UNIT_TEST_SAVE_HEADER;\r
+\r
+/**\r
+ This function is responsible for initializing the log buffer for a single test. It can\r
+ be used internally, but may also be consumed by the test framework to add pre-existing\r
+ data to a log before it's used.\r
+\r
+ @param[in,out] TestHandle A handle to the test being initialized.\r
+ @param[in] Buffer [Optional] A pointer to pre-existing log data that should\r
+ be used to initialize the log. Should include a NULL terminator.\r
+ @param[in] BufferSize [Optional] The size of the pre-existing log data.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestLogInit (\r
+ IN OUT UNIT_TEST *Test,\r
+ IN UINT8 *Buffer OPTIONAL,\r
+ IN UINTN BufferSize OPTIONAL\r
+ );\r
+\r
+/**\r
+ Internal helper function to return a handle to the currently executing framework.\r
+ This function is generally used for communication within the UnitTest framework, but is\r
+ defined here so that it can be consumed by the Assertion and Logging macros.\r
+\r
+ There should be no need to consume as a test writer, but it's there if you need it.\r
+\r
+ @retval Handle to the currently executing test framework.\r
+\r
+**/\r
+UNIT_TEST_FRAMEWORK_HANDLE\r
+GetActiveFrameworkHandle (\r
+ VOID\r
+ );\r
+\r
+#endif\r
--- /dev/null
+# Unit Test Framework Package\r
+\r
+## About\r
+\r
+This package adds a unit test framework capable of building tests for multiple contexts including\r
+the UEFI shell environment and host-based environments. It allows for unit test development to focus\r
+on the tests and leave error logging, result formatting, context persistance, and test running to the framework.\r
+The unit test framework works well for low level unit tests as well as system level tests and\r
+fits easily in automation frameworks.\r
+\r
+### UnitTestLib\r
+\r
+The main "framework" library. The core of the framework is the Framework object, which can have any number\r
+of test cases and test suites registered with it. The Framework object is also what drives test execution.\r
+\r
+The Framework also provides helper macros and functions for checking test conditions and\r
+reporting errors. Status and error info will be logged into the test context. There are a number\r
+of Assert macros that make the unit test code friendly to view and easy to understand.\r
+\r
+Finally, the Framework also supports logging strings during the test execution. This data is logged\r
+to the test context and will be available in the test reporting phase. This should be used for\r
+logging test details and helpful messages to resolve test failures.\r
+\r
+### UnitTestPersistenceLib\r
+\r
+Persistence lib has the main job of saving and restoring test context to a storage medium so that for tests\r
+that require exiting the active process and then resuming state can be maintained. This is critical\r
+in supporting a system reboot in the middle of a test run.\r
+\r
+### UnitTestResultReportLib\r
+\r
+Library provides function to run at the end of a framework test run and handles formatting the report.\r
+This is a common customization point and allows the unit test framework to fit its output reports into\r
+other test infrastructure. In this package a simple library instances has been supplied to output test\r
+results to the console as plain text.\r
+\r
+## Samples\r
+\r
+There is a sample unit test provided as both an example of how to write a unit test and leverage\r
+many of the features of the framework. This sample can be found in the `Test/UnitTest/Sample/SampleUnitTest`\r
+directory.\r
+\r
+The sample is provided in PEI, SMM, DXE, and UEFI App flavors. It also has a flavor for the HOST_APPLICATION\r
+build type, which can be run on a host system without needing a target.\r
+\r
+## Usage\r
+\r
+This section is built a lot like a "Getting Started". We'll go through some of the components that are needed\r
+when constructing a unit test and some of the decisions that are made by the test writer. We'll also describe\r
+how to check for expected conditions in test cases and a bit of the logging characteristics.\r
+\r
+Most of these examples will refer to the SampleUnitTestUefiShell app found in this package.\r
+\r
+### Requirements - INF\r
+\r
+In our INF file, we'll need to bring in the `UnitTestLib` library. Conveniently, the interface\r
+header for the `UnitTestLib` is located in `MdePkg`, so you shouldn't need to depend on any other\r
+packages. As long as your DSC file knows where to find the lib implementation that you want to use,\r
+you should be good to go.\r
+\r
+See this example in 'SampleUnitTestApp.inf'...\r
+\r
+```\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ UefiApplicationEntryPoint\r
+ BaseLib\r
+ DebugLib\r
+ UnitTestLib\r
+ PrintLib\r
+```\r
+\r
+### Requirements - Code\r
+\r
+Not to state the obvious, but let's make sure we have the following include before getting too far along...\r
+\r
+```c\r
+#include <Library/UnitTestLib.h>\r
+```\r
+\r
+Now that we've got that squared away, let's look at our 'Main()'' routine (or DriverEntryPoint() or whatever).\r
+\r
+### Configuring the Framework\r
+\r
+Everything in the UnitTestPkg framework is built around an object called -- conveniently -- the Framework.\r
+This Framework object will contain all the information about our test, the test suites and test cases associated\r
+with it, the current location within the test pass, and any results that have been recorded so far.\r
+\r
+To get started with a test, we must first create a Framework instance. The function for this is\r
+`InitUnitTestFramework`. It takes in `CHAR8` strings for the long name, short name, and test version.\r
+The long name and version strings are just for user presentation and relatively flexible. The short name\r
+will be used to name any cache files and/or test results, so should be a name that makes sense in that context.\r
+These strings are copied internally to the Framework, so using stack-allocated or literal strings is fine.\r
+\r
+In the 'SampleUnitTestUefiShell' app, the module name is used as the short name, so the init looks like this.\r
+\r
+```c\r
+DEBUG(( DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION ));\r
+\r
+//\r
+// Start setting up the test framework for running the tests.\r
+//\r
+Status = InitUnitTestFramework( &Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION );\r
+```\r
+\r
+The `&Framework` returned here is the handle to the Framework. If it's successfully returned, we can start adding\r
+test suites and test cases.\r
+\r
+Test suites exist purely to help organize test cases and to differentiate the results in reports. If you're writing\r
+a small unit test, you can conceivably put all test cases into a single suite. However, if you end up with 20+ test\r
+cases, it may be beneficial to organize them according to purpose. You _must_ have at least one test suite, even if\r
+it's just a catch-all. The function to create a test suite is `CreateUnitTestSuite`. It takes in a handle to\r
+the Framework object, a `CHAR8` string for the suite title and package name, and optional function pointers for\r
+a setup function and a teardown function.\r
+\r
+The suite title is for user presentation. The package name is for xUnit type reporting and uses a '.'-separated\r
+hierarchical format (see 'SampleUnitTestApp' for example). If provided, the setup and teardown functions will be\r
+called once at the start of the suite (before _any_ tests have run) and once at the end of the suite (after _all_\r
+tests have run), respectively. If either or both of these are unneeded, pass `NULL`. The function prototypes are\r
+`UNIT_TEST_SUITE_SETUP` and `UNIT_TEST_SUITE_TEARDOWN`.\r
+\r
+Looking at 'SampleUnitTestUefiShell' app, you can see that the first test suite is created as below...\r
+\r
+```c\r
+//\r
+// Populate the SimpleMathTests Unit Test Suite.\r
+//\r
+Status = CreateUnitTestSuite( &SimpleMathTests, Fw, "Simple Math Tests", "Sample.Math", NULL, NULL );\r
+```\r
+\r
+This test suite has no setup or teardown functions. The `&SimpleMathTests` returned here is a handle to the suite and\r
+will be used when adding test cases.\r
+\r
+Great! Now we've finished some of the cruft, red tape, and busy work. We're ready to add some tests. Adding a test\r
+to a test suite is accomplished with the -- you guessed it -- `AddTestCase` function. It takes in the suite handle;\r
+a `CHAR8` string for the description and class name; a function pointer for the test case itself; additional, optional\r
+function pointers for prerequisite check and cleanup routines; and and optional pointer to a context structure.\r
+\r
+Okay, that's a lot. Let's take it one piece at a time. The description and class name strings are very similar in\r
+usage to the suite title and package name strings in the test suites. The former is for user presentation and the\r
+latter is for xUnit parsing. The test case function pointer is what is actually executed as the "test" and the\r
+prototype should be `UNIT_TEST_FUNCTION`. The last three parameters require a little bit more explaining.\r
+\r
+The prerequisite check function has a prototype of `UNIT_TEST_PREREQUISITE` and -- if provided -- will be called\r
+immediately before the test case. If this function returns any error, the test case will not be run and will be\r
+recorded as `UNIT_TEST_ERROR_PREREQUISITE_NOT_MET`. The cleanup function (prototype `UNIT_TEST_CLEANUP`) will be called\r
+immediately after the test case to provide an opportunity to reset any global state that may have been changed in the\r
+test case. In the event of a prerequisite failure, the cleanup function will also be skipped. If either of these\r
+functions is not needed, pass `NULL`.\r
+\r
+The context pointer is entirely case-specific. It will be passed to the test case upon execution. One of the purposes\r
+of the context pointer is to allow test case reuse with different input data. (Another use is for testing that wraps\r
+around a system reboot, but that's beyond the scope of this guide.) The test case must know how to interpret the context\r
+pointer, so it could be a simple value, or it could be a complex structure. If unneeded, pass `NULL`.\r
+\r
+In 'SampleUnitTestUefiShell' app, the first test case is added using the code below...\r
+\r
+```c\r
+AddTestCase( SimpleMathTests, "Adding 1 to 1 should produce 2", "Addition", OnePlusOneShouldEqualTwo, NULL, NULL, NULL );\r
+```\r
+\r
+This test case calls the function `OnePlusOneShouldEqualTwo` and has no prerequisite, cleanup, or context.\r
+\r
+Once all the suites and cases are added, it's time to run the Framework.\r
+\r
+```c\r
+//\r
+// Execute the tests.\r
+//\r
+Status = RunAllTestSuites( Framework );\r
+```\r
+\r
+### A Simple Test Case\r
+\r
+We'll take a look at the below test case from 'SampleUnitTestApp'...\r
+\r
+```c\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+OnePlusOneShouldEqualTwo (\r
+ IN UNIT_TEST_FRAMEWORK_HANDLE Framework,\r
+ IN UNIT_TEST_CONTEXT Context\r
+ )\r
+{\r
+ UINTN A, B, C;\r
+\r
+ A = 1;\r
+ B = 1;\r
+ C = A + B;\r
+\r
+ UT_ASSERT_EQUAL(C, 2);\r
+ return UNIT_TEST_PASSED;\r
+} // OnePlusOneShouldEqualTwo()\r
+```\r
+\r
+The prototype for this function matches the `UNIT_TEST_FUNCTION` prototype. It takes in a handle to the Framework\r
+itself and the context pointer. The context pointer could be cast and interpreted as anything within this test case,\r
+which is why it's important to configure contexts carefully. The test case returns a value of `UNIT_TEST_STATUS`, which\r
+will be recorded in the Framework and reported at the end of all suites.\r
+\r
+In this test case, the `UT_ASSERT_EQUAL` assertion is being used to establish that the business logic has functioned\r
+correctly. There are several assertion macros, and you are encouraged to use one that matches as closely to your\r
+intended test criterium as possible, because the logging is specific to the macro and more specific macros have more\r
+detailed logs. When in doubt, there are always `UT_ASSERT_TRUE` and `UT_ASSERT_FALSE`. Assertion macros that fail their\r
+test criterium will immediately return from the test case with `UNIT_TEST_ERROR_TEST_FAILED` and log an error string.\r
+_Note_ that this early return can have implications for memory leakage.\r
+\r
+At the end, if all test criteria pass, you should return `UNIT_TEST_PASSED`.\r
+\r
+### More Complex Cases\r
+\r
+To write more advanced tests, first take a look at all the Assertion and Logging macros provided in the framework.\r
+\r
+Beyond that, if you're writing host-based tests and want to take a dependency on the UnitTestFrameworkPkg, you can\r
+leverage the `cmocka.h` interface and write tests with all the features of the Cmocka framework.\r
+\r
+Documentation for Cmocka can be found here:\r
+https://api.cmocka.org/\r
+\r
+## Development\r
+\r
+When using the EDK2 Pytools for CI testing, the host-based unit tests will be built and run on any build that includes the `NOOPT` build target.\r
+\r
+If you are trying to iterate on a single test, a convenient pattern is to build only that test module. For example, the following command will build only the SafeIntLib host-based test from the MdePkg...\r
+\r
+```bash\r
+stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=VS2017 -p MdePkg -t NOOPT BUILDMODULE=MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.inf\r
+```\r
+\r
+## Known Limitations\r
+\r
+### PEI, DXE, SMM\r
+\r
+While sample tests have been provided for these execution environments, only cursory build validation\r
+has been performed. Care has been taken while designing the frameworks to allow for execution during\r
+boot phases, but only UEFI Shell and host-based tests have been thoroughly evaluated. Full support for\r
+PEI, DXE, and SMM is forthcoming, but should be considered beta/staging for now.\r
+\r
+### Host-Based Support vs Other Tests\r
+\r
+The host-based test framework is powered internally by the Cmocka framework. As such, it has abilities\r
+that the target-based tests don't (yet). It would be awesome if this meant that it was a super set of\r
+the target-based tests, and it worked just like the target-based tests but with more features. Unfortunately,\r
+this is not the case. While care has been taken to keep them as close a possible, there are a few known\r
+inconsistencies that we're still ironing out. For example, the logging messages in the target-based tests\r
+are cached internally and associated with the running test case. They can be saved later as part of the\r
+reporting lib. This isn't currently possible with host-based. Only the assertion failures are logged.\r
+\r
+We will continue trying to make these as similar as possible.\r
+\r
+## Copyright\r
+\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
--- /dev/null
+## @file\r
+# This Package provides all definitions (including functions, MACROs,\r
+# structures library classes, and PCDs) and libraries instances, which are used\r
+# to support unit testing and interface testing.\r
+#\r
+# Copyright (c) Microsoft Corporation.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ DEC_SPECIFICATION = 0x00010005\r
+ PACKAGE_NAME = UnitTestFrameworkPkg\r
+ PACKAGE_UNI_FILE = UnitTestFrameworkPkg.uni\r
+ PACKAGE_GUID = 4A70C4A0-D72C-4D3F-9943-BE7C41C50BA3\r
+ PACKAGE_VERSION = 1.00\r
+\r
+[Includes]\r
+ Library/CmockaLib/cmocka/include\r
+\r
+[Includes.Common.Private]\r
+ PrivateInclude\r
+ Library/CmockaLib/cmocka/include/cmockery\r
+\r
+[LibraryClasses.Common.Private]\r
+ ## @libraryclass Allows save and restore unit test internal state\r
+ #\r
+ UnitTestPersistenceLib|PrivateInclude/Library/UnitTestPersistenceLib.h\r
+\r
+ ## @libraryclass Provides a unit test result report\r
+ #\r
+ UnitTestResultReportLib|PrivateInclude/Library/UnitTestResultReportLib.h\r
+\r
+ ## @libraryclass Provides boot-option routines useful in shell-based tests.\r
+ #\r
+ UnitTestBootLib|PrivateInclude/Library/UnitTestBootLib.h\r
+\r
+[Guids]\r
+ gUnitTestFrameworkPkgTokenSpaceGuid = { 0x833d3aba, 0x39b4, 0x43a2, { 0xb9, 0x30, 0x7a, 0x34, 0x53, 0x39, 0x31, 0xb3 } }\r
+\r
+[PcdsFixedAtBuild]\r
+ ## This flag is used to control build time optimization based on unit test\r
+ # log level. The default value is 0xFFFFFFFF to enable all unit test log\r
+ # messages.\r
+ # BIT0 - Error unit test log messages.<BR>\r
+ # BIT1 - Warning unit test log messages.<BR>\r
+ # BIT2 - Informational unit test log messages.<BR>\r
+ # BIT3 - Verbose unit test log messages.<BR>\r
+ # @Prompt Unit Test Log Message Level\r
+ gUnitTestFrameworkPkgTokenSpaceGuid.PcdUnitTestLogLevel|0xFFFFFFFF|UINT32|0x00000001\r
--- /dev/null
+// /** @file\r
+// This Package provides all definitions (including functions, MACROs,\r
+// structures library classes, and PCDs) and libraries instances, which are used\r
+// to support unit testing and interface testing.\r
+//\r
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+#string STR_PACKAGE_ABSTRACT #language en-US "This Package provides all definitions (including functions, MACROs, structures library classes, and PCDs) and libraries instances, which are used to support unit testing and interface testing."\r
+\r
+#string STR_PACKAGE_DESCRIPTION #language en-US "This Package provides all definitions (including functions, MACROs, structures library classes, and PCDs) and libraries instances, which are used to support unit testing and interface testing."\r
+\r
+#string STR_gUnitTestFrameworkPkgTokenSpaceGuid_PcdUnitTestLogLevel_PROMPT #language en-US "Unit Test Log Message Level"\r
+\r
+#string STR_gUnitTestFrameworkPkgTokenSpaceGuid_PcdUnitTestLogLevel_HELP #language en-US "This flag is used to control build time optimization based on unit test log level. The default value is 0xFFFFFFFF to enable all unit test log messages.<BR><BR>\n"\r
+ "BIT0 - Error unit test log messages.<BR>\n"\r
+ "BIT1 - Warning unit test log messages.<BR>\n"\r
+ "BIT2 - Informational unit test log messages.<BR>\n"\r
+ "BIT3 - Verbose unit test log messages.<BR>\n"\r