mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
UnitTestFrameworkPkg: Add CMocka MockUefiRuntimeServicesTableLib
Unit tests exercising code that calls UEFI Runtime Services have no way to control or verify gRT calls without a mock implementation. No such mock existed in UnitTestFrameworkPkg for CMocka-based tests. This adds a CMocka mock library for UefiRuntimeServicesTableLib covering all Runtime Services: GetTime, SetTime, GetWakeupTime, SetWakeupTime, SetVirtualAddressMap, ConvertPointer, GetVariable, GetNextVariableName, SetVariable, GetNextHighMonotonicCount, ResetSystem, UpdateCapsule, QueryCapsuleCapabilities, and QueryVariableInfo. Each mock validates input parameters per the UEFI specification before delegating to CMocka mock() and will_return(). A static gMockRuntime table is assigned to gRT at link time. Helper macros in the header reduce will_return() and expect_*() boilerplate for success, EFI_BUFFER_TOO_SMALL, and error cases. Signed-off-by: Vasudevan Sambandan <vasudevans@ami.com>
This commit is contained in:
parent
b03a21a63e
commit
62df42e16c
4 changed files with 1892 additions and 0 deletions
|
|
@ -0,0 +1,878 @@
|
|||
/** @file MockUefiRuntimeServicesTableLib.h
|
||||
Mock Unit Test UEFI Runtime Services Table Library Implementation for Unit Testing
|
||||
|
||||
This library provides comprehensive mocking of UEFI Runtime Services
|
||||
functions using CMocka framework. Each function can return data based
|
||||
on mock() implementation.
|
||||
|
||||
Copyright (c) 2026, American Megatrends International LLC. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#ifndef __MOCK_UEFI_RUNTIME_SERVICES_TABLE_LIB_H__
|
||||
#define __MOCK_UEFI_RUNTIME_SERVICES_TABLE_LIB_H__
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
/**
|
||||
Returns the current time and date information, and the time-keeping capabilities
|
||||
of the hardware platform.
|
||||
|
||||
@param[out] Time A pointer to storage to receive a snapshot of the current time.
|
||||
@param[out] Capabilities An optional pointer to a buffer to receive the real time clock
|
||||
device's capabilities.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER Time is NULL.
|
||||
@retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetTime (
|
||||
OUT EFI_TIME *Time,
|
||||
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Sets the current local time and date information.
|
||||
|
||||
@param[in] Time A pointer to the current time.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER A time field is out of range.
|
||||
@retval EFI_DEVICE_ERROR The time could not be set due to hardware error.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetTime (
|
||||
IN EFI_TIME *Time
|
||||
);
|
||||
|
||||
/**
|
||||
Returns the current wakeup alarm clock setting.
|
||||
|
||||
@param[out] Enabled Indicates if the alarm is currently enabled or disabled.
|
||||
@param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement.
|
||||
@param[out] Time If the alarm is enabled, returns the current alarm setting.
|
||||
|
||||
@retval EFI_SUCCESS The alarm settings were returned.
|
||||
@retval EFI_INVALID_PARAMETER Enabled is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Pending is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Time is NULL.
|
||||
@retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
|
||||
@retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetWakeupTime (
|
||||
OUT BOOLEAN *Enabled,
|
||||
OUT BOOLEAN *Pending,
|
||||
OUT EFI_TIME *Time
|
||||
);
|
||||
|
||||
/**
|
||||
Sets the system wakeup alarm clock time.
|
||||
|
||||
@param[in] Enable Enable or disable the wakeup alarm.
|
||||
@param[in] Time If Enable is TRUE, the time to set the wakeup alarm for.
|
||||
If Enable is FALSE, then this parameter is optional, and may be NULL.
|
||||
|
||||
@retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
|
||||
Enable is FALSE, then the wakeup alarm was disabled.
|
||||
@retval EFI_INVALID_PARAMETER A time field is out of range.
|
||||
@retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
|
||||
@retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetWakeupTime (
|
||||
IN BOOLEAN Enable,
|
||||
IN EFI_TIME *Time OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Changes the runtime addressing mode of EFI firmware from physical to virtual.
|
||||
|
||||
@param[in] MemoryMapSize The size in bytes of VirtualMap.
|
||||
@param[in] DescriptorSize The size in bytes of an entry in the VirtualMap.
|
||||
@param[in] DescriptorVersion The version of the structure entries in VirtualMap.
|
||||
@param[in] VirtualMap An array of memory descriptors which contain new virtual
|
||||
address mapping information for all runtime ranges.
|
||||
|
||||
@retval EFI_SUCCESS The virtual address map has been applied.
|
||||
@retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in
|
||||
virtual address mapped mode.
|
||||
@retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid.
|
||||
@retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory
|
||||
map that requires a mapping.
|
||||
@retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found
|
||||
in the memory map.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetVirtualAddressMap (
|
||||
IN UINTN MemoryMapSize,
|
||||
IN UINTN DescriptorSize,
|
||||
IN UINT32 DescriptorVersion,
|
||||
IN EFI_MEMORY_DESCRIPTOR *VirtualMap
|
||||
);
|
||||
|
||||
/**
|
||||
Determines the new virtual address that is to be used on subsequent memory accesses.
|
||||
|
||||
@param[in] DebugDisposition Supplies type information for the pointer being converted.
|
||||
@param[in,out] Address A pointer to a pointer that is to be fixed to be the value needed
|
||||
for the new virtual address mappings being applied.
|
||||
|
||||
@retval EFI_SUCCESS The pointer pointed to by Address was modified.
|
||||
@retval EFI_INVALID_PARAMETER Address is NULL.
|
||||
@retval EFI_INVALID_PARAMETER *Address is NULL and DebugDisposition does not have the
|
||||
EFI_OPTIONAL_PTR bit set.
|
||||
@retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part
|
||||
of the current memory map. This is normally fatal.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockConvertPointer (
|
||||
IN UINTN DebugDisposition,
|
||||
IN OUT VOID **Address
|
||||
);
|
||||
|
||||
/**
|
||||
Returns the value of a variable.
|
||||
|
||||
@param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[out] Attributes If not NULL, a pointer to the memory location to return the
|
||||
attributes bitmask for the variable.
|
||||
@param[in,out] DataSize On input, the size in bytes of the return Data buffer.
|
||||
On output the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the variable. May be NULL
|
||||
with a zero DataSize in order to determine the size buffer needed.
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully.
|
||||
@retval EFI_NOT_FOUND The variable was not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result.
|
||||
@retval EFI_INVALID_PARAMETER VariableName is NULL.
|
||||
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DataSize is NULL.
|
||||
@retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
|
||||
@retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetVariable (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
OUT UINT32 *Attributes OPTIONAL,
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Enumerates the current variable names.
|
||||
|
||||
@param[in,out] VariableNameSize The size of the VariableName buffer. The size must be large
|
||||
enough to fit input string supplied in VariableName buffer.
|
||||
@param[in,out] VariableName On input, supplies the last VariableName that was returned
|
||||
by GetNextVariableName(). On output, returns the Nullterminated
|
||||
string of the current variable.
|
||||
@param[in,out] VendorGuid On input, supplies the last VendorGuid that was returned by
|
||||
GetNextVariableName(). On output, returns the
|
||||
VendorGuid of the current variable.
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully.
|
||||
@retval EFI_NOT_FOUND The next variable was not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
|
||||
VariableNameSize has been updated with the size needed to complete the request.
|
||||
@retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
|
||||
@retval EFI_INVALID_PARAMETER VariableName is NULL.
|
||||
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
|
||||
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
|
||||
GUID of an existing variable.
|
||||
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
|
||||
the input VariableName buffer.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetNextVariableName (
|
||||
IN OUT UINTN *VariableNameSize,
|
||||
IN OUT CHAR16 *VariableName,
|
||||
IN OUT EFI_GUID *VendorGuid
|
||||
);
|
||||
|
||||
/**
|
||||
Sets the value of a variable.
|
||||
|
||||
@param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
|
||||
Each VariableName is unique for each VendorGuid. VariableName must
|
||||
contain 1 or more characters. If VariableName is an empty string,
|
||||
then EFI_INVALID_PARAMETER is returned.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[in] Attributes Attributes bitmask to set for the variable.
|
||||
@param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
|
||||
causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
|
||||
set, then a SetVariable() call with a DataSize of zero will not cause any change to
|
||||
the variable value (the timestamp associated with the variable may be updated however
|
||||
even if no new data value is provided,see the description of the
|
||||
EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
|
||||
be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
|
||||
@param[in] Data The contents for the variable.
|
||||
|
||||
@retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
|
||||
defined by the Attributes.
|
||||
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the
|
||||
DataSize exceeds the maximum allowed.
|
||||
@retval EFI_INVALID_PARAMETER VariableName is an empty string.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
|
||||
@retval EFI_WRITE_PROTECTED The variable in question is read-only.
|
||||
@retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
|
||||
@retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set,
|
||||
but the AuthInfo does NOT pass the validation check carried out by the firmware.
|
||||
@retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetVariable (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN UINT32 Attributes,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Returns the next high 32 bits of the platform's monotonic counter.
|
||||
|
||||
@param[out] HighCount Pointer to returned value.
|
||||
|
||||
@retval EFI_SUCCESS The next high monotonic count was returned.
|
||||
@retval EFI_INVALID_PARAMETER HighCount is NULL.
|
||||
@retval EFI_DEVICE_ERROR The device is not functioning properly.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetNextHighMonotonicCount (
|
||||
OUT UINT32 *HighCount
|
||||
);
|
||||
|
||||
/**
|
||||
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.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
MockResetSystem (
|
||||
IN EFI_RESET_TYPE ResetType,
|
||||
IN EFI_STATUS ResetStatus,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *ResetData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
|
||||
consumption, the firmware may process the capsule immediately. If the payload should persist
|
||||
across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
|
||||
be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
|
||||
part of the reset process.
|
||||
|
||||
@param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
|
||||
being passed into update capsule.
|
||||
@param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
|
||||
CapsuleHeaderArray.
|
||||
@param[in] ScatterGatherList Physical pointer to a set of
|
||||
EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
|
||||
location in physical memory of a set of capsules.
|
||||
|
||||
@retval EFI_SUCCESS Valid capsule was passed. If
|
||||
CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
|
||||
capsule has been successfully processed by the firmware.
|
||||
@retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were
|
||||
set in the capsule header.
|
||||
@retval EFI_INVALID_PARAMETER CapsuleCount is 0.
|
||||
@retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error.
|
||||
@retval EFI_UNSUPPORTED The capsule type is not supported on this platform.
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule
|
||||
is compatible with this platform but is not capable of being submitted or processed
|
||||
in runtime. The caller may resubmit the capsule prior to ExitBootServices().
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates
|
||||
the capsule is compatible with this platform but there are insufficient resources to process.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockUpdateCapsule (
|
||||
IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
|
||||
IN UINTN CapsuleCount,
|
||||
IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Returns if the capsule can be supported via UpdateCapsule().
|
||||
|
||||
@param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
|
||||
being passed into update capsule.
|
||||
@param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
|
||||
CapsuleHeaderArray.
|
||||
@param[out] MaximumCapsuleSize On output the maximum size that UpdateCapsule() can
|
||||
support as an argument to UpdateCapsule() via
|
||||
CapsuleHeaderArray and ScatterGatherList.
|
||||
@param[out] ResetType Returns the type of reset required for the capsule update.
|
||||
|
||||
@retval EFI_SUCCESS Valid answer returned.
|
||||
@retval EFI_UNSUPPORTED The capsule image is not supported on this platform, and
|
||||
MaximumCapsuleSize and ResetType are undefined.
|
||||
@retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule
|
||||
is compatible with this platform but is not capable of being submitted or processed
|
||||
in runtime. The caller may resubmit the capsule prior to ExitBootServices().
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates
|
||||
the capsule is compatible with this platform but there are insufficient resources to process.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockQueryCapsuleCapabilities (
|
||||
IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
|
||||
IN UINTN CapsuleCount,
|
||||
OUT UINT64 *MaximumCapsuleSize,
|
||||
OUT EFI_RESET_TYPE *ResetType
|
||||
);
|
||||
|
||||
/**
|
||||
Returns information about the EFI variables.
|
||||
|
||||
@param[in] Attributes Attributes bitmask to specify the type of variables on
|
||||
which to return information.
|
||||
@param[out] MaximumVariableStorageSize On output the maximum size of the storage space
|
||||
available for the EFI variables associated with the
|
||||
attributes specified.
|
||||
@param[out] RemainingVariableStorageSize Returns the remaining size of the storage space
|
||||
available for the EFI variables associated with the
|
||||
attributes specified.
|
||||
@param[out] MaximumVariableSize Returns the maximum size of the individual EFI
|
||||
variables associated with the attributes specified.
|
||||
|
||||
@retval EFI_SUCCESS Valid answer returned.
|
||||
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
|
||||
@retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the
|
||||
MaximumVariableStorageSize,
|
||||
RemainingVariableStorageSize, MaximumVariableSize
|
||||
are undefined.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockQueryVariableInfo (
|
||||
IN UINT32 Attributes,
|
||||
OUT UINT64 *MaximumVariableStorageSize,
|
||||
OUT UINT64 *RemainingVariableStorageSize,
|
||||
OUT UINT64 *MaximumVariableSize
|
||||
);
|
||||
|
||||
/**
|
||||
Initializes the Mock Runtime Services Table by replacing the global gRT pointer.
|
||||
@return VOID
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitMockRuntimeServicesTablePointer (
|
||||
VOID
|
||||
);
|
||||
|
||||
//
|
||||
// Helper Macros for setting up mock return values and expected parameters
|
||||
//
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetTime mock expectation.
|
||||
Queues EFI_SUCCESS as the return status and enqueues each field of
|
||||
the supplied EFI_TIME structure as successive mock return values.
|
||||
|
||||
@param[in] Time Pointer to an EFI_TIME structure whose fields are
|
||||
queued as the values that MockGetTime will output.
|
||||
**/
|
||||
#define MOCK_GET_TIME_RETURN_SUCCESS(Time) \
|
||||
will_return (MockGetTime, EFI_SUCCESS); \
|
||||
will_return (MockGetTime, (Time)->Year); \
|
||||
will_return (MockGetTime, (Time)->Month); \
|
||||
will_return (MockGetTime, (Time)->Day); \
|
||||
will_return (MockGetTime, (Time)->Hour); \
|
||||
will_return (MockGetTime, (Time)->Minute); \
|
||||
will_return (MockGetTime, (Time)->Second); \
|
||||
will_return (MockGetTime, (Time)->Nanosecond); \
|
||||
will_return (MockGetTime, (Time)->TimeZone); \
|
||||
will_return (MockGetTime, (Time)->Daylight);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetTime mock expectation that also returns
|
||||
hardware capability information.
|
||||
Queues EFI_SUCCESS as the return status, enqueues each field of the
|
||||
supplied EFI_TIME structure, and then enqueues each field of the
|
||||
supplied EFI_TIME_CAPABILITIES structure as successive mock return values.
|
||||
|
||||
@param[in] Time Pointer to an EFI_TIME structure whose fields are
|
||||
queued as the time values that MockGetTime will output.
|
||||
@param[in] Capabilities Pointer to an EFI_TIME_CAPABILITIES structure whose
|
||||
fields are queued as the capability values that
|
||||
MockGetTime will output.
|
||||
**/
|
||||
#define MOCK_GET_TIME_WITH_CAPABILITIES_RETURN_SUCCESS(Time, Capabilities) \
|
||||
will_return (MockGetTime, EFI_SUCCESS); \
|
||||
will_return (MockGetTime, (Time)->Year); \
|
||||
will_return (MockGetTime, (Time)->Month); \
|
||||
will_return (MockGetTime, (Time)->Day); \
|
||||
will_return (MockGetTime, (Time)->Hour); \
|
||||
will_return (MockGetTime, (Time)->Minute); \
|
||||
will_return (MockGetTime, (Time)->Second); \
|
||||
will_return (MockGetTime, (Time)->Nanosecond); \
|
||||
will_return (MockGetTime, (Time)->TimeZone); \
|
||||
will_return (MockGetTime, (Time)->Daylight); \
|
||||
will_return (MockGetTime, (Capabilities)->Resolution); \
|
||||
will_return (MockGetTime, (Capabilities)->Accuracy); \
|
||||
will_return (MockGetTime, (Capabilities)->SetsToZero);
|
||||
|
||||
/**
|
||||
Sets up a failing MockGetTime mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockGetTime reports a failure without populating any output fields.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_GET_TIME_RETURN_ERROR(Status) \
|
||||
will_return (MockGetTime, Status);
|
||||
|
||||
/**
|
||||
Sets up a MockSetTime mock expectation with the given return status.
|
||||
Queues Status as the mock return value so that MockSetTime returns
|
||||
the specified code when called by the code under test.
|
||||
|
||||
@param[in] Status The EFI_STATUS code to queue as the return value
|
||||
(e.g. EFI_SUCCESS, EFI_INVALID_PARAMETER).
|
||||
**/
|
||||
#define MOCK_SET_TIME_RETURN_STATUS(Status) \
|
||||
will_return (MockSetTime, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetWakeupTime mock expectation.
|
||||
Queues EFI_SUCCESS as the return status, then enqueues the Enabled and
|
||||
Pending boolean values, and finally enqueues each field of the supplied
|
||||
EFI_TIME structure as successive mock return values.
|
||||
|
||||
@param[in] Enabled Boolean value indicating whether the wakeup alarm is
|
||||
enabled; queued as a mock return value for MockGetWakeupTime.
|
||||
@param[in] Pending Boolean value indicating whether an alarm signal is pending;
|
||||
queued as a mock return value for MockGetWakeupTime.
|
||||
@param[in] Time Pointer to an EFI_TIME structure whose fields are queued
|
||||
as the alarm time values that MockGetWakeupTime will output.
|
||||
**/
|
||||
#define MOCK_GET_WAKEUP_TIME_RETURN_SUCCESS(Enabled, Pending, Time) \
|
||||
will_return (MockGetWakeupTime, EFI_SUCCESS); \
|
||||
will_return (MockGetWakeupTime, Enabled); \
|
||||
will_return (MockGetWakeupTime, Pending); \
|
||||
will_return (MockGetWakeupTime, (Time)->Year); \
|
||||
will_return (MockGetWakeupTime, (Time)->Month); \
|
||||
will_return (MockGetWakeupTime, (Time)->Day); \
|
||||
will_return (MockGetWakeupTime, (Time)->Hour); \
|
||||
will_return (MockGetWakeupTime, (Time)->Minute); \
|
||||
will_return (MockGetWakeupTime, (Time)->Second); \
|
||||
will_return (MockGetWakeupTime, (Time)->Nanosecond); \
|
||||
will_return (MockGetWakeupTime, (Time)->TimeZone); \
|
||||
will_return (MockGetWakeupTime, (Time)->Daylight);
|
||||
|
||||
/**
|
||||
Sets up a failing MockGetWakeupTime mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockGetWakeupTime reports a failure without populating any output fields.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_GET_WAKEUP_TIME_RETURN_ERROR(Status) \
|
||||
will_return (MockGetWakeupTime, Status);
|
||||
|
||||
/**
|
||||
Sets up a MockSetWakeupTime mock expectation with the given return status.
|
||||
Queues Status as the mock return value so that MockSetWakeupTime returns
|
||||
the specified code when called by the code under test.
|
||||
|
||||
@param[in] Status The EFI_STATUS code to queue as the return value
|
||||
(e.g. EFI_SUCCESS, EFI_INVALID_PARAMETER).
|
||||
**/
|
||||
#define MOCK_SET_WAKEUP_TIME_RETURN_STATUS(Status) \
|
||||
will_return (MockSetWakeupTime, Status);
|
||||
|
||||
/**
|
||||
Sets up a MockSetVirtualAddressMap mock expectation with the given return status.
|
||||
Queues Status as the mock return value so that MockSetVirtualAddressMap
|
||||
returns the specified code when called by the code under test.
|
||||
|
||||
@param[in] Status The EFI_STATUS code to queue as the return value
|
||||
(e.g. EFI_SUCCESS, EFI_UNSUPPORTED).
|
||||
**/
|
||||
#define MOCK_SET_VIRTUAL_ADDRESS_MAP_RETURN_STATUS(Status) \
|
||||
will_return (MockSetVirtualAddressMap, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockConvertPointer mock expectation.
|
||||
Queues EFI_SUCCESS as the return status and then enqueues
|
||||
ConvertedAddress as the converted virtual address that MockConvertPointer
|
||||
will write back to the caller's pointer.
|
||||
|
||||
@param[in] ConvertedAddress The virtual address value to queue as the
|
||||
converted pointer output of MockConvertPointer.
|
||||
**/
|
||||
#define MOCK_CONVERT_POINTER_RETURN_SUCCESS(ConvertedAddress) \
|
||||
will_return (MockConvertPointer, EFI_SUCCESS); \
|
||||
will_return (MockConvertPointer, ConvertedAddress);
|
||||
|
||||
/**
|
||||
Sets up a failing MockConvertPointer mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockConvertPointer reports a failure without modifying the caller's pointer.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_CONVERT_POINTER_RETURN_ERROR(Status) \
|
||||
will_return (MockConvertPointer, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetVariable mock expectation that validates
|
||||
exact input parameters and returns data when Attributes is NULL.
|
||||
Queues EFI_SUCCESS as the return status, registers exact-match
|
||||
expectations for VariableName, VendorGuid, and DataSize, and enqueues
|
||||
the data buffer pointer as the mock output.
|
||||
|
||||
@param[in] VarName Pointer to the Null-terminated Unicode variable name
|
||||
that the code under test is expected to pass.
|
||||
@param[in] VenGuid Pointer to the EFI_GUID that the code under test
|
||||
is expected to pass as VendorGuid.
|
||||
@param[in] Size The exact DataSize value the code under test is
|
||||
expected to pass on input.
|
||||
@param[in] Data Pointer to the data buffer to queue as the variable
|
||||
contents returned by MockGetVariable.
|
||||
**/
|
||||
#define MOCK_GET_VARIABLE_RETURN_SUCCESS(VarName, VenGuid, Size, Data) \
|
||||
will_return (MockGetVariable, EFI_SUCCESS); \
|
||||
expect_memory (MockGetVariable, VariableName, VarName, StrSize(VarName)); \
|
||||
expect_memory (MockGetVariable, VendorGuid, VenGuid, sizeof (EFI_GUID)); \
|
||||
expect_value (MockGetVariable, *DataSize, Size); \
|
||||
will_return (MockGetVariable, Data);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetVariable mock expectation that validates
|
||||
exact input parameters, returns data, and also returns an Attributes value.
|
||||
Queues EFI_SUCCESS as the return status, registers exact-match
|
||||
expectations for VariableName, VendorGuid, and DataSize, and enqueues
|
||||
both the data buffer pointer and the attributes value as mock outputs.
|
||||
Use this macro when the code under test passes a non-NULL Attributes pointer.
|
||||
|
||||
@param[in] VarName Pointer to the Null-terminated Unicode variable name
|
||||
that the code under test is expected to pass.
|
||||
@param[in] VenGuid Pointer to the EFI_GUID that the code under test
|
||||
is expected to pass as VendorGuid.
|
||||
@param[in] Size The exact DataSize value the code under test is
|
||||
expected to pass on input.
|
||||
@param[in] Data Pointer to the data buffer to queue as the variable
|
||||
contents returned by MockGetVariable.
|
||||
@param[in] Attr The UINT32 attributes bitmask to queue as the value
|
||||
written to the caller's Attributes output parameter.
|
||||
**/
|
||||
#define MOCK_GET_VARIABLE_RETURN_SUCCESS_WITH_ATTR(VarName, VenGuid, Size, Data, Attr) \
|
||||
will_return (MockGetVariable, EFI_SUCCESS); \
|
||||
expect_memory (MockGetVariable, VariableName, VarName, StrSize(VarName)); \
|
||||
expect_memory (MockGetVariable, VendorGuid, VenGuid, sizeof (EFI_GUID)); \
|
||||
expect_value (MockGetVariable, *DataSize, Size); \
|
||||
will_return (MockGetVariable, Data); \
|
||||
will_return (MockGetVariable, Attr);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetVariable mock expectation without validating
|
||||
the VariableName, VendorGuid, or DataSize inputs.
|
||||
Queues EFI_SUCCESS as the return status, accepts any value for VariableName,
|
||||
VendorGuid, and DataSize, and enqueues the data buffer pointer as the mock
|
||||
output. Use this macro when the code under test passes Attributes = NULL
|
||||
and exact input validation is not required.
|
||||
|
||||
@param[in] Data Pointer to the data buffer to queue as the variable
|
||||
contents returned by MockGetVariable.
|
||||
**/
|
||||
#define MOCK_GET_VARIABLE_RETURN_SUCCESS_ANY(Data) \
|
||||
will_return (MockGetVariable, EFI_SUCCESS); \
|
||||
expect_any (MockGetVariable, VariableName); \
|
||||
expect_any (MockGetVariable, VendorGuid); \
|
||||
expect_any (MockGetVariable, *DataSize); \
|
||||
will_return (MockGetVariable, Data);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetVariable mock expectation without validating
|
||||
the VariableName, VendorGuid, or DataSize inputs, and also returns an
|
||||
Attributes value.
|
||||
Queues EFI_SUCCESS as the return status, accepts any value for VariableName,
|
||||
VendorGuid, and DataSize, and enqueues both the data buffer pointer and the
|
||||
attributes value as mock outputs. Use this macro when the code under test
|
||||
passes a non-NULL Attributes pointer and exact input validation is not required.
|
||||
|
||||
@param[in] Data Pointer to the data buffer to queue as the variable
|
||||
contents returned by MockGetVariable.
|
||||
@param[in] Attr The UINT32 attributes bitmask to queue as the value
|
||||
written to the caller's Attributes output parameter.
|
||||
**/
|
||||
#define MOCK_GET_VARIABLE_RETURN_SUCCESS_ANY_WITH_ATTR(Data, Attr) \
|
||||
will_return (MockGetVariable, EFI_SUCCESS); \
|
||||
expect_any (MockGetVariable, VariableName); \
|
||||
expect_any (MockGetVariable, VendorGuid); \
|
||||
expect_any (MockGetVariable, *DataSize); \
|
||||
will_return (MockGetVariable, Data); \
|
||||
will_return (MockGetVariable, Attr);
|
||||
|
||||
/**
|
||||
Sets up a MockGetVariable mock expectation that returns EFI_BUFFER_TOO_SMALL.
|
||||
Queues EFI_BUFFER_TOO_SMALL as the return status and enqueues TargetSize
|
||||
as the required DataSize value that MockGetVariable will report back
|
||||
to the caller.
|
||||
|
||||
@param[in] TargetSize The UINTN buffer size value to queue as the required
|
||||
DataSize output when the caller's buffer is too small.
|
||||
**/
|
||||
#define MOCK_GET_VARIABLE_RETURN_BUFFER_TOO_SMALL(TargetSize) \
|
||||
will_return (MockGetVariable, EFI_BUFFER_TOO_SMALL); \
|
||||
will_return (MockGetVariable, TargetSize);
|
||||
|
||||
/**
|
||||
Sets up a failing MockGetVariable mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockGetVariable reports a failure without populating any output fields.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_GET_VARIABLE_RETURN_ERROR(Status) \
|
||||
will_return (MockGetVariable, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetNextVariableName mock expectation that validates
|
||||
exact input parameters and returns the next variable name and GUID.
|
||||
Registers exact-match expectations for VariableNameSize, VariableName, and
|
||||
VendorGuid, queues EFI_SUCCESS as the return status, and enqueues the
|
||||
returned variable name and vendor GUID pointers as mock output values.
|
||||
|
||||
@param[in] VarNameSize The exact value of *VariableNameSize the code under
|
||||
test is expected to pass on input.
|
||||
@param[in] VarName Pointer to the Null-terminated Unicode variable name
|
||||
that the code under test is expected to pass on input.
|
||||
@param[in] VenGuid Pointer to the EFI_GUID that the code under test is
|
||||
expected to pass as VendorGuid on input.
|
||||
@param[in] RetVarName Pointer to the Null-terminated Unicode string to queue
|
||||
as the next variable name output of MockGetNextVariableName.
|
||||
@param[in] RetVenGuid Pointer to the EFI_GUID to queue as the next vendor GUID
|
||||
output of MockGetNextVariableName.
|
||||
**/
|
||||
#define MOCK_GET_NEXT_VARIABLE_NAME_RETURN_SUCCESS(VarNameSize, VarName, VenGuid, RetVarName, RetVenGuid) \
|
||||
expect_value (MockGetNextVariableName, *VariableNameSize, VarNameSize); \
|
||||
expect_memory (MockGetNextVariableName, VariableName, VarName, VarNameSize); \
|
||||
expect_memory (MockGetNextVariableName, VendorGuid, VenGuid, sizeof (EFI_GUID)); \
|
||||
will_return (MockGetNextVariableName, EFI_SUCCESS); \
|
||||
will_return (MockGetNextVariableName, RetVarName); \
|
||||
will_return (MockGetNextVariableName, RetVenGuid);
|
||||
|
||||
/**
|
||||
Sets up a MockGetNextVariableName mock expectation that returns
|
||||
EFI_BUFFER_TOO_SMALL.
|
||||
Queues EFI_BUFFER_TOO_SMALL as the return status and enqueues TargetSize
|
||||
as the required VariableNameSize value that MockGetNextVariableName will
|
||||
report back to the caller.
|
||||
|
||||
@param[in] TargetSize The UINTN buffer size value to queue as the required
|
||||
VariableNameSize output when the caller's buffer is
|
||||
too small.
|
||||
**/
|
||||
#define MOCK_GET_NEXT_VARIABLE_NAME_RETURN_BUFFER_TOO_SMALL(TargetSize) \
|
||||
will_return (MockGetNextVariableName, EFI_BUFFER_TOO_SMALL); \
|
||||
will_return (MockGetNextVariableName, TargetSize);
|
||||
|
||||
/**
|
||||
Sets up a failing MockGetNextVariableName mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockGetNextVariableName reports a failure without populating any output fields.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_GET_NEXT_VARIABLE_NAME_RETURN_ERROR(Status) \
|
||||
will_return (MockGetNextVariableName, Status);
|
||||
|
||||
/**
|
||||
Sets up a MockSetVariable mock expectation that deletes a variable.
|
||||
Queues EFI_SUCCESS as the return status and registers exact-match expectations
|
||||
for VariableName, VendorGuid, and Attributes, with DataSize expected to be
|
||||
zero. Use this macro when the code under test calls SetVariable() to delete
|
||||
an existing variable (DataSize = 0, Data = NULL).
|
||||
|
||||
@param[in] VarName Pointer to the Null-terminated Unicode variable name
|
||||
that the code under test is expected to pass.
|
||||
@param[in] VenGuid Pointer to the EFI_GUID that the code under test is
|
||||
expected to pass as VendorGuid.
|
||||
@param[in] Attr The UINT32 attributes bitmask that the code under test
|
||||
is expected to pass as Attributes.
|
||||
**/
|
||||
#define MOCK_SET_VARIABLE_DELETE(VarName, VenGuid, Attr) \
|
||||
will_return (MockSetVariable, EFI_SUCCESS); \
|
||||
expect_memory (MockSetVariable, VariableName, VarName, StrSize(VarName)); \
|
||||
expect_memory (MockSetVariable, VendorGuid, VenGuid, sizeof (EFI_GUID)); \
|
||||
expect_value (MockSetVariable, Attributes, Attr); \
|
||||
expect_value (MockSetVariable, DataSize, 0);
|
||||
|
||||
/**
|
||||
Sets up a successful MockSetVariable mock expectation that validates all
|
||||
input parameters when writing variable data.
|
||||
Queues EFI_SUCCESS as the return status and registers exact-match
|
||||
expectations for VariableName, VendorGuid, Attributes, DataSize, and the
|
||||
contents of the Data buffer. Use this macro when the code under test calls
|
||||
SetVariable() to store a non-empty variable (DataSize > 0, Data != NULL).
|
||||
|
||||
@param[in] VarName Pointer to the Null-terminated Unicode variable name
|
||||
that the code under test is expected to pass.
|
||||
@param[in] VenGuid Pointer to the EFI_GUID that the code under test is
|
||||
expected to pass as VendorGuid.
|
||||
@param[in] Attr The UINT32 attributes bitmask that the code under test
|
||||
is expected to pass as Attributes.
|
||||
@param[in] Size The exact UINTN DataSize value the code under test is
|
||||
expected to pass.
|
||||
@param[in] DataBuffer Pointer to the data buffer whose contents the code
|
||||
under test is expected to pass in the Data parameter.
|
||||
**/
|
||||
#define MOCK_SET_VARIABLE_RETURN_SUCCESS(VarName, VenGuid, Attr, Size, DataBuffer) \
|
||||
will_return (MockSetVariable, EFI_SUCCESS); \
|
||||
expect_memory (MockSetVariable, VariableName, VarName, StrSize(VarName)); \
|
||||
expect_memory (MockSetVariable, VendorGuid, VenGuid, sizeof (EFI_GUID)); \
|
||||
expect_value (MockSetVariable, Attributes, Attr); \
|
||||
expect_value (MockSetVariable, DataSize, Size); \
|
||||
expect_memory (MockSetVariable, Data, DataBuffer, Size);
|
||||
|
||||
/**
|
||||
Sets up a successful MockSetVariable mock expectation without validating
|
||||
any input parameters.
|
||||
Queues EFI_SUCCESS as the return status and accepts any caller-supplied
|
||||
values for VariableName, VendorGuid, Attributes, DataSize, and Data.
|
||||
Use this macro when parameter validation is not required by the test.
|
||||
**/
|
||||
#define MOCK_SET_VARIABLE_RETURN_SUCCESS_ANY() \
|
||||
will_return (MockSetVariable, EFI_SUCCESS); \
|
||||
expect_any (MockSetVariable, VariableName); \
|
||||
expect_any (MockSetVariable, VendorGuid); \
|
||||
expect_any (MockSetVariable, Attributes); \
|
||||
expect_any (MockSetVariable, DataSize); \
|
||||
expect_any (MockSetVariable, Data)
|
||||
|
||||
/**
|
||||
Sets up a failing MockSetVariable mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockSetVariable reports a failure without storing any data.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_SET_VARIABLE_RETURN_ERROR(Status) \
|
||||
will_return (MockSetVariable, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockGetNextHighMonotonicCount mock expectation.
|
||||
Queues EFI_SUCCESS as the return status and enqueues HighCount as the
|
||||
high 32-bit counter value that MockGetNextHighMonotonicCount will output.
|
||||
|
||||
@param[in] HighCount The UINT32 high monotonic count value to queue as
|
||||
the output of MockGetNextHighMonotonicCount.
|
||||
**/
|
||||
#define MOCK_GET_NEXT_HIGH_MONOTONIC_COUNT_RETURN_SUCCESS(HighCount) \
|
||||
will_return (MockGetNextHighMonotonicCount, EFI_SUCCESS); \
|
||||
will_return (MockGetNextHighMonotonicCount, HighCount);
|
||||
|
||||
/**
|
||||
Sets up a failing MockGetNextHighMonotonicCount mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockGetNextHighMonotonicCount reports a failure without populating
|
||||
the HighCount output.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_GET_NEXT_HIGH_MONOTONIC_COUNT_RETURN_ERROR(Status) \
|
||||
will_return (MockGetNextHighMonotonicCount, Status);
|
||||
|
||||
/**
|
||||
Sets up a MockUpdateCapsule mock expectation with the given return status.
|
||||
Queues Status as the mock return value so that MockUpdateCapsule returns
|
||||
the specified code when called by the code under test.
|
||||
|
||||
@param[in] Status The EFI_STATUS code to queue as the return value
|
||||
(e.g. EFI_SUCCESS, EFI_UNSUPPORTED).
|
||||
**/
|
||||
#define MOCK_UPDATE_CAPSULE_RETURN_STATUS(Status) \
|
||||
will_return (MockUpdateCapsule, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockQueryCapsuleCapabilities mock expectation.
|
||||
Queues EFI_SUCCESS as the return status, then enqueues MaximumCapsuleSize
|
||||
and ResetType as the output values that MockQueryCapsuleCapabilities will
|
||||
return to the caller.
|
||||
|
||||
@param[in] MaximumCapsuleSize The UINT64 maximum capsule size value to
|
||||
queue as the output of
|
||||
MockQueryCapsuleCapabilities.
|
||||
@param[in] ResetType The EFI_RESET_TYPE value to queue as the
|
||||
required reset type output of
|
||||
MockQueryCapsuleCapabilities.
|
||||
**/
|
||||
#define MOCK_QUERY_CAPSULE_CAPABILITIES_RETURN_SUCCESS(MaximumCapsuleSize, ResetType) \
|
||||
will_return (MockQueryCapsuleCapabilities, EFI_SUCCESS); \
|
||||
will_return (MockQueryCapsuleCapabilities, MaximumCapsuleSize); \
|
||||
will_return (MockQueryCapsuleCapabilities, ResetType);
|
||||
|
||||
/**
|
||||
Sets up a failing MockQueryCapsuleCapabilities mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockQueryCapsuleCapabilities reports a failure without populating
|
||||
any output fields.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_QUERY_CAPSULE_CAPABILITIES_RETURN_ERROR(Status) \
|
||||
will_return (MockQueryCapsuleCapabilities, Status);
|
||||
|
||||
/**
|
||||
Sets up a successful MockQueryVariableInfo mock expectation.
|
||||
Queues EFI_SUCCESS as the return status, then enqueues
|
||||
MaximumVariableStorageSize, RemainingVariableStorageSize, and
|
||||
MaximumVariableSize as the successive output values that
|
||||
MockQueryVariableInfo will return to the caller.
|
||||
|
||||
@param[in] MaximumVariableStorageSize The UINT64 maximum variable storage
|
||||
size value to queue as output.
|
||||
@param[in] RemainingVariableStorageSize The UINT64 remaining variable storage
|
||||
size value to queue as output.
|
||||
@param[in] MaximumVariableSize The UINT64 maximum individual variable
|
||||
size value to queue as output.
|
||||
**/
|
||||
#define MOCK_QUERY_VARIABLE_INFO_RETURN_SUCCESS(MaximumVariableStorageSize, RemainingVariableStorageSize, MaximumVariableSize) \
|
||||
will_return (MockQueryVariableInfo, EFI_SUCCESS); \
|
||||
will_return (MockQueryVariableInfo, MaximumVariableStorageSize); \
|
||||
will_return (MockQueryVariableInfo, RemainingVariableStorageSize); \
|
||||
will_return (MockQueryVariableInfo, MaximumVariableSize);
|
||||
|
||||
/**
|
||||
Sets up a failing MockQueryVariableInfo mock expectation.
|
||||
Queues the given error status as the sole mock return value so that
|
||||
MockQueryVariableInfo reports a failure without populating any output fields.
|
||||
|
||||
@param[in] Status The EFI_STATUS error code to queue as the return value.
|
||||
**/
|
||||
#define MOCK_QUERY_VARIABLE_INFO_RETURN_ERROR(Status) \
|
||||
will_return (MockQueryVariableInfo, Status);
|
||||
|
||||
#endif // __MOCK_UEFI_RUNTIME_SERVICES_TABLE_LIB_H__
|
||||
|
|
@ -0,0 +1,977 @@
|
|||
/** @file MockUefiRuntimeServicesTableLib.c
|
||||
Mock Unit Test UEFI Runtime Services Table Library Implementation for
|
||||
Unit Testing
|
||||
|
||||
This library provides comprehensive mocking of UEFI Runtime Services
|
||||
functions using CMocka framework. Each function can return data based
|
||||
on mock() implementation.
|
||||
|
||||
Copyright (c) 2026, American Megatrends International LLC. All rights reserved.<BR>
|
||||
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/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/MockUefiRuntimeServicesTableLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/AuthVariableLib.h>
|
||||
|
||||
#define EARLIEST_YEAR 1900
|
||||
#define MAXIMUM_YEAR 9999
|
||||
|
||||
STATIC CONST UINT8 mDayOfMonth[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
#define EFI_VARIABLE_ATTRIBUTES_MASK (EFI_VARIABLE_NON_VOLATILE |\
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | \
|
||||
EFI_VARIABLE_RUNTIME_ACCESS | \
|
||||
EFI_VARIABLE_HARDWARE_ERROR_RECORD | \
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
|
||||
EFI_VARIABLE_APPEND_WRITE)
|
||||
|
||||
//
|
||||
// Helper Functions
|
||||
//
|
||||
|
||||
/**
|
||||
Check if a year is a leap year.
|
||||
|
||||
@param[in] Time Pointer to EFI_TIME structure.
|
||||
|
||||
@retval TRUE Year is a leap year.
|
||||
@retval FALSE Year is not a leap year.
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
IsLeapYear (
|
||||
IN EFI_TIME *Time
|
||||
)
|
||||
{
|
||||
if (Time->Year % 4 == 0) {
|
||||
if (Time->Year % 100 == 0) {
|
||||
if (Time->Year % 400 == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Validate time and date ranges per UEFI specification.
|
||||
|
||||
@param[in] Time Pointer to EFI_TIME structure to validate.
|
||||
|
||||
@retval TRUE Time is valid.
|
||||
@retval FALSE Time contains invalid values.
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
ValidateTimeFields (
|
||||
IN EFI_TIME *Time
|
||||
)
|
||||
{
|
||||
// Check year, month, day
|
||||
if ((Time->Year < EARLIEST_YEAR) || (Time->Year > MAXIMUM_YEAR)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((Time->Month < 1) || (Time->Month > 12)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check day of month
|
||||
if ((Time->Day < 1) ||
|
||||
(Time->Day > mDayOfMonth[Time->Month - 1]) ||
|
||||
((Time->Month == 2) && (!IsLeapYear (Time)) && (Time->Day > 28))
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check hour, minute, second, nanosecond
|
||||
if ((Time->Hour > 23) ||
|
||||
(Time->Minute > 59) ||
|
||||
(Time->Second > 59) ||
|
||||
(Time->Nanosecond > 999999999))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check timezone: must be -1440 to 1440 or EFI_UNSPECIFIED_TIMEZONE
|
||||
if (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check daylight
|
||||
if ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Mock Runtime Services function implementations
|
||||
//
|
||||
|
||||
/**
|
||||
Returns the current time and date information, and the time-keeping capabilities
|
||||
of the hardware platform.
|
||||
|
||||
@param[out] Time A pointer to storage to receive a snapshot of the current time.
|
||||
@param[out] Capabilities An optional pointer to a buffer to receive the real time clock
|
||||
device's capabilities.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER Time is NULL.
|
||||
@retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetTime (
|
||||
OUT EFI_TIME *Time,
|
||||
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Time is required parameter
|
||||
if (Time == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// Provide mock time data
|
||||
Time->Year = (UINT16)mock ();
|
||||
Time->Month = (UINT8)mock ();
|
||||
Time->Day = (UINT8)mock ();
|
||||
Time->Hour = (UINT8)mock ();
|
||||
Time->Minute = (UINT8)mock ();
|
||||
Time->Second = (UINT8)mock ();
|
||||
Time->Nanosecond = (UINT32)mock ();
|
||||
Time->TimeZone = (INT16)mock ();
|
||||
Time->Daylight = (UINT8)mock ();
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status) && (Capabilities != NULL)) {
|
||||
Capabilities->Resolution = (UINT32)mock ();
|
||||
Capabilities->Accuracy = (UINT32)mock ();
|
||||
Capabilities->SetsToZero = (BOOLEAN)mock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the current local time and date information.
|
||||
|
||||
@param[in] Time A pointer to the current time.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER A time field is out of range.
|
||||
@retval EFI_DEVICE_ERROR The time could not be set due to hardware error.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetTime (
|
||||
IN EFI_TIME *Time
|
||||
)
|
||||
{
|
||||
if (Time == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Validate time parameter
|
||||
if (!ValidateTimeFields (Time)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return (EFI_STATUS)mock ();
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the current wakeup alarm clock setting.
|
||||
|
||||
@param[out] Enabled Indicates if the alarm is currently enabled or disabled.
|
||||
@param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement.
|
||||
@param[out] Time If the alarm is enabled, returns the current alarm setting.
|
||||
|
||||
@retval EFI_SUCCESS The alarm settings were returned.
|
||||
@retval EFI_INVALID_PARAMETER Enabled is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Pending is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Time is NULL.
|
||||
@retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
|
||||
@retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetWakeupTime (
|
||||
OUT BOOLEAN *Enabled,
|
||||
OUT BOOLEAN *Pending,
|
||||
OUT EFI_TIME *Time
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// All output parameters are required
|
||||
if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*Enabled = (BOOLEAN)mock ();
|
||||
*Pending = (BOOLEAN)mock ();
|
||||
Time->Year = (UINT16)mock ();
|
||||
Time->Month = (UINT8)mock ();
|
||||
Time->Day = (UINT8)mock ();
|
||||
Time->Hour = (UINT8)mock ();
|
||||
Time->Minute = (UINT8)mock ();
|
||||
Time->Second = (UINT8)mock ();
|
||||
Time->Nanosecond = (UINT32)mock ();
|
||||
Time->TimeZone = (INT16)mock ();
|
||||
Time->Daylight = (UINT8)mock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the system wakeup alarm clock time.
|
||||
|
||||
@param[in] Enable Enable or disable the wakeup alarm.
|
||||
@param[in] Time If Enable is TRUE, the time to set the wakeup alarm for.
|
||||
If Enable is FALSE, then this parameter is optional, and may be NULL.
|
||||
|
||||
@retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
|
||||
Enable is FALSE, then the wakeup alarm was disabled.
|
||||
@retval EFI_INVALID_PARAMETER A time field is out of range.
|
||||
@retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
|
||||
@retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetWakeupTime (
|
||||
IN BOOLEAN Enable,
|
||||
IN EFI_TIME *Time OPTIONAL
|
||||
)
|
||||
{
|
||||
// If Enable is TRUE, Time must be valid
|
||||
if (Enable) {
|
||||
if (Time == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!ValidateTimeFields (Time)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
return (EFI_STATUS)mock ();
|
||||
}
|
||||
|
||||
/**
|
||||
Changes the runtime addressing mode of EFI firmware from physical to virtual.
|
||||
|
||||
@param[in] MemoryMapSize The size in bytes of VirtualMap.
|
||||
@param[in] DescriptorSize The size in bytes of an entry in the VirtualMap.
|
||||
@param[in] DescriptorVersion The version of the structure entries in VirtualMap.
|
||||
@param[in] VirtualMap An array of memory descriptors which contain new virtual
|
||||
address mapping information for all runtime ranges.
|
||||
|
||||
@retval EFI_SUCCESS The virtual address map has been applied.
|
||||
@retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in
|
||||
virtual address mapped mode.
|
||||
@retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid.
|
||||
@retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory
|
||||
map that requires a mapping.
|
||||
@retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found
|
||||
in the memory map.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetVirtualAddressMap (
|
||||
IN UINTN MemoryMapSize,
|
||||
IN UINTN DescriptorSize,
|
||||
IN UINT32 DescriptorVersion,
|
||||
IN EFI_MEMORY_DESCRIPTOR *VirtualMap
|
||||
)
|
||||
{
|
||||
if (VirtualMap == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION) || (DescriptorSize < sizeof (EFI_MEMORY_DESCRIPTOR))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((MemoryMapSize % DescriptorSize) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return (EFI_STATUS)mock ();
|
||||
}
|
||||
|
||||
/**
|
||||
Determines the new virtual address that is to be used on subsequent memory accesses.
|
||||
|
||||
@param[in] DebugDisposition Supplies type information for the pointer being converted.
|
||||
@param[in,out] Address A pointer to a pointer that is to be fixed to be the value needed
|
||||
for the new virtual address mappings being applied.
|
||||
|
||||
@retval EFI_SUCCESS The pointer pointed to by Address was modified.
|
||||
@retval EFI_INVALID_PARAMETER Address is NULL.
|
||||
@retval EFI_INVALID_PARAMETER *Address is NULL and DebugDisposition does not have the
|
||||
EFI_OPTIONAL_PTR bit set.
|
||||
@retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part
|
||||
of the current memory map. This is normally fatal.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockConvertPointer (
|
||||
IN UINTN DebugDisposition,
|
||||
IN OUT VOID **Address
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Address is required parameter
|
||||
if (Address == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// If this is a null pointer, return if it's allowed
|
||||
//
|
||||
if (*Address == 0) {
|
||||
if ((DebugDisposition & EFI_OPTIONAL_PTR) != 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// Simulate pointer conversion by providing mock converted address
|
||||
*Address = mock_ptr_type (VOID *);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the value of a variable.
|
||||
|
||||
@param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[out] Attributes If not NULL, a pointer to the memory location to return the
|
||||
attributes bitmask for the variable.
|
||||
@param[in,out] DataSize On input, the size in bytes of the return Data buffer.
|
||||
On output the size of data returned in Data.
|
||||
@param[out] Data The buffer to return the contents of the variable. May be NULL
|
||||
with a zero DataSize in order to determine the size buffer needed.
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully.
|
||||
@retval EFI_NOT_FOUND The variable was not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result.
|
||||
@retval EFI_INVALID_PARAMETER VariableName is NULL.
|
||||
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DataSize is NULL.
|
||||
@retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
|
||||
@retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetVariable (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
OUT UINT32 *Attributes OPTIONAL,
|
||||
IN OUT UINTN *DataSize,
|
||||
OUT VOID *Data OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// VariableName, VendorGuid, and DataSize are required parameters
|
||||
if ((VariableName == NULL) || (VendorGuid == NULL) || (DataSize == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (VariableName[0] == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
// Get required size
|
||||
*DataSize = (UINTN)mock ();
|
||||
|
||||
// Handle buffer too small case
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Since its a success case, and DataSize meets the
|
||||
// requirement, Data should be non-NULL
|
||||
// As per UEFI spec: "The DataSize is not too small and
|
||||
// Data is NULL" returns EFI_INVALID_PARAMETER
|
||||
//
|
||||
if (Data == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
check_expected_ptr (VariableName);
|
||||
check_expected_ptr (VendorGuid);
|
||||
check_expected (*DataSize);
|
||||
// Copy data - Data is guaranteed non-NULL at this point
|
||||
CopyMem (Data, mock_ptr_type (VOID *), *DataSize);
|
||||
|
||||
if (Attributes != NULL) {
|
||||
*Attributes = (UINT32)mock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Enumerates the current variable names.
|
||||
|
||||
@param[in,out] VariableNameSize The size of the VariableName buffer. The size must be large
|
||||
enough to fit input string supplied in VariableName buffer.
|
||||
@param[in,out] VariableName On input, supplies the last VariableName that was returned
|
||||
by GetNextVariableName(). On output, returns the Nullterminated
|
||||
string of the current variable.
|
||||
@param[in,out] VendorGuid On input, supplies the last VendorGuid that was returned by
|
||||
GetNextVariableName(). On output, returns the
|
||||
VendorGuid of the current variable.
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully.
|
||||
@retval EFI_NOT_FOUND The next variable was not found.
|
||||
@retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
|
||||
VariableNameSize has been updated with the size needed to complete the request.
|
||||
@retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
|
||||
@retval EFI_INVALID_PARAMETER VariableName is NULL.
|
||||
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
|
||||
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
|
||||
GUID of an existing variable.
|
||||
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
|
||||
the input VariableName buffer.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetNextVariableName (
|
||||
IN OUT UINTN *VariableNameSize,
|
||||
IN OUT CHAR16 *VariableName,
|
||||
IN OUT EFI_GUID *VendorGuid
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
BOOLEAN Found = FALSE;
|
||||
|
||||
// All parameters are required
|
||||
if ((VariableNameSize == NULL) || (VariableName == NULL) || (VendorGuid == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// VariableNameSize must be large enough to fit input string
|
||||
if ((*VariableNameSize > 0) && (VariableName[0] != 0)) {
|
||||
// Verify null-terminator exists within the buffer
|
||||
for (Index = 0; Index < (*VariableNameSize / sizeof (CHAR16)); Index++) {
|
||||
if (VariableName[Index] == 0) {
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Found) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
// Exit early for errors (except BUFFER_TOO_SMALL) without
|
||||
// checking expected values
|
||||
if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
*VariableNameSize = (UINTN)mock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Only check expected values when successful
|
||||
check_expected (*VariableNameSize);
|
||||
check_expected_ptr (VariableName);
|
||||
check_expected_ptr (VendorGuid);
|
||||
|
||||
// Copy mock variable name and GUID for successful case
|
||||
StrCpyS (VariableName, *VariableNameSize / sizeof (CHAR16), (CHAR16 *)mock_ptr_type (VOID *));
|
||||
CopyMem (VendorGuid, mock_ptr_type (VOID *), sizeof (EFI_GUID));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Sets the value of a variable.
|
||||
|
||||
@param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
|
||||
Each VariableName is unique for each VendorGuid. VariableName must
|
||||
contain 1 or more characters. If VariableName is an empty string,
|
||||
then EFI_INVALID_PARAMETER is returned.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[in] Attributes Attributes bitmask to set for the variable.
|
||||
@param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
|
||||
causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
|
||||
set, then a SetVariable() call with a DataSize of zero will not cause any change to
|
||||
the variable value (the timestamp associated with the variable may be updated however
|
||||
even if no new data value is provided,see the description of the
|
||||
EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
|
||||
be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
|
||||
@param[in] Data The contents for the variable.
|
||||
|
||||
@retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
|
||||
defined by the Attributes.
|
||||
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the
|
||||
DataSize exceeds the maximum allowed.
|
||||
@retval EFI_INVALID_PARAMETER VariableName is an empty string.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
|
||||
@retval EFI_WRITE_PROTECTED The variable in question is read-only.
|
||||
@retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
|
||||
@retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set,
|
||||
but the AuthInfo does NOT pass the validation check carried out by the firmware.
|
||||
@retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockSetVariable (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN UINT32 Attributes,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *Data
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN PayloadSize;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if ((VariableName == NULL) || (VariableName[0] == 0) || (VendorGuid == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((DataSize != 0) && (Data == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for reserverd bit in variable attribute.
|
||||
// EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated but we still allow
|
||||
// the delete operation of common authenticated variable at user physical presence.
|
||||
//
|
||||
if ((Attributes & (~(EFI_VARIABLE_ATTRIBUTES_MASK | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS))) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the combination of attribute bits is valid.
|
||||
//
|
||||
if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
|
||||
//
|
||||
// Make sure if runtime bit is set, boot service bit is set also.
|
||||
//
|
||||
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
} else {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
} else if ((Attributes & EFI_VARIABLE_ATTRIBUTES_MASK) == EFI_VARIABLE_NON_VOLATILE) {
|
||||
//
|
||||
// Only EFI_VARIABLE_NON_VOLATILE attribute is invalid
|
||||
//
|
||||
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
} else {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS and EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute
|
||||
// cannot be set both.
|
||||
//
|
||||
if ( ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
|
||||
&& ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) ==
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS))
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {
|
||||
//
|
||||
// If DataSize == AUTHINFO_SIZE and then PayloadSize is 0.
|
||||
// Maybe it's the delete operation of common authenticated variable at user physical presence.
|
||||
//
|
||||
if (DataSize != AUTHINFO_SIZE) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
PayloadSize = DataSize - AUTHINFO_SIZE;
|
||||
} else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) ==
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
|
||||
{
|
||||
//
|
||||
// Sanity check for EFI_VARIABLE_AUTHENTICATION_2 descriptor.
|
||||
//
|
||||
if ((DataSize < OFFSET_OF_AUTHINFO2_CERT_DATA) ||
|
||||
(((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->AuthInfo.Hdr.dwLength >
|
||||
DataSize - (OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo))) ||
|
||||
(((EFI_VARIABLE_AUTHENTICATION_2 *)Data)->AuthInfo.Hdr.dwLength <
|
||||
OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)))
|
||||
{
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
PayloadSize = DataSize - AUTHINFO2_SIZE (Data);
|
||||
} else {
|
||||
PayloadSize = DataSize;
|
||||
}
|
||||
|
||||
if ((UINTN)(~0) - PayloadSize < StrSize (VariableName)) {
|
||||
//
|
||||
// Prevent whole variable size overflow
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
check_expected_ptr (VariableName);
|
||||
check_expected_ptr (VendorGuid);
|
||||
check_expected (Attributes);
|
||||
check_expected (DataSize);
|
||||
// Only check Data pointer if DataSize is non-zero (Data can be NULL for variable deletion)
|
||||
if (DataSize != 0) {
|
||||
check_expected_ptr (Data);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the next high 32 bits of the platform's monotonic counter.
|
||||
|
||||
@param[out] HighCount Pointer to returned value.
|
||||
|
||||
@retval EFI_SUCCESS The next high monotonic count was returned.
|
||||
@retval EFI_INVALID_PARAMETER HighCount is NULL.
|
||||
@retval EFI_DEVICE_ERROR The device is not functioning properly.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockGetNextHighMonotonicCount (
|
||||
OUT UINT32 *HighCount
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// HighCount is required parameter
|
||||
if (HighCount == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*HighCount = (UINT32)mock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
MockResetSystem (
|
||||
IN EFI_RESET_TYPE ResetType,
|
||||
IN EFI_STATUS ResetStatus,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *ResetData OPTIONAL
|
||||
)
|
||||
{
|
||||
// Mock implementation - normally this function doesn't return
|
||||
}
|
||||
|
||||
/**
|
||||
Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
|
||||
consumption, the firmware may process the capsule immediately. If the payload should persist
|
||||
across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
|
||||
be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
|
||||
part of the reset process.
|
||||
|
||||
@param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
|
||||
being passed into update capsule.
|
||||
@param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
|
||||
CapsuleHeaderArray.
|
||||
@param[in] ScatterGatherList Physical pointer to a set of
|
||||
EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
|
||||
location in physical memory of a set of capsules.
|
||||
|
||||
@retval EFI_SUCCESS Valid capsule was passed. If
|
||||
CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
|
||||
capsule has been successfully processed by the firmware.
|
||||
@retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were
|
||||
set in the capsule header.
|
||||
@retval EFI_INVALID_PARAMETER CapsuleCount is 0.
|
||||
@retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error.
|
||||
@retval EFI_UNSUPPORTED The capsule type is not supported on this platform.
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule
|
||||
is compatible with this platform but is not capable of being submitted or processed
|
||||
in runtime. The caller may resubmit the capsule prior to ExitBootServices().
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates
|
||||
the capsule is compatible with this platform but there are insufficient resources to process.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockUpdateCapsule (
|
||||
IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
|
||||
IN UINTN CapsuleCount,
|
||||
IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
|
||||
)
|
||||
{
|
||||
// CapsuleHeaderArray is required, CapsuleCount must be > 0
|
||||
if (CapsuleHeaderArray == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (CapsuleCount == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return (EFI_STATUS)mock ();
|
||||
}
|
||||
|
||||
/**
|
||||
Returns if the capsule can be supported via UpdateCapsule().
|
||||
|
||||
@param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
|
||||
being passed into update capsule.
|
||||
@param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
|
||||
CapsuleHeaderArray.
|
||||
@param[out] MaximumCapsuleSize On output the maximum size that UpdateCapsule() can
|
||||
support as an argument to UpdateCapsule() via
|
||||
CapsuleHeaderArray and ScatterGatherList.
|
||||
@param[out] ResetType Returns the type of reset required for the capsule update.
|
||||
|
||||
@retval EFI_SUCCESS Valid answer returned.
|
||||
@retval EFI_UNSUPPORTED The capsule image is not supported on this platform, and
|
||||
MaximumCapsuleSize and ResetType are undefined.
|
||||
@retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule
|
||||
is compatible with this platform but is not capable of being submitted or processed
|
||||
in runtime. The caller may resubmit the capsule prior to ExitBootServices().
|
||||
@retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates
|
||||
the capsule is compatible with this platform but there are insufficient resources to process.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockQueryCapsuleCapabilities (
|
||||
IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
|
||||
IN UINTN CapsuleCount,
|
||||
OUT UINT64 *MaximumCapsuleSize,
|
||||
OUT EFI_RESET_TYPE *ResetType
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// All parameters except ScatterGatherList are required
|
||||
if ((CapsuleHeaderArray == NULL) || (MaximumCapsuleSize == NULL) || (ResetType == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (CapsuleCount == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*MaximumCapsuleSize = (UINT64)mock ();
|
||||
*ResetType = (EFI_RESET_TYPE)mock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns information about the EFI variables.
|
||||
|
||||
@param[in] Attributes Attributes bitmask to specify the type of variables on
|
||||
which to return information.
|
||||
@param[out] MaximumVariableStorageSize On output the maximum size of the storage space
|
||||
available for the EFI variables associated with the
|
||||
attributes specified.
|
||||
@param[out] RemainingVariableStorageSize Returns the remaining size of the storage space
|
||||
available for the EFI variables associated with the
|
||||
attributes specified.
|
||||
@param[out] MaximumVariableSize Returns the maximum size of the individual EFI
|
||||
variables associated with the attributes specified.
|
||||
|
||||
@retval EFI_SUCCESS Valid answer returned.
|
||||
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
|
||||
@retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the
|
||||
MaximumVariableStorageSize,
|
||||
RemainingVariableStorageSize, MaximumVariableSize
|
||||
are undefined.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MockQueryVariableInfo (
|
||||
IN UINT32 Attributes,
|
||||
OUT UINT64 *MaximumVariableStorageSize,
|
||||
OUT UINT64 *RemainingVariableStorageSize,
|
||||
OUT UINT64 *MaximumVariableSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// All output parameters are required
|
||||
if ((MaximumVariableStorageSize == NULL) ||
|
||||
(RemainingVariableStorageSize == NULL) ||
|
||||
(MaximumVariableSize == NULL))
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
|
||||
//
|
||||
// Deprecated attribute, make this check as highest priority.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((Attributes & EFI_VARIABLE_ATTRIBUTES_MASK) == 0) {
|
||||
//
|
||||
// Make sure the Attributes combination is supported by the platform.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
} else if ((Attributes & EFI_VARIABLE_ATTRIBUTES_MASK) == EFI_VARIABLE_NON_VOLATILE) {
|
||||
//
|
||||
// Only EFI_VARIABLE_NON_VOLATILE attribute is invalid
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
} else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) ==
|
||||
EFI_VARIABLE_RUNTIME_ACCESS)
|
||||
{
|
||||
//
|
||||
// Make sure if runtime bit is set, boot service bit is set also.
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
} else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) ==
|
||||
EFI_VARIABLE_HARDWARE_ERROR_RECORD)
|
||||
{
|
||||
//
|
||||
// Make sure Hw Attribute is set with NV.
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = (EFI_STATUS)mock ();
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*MaximumVariableStorageSize = (UINT64)mock ();
|
||||
*RemainingVariableStorageSize = (UINT64)mock ();
|
||||
*MaximumVariableSize = (UINT64)mock ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Global Mock Runtime Services Table for host application - initialized with mock functions
|
||||
//
|
||||
EFI_RUNTIME_SERVICES gMockRuntime = {
|
||||
.Hdr = {
|
||||
.Signature = EFI_RUNTIME_SERVICES_SIGNATURE,
|
||||
.Revision = EFI_RUNTIME_SERVICES_REVISION,
|
||||
.HeaderSize = sizeof (EFI_RUNTIME_SERVICES),
|
||||
.CRC32 = 0, // Not used in unit tests
|
||||
.Reserved = 0
|
||||
},
|
||||
.GetTime = MockGetTime,
|
||||
.SetTime = MockSetTime,
|
||||
.GetWakeupTime = MockGetWakeupTime,
|
||||
.SetWakeupTime = MockSetWakeupTime,
|
||||
.SetVirtualAddressMap = MockSetVirtualAddressMap,
|
||||
.ConvertPointer = MockConvertPointer,
|
||||
.GetVariable = MockGetVariable,
|
||||
.GetNextVariableName = MockGetNextVariableName,
|
||||
.SetVariable = MockSetVariable,
|
||||
.GetNextHighMonotonicCount = MockGetNextHighMonotonicCount,
|
||||
.ResetSystem = MockResetSystem,
|
||||
.UpdateCapsule = MockUpdateCapsule,
|
||||
.QueryCapsuleCapabilities = MockQueryCapsuleCapabilities,
|
||||
.QueryVariableInfo = MockQueryVariableInfo
|
||||
};
|
||||
|
||||
EFI_RUNTIME_SERVICES *gRT = &gMockRuntime;
|
||||
|
||||
/**
|
||||
Initializes the Mock Runtime Services Table by replacing the global gRT pointer.
|
||||
@return VOID
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitMockRuntimeServicesTablePointer (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
// Replace gRT with pre-initialized mock Runtime Services table
|
||||
gRT = &gMockRuntime;
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
## @file MockUefiRuntimeServicesTableLib.inf
|
||||
# Mock Unit Test UEFI Runtime Services Table Library
|
||||
#
|
||||
# This library provides mock implementations of UEFI Runtime Services
|
||||
# functions for unit testing purposes using CMocka framework.
|
||||
|
||||
# Copyright (c) 2026, American Megatrends International LLC. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = MockUefiRuntimeServicesTableLib
|
||||
FILE_GUID = 87654321-4321-4321-4321-210987654321
|
||||
MODULE_TYPE = HOST_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = UefiRuntimeServicesTableLib
|
||||
LIBRARY_CLASS = MockUefiRuntimeServicesTableLib
|
||||
|
||||
[Sources]
|
||||
MockUefiRuntimeServicesTableLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
|
||||
|
|
@ -44,6 +44,11 @@
|
|||
#
|
||||
HostMemoryAllocationBelowAddressLib|Include/Library/HostMemoryAllocationBelowAddressLib.h
|
||||
|
||||
## @libraryclass Provides a services table that can be used to mock UEFI Runtime Services in unit tests.
|
||||
# Only available to DXE and UEFI module types.
|
||||
#
|
||||
MockUefiRuntimeServicesTableLib|Include/Library/MockUefiRuntimeServicesTableLib.h
|
||||
|
||||
[LibraryClasses.Common.Private]
|
||||
## @libraryclass Provides a unit test result report
|
||||
#
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue