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 <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Acked-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
This commit is contained in:
Michael D Kinney 2020-01-22 10:16:14 -08:00 committed by mergify[bot]
parent e50c2bb383
commit 184ee9b1de
6 changed files with 428 additions and 1 deletions

View File

@ -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 <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UnitTestLib.h>
#include <Library/ResetSystemLib.h>
#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 ();
}

View File

@ -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

View File

@ -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 <Uefi.h>
extern EFI_RUNTIME_SERVICES MockRuntime;
EFI_RUNTIME_SERVICES *gRT = &MockRuntime;

View File

@ -0,0 +1,25 @@
## @file
# Mock implementation of the UEFI Runtime Services Table Library.
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# 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

View File

@ -9,6 +9,10 @@
"CompilerPlugin": {
"DscPath": "MdeModulePkg.dsc"
},
## options defined ci/Plugin/HostUnitTestCompilerPlugin
"HostUnitTestCompilerPlugin": {
"DscPath": "Test/MdeModulePkgHostTest.dsc"
},
## options defined ci/Plugin/CharEncodingCheck
"CharEncodingCheck": {
@ -24,7 +28,9 @@
"ArmPkg/ArmPkg.dec" # this should be fixed by promoting an abstraction
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[],
"AcceptableDependencies-HOST_APPLICATION":[
"UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
],
# For UEFI shell based apps
"AcceptableDependencies-UEFI_APPLICATION":[],
"IgnoreInf": []
@ -35,6 +41,11 @@
"IgnoreInf": [],
"DscPath": "MdeModulePkg.dsc"
},
## options defined ci/Plugin/HostUnitTestDscCompleteCheck
"HostUnitTestDscCompleteCheck": {
"IgnoreInf": [""],
"DscPath": "Test/MdeModulePkgHostTest.dsc"
},
## options defined ci/Plugin/GuidCheck
"GuidCheck": {

View File

@ -0,0 +1,32 @@
## @file
# MdeModulePkg DSC file used to build host-based unit tests.
#
# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (C) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
PLATFORM_NAME = MdeModulePkgHostTest
PLATFORM_GUID = F74AF7C6-698C-4EBA-BA49-FF6816916354
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/MdeModulePkg/HostTest
SUPPORTED_ARCHITECTURES = IA32|X64
BUILD_TARGETS = NOOPT
SKUID_IDENTIFIER = DEFAULT
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
[Components]
MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
#
# Build MdeModulePkg HOST_APPLICATION Tests
#
MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibUnitTestHost.inf {
<LibraryClasses>
ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf
UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
}