* [Patch v3 01/12] UnitTestFrameworkPkg: Add subhook submodule required for gmock
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 02/12] .pytool/CISettings.py: Add subhook submodule Michael D Kinney
` (10 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel
Cc: Chris Johnson, Andrew Fish, Leif Lindholm, Michael Kubacki,
Sean Brogan, Michael Kubacki, Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
Add subhook submodule that is required to hook internal functions
when using gmock.
https://github.com/Zeex/subhook
Add SubhookLib library class and SubhookLib library instance.
Include the SUBHOOK_STATIC define in the SubhookLib INF file so
it builds as a static library. Also include the SUBHOOK_STATIC
define in SubhookLib.h so all modules using SubhookLib properly
link SubhookLib as a static library.
Cc: Andrew Fish <afish@apple.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.gitmodules | 3 ++
ReadMe.rst | 1 +
.../Include/Library/SubhookLib.h | 15 +++++++++
.../Library/SubhookLib/SubhookLib.inf | 31 +++++++++++++++++++
.../Library/SubhookLib/SubhookLib.uni | 11 +++++++
.../Library/SubhookLib/subhook | 1 +
.../Test/UnitTestFrameworkPkgHostTest.dsc | 1 +
UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec | 2 ++
.../UnitTestFrameworkPkgHost.dsc.inc | 1 +
9 files changed, 66 insertions(+)
create mode 100644 UnitTestFrameworkPkg/Include/Library/SubhookLib.h
create mode 100644 UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
create mode 100644 UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni
create mode 160000 UnitTestFrameworkPkg/Library/SubhookLib/subhook
diff --git a/.gitmodules b/.gitmodules
index 8011a88d9d25..fe8a43be93ba 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -23,3 +23,6 @@
[submodule "UnitTestFrameworkPkg/Library/GoogleTestLib/googletest"]
path = UnitTestFrameworkPkg/Library/GoogleTestLib/googletest
url = https://github.com/google/googletest.git
+[submodule "UnitTestFrameworkPkg/Library/SubhookLib/subhook"]
+ path = UnitTestFrameworkPkg/Library/SubhookLib/subhook
+ url = https://github.com/Zeex/subhook.git
diff --git a/ReadMe.rst b/ReadMe.rst
index 497d96355908..91b9cf3c5e50 100644
--- a/ReadMe.rst
+++ b/ReadMe.rst
@@ -94,6 +94,7 @@ that are covered by additional licenses.
- `MdeModulePkg/Universal/RegularExpressionDxe/oniguruma <https://github.com/kkos/oniguruma/blob/abfc8ff81df4067f309032467785e06975678f0d/COPYING>`__
- `UnitTestFrameworkPkg/Library/CmockaLib/cmocka <https://github.com/tianocore/edk2-cmocka/blob/f5e2cd77c88d9f792562888d2b70c5a396bfbf7a/COPYING>`__
- `UnitTestFrameworkPkg/Library/GoogleTestLib/googletest <https://github.com/google/googletest/blob/86add13493e5c881d7e4ba77fb91c1f57752b3a4/LICENSE>`__
+- `UnitTestFrameworkPkg/Library/SubhookLib/subhook <https://github.com/Zeex/subhook/blob/83d4e1ebef3588fae48b69a7352cc21801cb70bc/LICENSE.txt>`__
- `RedfishPkg/Library/JsonLib/jansson <https://github.com/akheron/jansson/blob/2882ead5bb90cf12a01b07b2c2361e24960fae02/LICENSE>`__
The EDK II Project is composed of packages. The maintainers for each package
diff --git a/UnitTestFrameworkPkg/Include/Library/SubhookLib.h b/UnitTestFrameworkPkg/Include/Library/SubhookLib.h
new file mode 100644
index 000000000000..46783adfccfb
--- /dev/null
+++ b/UnitTestFrameworkPkg/Include/Library/SubhookLib.h
@@ -0,0 +1,15 @@
+/** @file
+ SubhookLib class with APIs from the subhook project
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SUBHOOK_LIB_H_
+#define SUBHOOK_LIB_H_
+
+#define SUBHOOK_STATIC
+#include <subhook.h>
+
+#endif
diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
new file mode 100644
index 000000000000..a67be890d8cd
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
@@ -0,0 +1,31 @@
+## @file
+# This module provides Subhook Library implementation.
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010018
+ BASE_NAME = SubhookLib
+ MODULE_UNI_FILE = SubhookLib.uni
+ FILE_GUID = 70E03378-E140-46A8-8E65-7719DA14A240
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 0.1
+ LIBRARY_CLASS = SubhookLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ subhook/subhook.c
+
+[Packages]
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS == /c /EHsc /Zi /DSUBHOOK_STATIC /Od
+ GCC:*_*_IA32_CC_FLAGS == -g -c -O0 -m32
+ GCC:*_*_X64_CC_FLAGS == -g -c -O0 -m64
diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni
new file mode 100644
index 000000000000..eb61f034047e
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni
@@ -0,0 +1,11 @@
+// /** @file
+// This module provides Subhook Library implementation.
+//
+// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Subhook Library implementation"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides Subhook Library implementation."
diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook b/UnitTestFrameworkPkg/Library/SubhookLib/subhook
new file mode 160000
index 000000000000..83d4e1ebef35
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook
@@ -0,0 +1 @@
+Subproject commit 83d4e1ebef3588fae48b69a7352cc21801cb70bc
diff --git a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
index 708ef7f9ab35..722509c8f26f 100644
--- a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
+++ b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
@@ -33,6 +33,7 @@ [Components]
#
UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
+ UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
index 14e387d63a0f..30b489915d4a 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
@@ -20,6 +20,7 @@ [Includes]
Library/CmockaLib/cmocka/include
Library/GoogleTestLib/googletest/googletest/include
Library/GoogleTestLib/googletest/googlemock/include
+ Library/SubhookLib/subhook
[Includes.Common.Private]
PrivateInclude
@@ -34,6 +35,7 @@ [LibraryClasses]
## @libraryclass GoogleTest infrastructure
#
GoogleTestLib|Include/Library/GoogleTestLib.h
+ SubhookLib|Include/Library/SubhookLib.h
[LibraryClasses.Common.Private]
## @libraryclass Provides a unit test result report
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index 7f5dfa30ed60..e77897bd326f 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -15,6 +15,7 @@ [LibraryClasses.common.HOST_APPLICATION]
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLibNull/BaseCacheMaintenanceLibNull.inf
CmockaLib|UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
GoogleTestLib|UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
+ SubhookLib|UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf
DebugLib|UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 02/12] .pytool/CISettings.py: Add subhook submodule
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
2023-04-07 22:20 ` [Patch v3 01/12] UnitTestFrameworkPkg: Add subhook submodule required for gmock Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 03/12] UnitTestFrameworkPkg: Add gmock support to GoogleTestLib Michael D Kinney
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel
Cc: Chris Johnson, Sean Brogan, Michael Kubacki, Liming Gao,
Leif Lindholm, Michael Kubacki, Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
Add submodule for https://github.com/Zeex/subhook
This submodule is required to hook internal functions
when using gmock.
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.pytool/CISettings.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index d87c8e838e61..e3f44add5834 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -193,6 +193,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
"BaseTools/Source/C/BrotliCompress/brotli", False))
rs.append(RequiredSubmodule(
"RedfishPkg/Library/JsonLib/jansson", False))
+ rs.append(RequiredSubmodule(
+ "UnitTestFrameworkPkg/Library/SubhookLib/subhook", False))
return rs
def GetName(self):
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 03/12] UnitTestFrameworkPkg: Add gmock support to GoogleTestLib
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
2023-04-07 22:20 ` [Patch v3 01/12] UnitTestFrameworkPkg: Add subhook submodule required for gmock Michael D Kinney
2023-04-07 22:20 ` [Patch v3 02/12] .pytool/CISettings.py: Add subhook submodule Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 04/12] UnitTestFrameworkPkg/ReadMe.md: Add gmock documentation Michael D Kinney
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel
Cc: Chris Johnson, Sean Brogan, Michael Kubacki, Michael Kubacki,
Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
* Add gmock support to GoogleTestLib
* Add FunctionMockLib library class and library instance
* Add GoogleTest extension to GoogleTestLib.h for CHAR16 type
* Add GoogleTest extension to GoogleTestLib.h for buffer types
* HOST_APPLICATION only supports IA32/X64
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../Include/Library/FunctionMockLib.h | 131 ++++++++++++++++++
.../Include/Library/GoogleTestLib.h | 96 +++++++++++++
.../Library/CmockaLib/CmockaLib.inf | 2 +-
.../Library/FunctionMockLib/FunctionMockLib.c | 7 +
.../FunctionMockLib/FunctionMockLib.inf | 31 +++++
.../FunctionMockLib/FunctionMockLib.uni | 11 ++
.../Library/GoogleTestLib/GoogleTestLib.inf | 21 ++-
.../Library/GoogleTestLib/GoogleTestLib.uni | 3 -
.../Test/UnitTestFrameworkPkgHostTest.dsc | 3 +-
.../UnitTestFrameworkPkg.ci.yaml | 7 +-
UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec | 2 +
.../UnitTestFrameworkPkgHost.dsc.inc | 1 +
12 files changed, 297 insertions(+), 18 deletions(-)
create mode 100644 UnitTestFrameworkPkg/Include/Library/FunctionMockLib.h
create mode 100644 UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c
create mode 100644 UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
create mode 100644 UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni
diff --git a/UnitTestFrameworkPkg/Include/Library/FunctionMockLib.h b/UnitTestFrameworkPkg/Include/Library/FunctionMockLib.h
new file mode 100644
index 000000000000..bf7a7066560a
--- /dev/null
+++ b/UnitTestFrameworkPkg/Include/Library/FunctionMockLib.h
@@ -0,0 +1,131 @@
+/** @file
+ This header allows the mocking of free (C style) functions using gmock.
+
+ Copyright (c) 2023, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef FUNCTION_MOCK_LIB_H_
+#define FUNCTION_MOCK_LIB_H_
+
+#include <Library/GoogleTestLib.h>
+#include <Library/SubhookLib.h>
+#include <type_traits>
+
+//////////////////////////////////////////////////////////////////////////////
+// The below macros are the public function mock interface that are intended
+// to be used outside this file.
+
+#define MOCK_INTERFACE_DECLARATION(MOCK) \
+ static MOCK * Instance; \
+ MOCK (); \
+ ~MOCK ();
+
+#define MOCK_INTERFACE_DEFINITION(MOCK) \
+ MOCK_STATIC_INSTANCE_DEFINITION (MOCK) \
+ MOCK_INTERFACE_CONSTRUCTOR (MOCK) \
+ MOCK_INTERFACE_DECONSTRUCTOR (MOCK)
+
+// Mock function declaration for external functions (i.e. functions to
+// mock that do not exist in the compilation unit).
+#define MOCK_FUNCTION_DECLARATION(RET_TYPE, FUNC, ARGS) \
+ MOCK_FUNCTION_TYPE_DEFINITIONS(RET_TYPE, FUNC, ARGS) \
+ MOCK_METHOD (RET_TYPE, FUNC, ARGS);
+
+// Mock function definition for external functions (i.e. functions to
+// mock that do not exist in the compilation unit).
+#define MOCK_FUNCTION_DEFINITION(MOCK, FUNC, NUM_ARGS, CALL_TYPE) \
+ FUNCTION_DEFINITION_TO_CALL_MOCK(MOCK, FUNC, FUNC, NUM_ARGS, CALL_TYPE)
+
+// Mock function declaration for internal functions (i.e. functions to
+// mock that already exist in the compilation unit).
+#define MOCK_FUNCTION_INTERNAL_DECLARATION(RET_TYPE, FUNC, ARGS) \
+ MOCK_FUNCTION_DECLARATION(RET_TYPE, FUNC, ARGS) \
+ MOCK_FUNCTION_HOOK_DECLARATIONS(FUNC)
+
+// Mock function definition for internal functions (i.e. functions to
+// mock that already exist in the compilation unit). This definition also
+// implements MOCK_FUNC() which is later hooked as FUNC().
+#define MOCK_FUNCTION_INTERNAL_DEFINITION(MOCK, FUNC, NUM_ARGS, CALL_TYPE) \
+ FUNCTION_DEFINITION_TO_CALL_MOCK(MOCK, FUNC, MOCK##_##FUNC, NUM_ARGS, CALL_TYPE) \
+ MOCK_FUNCTION_HOOK_DEFINITIONS(MOCK, FUNC)
+
+//////////////////////////////////////////////////////////////////////////////
+// The below macros are private and should not be used outside this file.
+
+#define MOCK_FUNCTION_HOOK_DECLARATIONS(FUNC) \
+ static subhook::Hook Hook##FUNC; \
+ struct MockContainer_##FUNC { \
+ MockContainer_##FUNC (); \
+ ~MockContainer_##FUNC (); \
+ }; \
+ MockContainer_##FUNC MockContainerInst_##FUNC;
+
+// This definition implements a constructor and destructor inside a nested
+// class to enable automatic installation of the hooks to the associated
+// MOCK_FUNC() when the mock object is instantiated in scope and automatic
+// removal when the instantiated mock object goes out of scope.
+#define MOCK_FUNCTION_HOOK_DEFINITIONS(MOCK, FUNC) \
+ subhook :: Hook MOCK :: Hook##FUNC; \
+ MOCK :: MockContainer_##FUNC :: MockContainer_##FUNC () { \
+ if (MOCK :: Instance == NULL) \
+ MOCK :: Hook##FUNC .Install( \
+ (FUNC##_ret_type *) ::FUNC, \
+ (FUNC##_ret_type *) MOCK##_##FUNC); \
+ } \
+ MOCK :: MockContainer_##FUNC :: ~MockContainer_##FUNC () { \
+ MOCK :: Hook##FUNC .Remove(); \
+ } \
+ static_assert( \
+ std::is_same<decltype(&::FUNC), decltype(&MOCK##_##FUNC)>::value, \
+ "Function signature from 'MOCK_FUNCTION_INTERNAL_DEFINITION' macro " \
+ "invocation for '" #FUNC "' does not match the function signature " \
+ "of '" #FUNC "' function it is mocking. Mismatch could be due to " \
+ "different return type, arguments, or calling convention. See " \
+ "associated 'MOCK_FUNCTION_INTERNAL_DECLARATION' macro invocation " \
+ "for more details.");
+
+#define MOCK_FUNCTION_TYPE_DEFINITIONS(RET_TYPE, FUNC, ARGS) \
+ using FUNC##_ret_type = RET_TYPE; \
+ using FUNC##_type = FUNC##_ret_type ARGS;
+
+// This function definition simply calls MOCK::Instance->FUNC() which is the
+// mocked counterpart of the original function. This allows using gmock with
+// C free functions (since by default gmock only works with object methods).
+#define FUNCTION_DEFINITION_TO_CALL_MOCK(MOCK, FUNC, FUNC_DEF_NAME, NUM_ARGS, CALL_TYPE) \
+ extern "C" { \
+ typename MOCK :: FUNC##_ret_type CALL_TYPE FUNC_DEF_NAME( \
+ GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, \
+ (MOCK :: FUNC##_type), \
+ NUM_ARGS)) \
+ { \
+ EXPECT_TRUE(MOCK :: Instance != NULL) \
+ << "Called '" #FUNC "' in '" #MOCK "' function mock object before " \
+ << "an instance of '" #MOCK "' was created in test '" \
+ << ::testing::UnitTest::GetInstance()->current_test_info()->name() \
+ << "'."; \
+ return MOCK :: Instance->FUNC( \
+ GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, \
+ (MOCK :: FUNC##_type), \
+ NUM_ARGS)); \
+ } \
+ }
+
+#define MOCK_STATIC_INSTANCE_DEFINITION(MOCK) MOCK * MOCK :: Instance = NULL;
+
+#define MOCK_INTERFACE_CONSTRUCTOR(MOCK) \
+ MOCK :: MOCK () { \
+ EXPECT_TRUE(MOCK :: Instance == NULL) \
+ << "Multiple instances of '" #MOCK "' function mock object were " \
+ << "created and only one instance is allowed in test '" \
+ << ::testing::UnitTest::GetInstance()->current_test_info()->name() \
+ << "'."; \
+ MOCK :: Instance = this; \
+ }
+
+#define MOCK_INTERFACE_DECONSTRUCTOR(MOCK) \
+ MOCK :: ~ MOCK () { \
+ MOCK :: Instance = NULL; \
+ }
+
+#endif // FUNCTION_MOCK_LIB_H_
diff --git a/UnitTestFrameworkPkg/Include/Library/GoogleTestLib.h b/UnitTestFrameworkPkg/Include/Library/GoogleTestLib.h
index ebec766d4cf7..c0a3d8e66011 100644
--- a/UnitTestFrameworkPkg/Include/Library/GoogleTestLib.h
+++ b/UnitTestFrameworkPkg/Include/Library/GoogleTestLib.h
@@ -10,5 +10,101 @@
#define GOOGLE_TEST_LIB_H_
#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <cstring>
+
+extern "C" {
+#include <Uefi.h>
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Below are the action extensions to GoogleTest and gmock for EDK2 types.
+// These actions are intended to be used in EXPECT_CALL (and related gmock
+// macros) to support assignments to output arguments in the expected call.
+//
+
+// Action to support pointer types to a buffer (such as UINT8* or VOID*)
+ACTION_TEMPLATE (
+ SetArgBuffer,
+ HAS_1_TEMPLATE_PARAMS (size_t, ArgNum),
+ AND_2_VALUE_PARAMS (Buffer, ByteSize)
+ ) {
+ auto ArgBuffer = std::get<ArgNum>(args);
+
+ std::memcpy (ArgBuffer, Buffer, ByteSize);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Below are the matcher extensions to GoogleTest and gmock for EDK2 types.
+// These matchers are intended to be used in EXPECT_CALL (and related gmock
+// macros) to support comparisons to input arguments in the expected call.
+//
+// Note that these matchers can also be used in the EXPECT_THAT or ASSERT_THAT
+// macros to compare whether two values are equal.
+//
+
+// Matcher to support pointer types to a buffer (such as UINT8* or VOID* or
+// any structure pointer)
+MATCHER_P2 (
+ BufferEq,
+ Buffer,
+ ByteSize,
+ std::string ("buffer data to ") + (negation ? "not " : "") + "be the same"
+ ) {
+ UINT8 *Actual = (UINT8 *)arg;
+ UINT8 *Expected = (UINT8 *)Buffer;
+
+ for (size_t i = 0; i < ByteSize; i++) {
+ if (Actual[i] != Expected[i]) {
+ *result_listener << "byte at offset " << i
+ << " does not match expected. [" << std::hex
+ << "Actual: 0x" << std::setw (2) << std::setfill ('0')
+ << (unsigned int)Actual[i] << ", "
+ << "Expected: 0x" << std::setw (2) << std::setfill ('0')
+ << (unsigned int)Expected[i] << "]";
+ return false;
+ }
+ }
+
+ *result_listener << "all bytes match";
+ return true;
+}
+
+// Matcher to support CHAR16* type
+MATCHER_P (
+ Char16StrEq,
+ String,
+ std::string ("strings to ") + (negation ? "not " : "") + "be the same"
+ ) {
+ CHAR16 *Actual = (CHAR16 *)arg;
+ CHAR16 *Expected = (CHAR16 *)String;
+
+ for (size_t i = 0; Actual[i] != 0; i++) {
+ if (Actual[i] != Expected[i]) {
+ *result_listener << "character at offset " << i
+ << " does not match expected. [" << std::hex
+ << "Actual: 0x" << std::setw (4) << std::setfill ('0')
+ << Actual[i];
+
+ if (std::isprint (Actual[i])) {
+ *result_listener << " ('" << (char)Actual[i] << "')";
+ }
+
+ *result_listener << ", Expected: 0x" << std::setw (4) << std::setfill ('0')
+ << Expected[i];
+
+ if (std::isprint (Expected[i])) {
+ *result_listener << " ('" << (char)Expected[i] << "')";
+ }
+
+ *result_listener << "]";
+
+ return false;
+ }
+ }
+
+ *result_listener << "strings match";
+ return true;
+}
#endif
diff --git a/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf b/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
index 052c7f557210..eeee6bc2b3f5 100644
--- a/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
+++ b/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
@@ -16,7 +16,7 @@ [Defines]
LIBRARY_CLASS = CmockaLib|HOST_APPLICATION
#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
diff --git a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c
new file mode 100644
index 000000000000..b7bb23f1868b
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c
@@ -0,0 +1,7 @@
+/** @file
+ Macro-only FunctionMockLib library instance with no services.
+
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
diff --git a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
new file mode 100644
index 000000000000..44c5946be533
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
@@ -0,0 +1,31 @@
+## @file
+# This module provides FunctionMockLib Library implementation.
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010018
+ BASE_NAME = FunctionMockLib
+ MODULE_UNI_FILE = FunctionMockLib.uni
+ FILE_GUID = DF1CAF2F-D584-4EC1-9ABF-07E8B10AD560
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 0.1
+ LIBRARY_CLASS = FunctionMockLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ FunctionMockLib.c
+
+[LibraryClasses]
+ GoogleTestLib
+ SubhookLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
diff --git a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni
new file mode 100644
index 000000000000..13e5308ce0e7
--- /dev/null
+++ b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni
@@ -0,0 +1,11 @@
+// /** @file
+// This module provides FunctionMockLib Library implementation.
+//
+// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "FunctionMockLib Library implementation"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides FunctionMockLib Library implementation."
diff --git a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
index 68db75d7023f..0104384953c3 100644
--- a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
+++ b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
@@ -7,30 +7,27 @@
##
[Defines]
- INF_VERSION = 0x00010005
+ INF_VERSION = 0x00010018
BASE_NAME = GoogleTestLib
MODULE_UNI_FILE = GoogleTestLib.uni
FILE_GUID = A90E4751-AD30-43CC-980B-01E356B49ADF
- MODULE_TYPE = BASE
+ MODULE_TYPE = HOST_APPLICATION
VERSION_STRING = 0.1
- LIBRARY_CLASS = GoogleTestLib|HOST_APPLICATION
+ LIBRARY_CLASS = GoogleTestLib
#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
googletest/googletest/src/gtest-all.cc
+ googletest/googlemock/src/gmock-all.cc
[Packages]
+ MdePkg/MdePkg.dec
UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
[BuildOptions]
- MSFT:*_*_*_CC_FLAGS == /c /EHsc /Zi
- MSFT:NOOPT_*_*_CC_FLAGS = /Od
-
- GCC:*_*_*_CC_FLAGS == -g -c
-
- GCC:NOOPT_*_*_CC_FLAGS = -O0
- GCC:*_*_IA32_CC_FLAGS = -m32
- GCC:*_*_X64_CC_FLAGS = -m64
+ MSFT:*_*_*_CC_FLAGS == /c /EHsc /Zi /Od
+ GCC:*_*_IA32_CC_FLAGS == -g -c -fshort-wchar -O0 -m32
+ GCC:*_*_X64_CC_FLAGS == -g -c -fshort-wchar -O0 -m64
diff --git a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni
index 14c862a23744..695588ce3f46 100644
--- a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni
+++ b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni
@@ -1,10 +1,7 @@
// /** @file
// This module provides GoogleTest Library implementation.
//
-// This module provides GoogleTest Library implementation.
-//
// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
-//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// **/
diff --git a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
index 722509c8f26f..dbb429faaeca 100644
--- a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
+++ b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc
@@ -32,8 +32,9 @@ [Components]
# Build HOST_APPLICATION Libraries
#
UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
+ UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
- UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
+ UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml
index d8f8e024c476..be839d1af0a7 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml
@@ -79,9 +79,14 @@
"AuditOnly": False, # Fails test but run in AuditOnly mode to collect log
"IgnoreFiles": [ # use gitignore syntax to ignore errors in matching files
"Library/CmockaLib/cmocka/**/*.*", # not going to spell check a submodule
- "Library/GoogleTestLib/googletest/**/*.*" # not going to spell check a submodule
+ "Library/GoogleTestLib/googletest/**/*.*", # not going to spell check a submodule
+ "Library/SubhookLib/subhook/**/*.*" # not going to spell check a submodule
],
"ExtendWords": [ # words to extend to the dictionary for this package
+ "Pointee",
+ "gmock",
+ "GMOCK",
+ "DSUBHOOK",
"testcase",
"testsuites",
"cmocka",
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
index 30b489915d4a..ef0a148d4876 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
@@ -26,6 +26,7 @@ [Includes.Common.Private]
PrivateInclude
Library/CmockaLib/cmocka/include/cmockery
Library/GoogleTestLib/googletest/googletest
+ Library/GoogleTestLib/googletest/googlemock
[LibraryClasses]
## @libraryclass Allows save and restore unit test internal state
@@ -36,6 +37,7 @@ [LibraryClasses]
#
GoogleTestLib|Include/Library/GoogleTestLib.h
SubhookLib|Include/Library/SubhookLib.h
+ FunctionMockLib|Include/Library/FunctionMockLib.h
[LibraryClasses.Common.Private]
## @libraryclass Provides a unit test result report
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index e77897bd326f..7866c36e6693 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -16,6 +16,7 @@ [LibraryClasses.common.HOST_APPLICATION]
CmockaLib|UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
GoogleTestLib|UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
SubhookLib|UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
+ FunctionMockLib|UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf
DebugLib|UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 04/12] UnitTestFrameworkPkg/ReadMe.md: Add gmock documentation
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (2 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 03/12] UnitTestFrameworkPkg: Add gmock support to GoogleTestLib Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 05/12] MdePkg: Add gmock examples Michael D Kinney
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel
Cc: Chris Johnson, Sean Brogan, Michael Kubacki, Michael Kubacki,
Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
UnitTestFrameworkPkg/ReadMe.md | 1013 ++++++++++++++++++++++++++++++--
1 file changed, 970 insertions(+), 43 deletions(-)
diff --git a/UnitTestFrameworkPkg/ReadMe.md b/UnitTestFrameworkPkg/ReadMe.md
index 3fa4e1910f71..7da6a320a7f1 100644
--- a/UnitTestFrameworkPkg/ReadMe.md
+++ b/UnitTestFrameworkPkg/ReadMe.md
@@ -20,12 +20,15 @@ that require mocked interfaces can use the mocking infrastructure provided by
### GoogleTest
The second unit test framework supported by the UnitTestFrameworkPkg is
-[GoogleTest](http://google.github.io/googletest/) that can be used to implement host-based unit tests.
-Use of GoogleTest for target-based unit tests of EDK II components is not supported. If a
-host-based unit test requires mocked interfaces, then the Framework with cmocka support should be
-used instead. Enabling support for mocked interfaces with GoogleTest is being actively investigated.
+[GoogleTest](http://google.github.io/googletest/) and can be used to implement host-based unit tests.
[GoogleTest on GitHub](https://github.com/google/googletest) is included in the UnitTestFrameworkPkg
-as a submodule.
+as a submodule. Use of GoogleTest for target-based unit tests of EDK II components is not supported.
+Host-based unit tests that require mocked interfaces can use the mocking infrastructure included with
+GoogleTest called [gMock](https://github.com/google/googletest/tree/main/googlemock). Note that the
+gMock framework does not directly support mocking of free (C style) functions, so the FunctionMockLib
+(containing a set of macros that wrap gMock's MOCK_METHOD macro) was created within the
+UnitTestFrameworkPkg to enable this support. The details and usage of these macros in the
+FunctionMockLib are described later.
GoogleTest requires less overhead to register test suites and test cases compared to the Framework.
There are also a number of tools that layer on top of GoogleTest that improve developer productivity.
@@ -33,13 +36,19 @@ One example is the VS Code extension
[C++ TestMate](https://marketplace.visualstudio.com/items?itemName=matepek.vscode-catch2-test-adapter)
that may be used to implement, run, and debug unit tests implemented using GoogleTest.
-If a component can be tested with host-based unit tests without support for mocked interfaces,
-then GoogleTest is recommended. The MdePkg contains a port of the BaseSafeIntLib unit tests in
-the GoogleTest style so the differences between GoogleTest and Framework unit tests can be reviewed.
-The paths to the BaseSafeIntLib unit tests are:
+If a component can be tested with host-based unit tests, then GoogleTest is recommended. The MdePkg
+contains a port of the BaseSafeIntLib unit tests in the GoogleTest style so the differences between
+GoogleTest and Framework unit tests can be reviewed. The paths to the BaseSafeIntLib unit tests are:
-* MdePkg\Test\UnitTest\Library\BaseSafeIntLib
-* MdePkg\Test\GoogleTest\Library\BaseSafeIntLib
+* `MdePkg/Test/UnitTest/Library/BaseSafeIntLib`
+* `MdePkg/Test/GoogleTest/Library/BaseSafeIntLib`
+
+Furthermore, the SecurityPkg contains unit tests for the SecureBootVariableLib using mocks in both
+the Framework/cmocka and GoogleTest/gMock style so the differences between cmocka and gMock can be
+reviewed. The paths to the SecureBootVariableLib unit tests are:
+
+* `SecurityPkg/Library/SecureBootVariableLib/UnitTest`
+* `SecurityPkg/Library/SecureBootVariableLib/GoogleTest`
## Framework and GoogleTest Feature Comparison
@@ -56,7 +65,7 @@ The paths to the BaseSafeIntLib unit tests are:
| Typed Tests | NO | YES |
| Type-Parameterized Tests | NO | YES |
| Timeout Support | NO | YES |
-| Mocking Support | Cmocka | NO |
+| Mocking Support | Cmocka | gMock |
| JUNIT XML Reports | YES | YES |
| Execute subset of tests | NO | YES |
| VS Code Extensions | NO | YES |
@@ -104,7 +113,7 @@ This section is built a lot like a "Getting Started". We'll go through some of t
when constructing a unit test and some of the decisions that are made by the test writer. We'll also describe
how to check for expected conditions in test cases and a bit of the logging characteristics.
-Most of these examples will refer to the SampleUnitTestUefiShell app found in this package.
+Most of these examples will refer to the `SampleUnitTestUefiShell` app found in this package.
### Framework Requirements - INF
@@ -113,7 +122,7 @@ header for the `UnitTestLib` is located in `MdePkg`, so you shouldn't need to de
packages. As long as your DSC file knows where to find the lib implementation that you want to use,
you should be good to go.
-See this example in 'SampleUnitTestUefiShell.inf'...
+See this example in `SampleUnitTestUefiShell.inf`...
```
[Packages]
@@ -127,7 +136,7 @@ See this example in 'SampleUnitTestUefiShell.inf'...
PrintLib
```
-Also, if you want you test to automatically be picked up by the Test Runner plugin, you will need
+Also, if you want your test to automatically be picked up by the Test Runner plugin, you will need
to make sure that the module `BASE_NAME` contains the word `Test`...
```
@@ -135,6 +144,43 @@ to make sure that the module `BASE_NAME` contains the word `Test`...
BASE_NAME = SampleUnitTestUefiShell
```
+### Framework Requirements - DSC
+
+In our DSC file, we'll need to bring in the INF file that was just created into the `[Components]`
+section so that the unit tests will be built.
+
+See this example in `UnitTestFrameworkPkg.dsc`...
+
+```
+[Components]
+ UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf
+```
+
+Also, based on the type of tests that are being created, the associated DSC include file from the
+UnitTestFrameworkPkg for Host or Target based tests should also be included at the top of the DSC
+file.
+
+```
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
+```
+
+Lastly, in the case that the test build has specific dependent libraries associated with it,
+they should be added in the \<LibraryClasses\> sub-section for the INF file in the
+`[Components]` section of the DSC file.
+
+See this example in `SecurityPkgHostTest.dsc`...
+
+```
+[Components]
+ SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf {
+ <LibraryClasses>
+ SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+ UefiRuntimeServicesTableLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+ PlatformPKProtectionLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
+ UefiLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
+ }
+```
+
### Framework Requirements - Code
Not to state the obvious, but let's make sure we have the following include before getting too far along...
@@ -143,7 +189,7 @@ Not to state the obvious, but let's make sure we have the following include befo
#include <Library/UnitTestLib.h>
```
-Now that we've got that squared away, let's look at our 'Main()'' routine (or DriverEntryPoint() or whatever).
+Now that we've got that squared away, let's look at our 'Main()' routine (or DriverEntryPoint() or whatever).
### Framework Configuration
@@ -157,7 +203,7 @@ The long name and version strings are just for user presentation and relatively
will be used to name any cache files and/or test results, so should be a name that makes sense in that context.
These strings are copied internally to the Framework, so using stack-allocated or literal strings is fine.
-In the 'SampleUnitTestUefiShell' app, the module name is used as the short name, so the initialization looks like this.
+In the `SampleUnitTestUefiShell` app, the module name is used as the short name, so the initialization looks like this.
```c
DEBUG(( DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION ));
@@ -184,7 +230,7 @@ called once at the start of the suite (before _any_ tests have run) and once at
tests have run), respectively. If either or both of these are unneeded, pass `NULL`. The function prototypes are
`UNIT_TEST_SUITE_SETUP` and `UNIT_TEST_SUITE_TEARDOWN`.
-Looking at 'SampleUnitTestUefiShell' app, you can see that the first test suite is created as below...
+Looking at `SampleUnitTestUefiShell` app, you can see that the first test suite is created as below...
```c
//
@@ -218,7 +264,7 @@ of the context pointer is to allow test case reuse with different input data. (A
around a system reboot, but that's beyond the scope of this guide.) The test case must know how to interpret the context
pointer, so it could be a simple value, or it could be a complex structure. If unneeded, pass `NULL`.
-In 'SampleUnitTestUefiShell' app, the first test case is added using the code below...
+In `SampleUnitTestUefiShell` app, the first test case is added using the code below...
```c
AddTestCase( SimpleMathTests, "Adding 1 to 1 should produce 2", "Addition", OnePlusOneShouldEqualTwo, NULL, NULL, NULL );
@@ -282,6 +328,617 @@ leverage the `cmocka.h` interface and write tests with all the features of the C
Documentation for Cmocka can be found here:
https://api.cmocka.org/
+## GoogleTest Libraries
+
+### GoogleTestLib
+
+GoogleTestLib is the core library used for GoogleTest in EDK II. This library is mainly a wrapper
+around the GoogleTest and gMock header and source files. So all the standard
+[GoogleTest](http://google.github.io/googletest/) and
+[gMock](https://github.com/google/googletest/tree/main/googlemock) documentation for writing tests
+and using mocks applies.
+
+Additionally, to support the use of some primitive types that are not directly supported by
+GoogleTest and gMock (but are needed to allow gMock to be used in EDK II), some custom gMock
+actions and matchers were added to GoogleTestLib. These customizations are briefly described in
+the following tables.
+
+#### Custom Actions
+
+| Action Name | Similar gMock Generic Action | Usage |
+|:--- |:--- |:--- |
+| `SetArgBuffer()` | `SetArgPointee()` | Used to set a buffer output argument (such as UINT8*, VOID*, a structure pointer, etc.) with data in an expect call. Can be used in an `EXPECT_CALL()` |
+
+#### Custom Matchers
+
+| Matcher Name | Similar gMock Generic Matcher | Usage |
+|:--- |:--- |:--- |
+| `BufferEq()` | `Pointee(Eq())` | Used to compare two buffer pointer types (such as UINT8*, VOID*, a structure pointer, etc.). Can be used in an `EXPECT_CALL()`, `EXPECT_THAT()`, or anywhere else a matcher to compare two buffers is needed. |
+| `Char16StrEq()` | `Pointee(Eq())` | Used to compare two CHAR16* strings. Can be used in an `EXPECT_CALL()`, `EXPECT_THAT()`, or anywhere else a matcher to compare two CHAR16* strings is needed. |
+
+### FunctionMockLib
+
+FunctionMockLib is the library that allows gMock to be used with free (C style) functions. This
+library contains a set of macros that wrap gMock's MOCK_METHOD macro to enable the standard gMock
+capabilities to be used with free functions. The details of how this is implemented is outside the
+scope of this document, but a brief description of each of the public macros in FunctionMockLib is
+described below. A full example of how to use these macros to create a mock is described in a
+later section.
+
+In total there are six public macros in FunctionMockLib. Four of the macros are related to creating
+the mock functions, and the other two macros are related to creating an interface that is necessary
+to contain the mock functions and connect them into the gMock framework.
+
+The macros used to create the interface are...
+1. `MOCK_INTERFACE_DECLARATION(MOCK)`
+2. `MOCK_INTERFACE_DEFINITION(MOCK)`
+
+These macros both take one argument which is the name of the interface for the mock. The
+`MOCK_INTERFACE_DECLARATION` macro is used to declare the interface in the `.h` file and the
+`MOCK_INTERFACE_DEFINITION` macro is used to define the interface in the `.cpp` file. For
+example, to create a mock for the `UefiLib`, a `MockUefiLib.h` file would be created and the
+below code would be added to it.
+
+```cpp
+struct MockUefiLib {
+ MOCK_INTERFACE_DECLARATION(MockUefiLib);
+};
+```
+
+Additionally, the below code would be written into a `MockUefiLib.cpp` file.
+
+```cpp
+MOCK_INTERFACE_DEFINITION(MockUefiLib);
+```
+
+The macros used to create the mock functions are...
+1. `MOCK_FUNCTION_DECLARATION(RET_TYPE, FUNC, ARGS)`
+2. `MOCK_FUNCTION_DEFINITION(MOCK, FUNC, NUM_ARGS, CALL_TYPE)`
+3. `MOCK_FUNCTION_INTERNAL_DECLARATION(RET_TYPE, FUNC, ARGS)`
+4. `MOCK_FUNCTION_INTERNAL_DEFINITION(MOCK, FUNC, NUM_ARGS, CALL_TYPE)`
+
+You will notice that there are two sets of macros: one to mock external functions and
+another to mock internal functions. Each set of macros has the exact same arguments, but
+they are used for slightly different use cases. The details of these different use cases
+is described in detail in a later section. For now, we will focus on the usage of the macro
+arguments since that is common between them.
+
+The `MOCK_FUNCTION_DECLARATION` macro is used to declare the mock function in the `.h` file,
+and it takes three arguments: return type, function name, and argument list. The
+`MOCK_FUNCTION_DEFINITION` macro is used to define the mock function in the `.cpp` file,
+and it takes four arguments: name of the interface for the mock, function name, number of
+arguments the function takes, and calling convention type of the function. For example, to
+continue with the `UefiLib` mock example above, the `GetVariable2` and `GetEfiGlobalVariable2`
+functions are declared in `UefiLib.h` as shown below.
+
+```cpp
+EFI_STATUS
+EFIAPI
+GetVariable2 (
+ IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+GetEfiGlobalVariable2 (
+ IN CONST CHAR16 *Name,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL
+ );
+```
+
+To declare mocks for these functions within the previously created `MockUefiLib` interface,
+the below code would be added to the `MockUefiLib.h` file. Note that the previously added
+interface declaration is also included in the code below for context.
+
+```cpp
+struct MockUefiLib {
+ MOCK_INTERFACE_DECLARATION (MockUefiLib);
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ GetVariable2,
+ (IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL)
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ GetEfiGlobalVariable2,
+ (IN CONST CHAR16 *Name,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL)
+ );
+};
+```
+
+Additionally, the below code would be added into the `MockUefiLib.cpp` file to provide
+the definitions for these mock functions. Again, the previously added interface
+definition is also included in the code below for context.
+
+```cpp
+MOCK_INTERFACE_DEFINITION(MockUefiLib);
+
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, EFIAPI);
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetEfiGlobalVariable2, 3, EFIAPI);
+```
+
+That concludes the basic overview on how to use the macros, but a more detailed
+description on how to name the mocks, where to put the files, how to build the
+mocks, and how to use the mocks is described in detail later.
+
+### SubhookLib
+
+SubhookLib is the library used by FunctionMockLib to implement the macros to
+mock internal functions: `MOCK_FUNCTION_INTERNAL_DECLARATION` and
+`MOCK_FUNCTION_INTERNAL_DEFINITION`. These macros require the additional
+functionality provided by SubhookLib because they create mock functions
+for functions that are already defined and compiled within the module being
+tested. More detail on this is provided in a later section, but for now it is
+sufficient to know that the SubhookLib allows a second definition of the
+function to be compiled into the test application and then hooked to during a
+test.
+
+This library is mainly a wrapper around the
+[subhook](https://github.com/Zeex/subhook) header and source files. It is
+important to note that the use of the mock function macros and the creation
+of mock functions requires no knowledge about the SubhookLib. The SubhookLib
+library is entirely hidden and encapsulated within FunctionMockLib, and it
+is only mentioned here to provide a complete explanation on all the libraries
+used in the implementation.
+
+## FunctionMockLib Mocks
+
+This section describes the details on how to use the mock function macros in
+FunctionMockLib to create mock functions, name them, organize their files,
+and build them so that they can be used within GoogleTest tests. The usage
+of the mock functions is detailed in a later section while this section
+simply details how to create them, build them, and where to put them.
+
+### FunctionMockLib Mocks - External vs. Internal
+
+The first question to ask when creating a mock function is if the function being
+mocked is external or internal to the module being tested. This is very important
+because the macros in FunctionMockLib used to create the mock function are named
+differently for these two use cases. Fortunately, the arguments to these macros
+and the usage of the mock functions within the tests are exactly the same.
+However, because of the different underlying implementations, two different sets
+of macros are used.
+
+A more detailed description of when to use the external vs. internal mock function
+macros is in the following sections, but the quick summary is as follows.
+
+* External mock function macros are used to mock functions that are outside the
+module being tested and use link-time replacement.
+* Internal mock function macros are used to mock functions that are inside the
+module being tested and use run-time replacement.
+
+The below table shows which macros to use in these two use cases. However, note that
+for the creation of the interface, the same macros are used in both cases.
+
+| Mock Function Use Case | Mock Interface Macros | Mock Function Macros |
+|:--- |:--- |:--- |
+| External mock functions | `MOCK_INTERFACE_DECLARATION`</br>`MOCK_INTERFACE_DEFINITION` | `MOCK_FUNCTION_DECLARATION`</br>`MOCK_FUNCTION_DEFINITION` |
+| Internal mock functions | `MOCK_INTERFACE_DECLARATION`</br>`MOCK_INTERFACE_DEFINITION` | `MOCK_FUNCTION_INTERNAL_DECLARATION`</br>`MOCK_FUNCTION_INTERNAL_DEFINITION` |
+
+#### FunctionMockLib Mocks - External mock function
+
+The external mock function macros are used to create mock function definitions
+for a library, global service, or protocol that is defined outside of the module
+being tested. These mock function definitions are linked into the test application
+instead of linking in the design function definitions. In other words, the
+external mock function macros use link-time replacement of the design functions.
+
+The `.h/.cpp` files for these mock functions are created within the package
+directory where the library, global table, or protocol that is being mocked is
+declared. These files are compiled into their own separate library (using
+an INF file) that can be shared and linked into many test applications, but more
+on that later.
+
+#### FunctionMockLib Mocks - Internal mock function
+
+The internal mock function macros are used to create mock function definitions
+for functions that are defined within the module being tested. These mock
+function definitions are compiled into the test application along with the design
+function definitions. This is possible because the mock functions are given a
+slightly different name during compilation. Then during test execution, the
+design function is hooked and replaced with the mock function. In other words,
+the internal mock function macros use run-time replacement of the design
+functions.
+
+The `.h/.cpp` files for these mock functions are created within the GoogleTest
+directory containing the specific tests that are using them. These files are
+compiled directly in the GoogleTest INF file that builds the test application,
+and they are not shared outside of that GoogleTest directory, but more on that
+later.
+
+### FunctionMockLib Mocks - Declaration
+
+The declaration of mock functions using the FunctionMockLib macros are done
+in header files. The name of the header file is determined by the interface
+(such as a library or a protocol) that is being created for the mock functions.
+The rules for naming the file are shown in the table below.
+
+| Interface Type | Header File Name |
+| :--- | :--- |
+| Library | Mock\<LibraryName\>Lib.h |
+| Global Table (e.g. gRT, gBS, etc.) | Mock\<GlobalTableLibraryName\>Lib.h |
+| Protocol | Mock\<ProtocolName\>Protocol.h |
+
+The below table shows examples for file names with each of the above cases.
+
+| Interface Type | Interface Name | Header File Name |
+| :--- | :--- | :--- |
+| Library | UefiLib | MockUefiLib.h |
+| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MockUefiRuntimeServicesTableLib.h |
+| Protocol | EFI_USB_IO_PROTOCOL | MockEfiUsbIoProtocol.h |
+
+Once the header file name is known, the file needs to be created in the proper
+location. For internal mock functions, the location is simply the same
+GoogleTest directory that contains the INF file that builds the test application.
+For external mock functions, the location is within the `Test` directory under the
+package where the library, global table, or protocol that is being mocked is
+declared. The exact location depends on the interface type and is shown in the
+below table.
+
+| Interface Type | Header File Location |
+| :--- | :--- |
+| Library | \<PackageName\>/Test/Mock/Include/GoogleTest/Library |
+| Global Table (e.g. gRT, gBS, etc.) | \<PackageName\>/Test/Mock/Include/GoogleTest/Library |
+| Protocol | \<PackageName\>/Test/Mock/Include/GoogleTest/Protocol |
+
+The below table shows examples for file locations with each of the above cases.
+
+| Interface Type | Interface Name | Header File Location |
+| :--- | :--- | :--- |
+| Library | UefiLib | MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiLib.h |
+| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h |
+| Protocol | EFI_USB_IO_PROTOCOL | MdePkg/Test/Mock/Include/GoogleTest/Protocol/MockEfiUsbIoProtocol.h |
+
+Now that the file location is known, the contents can be added to it. After the
+standard `#ifndef` for a header file is added at the top of the file, the
+`GoogleTestLib.h` and `FunctionMockLib.h` files are always added. Following these
+includes other EDK II related include files are added and must be wrapped in
+`extern "C" {}` because they are C include files. Failure to do this will cause
+link errors to occur. Note that a `#include` of the interface being mocked must
+also be added. This causes the declarations of the functions being mocked to be
+included in the compilation and allows the compilation to verify that the function
+signatures of the mock and design functions are identical.
+
+After all the needed includes have been added in the file , a `struct` is declared
+using the same name as the header file (which was determined using the rules
+above). Within this structure declaration a `MOCK_INTERFACE_DECLARATION` is
+added along with a `MOCK_FUNCTION_DECLARATION` (or a
+`MOCK_FUNCTION_INTERNAL_DECLARATION` if this interface is for internal mock
+functions) for each function in the interface. To build on the examples above,
+the complete `MockUefiLib.h` file would be as shown below. Note that for brevity
+only the `GetVariable2` and `GetEfiGlobalVariable2` declarations are included in
+the example.
+
+```cpp
+#ifndef MOCK_UEFI_LIB_H_
+#define MOCK_UEFI_LIB_H_
+
+#include <Library/GoogleTestLib.h>
+#include <Library/FunctionMockLib.h>
+extern "C" {
+ #include <Uefi.h>
+ #include <Library/UefiLib.h>
+}
+
+struct MockUefiLib {
+ MOCK_INTERFACE_DECLARATION (MockUefiLib);
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ GetVariable2,
+ (IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL)
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ GetEfiGlobalVariable2,
+ (IN CONST CHAR16 *Name,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL)
+ );
+};
+
+#endif
+```
+
+In the case of libraries, the function names in the mock declarations
+align exactly with the function names in the design. However, in the
+case of global tables and protocols, to eliminate possible function
+name collisions, the names are adjusted slightly in the mock
+declarations as shown in the below table.
+
+| Mock Function Use Case | Design Function Name | Mock Function Name |
+| :--- | :--- | :--- |
+| Library | GetVariable2 | GetVariable2 |
+| Global Table (e.g. gRT, gBS, etc.) | gRT->GetVariable | gRT_GetVariable |
+| Protocol | UsbIoProtocol->UsbPortReset | UsbIoProtocol_UsbPortReset |
+
+Lastly, when creating mock functions, there are two limitations to be
+aware of in gMock that extend into FunctionMockLib.
+
+1. gMock does not support mocking functions that have more than 15 arguments.
+2. gMock does not support mocking variadic functions.
+
+With those limitations in mind, that completes the mock function
+declarations, and now the mock function definitions for those declarations
+can be created.
+
+### FunctionMockLib Mocks - Definition
+
+The definition of mock functions using the FunctionMockLib macros are done
+in source files. The name of the source file is determined by the interface
+(such as a library or a protocol) that is being created for the mock functions.
+The rules for naming the file align with the naming of the file for declarations
+and are shown in the table below.
+
+| Interface Type | Source File Name |
+| :--- | :--- |
+| Library | Mock\<LibraryName\>Lib.cpp |
+| Global Table (e.g. gRT, gBS, etc.) | Mock\<GlobalTableLibraryName\>Lib.cpp |
+| Protocol | Mock\<ProtocolName\>Protocol.cpp |
+
+The below table shows examples for file names with each of the above cases.
+
+| Interface Type | Interface Name | Source File Name |
+| :--- | :--- | :--- |
+| Library | UefiLib | MockUefiLib.cpp |
+| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MockUefiRuntimeServicesTableLib.cpp |
+| Protocol | EFI_USB_IO_PROTOCOL | MockEfiUsbIoProtocol.cpp |
+
+Once the source file name is known, the file needs to be created in the proper
+location. The location of the source file is aligned with the location for the
+header file. For internal mock functions, the location is simply the same
+GoogleTest directory that contains the INF file that builds the test application.
+For external mock functions, the location is within the `Test` directory under the
+package where the library, global table, or protocol that is being mocked is
+declared. The exact location depends on the interface type and is shown in the
+below table.
+
+| Interface Type | Source File Location |
+| :--- | :--- |
+| Library | \<PackageName\>/Test/Mock/Library/GoogleTest/Mock\<LibraryName\>Lib |
+| Global Table (e.g. gRT, gBS, etc.) | \<PackageName\>/Test/Mock/Library/GoogleTest/Mock\<GlobalTableLibraryName\>Lib |
+| Protocol | \<PackageName\>/Test/Mock/Library/GoogleTest/Mock\<ProtocolName\>Protocol |
+
+The below table shows examples for file locations with each of the above cases.
+
+| Interface Type | Interface Name | Source File Location |
+| :--- | :--- | :--- |
+| Library | UefiLib | MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.cpp |
+| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp |
+| Protocol | EFI_USB_IO_PROTOCOL | MdePkg/Test/Mock/Library/GoogleTest/MockEfiUsbIoProtocol/MockEfiUsbIoProtocol.cpp |
+
+Now that the file location is known, the contents can be added to it. At the top
+of the file, the header file containing the mock function declarations is always
+added. After this `#include`, the interface definition is created using
+`MOCK_INTERFACE_DEFINITION` with the interface name that was used in the mock
+function declaration header file. A `MOCK_FUNCTION_DEFINITION` is then added (or
+a `MOCK_FUNCTION_INTERNAL_DEFINITION` if this interface is for internal mock
+functions) for each function that was declared in the interface. To build on the
+prior declaration examples, the complete `MockUefiLib.cpp` file would be as shown
+below. Note that for brevity only the `GetVariable2` and `GetEfiGlobalVariable2`
+definitions are included in the example.
+
+```cpp
+#include <GoogleTest/Library/MockUefiLib.h>
+
+MOCK_INTERFACE_DEFINITION(MockUefiLib);
+
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, EFIAPI);
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetEfiGlobalVariable2, 3, EFIAPI);
+```
+
+When creating the defintions, there are a few things to keep in mind.
+
+First, when using `MOCK_FUNCTION_DEFINITION`, some functions being mocked do
+not specify a calling convention. In this case, it is fine to leave the last
+argument of `MOCK_FUNCTION_DEFINITION` empty. For example, if `GetVariable2`
+did not specify the `EFIAPI` calling convention in its declaration, then the
+below code would be used for the mock function definition.
+
+```cpp
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, );
+```
+
+Second, the function name used in `MOCK_FUNCTION_DEFINITION` must align with
+the function name used in the associated `MOCK_FUNCTION_DECLARATION` in the
+header file.
+
+Last, if the interface is mocking a global table or protocol, then the structure
+of function pointers for that interface must also be defined within the source
+file as a `static` structure with the mock function definitions being assigned
+to the associated entries in the structure. The address of this `static`
+structure is then assigned to the global table or protocol pointer. Note that
+this pointer must be wrapped in `extern "C" {}` because it needs C style
+linkage. Failure to do this will cause link errors to occur. For example, when
+creating the definition of the mock for the global runtime services table, the
+complete `MockUefiRuntimeServicesTableLib.cpp` file would be as shown below.
+Note that for brevity only the `GetVariable` and `SetVariable` definitions are
+included in the example.
+
+```cpp
+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
+
+MOCK_INTERFACE_DEFINITION(MockUefiRuntimeServicesTableLib);
+
+MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_GetVariable, 5, EFIAPI);
+MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_SetVariable, 5, EFIAPI);
+
+static EFI_RUNTIME_SERVICES localRt = {
+ {0}, // EFI_TABLE_HEADER
+
+ NULL, // EFI_GET_TIME
+ NULL, // EFI_SET_TIME
+ NULL, // EFI_GET_WAKEUP_TIME
+ NULL, // EFI_SET_WAKEUP_TIME
+
+ NULL, // EFI_SET_VIRTUAL_ADDRESS_MAP
+ NULL, // EFI_CONVERT_POINTER
+
+ gRT_GetVariable, // EFI_GET_VARIABLE
+ NULL, // EFI_GET_NEXT_VARIABLE_NAME
+ gRT_SetVariable, // EFI_SET_VARIABLE
+
+ NULL, // EFI_GET_NEXT_HIGH_MONO_COUNT
+ NULL, // EFI_RESET_SYSTEM
+
+ NULL, // EFI_UPDATE_CAPSULE
+ NULL, // EFI_QUERY_CAPSULE_CAPABILITIES
+
+ NULL, // EFI_QUERY_VARIABLE_INFO
+};
+
+extern "C" {
+ EFI_RUNTIME_SERVICES* gRT = &localRt;
+}
+```
+
+That completes the mock function definitions. So now these mock function
+definitions can be compiled.
+
+### FunctionMockLib Mocks - Build
+
+The building of mock functions using FunctionMockLib is done slightly
+differently for external and internal function mocks. External mock
+functions are built using their own separate INF file and internal mock
+functions are built as source files directly referenced in the GoogleTest
+INF file that builds the test application.
+
+#### FunctionMockLib Mocks - Build External Mock Functions
+
+The building of external mock functions is done using their own separate INF
+file which is placed in the same location as the associated source file
+containing the mock function definitions. The name of the INF file is exactly
+the same as the mock function definitions file, but uses the `.inf` extension
+rather than `.cpp`.
+
+Within the `.inf` file the `BASE_NAME` should be set to the same name as the
+file (minus the extension), the `MODULE_TYPE` should be set to
+`HOST_APPLICATION`, and the `LIBRARY_CLASS` should be the same as the
+`BASE_NAME` but without the `Mock` prefix.
+
+The `[Sources]` section will contain the single mock function definition
+source file, the `[Packages]` section will contain all the necessary DEC
+files to compile the mock functions (which at a minimum will include the
+`UnitTestFrameworkPkg.dec` file), the `[LibraryClasses]` section will contain
+the `GoogleTestLib`, and the `[BuildOptions]` will need to append the `/EHsc`
+compilation flag to all MSFT builds to enable proper use of the C++ exception
+handler. Below is the complete `MockUefiLib.inf` as an example.
+
+```
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MockUefiLib
+ FILE_GUID = 47211F7A-6D90-4DFB-BDF9-610B69197C2E
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MockUefiLib.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /EHsc
+```
+
+To ensure that this specific set of mock functions are always buildable even
+if no test uses it yet, this created INF file needs to be added into the
+`[Components]` section of the associated `Test` DSC file for the package in
+which this INF file resides. For example, the above `MockUefiLib.inf` would
+need to be added to the `MdePkg/Test/MdePkgHostTest.dsc` file as shown below.
+
+```
+[Components]
+ MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
+```
+
+This created INF file will also be referenced within the necessary `Test` DSC
+files in order to include the mock function definitions in the test
+applications which use this set of mock functions, but more on that later.
+
+One small additional requirement is that if this INF file is added into a
+package that does not yet have any other external mock functions in it, then
+that package's DEC file will need to have the mock include directory (more
+specifically the `Test/Mock/Include` directory) added to its `[Includes]`
+section so that test files who want to use the mock functions will be able to
+locate the mock function header file. For example, if `MockUefiLib.inf` were
+the first mock added to the `MdePkg`, then the below snippet would need to be
+added to the `MdePkg.dec` file.
+
+```
+[Includes]
+ Test/Mock/Include
+```
+
+#### FunctionMockLib Mocks - Build Internal Mock Functions
+
+The building of internal mock functions is done using the GoogleTest INF file
+that already needs to exist to build the test application. This is easy to
+manage since the source and header files for the internal mock functions are
+also located in the same GoogleTest directory as the GoogleTest INF file that
+will reference them.
+
+The only additions that are required to the GoogleTest INF file are that the
+mock function definitions file be added to the `[Sources]` section, the
+`UnitTestFrameworkPkg.dec` file be added to the `[Packages]` section, and the
+`GoogleTestLib` and `SubhookLib` be added to the `[LibraryClasses]` section.
+Below is a minimal contrived example for a `MyModuleGoogleTest.inf` that uses a
+`MockMyModuleInternalFunctions.cpp` source file for its internal mock functions.
+
+```
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = MyModuleGoogleTest
+ FILE_GUID = 814B09B9-2D51-4786-8A77-2E10CD1C55F3
+ VERSION_STRING = 1.0
+ MODULE_TYPE = HOST_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MyModuleGoogleTest.cpp
+ MockMyModuleInternalFunctions.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+ SubhookLib
+```
+
## GoogleTest Samples
There is a sample unit test provided as both an example of how to write a unit test and leverage
@@ -291,22 +948,31 @@ directory.
The sample is provided for the HOST_APPLICATION build type, which can be run on a host system without
needing a target.
+There is also a sample unit test provided as both an example of how to write a unit test with
+mock functions and leverage some of the gMock features. This sample can be found in the
+`SecurityPkg/Library/SecureBootVariableLib/GoogleTest` directory.
+
+It too is provided for the HOST_APPLICATION build type, which can be run on a host system without
+needing a target.
+
## GoogleTest Usage
This section is built a lot like a "Getting Started". We'll go through some of the components that are needed
when constructing a unit test and some of the decisions that are made by the test writer. We'll also describe
how to check for expected conditions in test cases and a bit of the logging characteristics.
-Most of these examples will refer to the SampleGoogleTestHost app found in this package.
+Most of these examples will refer to the `SampleGoogleTestHost` app found in this package, but
+the examples related to mock functions will refer to the `SecureBootVariableLibGoogleTest` app
+found in the `SecurityPkg`.
### GoogleTest Requirements - INF
-In our INF file, we'll need to bring in the `GoogleTest` library. Conveniently, the interface
-header for the `GoogleTest` is in `UnitTestFrameworkPkg`, so you shouldn't need to depend on any other
+In our INF file, we'll need to bring in the `GoogleTestLib` library. Conveniently, the interface
+header for the `GoogleTestLib` is in `UnitTestFrameworkPkg`, so you shouldn't need to depend on any other
packages. As long as your DSC file knows where to find the lib implementation that you want to use,
you should be good to go.
-See this example in 'SampleGoogleTestHost.inf'...
+See this example in `SampleGoogleTestHost.inf`...
```
[Packages]
@@ -319,7 +985,7 @@ See this example in 'SampleGoogleTestHost.inf'...
DebugLib
```
-Also, if you want you test to automatically be picked up by the Test Runner plugin, you will need
+Also, if you want your test to automatically be picked up by the Test Runner plugin, you will need
to make sure that the module `BASE_NAME` contains the word `Test`...
```
@@ -327,12 +993,54 @@ to make sure that the module `BASE_NAME` contains the word `Test`...
BASE_NAME = SampleGoogleTestHost
```
+### GoogleTest Requirements - DSC
+
+In our DSC file, we'll need to bring in the INF file that was just created into the `[Components]`
+section so that the unit tests will be built.
+
+See this example in `UnitTestFrameworkPkgHostTest.dsc`...
+
+```
+[Components]
+ UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTest/SampleGoogleTestHost.inf
+```
+
+Also, based on the type of tests that are being created, the associated DSC include file from the
+UnitTestFrameworkPkg for Host or Target based tests should also be included at the top of the DSC
+file.
+
+```
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+```
+
+Lastly, in the case that the test build has specific dependent libraries associated with it,
+they should be added in the \<LibraryClasses\> sub-section for the INF file in the
+`[Components]` section of the DSC file. Note that it is within this sub-section where you can
+control whether the design or mock version of a component is linked into the test exectuable.
+
+See this example in `SecurityPkgHostTest.dsc` where the `SecureBootVariableLib` design is
+being tested using mock versions of `UefiRuntimeServicesTableLib`, `PlatformPKProtectionLib`,
+and `UefiLib`...
+
+```
+[Components]
+ SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf {
+ <LibraryClasses>
+ SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
+ PlatformPKProtectionLib|SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
+ UefiLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
+ }
+```
+
### GoogleTest Requirements - Code
-Not to state the obvious, but let's make sure we have the following include before getting too far along...
+GoogleTest applications are implemented in C++, so make sure that your test file has
+a `.cpp` extension. With that behind us, not to state the obvious, but let's make sure
+we have the following includes before getting too far along in the file...
-```
-#include <gtest/gtest.h>
+```cpp
+#include <Library/GoogleTestLib.h>
extern "C" {
#include <Uefi.h>
#include <Library/BaseLib.h>
@@ -340,33 +1048,75 @@ extern "C" {
}
```
-GoogleTest applications are implemented in C++. The first include brings in the
-GoogleTest definitions. Other EDK II related include files must be wrapped in
-`extern "C" {}` because they are C include files. Link failures will occur if
-this is not done.
+The first include brings in the GoogleTest definitions. Other EDK II related include
+files must be wrapped in `extern "C" {}` because they are C include files. Link
+failures will occur if this is not done.
-Now that we've got that squared away, let's look at our 'Main()'' routine (or DriverEntryPoint() or whatever).
+Also, when using GoogleTest it is helpful to add a `using` declaration for its
+`testing` namespace. This `using` statement greatly reduces the amount of code you
+need to write in the tests when referencing the utilities within the `testing`
+namespace. For example, instead of writing `::testing::Return` or `::testing::Test`,
+you can just write `Return` or `Test` respectively, and these types of references
+occur numerous times within the tests.
+
+Lastly, in the case that tests within a GoogleTest application require the usage of
+mock functions, it is also necessary to include the header files for those interfaces
+as well. As an example, the `SecureBootVariableLibGoogleTest` uses the mock versions
+of `UefiLib` and `UefiRuntimeServicesTableLib`. So its test file contains the below
+includes. Note that the `using` declaration mentioned above is also shown in the code
+below for completeness of the example.
+
+```cpp
+#include <Library/GoogleTestLib.h>
+#include <GoogleTest/Library/MockUefiLib.h>
+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
+
+extern "C" {
+ #include <Uefi.h>
+ ...
+}
+
+using namespace testing;
+```
+
+Now that we've got that squared away, let's look at our 'Main()' routine (or DriverEntryPoint() or whatever).
### GoogleTest Configuration
Unlike the Framework, GoogleTest does not require test suites or test cases to
be registered. Instead, the test cases declare the test suite name and test
case name as part of their implementation. The only requirement for GoogleTest
-is to have a `main()` function that initialize the GoogleTest infrastructure and
-call the service `RUN_ALL_TESTS()` to run all the unit tests.
+is to have a `main()` function that initializes the GoogleTest infrastructure
+and calls the service `RUN_ALL_TESTS()` to run all the unit tests.
-```c
+```cpp
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
```
+However, while GoogleTest does not require test suites or test cases to be
+registered, there is still one rule within EDK II that currently needs to be
+followed. This rule is that all tests for a given GoogleTest application must
+be contained within the same source file that contains the `main()` function
+shown above. These tests can be written directly in the file or a `#include`
+can be used to add them into the file indirectly.
+
+The reason for this is due to EDK II taking the host application INF file and
+first compiling all of its source files into a static library. This static
+library is then linked into the final host application. The problem with this
+method is that only the tests in the object file containing the `main()`
+function are linked into the final host application. This is because the other
+tests are contained in their own object files within the static library and
+they have no symbols in them that the final host application depends on, so
+those object files are not linked into the final host application.
+
### GoogleTest - A Simple Test Case
-We'll look at the below test case from 'SampleGoogleTestHost'...
+Below is a sample test case from `SampleGoogleTestHost`.
-```c
+```cpp
TEST(SimpleMathTests, OnePlusOneShouldEqualTwo) {
UINTN A;
UINTN B;
@@ -393,9 +1143,175 @@ detailed logs. When in doubt, there are always `ASSERT_TRUE` and `ASSERT_FALSE`.
test criterium will immediately return from the test case with a failed status and log an error string.
_Note_ that this early return can have implications for memory leakage.
-There is no return status from a GooglTest unit test. If no assertions are
+For most `ASSERT` macros in GoogleTest there is also an equivalent `EXPECT` macro. Both macro versions
+will ultimately cause the `TEST` to fail if the check fails. However, the difference between the two
+macro versions is that when the check fails, the `ASSERT` version immediately returns from the `TEST`
+while the `EXPECT` version continues running the `TEST`.
+
+There is no return status from a GooglTest unit test. If no assertions (or expectations) are
triggered then the unit test has a passing status.
+### GoogleTest - A gMock Test Case
+
+Below is a sample test case from `SecureBootVariableLibGoogleTest`. Although
+actually, the test case is not written exactly like this in the test file, but
+more on that in a bit.
+
+```cpp
+TEST(SetSecureBootModeTest, SetVarError) {
+ MockUefiRuntimeServicesTableLib RtServicesMock;
+ UINT8 SecureBootMode;
+ EFI_STATUS Status;
+
+ // Any random magic number can be used for these tests
+ SecureBootMode = 0xAB;
+
+ EXPECT_CALL(RtServicesMock, gRT_SetVariable)
+ .WillOnce(Return(EFI_INVALID_PARAMETER));
+
+ Status = SetSecureBootMode(SecureBootMode);
+ EXPECT_EQ(Status, EFI_INVALID_PARAMETER);
+}
+```
+
+Keep in mind that this test is written to verify that `SetSecureBootMode()` will
+return `EFI_INVALID_PARAMETER` when the call to `gRT->SetVariable()` within the
+implementation of `SetSecureBootMode()` returns `EFI_INVALID_PARAMETER`. With that
+in mind, let's discuss how a mock function is used to accomplish this in the test.
+
+In this test case, the `MockUefiRuntimeServicesTableLib` interface is instantiated as
+`RtServicesMock` which enables its associated mock functions. These interface
+instantiations that contain the mock functions are very important for mock function
+based unit tests because without these instantiations, the mock functions within that
+interface will not exist and can not be used.
+
+The next line of interest is the `EXPECT_CALL`, which is a standard part of the gMock
+framework. This macro is telling the test that a call is expected to occur to a
+specific function on a specific interface. The first argument is the name of the
+interface object that was instantiated in this test, and the second argument is the
+name of the mock function within that interface that is expected to be called. The
+`WillOnce(Return(EFI_INVALID_PARAMETER))` associated with this `EXPECT_CALL` states
+that the `gRT_SetVariable()` function (remember from earlier in this documentation
+that this refers to the `gRT->SetVariable()` function) will be called once during
+this test, and when it does get called, we want it to return `EFI_INVALID_PARAMETER`.
+
+Once this `EXPECT_CALL` has been setup, the call to `SetSecureBootMode()` occurs in
+the test, and its return value is saved in `Status` so that it can be tested. Based
+on the `EXPECT_CALL` that was setup earlier, when `SetSecureBootMode()` internally
+calls `gRT->SetVariable()`, it returns `EFI_INVALID_PARAMETER`. This value should
+then be returned by `SetSecureBootMode()`, and the
+`EXPECT_EQ(Status, EFI_INVALID_PARAMETER)` verifies this is the case.
+
+There is much more that can be done with `EXPECT_CALL` and mock functions, but we
+will leave those details to be explained in the gMock documentation.
+
+Now it was mentioned earlier that this test case is not written exactly like this
+in the test file, and the next section describes how this test is slightly
+refactored to reduce the total amount of code in the entire test suite.
+
+### GoogleTest - A gMock Test Case (refactored)
+
+The sample test case from `SecureBootVariableLibGoogleTest` in the prior section is
+actually written as shown below.
+
+```cpp
+class SetSecureBootModeTest : public Test {
+ protected:
+ MockUefiRuntimeServicesTableLib RtServicesMock;
+ UINT8 SecureBootMode;
+ EFI_STATUS Status;
+
+ void SetUp() override {
+ // Any random magic number can be used for these tests
+ SecureBootMode = 0xAB;
+ }
+};
+
+TEST_F(SetSecureBootModeTest, SetVarError) {
+ EXPECT_CALL(RtServicesMock, gRT_SetVariable)
+ .WillOnce(Return(EFI_INVALID_PARAMETER));
+
+ Status = SetSecureBootMode(SecureBootMode);
+ EXPECT_EQ(Status, EFI_INVALID_PARAMETER);
+}
+```
+
+This code may at first seem more complicated, but you will notice that the code
+with in it is still the same. There is still a `MockUefiRuntimeServicesTableLib`
+instantiation, there is still a `SecureBootMode` and `Status` variable defined,
+there is still an `EXPECT_CALL`, and etc. However, the benefit of constructing
+the test this way is that the new `TEST_F()` requires less code than the prior
+`TEST()`.
+
+This is made possible by the usage of what GoogleTest calls a _test fixture_.
+This concept of a test fixture allows multiple tests to use (or more specifically
+inherit from a base class) a common set of variables and initial conditions.
+Notice that using `TEST_F()` requires the first argument to be a name that aligns
+with a test fixture (in this case `SetSecureBootModeTest`), and the second
+argument is the name of the test (just like in the `TEST()` macro).
+
+All `TEST_F()` tests that use a specific test fixture can be thought of as having
+all of that test fixture's variables automatically defined in the test as well as
+having that text fixture's `SetUp()` function called before entering the test.
+
+This means that another `TEST_F()` can be written without needing to worry about
+defining a bunch of variables or instantiating a bunch of interfaces for mock
+functions. For example, the below test (also in `SecureBootVariableLibGoogleTest`)
+uses the same test fixture and makes use of its `RtServicesMock`, `Status`, and
+`SecureBootMode` variables.
+
+```cpp
+TEST_F(SetSecureBootModeTest, PropogateModeToSetVar) {
+ EXPECT_CALL(RtServicesMock,
+ gRT_SetVariable(
+ Char16StrEq(EFI_CUSTOM_MODE_NAME),
+ BufferEq(&gEfiCustomModeEnableGuid, sizeof(EFI_GUID)),
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(SecureBootMode),
+ BufferEq(&SecureBootMode, sizeof(SecureBootMode))))
+ .WillOnce(Return(EFI_SUCCESS));
+
+ Status = SetSecureBootMode(SecureBootMode);
+ EXPECT_EQ(Status, EFI_SUCCESS);
+}
+```
+
+The biggest benefit is that the `TEST_F()` code can now focus on what is being
+tested and not worry about any repetitive setup. There is more that can be done
+with test fixtures, but we will leave those details to be explained in the
+gMock documentation.
+
+Now, as for what is in the above test, it is slightly more complicated than the
+first test. So let's explain this added complexity and what it is actually
+testing. In this test, there is still an `EXPECT_CALL` for the
+`gRT_SetVariable()` function. However, in this test we are stating that we
+expect the input arguments passed to `gRT_SetVariable()` be specific values.
+The order they are provided in the `EXPECT_CALL` align with the order of the
+arguments in the `gRT_SetVariable()` function. In this case the order of the
+`gRT_SetVariable()` arguments is as shown below.
+
+```cpp
+IN CHAR16 *VariableName,
+IN EFI_GUID *VendorGuid,
+IN UINT32 Attributes,
+IN UINTN DataSize,
+IN VOID *Data
+```
+
+So in the `EXPECT_CALL` we are stating that the call to `gRT_SetVariable()`
+will be made with the below input argument values.
+
+1. `VariableName` is equal to the `EFI_CUSTOM_MODE_NAME` string
+2. `VendorGuid` is equal to the `gEfiCustomModeEnableGuid` GUID (which has a byte length of `sizeof(EFI_GUID)`)
+3. `Attributes` is equal to `EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS`
+4. `DataSize` is equal to `sizeof(SecureBootMode)`
+5. `Data` is equal to `SecureBootMode` (which has a byte length of `sizeof(SecureBootMode)`)
+
+If any one of these input arguments does not match in the actual call to
+`gRT_SetVariable()` in the design, then the test will fail. There is much more
+that can be done with `EXPECT_CALL` and mock functions, but again we will
+leave those details to be explained in the gMock documentation.
+
### GoogleTest - More Complex Cases
To write more advanced tests, take a look at the
@@ -587,7 +1503,7 @@ This mode is used by the test running plugin to aggregate the results for CI tes
Host based Unit Tests will automatically enable coverage data.
-For Windows, This is primarily leverage for pipeline builds, but this can be leveraged locally using the
+For Windows, this is primarily leveraged for pipeline builds, but this can be leveraged locally using the
OpenCppCoverage windows tool to parse coverage data to cobertura xml format.
- Windows Prerequisite
@@ -607,7 +1523,7 @@ OpenCppCoverage windows tool to parse coverage data to cobertura xml format.
```
-For Linux, This is primarily leveraged for pipeline builds, but this can be leveraged locally using the
+For Linux, this is primarily leveraged for pipeline builds, but this can be leveraged locally using the
lcov linux tool, and parsed using the lcov_cobertura python tool to parse it to cobertura xml format.
- Linux Prerequisite
@@ -654,8 +1570,8 @@ We will continue trying to make these as similar as possible.
Code/Test | Location
--------- | --------
-Host-Based Unit Tests for a Library/Protocol/PPI/GUID Interface | If what's being tested is an interface (e.g. a library with a public header file, like DebugLib), the test should be scoped to the parent package.<br/>Example: `MdePkg/Test/UnitTest/[Library/Protocol/Ppi/Guid]/`<br/><br/>A real-world example of this is the BaseSafeIntLib test in MdePkg.<br/>`MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost.inf`
-Host-Based Unit Tests for a Library/Driver (PEI/DXE/SMM) implementation | If what's being tested is a specific implementation (e.g. BaseDebugLibSerialPort for DebugLib), the test should be scoped to the implementation directory itself, in a UnitTest subdirectory.<br/><br/>Module Example: `MdeModulePkg/Universal/EsrtFmpDxe/UnitTest/`<br/>Library Example: `MdePkg/Library/BaseMemoryLib/UnitTest/`
+Host-Based Unit Tests for a Library/Protocol/PPI/GUID Interface | If what's being tested is an interface (e.g. a library with a public header file, like DebugLib) and the test is agnostic to a specific implementation, then the test should be scoped to the parent package.<br/>Example: `MdePkg/Test/UnitTest/[Library/Protocol/Ppi/Guid]/`<br/><br/>A real-world example of this is the BaseSafeIntLib test in MdePkg.<br/>`MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost.inf`
+Host-Based Unit Tests for a Library/Driver (PEI/DXE/SMM) implementation | If what's being tested is a specific implementation (e.g. BaseDebugLibSerialPort for DebugLib), then the test should be scoped to the implementation directory itself, in a UnitTest (or GoogleTest) subdirectory.<br/><br/>Module Example: `MdeModulePkg/Universal/EsrtFmpDxe/UnitTest/`<br/>Library Example: `MdePkg/Library/BaseMemoryLib/UnitTest/`<br/>Library Example (GoogleTest): `SecurityPkg/Library/SecureBootVariableLib/GoogleTest/`
Host-Based Tests for a Functionality or Feature | If you're writing a functional test that operates at the module level (i.e. if it's more than a single file or library), the test should be located in the package-level Tests directory under the HostFuncTest subdirectory.<br/>For example, if you were writing a test for the entire FMP Device Framework, you might put your test in:<br/>`FmpDevicePkg/Test/HostFuncTest/FmpDeviceFramework`<br/><br/>If the feature spans multiple packages, it's location should be determined by the package owners related to the feature.
Non-Host-Based (PEI/DXE/SMM/Shell) Tests for a Functionality or Feature | Similar to Host-Based, if the feature is in one package, should be located in the `*Pkg/Test/[Shell/Dxe/Smm/Pei]Test` directory.<br/><br/>If the feature spans multiple packages, it's location should be determined by the package owners related to the feature.<br/><br/>USAGE EXAMPLES<br/>PEI Example: MP_SERVICE_PPI. Or check MTRR configuration in a notification function.<br/> SMM Example: a test in a protocol callback function. (It is different with the solution that SmmAgent+ShellApp)<br/>DXE Example: a test in a UEFI event call back to check SPI/SMRAM status. <br/> Shell Example: the SMM handler audit test has a shell-based app that interacts with an SMM handler to get information. The SMM paging audit test gathers information about both DXE and SMM. And the SMM paging functional test actually forces errors into SMM via a DXE driver.
@@ -713,8 +1629,19 @@ Non-Host-Based (PEI/DXE/SMM/Shell) Tests for a Functionality or Feature | Simi
GeneralPurposeLibTest.c
GeneralPurposeLibHostUnitTest.inf
+ Mock/
+ Include/
+ GoogleTest/
+ Library/
+ MockGeneralPurposeLib.h
+
+ Library/
+ GoogleTest/
+ MockGeneralPurposeLib/
+ MockGeneralPurposeLib.cpp
+ MockGeneralPurposeLib.inf
+
<Package>Pkg.dsc # Standard Modules and any Target-Based Test Apps (including in Test/)
-
```
### Future Locations in Consideration
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 05/12] MdePkg: Add gmock examples
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (3 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 04/12] UnitTestFrameworkPkg/ReadMe.md: Add gmock documentation Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 06/12] MdeModulePkg/Library/UefiSortLib: Add GoogleTestLib example Michael D Kinney
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Chris Johnson, Liming Gao, Zhiguang Liu, Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Acked-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
MdePkg/MdePkg.dec | 1 +
MdePkg/Test/MdePkgHostTest.dsc | 2 +
.../Include/GoogleTest/Library/MockUefiLib.h | 39 +++++++++++++++++
.../Library/MockUefiRuntimeServicesTableLib.h | 42 +++++++++++++++++++
.../GoogleTest/MockUefiLib/MockUefiLib.cpp | 12 ++++++
.../GoogleTest/MockUefiLib/MockUefiLib.inf | 33 +++++++++++++++
.../MockUefiRuntimeServicesTableLib.cpp | 40 ++++++++++++++++++
.../MockUefiRuntimeServicesTableLib.inf | 33 +++++++++++++++
8 files changed, 202 insertions(+)
create mode 100644 MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiLib.h
create mode 100644 MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h
create mode 100644 MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.cpp
create mode 100644 MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
create mode 100644 MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp
create mode 100644 MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 5cf04bc0cb69..a46f28fff40a 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -27,6 +27,7 @@ [Defines]
[Includes]
Include
Test/UnitTest/Include
+ Test/Mock/Include
[Includes.IA32]
Include/Ia32
diff --git a/MdePkg/Test/MdePkgHostTest.dsc b/MdePkg/Test/MdePkgHostTest.dsc
index b8b186dd8b17..35e3ef6d9729 100644
--- a/MdePkg/Test/MdePkgHostTest.dsc
+++ b/MdePkg/Test/MdePkgHostTest.dsc
@@ -34,3 +34,5 @@ [Components]
# Build HOST_APPLICATION Libraries
#
MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
+ MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
+ MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiLib.h
new file mode 100644
index 000000000000..dec2c93e1b34
--- /dev/null
+++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiLib.h
@@ -0,0 +1,39 @@
+/** @file
+ Google Test mocks for UefiLib
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MOCK_UEFI_LIB_H_
+#define MOCK_UEFI_LIB_H_
+
+#include <Library/GoogleTestLib.h>
+#include <Library/FunctionMockLib.h>
+extern "C" {
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+}
+
+struct MockUefiLib {
+ MOCK_INTERFACE_DECLARATION (MockUefiLib);
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ GetVariable2,
+ (IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL)
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ GetEfiGlobalVariable2,
+ (IN CONST CHAR16 *Name,
+ OUT VOID **Value,
+ OUT UINTN *Size OPTIONAL)
+ );
+};
+
+#endif
diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h
new file mode 100644
index 000000000000..afdfc6b85597
--- /dev/null
+++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h
@@ -0,0 +1,42 @@
+/** @file
+ Google Test mocks for UefiRuntimeServicesTableLib
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MOCK_UEFI_RUNTIME_SERVICES_TABLE_LIB_H_
+#define MOCK_UEFI_RUNTIME_SERVICES_TABLE_LIB_H_
+
+#include <Library/GoogleTestLib.h>
+#include <Library/FunctionMockLib.h>
+extern "C" {
+#include <Uefi.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+}
+
+struct MockUefiRuntimeServicesTableLib {
+ MOCK_INTERFACE_DECLARATION (MockUefiRuntimeServicesTableLib);
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ gRT_GetVariable,
+ (IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data)
+ );
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ gRT_SetVariable,
+ (IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data)
+ );
+};
+
+#endif
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.cpp b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.cpp
new file mode 100644
index 000000000000..5339d040c999
--- /dev/null
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.cpp
@@ -0,0 +1,12 @@
+/** @file
+ Google Test mocks for UefiLib
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <GoogleTest/Library/MockUefiLib.h>
+
+MOCK_INTERFACE_DEFINITION(MockUefiLib);
+
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, EFIAPI);
+MOCK_FUNCTION_DEFINITION(MockUefiLib, GetEfiGlobalVariable2, 3, EFIAPI);
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
new file mode 100644
index 000000000000..1a7461e44449
--- /dev/null
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Google Test mocks for UefiLib
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MockUefiLib
+ FILE_GUID = 47211F7A-6D90-4DFB-BDF9-610B69197C2E
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MockUefiLib.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /EHsc
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp
new file mode 100644
index 000000000000..ecd1ba82366c
--- /dev/null
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp
@@ -0,0 +1,40 @@
+/** @file
+ Google Test mocks for UefiRuntimeServicesTableLib
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
+
+MOCK_INTERFACE_DEFINITION(MockUefiRuntimeServicesTableLib);
+
+MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_GetVariable, 5, EFIAPI);
+MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_SetVariable, 5, EFIAPI);
+
+static EFI_RUNTIME_SERVICES localRt = {
+ {0}, // EFI_TABLE_HEADER
+
+ NULL, // EFI_GET_TIME
+ NULL, // EFI_SET_TIME
+ NULL, // EFI_GET_WAKEUP_TIME
+ NULL, // EFI_SET_WAKEUP_TIME
+
+ NULL, // EFI_SET_VIRTUAL_ADDRESS_MAP
+ NULL, // EFI_CONVERT_POINTER
+
+ gRT_GetVariable, // EFI_GET_VARIABLE
+ NULL, // EFI_GET_NEXT_VARIABLE_NAME
+ gRT_SetVariable, // EFI_SET_VARIABLE
+
+ NULL, // EFI_GET_NEXT_HIGH_MONO_COUNT
+ NULL, // EFI_RESET_SYSTEM
+
+ NULL, // EFI_UPDATE_CAPSULE
+ NULL, // EFI_QUERY_CAPSULE_CAPABILITIES
+
+ NULL, // EFI_QUERY_VARIABLE_INFO
+};
+
+extern "C" {
+ EFI_RUNTIME_SERVICES* gRT = &localRt;
+}
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
new file mode 100644
index 000000000000..7ba74d93bfc2
--- /dev/null
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Google Test mocks for UefiRuntimeServicesTableLib
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MockUefiRuntimeServicesTableLib
+ FILE_GUID = 0A0E13C2-4176-4293-89C7-C2497AA31B92
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiRuntimeServicesTableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MockUefiRuntimeServicesTableLib.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /EHsc
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 06/12] MdeModulePkg/Library/UefiSortLib: Add GoogleTestLib example
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (4 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 05/12] MdePkg: Add gmock examples Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 07/12] SecurityPkg: Add gmock example Michael D Kinney
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Chris Johnson, Jian J Wang, Liming Gao, Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../MockUefiRuntimeServicesTableLib.inf | 4 +-
.../GoogleTest/UefiSortLibGoogleTest.cpp | 61 +++++++++++++++++++
.../GoogleTest/UefiSortLibGoogleTest.inf | 31 ++++++++++
MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 6 ++
4 files changed, 100 insertions(+), 2 deletions(-)
create mode 100644 MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.cpp
create mode 100644 MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.inf
diff --git a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
index e716b855a31a..15eb646d7c38 100644
--- a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+++ b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
@@ -10,9 +10,9 @@ [Defines]
INF_VERSION = 0x00010005
BASE_NAME = MockUefiRuntimeServicesTableLib
FILE_GUID = 4EA215EE-85C1-4A0A-847F-D2A8DE20805F
- MODULE_TYPE = UEFI_DRIVER
+ MODULE_TYPE = HOST_APPLICATION
VERSION_STRING = 1.0
- LIBRARY_CLASS = UefiRuntimeServicesTableLib|HOST_APPLICATION
+ LIBRARY_CLASS = UefiRuntimeServicesTableLib
#
# VALID_ARCHITECTURES = IA32 X64 EBC
diff --git a/MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.cpp b/MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.cpp
new file mode 100644
index 000000000000..23f6e9cc0611
--- /dev/null
+++ b/MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.cpp
@@ -0,0 +1,61 @@
+/** @file
+ Unit tests for the implementation of UefiSortLib.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/GoogleTestLib.h>
+
+extern "C" {
+ #include <Uefi.h>
+ #include <Library/SortLib.h>
+}
+
+using namespace testing;
+
+INTN
+EFIAPI
+CompareUint32 (
+ IN CONST VOID *Left,
+ IN CONST VOID *Right
+ )
+{
+ if (*(UINT32*)Right > *(UINT32*)Left) {
+ return 1;
+ } else if (*(UINT32*)Right < *(UINT32*)Left) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Test PerformQuickSort() API from UefiSortLib to verify a UINT32 array
+// with 9 elements in ascending order is sorted into descending order.
+TEST(PerformQuickSortTest, SortUint32AscendingArray_Size9) {
+ CONST UINT32 ArraySize = 9;
+ UINT32 BuffActual[ArraySize];
+ UINT32 BuffExpected[ArraySize];
+
+ for (UINT32 Index = 0; Index < ArraySize; Index++) {
+ BuffActual[Index] = Index + 1;
+ BuffExpected[Index] = ArraySize - Index;
+ }
+
+ PerformQuickSort (BuffActual, (UINTN)ArraySize, sizeof(UINT32), (SORT_COMPARE)CompareUint32);
+ EXPECT_THAT(BuffActual, ElementsAreArray(BuffExpected, ArraySize));
+}
+
+// Test StringCompare() API from UefiSortLib to verify the comparison
+// succeeds when the same buffer is compared with itself.
+TEST(StringCompareTest, CompareSameBuffer) {
+ INTN RetVal;
+ CONST CHAR16 *Buffer = (CHAR16*)L"abcdefg";
+
+ RetVal = StringCompare (&Buffer, &Buffer);
+ EXPECT_EQ(RetVal, 0);
+}
+
+int main(int argc, char* argv[]) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.inf b/MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.inf
new file mode 100644
index 000000000000..ac5ffb3bc29d
--- /dev/null
+++ b/MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.inf
@@ -0,0 +1,31 @@
+## @file
+# Unit test suite for the UefiSortLib using Google Test
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = UefiSortLibGoogleTest
+ FILE_GUID = 78FB0BEE-D0EA-4E1A-BD38-67458C8ECDEF
+ VERSION_STRING = 1.0
+ MODULE_TYPE = HOST_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ UefiSortLibGoogleTest.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+ UefiSortLib
diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
index c9ec835df65d..a2bbbe8adf44 100644
--- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
+++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
@@ -47,3 +47,9 @@ [Components]
UefiSortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
}
+
+ MdeModulePkg/Library/UefiSortLib/GoogleTest/UefiSortLibGoogleTest.inf {
+ <LibraryClasses>
+ UefiSortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ }
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 07/12] SecurityPkg: Add gmock example
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (5 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 06/12] MdeModulePkg/Library/UefiSortLib: Add GoogleTestLib example Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 08/12] SecurityPkg/Library/SecureBootVariableLib: Fix VS20xx 4122 errors Michael D Kinney
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Chris Johnson, Jiewen Yao, Jian J Wang, Oliver Smith-Denny
From: Chris Johnson <chris.n.johnson@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4389
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Chris Johnson <chris.n.johnson@intel.com>
Acked-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
.../SecureBootVariableLibGoogleTest.cpp | 174 ++++++++++++++++++
.../SecureBootVariableLibGoogleTest.inf | 32 ++++
.../UnitTest/MockPlatformPKProtectionLib.inf | 4 +-
.../UnitTest/MockUefiLib.inf | 4 +-
.../MockUefiRuntimeServicesTableLib.inf | 4 +-
.../UnitTest/SecureBootVariableLibUnitTest.c | 2 +-
SecurityPkg/SecurityPkg.dec | 1 +
.../Library/MockPlatformPKProtectionLib.h | 28 +++
.../MockPlatformPKProtectionLib.cpp | 11 ++
.../MockPlatformPKProtectionLib.inf | 34 ++++
SecurityPkg/Test/SecurityPkgHostTest.dsc | 8 +
11 files changed, 295 insertions(+), 7 deletions(-)
create mode 100644 SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.cpp
create mode 100644 SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf
create mode 100644 SecurityPkg/Test/Mock/Include/GoogleTest/Library/MockPlatformPKProtectionLib.h
create mode 100644 SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.cpp
create mode 100644 SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
diff --git a/SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.cpp b/SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.cpp
new file mode 100644
index 000000000000..c9190c8ffd61
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.cpp
@@ -0,0 +1,174 @@
+/** @file
+ Unit tests for the implementation of SecureBootVariableLib.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/GoogleTestLib.h>
+#include <GoogleTest/Library/MockUefiLib.h>
+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
+
+extern "C" {
+ #include <Uefi.h>
+ #include <UefiSecureBoot.h>
+ #include <Guid/AuthenticatedVariableFormat.h>
+ #include <Guid/ImageAuthentication.h>
+ #include <Library/SecureBootVariableLib.h>
+ #include <Library/MemoryAllocationLib.h>
+}
+
+using namespace testing;
+
+//////////////////////////////////////////////////////////////////////////////
+class SetSecureBootModeTest : public Test {
+ protected:
+ MockUefiRuntimeServicesTableLib RtServicesMock;
+ UINT8 SecureBootMode;
+ EFI_STATUS Status;
+
+ void SetUp() override {
+ // Any random magic number can be used for these tests
+ SecureBootMode = 0xAB;
+ }
+};
+
+// Test SetSecureBootMode() API from SecureBootVariableLib to verify the
+// expected error is returned when the call to gRT->SetVariable() fails.
+TEST_F(SetSecureBootModeTest, SetVarError) {
+ EXPECT_CALL(RtServicesMock, gRT_SetVariable)
+ .WillOnce(Return(EFI_INVALID_PARAMETER));
+
+ Status = SetSecureBootMode(SecureBootMode);
+ EXPECT_EQ(Status, EFI_INVALID_PARAMETER);
+}
+
+// Test SetSecureBootMode() API from SecureBootVariableLib to verify the
+// expected secure boot mode is written to the correct variable in the call
+// to gRT->SetVariable().
+TEST_F(SetSecureBootModeTest, PropogateModeToSetVar) {
+ EXPECT_CALL(RtServicesMock,
+ gRT_SetVariable(
+ Char16StrEq(EFI_CUSTOM_MODE_NAME),
+ BufferEq(&gEfiCustomModeEnableGuid, sizeof(EFI_GUID)),
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(SecureBootMode),
+ BufferEq(&SecureBootMode, sizeof(SecureBootMode))))
+ .WillOnce(Return(EFI_SUCCESS));
+
+ Status = SetSecureBootMode(SecureBootMode);
+ EXPECT_EQ(Status, EFI_SUCCESS);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+class GetSetupModeTest : public Test {
+ protected:
+ MockUefiRuntimeServicesTableLib RtServicesMock;
+ UINT8 SetupMode;
+ EFI_STATUS Status;
+ UINT8 ExpSetupMode;
+
+ void SetUp() override {
+ // Any random magic number can be used for these tests
+ ExpSetupMode = 0xAB;
+ }
+};
+
+// Test GetSetupMode() API from SecureBootVariableLib to verify the expected
+// error is returned when the call to gRT->GetVariable() fails.
+TEST_F(GetSetupModeTest, GetVarError) {
+ EXPECT_CALL(RtServicesMock, gRT_GetVariable)
+ .WillOnce(Return(EFI_INVALID_PARAMETER));
+
+ Status = GetSetupMode (&SetupMode);
+ EXPECT_EQ(Status, EFI_INVALID_PARAMETER);
+}
+
+// Test GetSetupMode() API from SecureBootVariableLib to verify the expected
+// setup mode is returned (and with a success return code) when the mode is
+// successfully read from the call to gRT->GetVariable().
+TEST_F(GetSetupModeTest, FetchModeFromGetVar) {
+ EXPECT_CALL(RtServicesMock,
+ gRT_GetVariable(
+ Char16StrEq(EFI_SETUP_MODE_NAME),
+ BufferEq(&gEfiGlobalVariableGuid, sizeof(EFI_GUID)),
+ _,
+ Pointee(Eq(sizeof(SetupMode))),
+ NotNull()))
+ .WillOnce(DoAll(
+ SetArgPointee<3>(sizeof(ExpSetupMode)),
+ SetArgBuffer<4>(&ExpSetupMode, sizeof(ExpSetupMode)),
+ Return(EFI_SUCCESS)));
+
+ Status = GetSetupMode (&SetupMode);
+ ASSERT_EQ(Status, EFI_SUCCESS);
+ EXPECT_EQ(SetupMode, ExpSetupMode);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+class IsSecureBootEnabledTest : public Test {
+ protected:
+ MockUefiLib UefiLibMock;
+ BOOLEAN Enabled;
+};
+
+// Test IsSecureBootEnabled() API from SecureBootVariableLib to verify FALSE
+// is returned when the call to GetEfiGlobalVariable2() fails.
+TEST_F(IsSecureBootEnabledTest, GetVarError) {
+ EXPECT_CALL(UefiLibMock, GetEfiGlobalVariable2)
+ .WillOnce(Return(EFI_ABORTED));
+
+ Enabled = IsSecureBootEnabled ();
+ EXPECT_EQ(Enabled, FALSE);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+class IsSecureBootEnabledAllocTest : public IsSecureBootEnabledTest {
+ protected:
+ UINT8 *BootEnabledBuffer;
+
+ void SetUp() override {
+ BootEnabledBuffer = (UINT8*) AllocatePool(1);
+ ASSERT_NE(BootEnabledBuffer, nullptr);
+ }
+};
+
+// Test IsSecureBootEnabled() API from SecureBootVariableLib to verify TRUE
+// is returned when the call to GetEfiGlobalVariable2() is successful and
+// returns SECURE_BOOT_MODE_ENABLE.
+TEST_F(IsSecureBootEnabledAllocTest, IsEnabled) {
+ *BootEnabledBuffer = SECURE_BOOT_MODE_ENABLE;
+ EXPECT_CALL(UefiLibMock,
+ GetEfiGlobalVariable2(
+ Char16StrEq(EFI_SECURE_BOOT_MODE_NAME),
+ NotNull(),
+ _))
+ .WillOnce(DoAll(
+ SetArgBuffer<1>(&BootEnabledBuffer, sizeof(VOID*)),
+ Return(EFI_SUCCESS)));
+
+ Enabled = IsSecureBootEnabled ();
+ EXPECT_EQ(Enabled, TRUE);
+}
+
+// Test IsSecureBootEnabled() API from SecureBootVariableLib to verify FALSE
+// is returned when the call to GetEfiGlobalVariable2() is successful and
+// returns SECURE_BOOT_MODE_DISABLE.
+TEST_F(IsSecureBootEnabledAllocTest, IsDisabled) {
+ *BootEnabledBuffer = SECURE_BOOT_MODE_DISABLE;
+ EXPECT_CALL(UefiLibMock,
+ GetEfiGlobalVariable2(
+ Char16StrEq(EFI_SECURE_BOOT_MODE_NAME),
+ NotNull(),
+ _))
+ .WillOnce(DoAll(
+ SetArgBuffer<1>(&BootEnabledBuffer, sizeof(VOID*)),
+ Return(EFI_SUCCESS)));
+
+ Enabled = IsSecureBootEnabled ();
+ EXPECT_EQ(Enabled, FALSE);
+}
+
+int main(int argc, char* argv[]) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf b/SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf
new file mode 100644
index 000000000000..5503dcfa32d1
--- /dev/null
+++ b/SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf
@@ -0,0 +1,32 @@
+## @file
+# Unit test suite for the SecureBootVariableLib using Google Test
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = SecureBootVariableLibGoogleTest
+ FILE_GUID = C88372AB-726B-4344-A250-6C7F826C874E
+ VERSION_STRING = 1.0
+ MODULE_TYPE = HOST_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SecureBootVariableLibGoogleTest.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+ SecureBootVariableLib
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
index 1e19033c5a91..c927ef709958 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
@@ -10,9 +10,9 @@ [Defines]
INF_VERSION = 0x00010005
BASE_NAME = MockPlatformPKProtectionLib
FILE_GUID = 5FCD74D3-3965-4D56-AB83-000B9B4806A0
- MODULE_TYPE = DXE_DRIVER
+ MODULE_TYPE = HOST_APPLICATION
VERSION_STRING = 1.0
- LIBRARY_CLASS = PlatformPKProtectionLib|HOST_APPLICATION
+ LIBRARY_CLASS = PlatformPKProtectionLib
#
# The following information is for reference only and not required by the build tools.
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
index a84242ac7205..fecf46841131 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
@@ -18,9 +18,9 @@ [Defines]
INF_VERSION = 0x00010005
BASE_NAME = MockUefiLib
FILE_GUID = E3B7AEF9-4E55-49AF-B035-ED776C928EC6
- MODULE_TYPE = UEFI_DRIVER
+ MODULE_TYPE = HOST_APPLICATION
VERSION_STRING = 1.0
- LIBRARY_CLASS = UefiLib|HOST_APPLICATION
+ LIBRARY_CLASS = UefiLib
#
# VALID_ARCHITECTURES = IA32 X64 EBC
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
index f832a93e2254..6fe04189606e 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
@@ -10,9 +10,9 @@ [Defines]
INF_VERSION = 0x00010005
BASE_NAME = MockUefiRuntimeServicesTableLib
FILE_GUID = 84CE0021-ABEE-403C-9A1B-763CCF2D40F1
- MODULE_TYPE = UEFI_DRIVER
+ MODULE_TYPE = HOST_APPLICATION
VERSION_STRING = 1.0
- LIBRARY_CLASS = UefiRuntimeServicesTableLib|HOST_APPLICATION
+ LIBRARY_CLASS = UefiRuntimeServicesTableLib
#
# VALID_ARCHITECTURES = IA32 X64 EBC
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
index a23135dfb016..3a92d5d83457 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
@@ -163,7 +163,7 @@ MockGetVariable (
return EFI_BUFFER_TOO_SMALL;
} else {
assert_non_null (Data);
- CopyMem (Data, (VOID *)mock (), TargetSize);
+ CopyMem (Data, (VOID *)(UINTN)mock (), TargetSize);
}
return EFI_SUCCESS;
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 0382090f4e75..0a8042d63fe1 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -21,6 +21,7 @@ [Defines]
[Includes]
Include
+ Test/Mock/Include
[LibraryClasses]
## @libraryclass Provides hash interfaces from different implementations.
diff --git a/SecurityPkg/Test/Mock/Include/GoogleTest/Library/MockPlatformPKProtectionLib.h b/SecurityPkg/Test/Mock/Include/GoogleTest/Library/MockPlatformPKProtectionLib.h
new file mode 100644
index 000000000000..8024f4be2975
--- /dev/null
+++ b/SecurityPkg/Test/Mock/Include/GoogleTest/Library/MockPlatformPKProtectionLib.h
@@ -0,0 +1,28 @@
+/** @file
+ Google Test mocks for PlatformPKProtectionLib
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MOCK_PLATFORM_PK_PROTECTION_LIB_H_
+#define MOCK_PLATFORM_PK_PROTECTION_LIB_H_
+
+#include <Library/GoogleTestLib.h>
+#include <Library/FunctionMockLib.h>
+extern "C" {
+#include <Uefi.h>
+#include <Library/PlatformPKProtectionLib.h>
+}
+
+struct MockPlatformPKProtectionLib {
+ MOCK_INTERFACE_DECLARATION (MockPlatformPKProtectionLib);
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ DisablePKProtection,
+ ()
+ );
+};
+
+#endif
diff --git a/SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.cpp b/SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.cpp
new file mode 100644
index 000000000000..5ea030f6dfcf
--- /dev/null
+++ b/SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.cpp
@@ -0,0 +1,11 @@
+/** @file
+ Google Test mocks for PlatformPKProtectionLib
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <GoogleTest/Library/MockPlatformPKProtectionLib.h>
+
+MOCK_INTERFACE_DEFINITION(MockPlatformPKProtectionLib);
+
+MOCK_FUNCTION_DEFINITION(MockPlatformPKProtectionLib, DisablePKProtection, 0, EFIAPI);
diff --git a/SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf b/SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
new file mode 100644
index 000000000000..3ed638eaf74c
--- /dev/null
+++ b/SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Google Test mocks for PlatformPKProtectionLib
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MockPlatformPKProtectionLib
+ FILE_GUID = C1383D85-E0ED-44E0-A0A6-125F1D78B6E9
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformPKProtectionLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MockPlatformPKProtectionLib.cpp
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /EHsc
diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc
index c4df01fe1b73..ad5b4fc350ea 100644
--- a/SecurityPkg/Test/SecurityPkgHostTest.dsc
+++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc
@@ -25,6 +25,7 @@ [Components]
SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
+ SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
#
# Build SecurityPkg HOST_APPLICATION Tests
@@ -36,3 +37,10 @@ [Components]
PlatformPKProtectionLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
UefiLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
}
+ SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf {
+ <LibraryClasses>
+ SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
+ PlatformPKProtectionLib|SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
+ UefiLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
+ }
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 08/12] SecurityPkg/Library/SecureBootVariableLib: Fix VS20xx 4122 errors
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (6 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 07/12] SecurityPkg: Add gmock example Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 09/12] SecurityPkg/Library/SecureBootVariableLib: HOST_APPLICATION IA32/X64 only Michael D Kinney
` (3 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Jiewen Yao, Jian J Wang, Oliver Smith-Denny
The unit test code for the SecureBootVariableLib is initializing
local variable structures in their declaration from other local
variables that are also initialized in their declaration. ANSI C
does not allow this and error 4122 is generated on VS20xx compilers.
The test cases are updated to initialize the local structure
fields in C statements instead of their local variable declaration.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
---
.../UnitTest/SecureBootVariableLibUnitTest.c | 170 +++++++++---------
1 file changed, 83 insertions(+), 87 deletions(-)
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
index 3a92d5d83457..e4cdc68bbb35 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.c
@@ -351,10 +351,10 @@ SecureBootCreateDataFromInputSimple (
UINTN SigListSize = 0;
EFI_STATUS Status;
UINT8 TestData[] = { 0 };
- SECURE_BOOT_CERTIFICATE_INFO KeyInfo = {
- .Data = TestData,
- .DataSize = sizeof (TestData)
- };
+ SECURE_BOOT_CERTIFICATE_INFO KeyInfo;
+
+ KeyInfo.Data = TestData;
+ KeyInfo.DataSize = sizeof (TestData);
Status = SecureBootCreateDataFromInput (&SigListSize, &SigList, 1, &KeyInfo);
@@ -441,16 +441,12 @@ SecureBootCreateDataFromInputMultiple (
UINT8 TestData1[] = { 0 };
UINT8 TestData2[] = { 1, 2 };
EFI_STATUS Status;
- SECURE_BOOT_CERTIFICATE_INFO KeyInfo[2] = {
- {
- .Data = TestData1,
- .DataSize = sizeof (TestData1)
- },
- {
- .Data = TestData2,
- .DataSize = sizeof (TestData2)
- }
- };
+ SECURE_BOOT_CERTIFICATE_INFO KeyInfo[2];
+
+ KeyInfo[0].Data = TestData1;
+ KeyInfo[0].DataSize = sizeof (TestData1);
+ KeyInfo[1].Data = TestData2;
+ KeyInfo[1].DataSize = sizeof (TestData2);
Status = SecureBootCreateDataFromInput (&SigListSize, &SigList, 2, KeyInfo);
UT_ASSERT_NOT_EFI_ERROR (Status);
@@ -1219,19 +1215,19 @@ SetSecureBootVariablesShouldComplete (
UINT8 PkDummy = 0xFE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbPtr = &DbDummy,
- .DbSize = sizeof (DbDummy),
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .DbtPtr = &DbtDummy,
- .DbtSize = sizeof (DbtDummy),
- .KekPtr = &KekDummy,
- .KekSize = sizeof (KekDummy),
- .PkPtr = &PkDummy,
- .PkSize = sizeof (PkDummy),
- .SecureBootKeyName = L"Food"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbPtr = &DbDummy;
+ PayloadInfo.DbSize = sizeof (DbDummy);
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.DbtPtr = &DbtDummy;
+ PayloadInfo.DbtSize = sizeof (DbtDummy);
+ PayloadInfo.KekPtr = &KekDummy;
+ PayloadInfo.KekSize = sizeof (KekDummy);
+ PayloadInfo.PkPtr = &PkDummy;
+ PayloadInfo.PkSize = sizeof (PkDummy);
+ PayloadInfo.SecureBootKeyName = L"Food";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
@@ -1385,11 +1381,11 @@ SetSecureBootVariablesShouldStopFailDBX (
UINT8 DbxDummy = 0xBE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbxDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .SecureBootKeyName = L"Fail DBX"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.SecureBootKeyName = L"Fail DBX";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
@@ -1442,13 +1438,13 @@ SetSecureBootVariablesShouldStopFailDB (
UINT8 DbxDummy = 0xBE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbPtr = &DbDummy,
- .DbSize = sizeof (DbDummy),
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .SecureBootKeyName = L"Fail DB"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbPtr = &DbDummy;
+ PayloadInfo.DbSize = sizeof (DbDummy);
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.SecureBootKeyName = L"Fail DB";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
@@ -1516,15 +1512,15 @@ SetSecureBootVariablesShouldStopFailDBT (
UINT8 DbxDummy = 0xBE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbPtr = &DbDummy,
- .DbSize = sizeof (DbDummy),
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .DbtPtr = &DbtDummy,
- .DbtSize = sizeof (DbtDummy),
- .SecureBootKeyName = L"Fail DBT"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbPtr = &DbDummy;
+ PayloadInfo.DbSize = sizeof (DbDummy);
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.DbtPtr = &DbtDummy;
+ PayloadInfo.DbtSize = sizeof (DbtDummy);
+ PayloadInfo.SecureBootKeyName = L"Fail DBT";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
@@ -1608,19 +1604,19 @@ SetSecureBootVariablesShouldStopFailKEK (
UINT8 PkDummy = 0xFE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbPtr = &DbDummy,
- .DbSize = sizeof (DbDummy),
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .DbtPtr = &DbtDummy,
- .DbtSize = sizeof (DbtDummy),
- .KekPtr = &KekDummy,
- .KekSize = sizeof (KekDummy),
- .PkPtr = &PkDummy,
- .PkSize = sizeof (PkDummy),
- .SecureBootKeyName = L"Food"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbPtr = &DbDummy;
+ PayloadInfo.DbSize = sizeof (DbDummy);
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.DbtPtr = &DbtDummy;
+ PayloadInfo.DbtSize = sizeof (DbtDummy);
+ PayloadInfo.KekPtr = &KekDummy;
+ PayloadInfo.KekSize = sizeof (KekDummy);
+ PayloadInfo.PkPtr = &PkDummy;
+ PayloadInfo.PkSize = sizeof (PkDummy);
+ PayloadInfo.SecureBootKeyName = L"Food";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
@@ -1718,19 +1714,19 @@ SetSecureBootVariablesShouldStopFailPK (
UINT8 PkDummy = 0xFE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbPtr = &DbDummy,
- .DbSize = sizeof (DbDummy),
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .DbtPtr = &DbtDummy,
- .DbtSize = sizeof (DbtDummy),
- .KekPtr = &KekDummy,
- .KekSize = sizeof (KekDummy),
- .PkPtr = &PkDummy,
- .PkSize = sizeof (PkDummy),
- .SecureBootKeyName = L"Food"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbPtr = &DbDummy;
+ PayloadInfo.DbSize = sizeof (DbDummy);
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.DbtPtr = &DbtDummy;
+ PayloadInfo.DbtSize = sizeof (DbtDummy);
+ PayloadInfo.KekPtr = &KekDummy;
+ PayloadInfo.KekSize = sizeof (KekDummy);
+ PayloadInfo.PkPtr = &PkDummy;
+ PayloadInfo.PkSize = sizeof (PkDummy);
+ PayloadInfo.SecureBootKeyName = L"Food";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
@@ -1841,19 +1837,19 @@ SetSecureBootVariablesDBTOptional (
UINT8 PkDummy = 0xFE;
UINT8 *Payload = NULL;
UINTN PayloadSize = sizeof (DbDummy);
- SECURE_BOOT_PAYLOAD_INFO PayloadInfo = {
- .DbPtr = &DbDummy,
- .DbSize = sizeof (DbDummy),
- .DbxPtr = &DbxDummy,
- .DbxSize = sizeof (DbxDummy),
- .DbtPtr = NULL,
- .DbtSize = 0,
- .KekPtr = &KekDummy,
- .KekSize = sizeof (KekDummy),
- .PkPtr = &PkDummy,
- .PkSize = sizeof (PkDummy),
- .SecureBootKeyName = L"Food"
- };
+ SECURE_BOOT_PAYLOAD_INFO PayloadInfo;
+
+ PayloadInfo.DbPtr = &DbDummy;
+ PayloadInfo.DbSize = sizeof (DbDummy);
+ PayloadInfo.DbxPtr = &DbxDummy;
+ PayloadInfo.DbxSize = sizeof (DbxDummy);
+ PayloadInfo.DbtPtr = NULL;
+ PayloadInfo.DbtSize = 0;
+ PayloadInfo.KekPtr = &KekDummy;
+ PayloadInfo.KekSize = sizeof (KekDummy);
+ PayloadInfo.PkPtr = &PkDummy;
+ PayloadInfo.PkSize = sizeof (PkDummy);
+ PayloadInfo.SecureBootKeyName = L"Food";
expect_memory (MockGetVariable, VariableName, EFI_SECURE_BOOT_MODE_NAME, sizeof (EFI_SECURE_BOOT_MODE_NAME));
expect_value (MockGetVariable, VendorGuid, &gEfiGlobalVariableGuid);
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 09/12] SecurityPkg/Library/SecureBootVariableLib: HOST_APPLICATION IA32/X64 only
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (7 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 08/12] SecurityPkg/Library/SecureBootVariableLib: Fix VS20xx 4122 errors Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 10/12] MdePkg/Library/BaseLib: " Michael D Kinney
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Jiewen Yao, Jian J Wang, Oliver Smith-Denny
Update SecureBootVariableLib host-based unit test INF file to only
list VALID_ARCHITECTURES of IA32 and X64 to align with all other
host-based unit test INF files. The UnitTestFrameworkPkg only
provides build support of host-based unit tests to OS applications
for IA32 and X64.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
---
.../UnitTest/MockPlatformPKProtectionLib.inf | 2 +-
.../Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf | 2 +-
.../UnitTest/MockUefiRuntimeServicesTableLib.inf | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
index c927ef709958..3698e4fad059 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
@@ -17,7 +17,7 @@ [Defines]
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 AARCH64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
index fecf46841131..e02d04f376da 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
@@ -23,7 +23,7 @@ [Defines]
LIBRARY_CLASS = UefiLib
#
-# VALID_ARCHITECTURES = IA32 X64 EBC
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
diff --git a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
index 6fe04189606e..e59a3394d58f 100644
--- a/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+++ b/SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
@@ -15,7 +15,7 @@ [Defines]
LIBRARY_CLASS = UefiRuntimeServicesTableLib
#
-# VALID_ARCHITECTURES = IA32 X64 EBC
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 10/12] MdePkg/Library/BaseLib: HOST_APPLICATION IA32/X64 only
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (8 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 09/12] SecurityPkg/Library/SecureBootVariableLib: HOST_APPLICATION IA32/X64 only Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-07 22:20 ` [Patch v3 11/12] MdeModulePkg: " Michael D Kinney
2023-04-07 22:20 ` [Patch v3 12/12] PrmPkg/Library: " Michael D Kinney
11 siblings, 0 replies; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Liming Gao, Zhiguang Liu, Oliver Smith-Denny
Update BaseLib host-based unit test INF file to only list
VALID_ARCHITECTURES of IA32 and X64 to align with all other
host-based unit test INF files. The UnitTestFrameworkPkg only
provides build support of host-based unit tests to OS applications
for IA32 and X64.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
---
MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
index 12a5cdcc0a9e..1d53f940f5d0 100644
--- a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
+++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
@@ -23,7 +23,7 @@ [Defines]
LIBRARY_CLASS = UnitTestHostBaseLib|HOST_APPLICATION
#
-# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Patch v3 11/12] MdeModulePkg: HOST_APPLICATION IA32/X64 only
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (9 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 10/12] MdePkg/Library/BaseLib: " Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-10 1:16 ` 回复: [edk2-devel] " gaoliming
2023-04-07 22:20 ` [Patch v3 12/12] PrmPkg/Library: " Michael D Kinney
11 siblings, 1 reply; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Jian J Wang, Liming Gao, Oliver Smith-Denny
Update MdeModulePkg host-based unit test INF files to only list
VALID_ARCHITECTURES of IA32 and X64 to align with all other
host-based unit test INF files. The UnitTestFrameworkPkg only
provides build support of host-based unit tests to OS applications
for IA32 and X64.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
---
.../UnitTest/MockUefiRuntimeServicesTableLib.inf | 2 +-
.../RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
index 15eb646d7c38..24dc934f8d25 100644
--- a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
+++ b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
@@ -15,7 +15,7 @@ [Defines]
LIBRARY_CLASS = UefiRuntimeServicesTableLib
#
-# VALID_ARCHITECTURES = IA32 X64 EBC
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf
index 2a659d7e1370..59c743ad1fa6 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf
@@ -15,7 +15,7 @@ [Defines]
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* 回复: [edk2-devel] [Patch v3 11/12] MdeModulePkg: HOST_APPLICATION IA32/X64 only
2023-04-07 22:20 ` [Patch v3 11/12] MdeModulePkg: " Michael D Kinney
@ 2023-04-10 1:16 ` gaoliming
0 siblings, 0 replies; 15+ messages in thread
From: gaoliming @ 2023-04-10 1:16 UTC (permalink / raw)
To: devel, michael.d.kinney
Cc: 'Jian J Wang', 'Oliver Smith-Denny'
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Michael D
> Kinney
> 发送时间: 2023年4月8日 6:21
> 收件人: devel@edk2.groups.io
> 抄送: Jian J Wang <jian.j.wang@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Oliver Smith-Denny
> <osde@linux.microsoft.com>
> 主题: [edk2-devel] [Patch v3 11/12] MdeModulePkg: HOST_APPLICATION
> IA32/X64 only
>
> Update MdeModulePkg host-based unit test INF files to only list
> VALID_ARCHITECTURES of IA32 and X64 to align with all other
> host-based unit test INF files. The UnitTestFrameworkPkg only
> provides build support of host-based unit tests to OS applications
> for IA32 and X64.
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
> Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
> ---
> .../UnitTest/MockUefiRuntimeServicesTableLib.inf | 2 +-
> .../RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git
> a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeSe
> rvicesTableLib.inf
> b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeSe
> rvicesTableLib.inf
> index 15eb646d7c38..24dc934f8d25 100644
> ---
> a/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeSe
> rvicesTableLib.inf
> +++
> b/MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeSe
> rvicesTableLib.inf
> @@ -15,7 +15,7 @@ [Defines]
> LIBRARY_CLASS = UefiRuntimeServicesTableLib
>
> #
> -# VALID_ARCHITECTURES = IA32 X64 EBC
> +# VALID_ARCHITECTURES = IA32 X64
> #
>
> [Sources]
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari
> ableLockRequestToLockUnitTest.inf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari
> ableLockRequestToLockUnitTest.inf
> index 2a659d7e1370..59c743ad1fa6 100644
> ---
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari
> ableLockRequestToLockUnitTest.inf
> +++
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari
> ableLockRequestToLockUnitTest.inf
> @@ -15,7 +15,7 @@ [Defines]
> #
> # The following information is for reference only and not required by the
> build tools.
> #
> -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
> +# VALID_ARCHITECTURES = IA32 X64
> #
>
> [Sources]
> --
> 2.39.1.windows.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Patch v3 12/12] PrmPkg/Library: HOST_APPLICATION IA32/X64 only
2023-04-07 22:20 [Patch v3 00/12] Add gmock support for host-based unit testing Michael D Kinney
` (10 preceding siblings ...)
2023-04-07 22:20 ` [Patch v3 11/12] MdeModulePkg: " Michael D Kinney
@ 2023-04-07 22:20 ` Michael D Kinney
2023-04-08 2:41 ` Michael Kubacki
11 siblings, 1 reply; 15+ messages in thread
From: Michael D Kinney @ 2023-04-07 22:20 UTC (permalink / raw)
To: devel; +Cc: Michael Kubacki, Nate DeSimone, Oliver Smith-Denny
Update PrmPkg host-based unit test INF files to only list
VALID_ARCHITECTURES of IA32 and X64 to align with all other
host-based unit test INF files. The UnitTestFrameworkPkg only
provides build support of host-based unit tests to OS applications
for IA32 and X64.
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
---
.../UnitTest/DxePrmContextBufferLibUnitTestHost.inf | 2 +-
.../UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
index 7cf6a16867d4..eefaddb10aaf 100644
--- a/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
+++ b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
@@ -17,7 +17,7 @@ [Defines]
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
index 8aae1f7cd78a..fd4b44a9bf85 100644
--- a/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
@@ -17,7 +17,7 @@ [Defines]
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
--
2.39.1.windows.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Patch v3 12/12] PrmPkg/Library: HOST_APPLICATION IA32/X64 only
2023-04-07 22:20 ` [Patch v3 12/12] PrmPkg/Library: " Michael D Kinney
@ 2023-04-08 2:41 ` Michael Kubacki
0 siblings, 0 replies; 15+ messages in thread
From: Michael Kubacki @ 2023-04-08 2:41 UTC (permalink / raw)
To: Michael D Kinney, devel; +Cc: Nate DeSimone, Oliver Smith-Denny
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
On 4/7/2023 6:20 PM, Michael D Kinney wrote:
> Update PrmPkg host-based unit test INF files to only list
> VALID_ARCHITECTURES of IA32 and X64 to align with all other
> host-based unit test INF files. The UnitTestFrameworkPkg only
> provides build support of host-based unit tests to OS applications
> for IA32 and X64.
>
> Cc: Michael Kubacki <mikuback@linux.microsoft.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
> Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
> ---
> .../UnitTest/DxePrmContextBufferLibUnitTestHost.inf | 2 +-
> .../UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
> index 7cf6a16867d4..eefaddb10aaf 100644
> --- a/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
> +++ b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
> @@ -17,7 +17,7 @@ [Defines]
> #
> # The following information is for reference only and not required by the build tools.
> #
> -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
> +# VALID_ARCHITECTURES = IA32 X64
> #
>
> [Sources]
> diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
> index 8aae1f7cd78a..fd4b44a9bf85 100644
> --- a/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
> +++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
> @@ -17,7 +17,7 @@ [Defines]
> #
> # The following information is for reference only and not required by the build tools.
> #
> -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
> +# VALID_ARCHITECTURES = IA32 X64
> #
>
> [Sources]
^ permalink raw reply [flat|nested] 15+ messages in thread