From: Michael D Kinney Date: Wed, 22 Jan 2020 18:11:06 +0000 (-0800) Subject: UnitTestFrameworkPkg/Test: Add unit test samples X-Git-Tag: edk2-stable202002~153 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=f74abe4a2c48e559168156c08842a5405b694480 UnitTestFrameworkPkg/Test: Add unit test samples https://bugzilla.tianocore.org/show_bug.cgi?id=2505 Add an implementation of a sample unit test that demonstrates the use of the UnitTestLib services and macros and supports being built for execution in a host environment or for execution on a target in PEI, DXE, SMM, or UEFI Shell. Cc: Sean Brogan Cc: Bret Barkelew Signed-off-by: Michael D Kinney Reviewed-by: Bret Barkelew --- diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTest.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTest.c new file mode 100644 index 0000000000..37d5747bca --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTest.c @@ -0,0 +1,289 @@ +/** @file + This is a sample to demostrate the usage of the Unit Test Library that + supports the PEI, DXE, SMM, UEFI SHell, and host execution environments. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_NAME "Sample Unit Test" +#define UNIT_TEST_VERSION "0.1" + +/// +/// Global variables used in unit tests +/// +BOOLEAN mSampleGlobalTestBoolean = FALSE; +VOID *mSampleGlobalTestPointer = NULL; + +/** + Sample Unit-Test Prerequisite Function that checks to make sure the global + pointer used in the test is already set to NULL. + + Functions 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 parameter 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. + +**/ +UNIT_TEST_STATUS +EFIAPI +MakeSureThatPointerIsNull ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UT_ASSERT_EQUAL ((UINTN)mSampleGlobalTestPointer, (UINTN)NULL); + return UNIT_TEST_PASSED; +} + +/** + Sample Unit-Test Cleanup (after) function that resets the global pointer to + NULL. + + Functions 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 parameter 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. + +**/ +VOID +EFIAPI +ClearThePointer ( + IN UNIT_TEST_CONTEXT Context + ) +{ + mSampleGlobalTestPointer = NULL; +} + +/** + Sample unit test that verifies the expected result of an unsigned integer + addition operation. + + @param[in] Context [Optional] An optional parameter 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. +**/ +UNIT_TEST_STATUS +EFIAPI +OnePlusOneShouldEqualTwo ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINTN A; + UINTN B; + UINTN C; + + A = 1; + B = 1; + C = A + B; + + UT_ASSERT_EQUAL (C, 2); + + return UNIT_TEST_PASSED; +} + +/** + Sample unit test that verifies that a global BOOLEAN is updatable. + + @param[in] Context [Optional] An optional parameter 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. +**/ +UNIT_TEST_STATUS +EFIAPI +GlobalBooleanShouldBeChangeable ( + IN UNIT_TEST_CONTEXT Context + ) +{ + mSampleGlobalTestBoolean = TRUE; + UT_ASSERT_TRUE (mSampleGlobalTestBoolean); + + mSampleGlobalTestBoolean = FALSE; + UT_ASSERT_FALSE (mSampleGlobalTestBoolean); + + return UNIT_TEST_PASSED; +} + +/** + Sample unit test that logs a warning message and verifies that a global + pointer is updatable. + + @param[in] Context [Optional] An optional parameter 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. +**/ +UNIT_TEST_STATUS +EFIAPI +GlobalPointerShouldBeChangeable ( + IN UNIT_TEST_CONTEXT Context + ) +{ + // + // Example of logging. + // + UT_LOG_WARNING ("About to change a global pointer! Current value is 0x%X\n", mSampleGlobalTestPointer); + + mSampleGlobalTestPointer = (VOID *)-1; + UT_ASSERT_EQUAL ((UINTN)mSampleGlobalTestPointer, (UINTN)((VOID *)-1)); + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + sample unit tests and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE SimpleMathTests; + UNIT_TEST_SUITE_HANDLE GlobalVarTests; + + Framework = NULL; + + DEBUG(( DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION )); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the SimpleMathTests Unit Test Suite. + // + Status = CreateUnitTestSuite (&SimpleMathTests, Framework, "Simple Math Tests", "Sample.Math", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SimpleMathTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (SimpleMathTests, "Adding 1 to 1 should produce 2", "Addition", OnePlusOneShouldEqualTwo, NULL, NULL, NULL); + + // + // Populate the GlobalVarTests Unit Test Suite. + // + Status = CreateUnitTestSuite (&GlobalVarTests, Framework, "Global Variable Tests", "Sample.Globals", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for GlobalVarTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (GlobalVarTests, "You should be able to change a global BOOLEAN", "Boolean", GlobalBooleanShouldBeChangeable, NULL, NULL, NULL); + AddTestCase (GlobalVarTests, "You should be able to change a global pointer", "Pointer", GlobalPointerShouldBeChangeable, MakeSureThatPointerIsNull, ClearThePointer, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard PEIM entry point for target based unit test execution from PEI. +**/ +EFI_STATUS +EFIAPI +PeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + return UefiTestMain (); +} + +/** + Standard UEFI entry point for target based unit test execution from DXE, SMM, + UEFI Shell. +**/ +EFI_STATUS +EFIAPI +DxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return UefiTestMain (); +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UefiTestMain (); +} diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf new file mode 100644 index 0000000000..e253cf6e16 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf @@ -0,0 +1,36 @@ +## @file +# Sample UnitTest built for execution in DXE. +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = SampleUnitTestDxe + FILE_GUID = 96BB18BD-FF2B-4B51-B683-0DC9A4BF12CF + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = DxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + UnitTestLib + PrintLib + +[Depex] + TRUE diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestHost.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestHost.inf new file mode 100644 index 0000000000..59a367cc6e --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestHost.inf @@ -0,0 +1,30 @@ +## @file +# Sample UnitTest built for execution on a Host/Dev machine. +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SampleUnitTestHost + FILE_GUID = CC0EA77E-BF2D-4134-B419-0C02E15CE08E + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf new file mode 100644 index 0000000000..60f5252c34 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf @@ -0,0 +1,36 @@ +## @file +# Sample UnitTest built for execution in PEI. +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = SampleUnitTestPei + FILE_GUID = B9BD9451-3DC8-48EA-A6F0-55753BF186F1 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PeiEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + PeimEntryPoint + BaseLib + DebugLib + UnitTestLib + PrintLib + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf new file mode 100644 index 0000000000..324ad2686e --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf @@ -0,0 +1,37 @@ +## @file +# Sample UnitTest built for execution in SMM. +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = SampleUnitTestSmm + FILE_GUID = 389B16DB-F622-424C-9000-9E43C69CBF71 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = DxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + UnitTestLib + PrintLib + +[Depex] + gEfiSmmCpuProtocolGuid diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf new file mode 100644 index 0000000000..6e39c229d4 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf @@ -0,0 +1,33 @@ +## @file +# Sample UnitTest built for execution in UEFI Shell. +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = SampleUnitTestUefiShell + FILE_GUID = 9E8F461A-17E1-4312-B49C-E66F0A88EA8B + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = DxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + BaseLib + DebugLib + UnitTestLib + PrintLib