From 184ee9b1de4ecd1ea4aa479dc66840a14f50ccb2 Mon Sep 17 00:00:00 2001 From: Michael D Kinney Date: Wed, 22 Jan 2020 10:16:14 -0800 Subject: MdeModulePkg: Add DxeResetSystemLib unit test https://bugzilla.tianocore.org/show_bug.cgi?id=2505 * Add unit test of DxeResetSystemLib library instance that uses cmocka interfaces to mock the UEFI Runtime Services Table and its ResetSystem() service. When a unit test uses the cmocka interfaces, the unit test does not support being run from target environments. cmocka APIs: https://api.cmocka.org/index.html This example puts the unit test in a UnitTest directory below the library INF file and this location means the unit test is only designed to work this this one library instance. * Add Test/MdeModulePkgHostTest.dsc to build host based unit tests Cc: Sean Brogan Cc: Bret Barkelew Cc: Liming Gao Cc: Hao A Wu Signed-off-by: Michael D Kinney Acked-by: Hao A Wu Reviewed-by: Bret Barkelew --- .../UnitTest/DxeResetSystemLibUnitTest.c | 312 +++++++++++++++++++++ .../UnitTest/DxeResetSystemLibUnitTestHost.inf | 34 +++ .../UnitTest/MockUefiRuntimeServicesTableLib.c | 13 + .../UnitTest/MockUefiRuntimeServicesTableLib.inf | 25 ++ 4 files changed, 384 insertions(+) create mode 100644 MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTest.c create mode 100644 MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTestHost.inf create mode 100644 MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.c create mode 100644 MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf (limited to 'MdeModulePkg/Library') diff --git a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTest.c b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTest.c new file mode 100644 index 0000000000..3bba38b579 --- /dev/null +++ b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTest.c @@ -0,0 +1,312 @@ +/** @file + Unit tests of the DxeResetSystemLib instance of the ResetSystemLib class + + Copyright (C) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define UNIT_TEST_APP_NAME "DxeResetSystemLib Unit Tests" +#define UNIT_TEST_APP_VERSION "1.0" + +/** + Resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or + EfiResetShutdown the data buffer starts with a Null-terminated + string, optionally followed by additional binary data. + The string is a description that the caller may use to further + indicate the reason for the system reset. + For a ResetType of EfiResetPlatformSpecific the data buffer + also starts with a Null-terminated string that is followed + by an EFI_GUID that describes the specific type of reset to perform. +**/ +STATIC +VOID +EFIAPI +MockResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + check_expected_ptr (ResetType); + check_expected_ptr (ResetStatus); + + // + // NOTE: Mocked functions can also return values, but that + // is for another demo. +} + +/// +/// Mock version of the UEFI Runtime Services Table +/// +EFI_RUNTIME_SERVICES MockRuntime = { + { + EFI_RUNTIME_SERVICES_SIGNATURE, // Signature + EFI_RUNTIME_SERVICES_REVISION, // Revision + sizeof (EFI_RUNTIME_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + NULL, // GetTime + NULL, // SetTime + NULL, // GetWakeupTime + NULL, // SetWakeupTime + NULL, // SetVirtualAddressMap + NULL, // ConvertPointer + NULL, // GetVariable + NULL, // GetNextVariableName + NULL, // SetVariable + NULL, // GetNextHighMonotonicCount + MockResetSystem, // ResetSystem + NULL, // UpdateCapsule + NULL, // QueryCapsuleCapabilities + NULL // QueryVariableInfo +}; + +/** + Unit test for ColdReset () API of the ResetSystemLib. + + @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 +ResetColdShouldIssueAColdReset ( + IN UNIT_TEST_CONTEXT Context + ) +{ + expect_value (MockResetSystem, ResetType, EfiResetCold); + expect_value (MockResetSystem, ResetStatus, EFI_SUCCESS); + + ResetCold (); + + return UNIT_TEST_PASSED; +} + +/** + Unit test for WarmReset () API of the ResetSystemLib. + + @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 +ResetWarmShouldIssueAWarmReset ( + IN UNIT_TEST_CONTEXT Context + ) +{ + expect_value (MockResetSystem, ResetType, EfiResetWarm); + expect_value (MockResetSystem, ResetStatus, EFI_SUCCESS); + + ResetWarm (); + + return UNIT_TEST_PASSED; +} + +/** + Unit test for ResetShutdown () API of the ResetSystemLib. + + @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 +ResetShutdownShouldIssueAShutdown ( + IN UNIT_TEST_CONTEXT Context + ) +{ + expect_value (MockResetSystem, ResetType, EfiResetShutdown); + expect_value (MockResetSystem, ResetStatus, EFI_SUCCESS); + + ResetShutdown (); + + return UNIT_TEST_PASSED; +} + +/** + Unit test for ResetPlatformSpecific () API of the ResetSystemLib. + + @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 +ResetPlatformSpecificShouldIssueAPlatformSpecificReset ( + IN UNIT_TEST_CONTEXT Context + ) +{ + expect_value (MockResetSystem, ResetType, EfiResetPlatformSpecific); + expect_value (MockResetSystem, ResetStatus, EFI_SUCCESS); + + ResetPlatformSpecific (0, NULL); + + return UNIT_TEST_PASSED; +} + +/** + Unit test for ResetSystem () API of the ResetSystemLib. + + @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 +ResetSystemShouldPassTheParametersThrough ( + IN UNIT_TEST_CONTEXT Context + ) +{ + expect_value (MockResetSystem, ResetType, EfiResetCold); + expect_value (MockResetSystem, ResetStatus, EFI_SUCCESS); + + ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + + expect_value (MockResetSystem, ResetType, EfiResetShutdown); + expect_value (MockResetSystem, ResetStatus, EFI_SUCCESS); + + ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); + + return UNIT_TEST_PASSED; +} + +/** + Initialze the unit test framework, suite, and unit tests for the + ResetSystemLib and run the ResetSystemLib unit test. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +STATIC +EFI_STATUS +EFIAPI +UnitTestingEntry ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE ResetTests; + + Framework = NULL; + + DEBUG(( DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION )); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the ResetSytemLib Unit Test Suite. + // + Status = CreateUnitTestSuite (&ResetTests, Framework, "DxeResetSystemLib Reset Tests", "ResetSystemLib.Reset", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for ResetTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // + // --------------Suite-----------Description--------------Name----------Function--------Pre---Post-------------------Context----------- + // + AddTestCase (ResetTests, "ResetCold should issue a cold reset", "Cold", ResetColdShouldIssueAColdReset, NULL, NULL, NULL); + AddTestCase (ResetTests, "ResetWarm should issue a warm reset", "Warm", ResetWarmShouldIssueAWarmReset, NULL, NULL, NULL); + AddTestCase (ResetTests, "ResetShutdown should issue a shutdown", "Shutdown", ResetShutdownShouldIssueAShutdown, NULL, NULL, NULL); + AddTestCase (ResetTests, "ResetPlatformSpecific should issue a platform-specific reset", "Platform", ResetPlatformSpecificShouldIssueAPlatformSpecificReset, NULL, NULL, NULL); + AddTestCase (ResetTests, "ResetSystem should pass all parameters through", "Parameters", ResetSystemShouldPassTheParametersThrough, NULL, NULL, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UnitTestingEntry (); +} diff --git a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTestHost.inf b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTestHost.inf new file mode 100644 index 0000000000..54f968e810 --- /dev/null +++ b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTestHost.inf @@ -0,0 +1,34 @@ +## @file +# Unit tests of the DxeResetSystemLib instance of the ResetSystemLib class +# +# Copyright (C) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = DxeResetSystemLibUnitTestHost + FILE_GUID = 83E35653-B943-4C5F-BA08-9B2996AE9273 + 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] + DxeResetSystemLibUnitTest.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + ResetSystemLib + BaseLib + BaseMemoryLib + DebugLib + UnitTestLib diff --git a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.c b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.c new file mode 100644 index 0000000000..3540e1c039 --- /dev/null +++ b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.c @@ -0,0 +1,13 @@ +/** @file + Mock implementation of the UEFI Runtime Services Table Library. + + Copyright (C) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +extern EFI_RUNTIME_SERVICES MockRuntime; + +EFI_RUNTIME_SERVICES *gRT = &MockRuntime; diff --git a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf new file mode 100644 index 0000000000..e716b855a3 --- /dev/null +++ b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf @@ -0,0 +1,25 @@ +## @file +# Mock implementation of the UEFI Runtime Services Table Library. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MockUefiRuntimeServicesTableLib + FILE_GUID = 4EA215EE-85C1-4A0A-847F-D2A8DE20805F + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiRuntimeServicesTableLib|HOST_APPLICATION + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + MockUefiRuntimeServicesTableLib.c + +[Packages] + MdePkg/MdePkg.dec -- cgit v1.2.3