diff --git a/AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.cpp b/AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.cpp new file mode 100644 index 0000000000..78306ccaee --- /dev/null +++ b/AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.cpp @@ -0,0 +1,225 @@ +/** @file AdvancedLoggerPeiLibGoogleTest.cpp + + This file contains the unit tests for the Advanced Logger DXE Library. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +extern "C" { + #include + #include + #include + #include + #include + #include "../../AdvancedLoggerCommon.h" +} + +using namespace testing; + +/** + Test class for AdvancedLoggerWrite Function +**/ +class AdvancedLoggerWriteTestPei : public Test { +protected: + StrictMock PeiServicesMock; + StrictMock AdvancedLoggerPpiMock; + UINTN DebugLevel; + CHAR8 *Buffer; + UINTN NumberOfBytes; + + void + SetUp ( + ) override + { + CHAR8 OutputBuf[] = "MyUnitTestLog"; + + NumberOfBytes = sizeof (OutputBuf); + Buffer = OutputBuf; + DebugLevel = DEBUG_ERROR; + gALPpi->Signature = ADVANCED_LOGGER_PPI_SIGNATURE; + gALPpi->Signature = ADVANCED_LOGGER_PPI_VERSION; + } +}; + +TEST_F (AdvancedLoggerWriteTestPei, PpiNotFounfFailure) { + // Expect the locate PPI call to fail + EXPECT_CALL ( + PeiServicesMock, + PeiServicesLocatePpi ( + BufferEq (&gAdvancedLoggerPpiGuid, sizeof (EFI_GUID)), + Eq (0), + IsNull (), + NotNull () + ) + ) + .WillOnce ( + Return (EFI_NOT_FOUND) + ); + + AdvancedLoggerWrite (DebugLevel, Buffer, NumberOfBytes); +} + +TEST_F (AdvancedLoggerWriteTestPei, AdvLoggerWriteSuccess) { + // Expect the call to LocatePpi to return success, "found" AdvancedLoggerPpi (mocked) + EXPECT_CALL ( + PeiServicesMock, + PeiServicesLocatePpi ( + BufferEq (&gAdvancedLoggerPpiGuid, sizeof (EFI_GUID)), + Eq (0), + IsNull (), + NotNull () + ) + ) + .WillOnce ( + DoAll ( + SetArgPointee<3>(ByRef (gALPpi)), + Return (EFI_SUCCESS) + ) + ); + + // Expect the call to AdvancedLoggerWritePpi + EXPECT_CALL ( + AdvancedLoggerPpiMock, + gAL_AdvancedLoggerWritePpi ( + Eq (DebugLevel), + BufferEq (Buffer, NumberOfBytes), + Eq (NumberOfBytes) + ) + ) + .WillOnce ( + Return () + ); + + AdvancedLoggerWrite (DebugLevel, Buffer, NumberOfBytes); +} + +/* Passing an invalid buffer - should be caught/handled by the protocol */ +TEST_F (AdvancedLoggerWriteTestPei, AdvLoggerWriteInvalidBuffer) { + Buffer = nullptr; + UINTN numBytesZero = 0; + + // Expect the call to LocatePpi to return success, "found" AdvancedLoggerPpi (mocked) + EXPECT_CALL ( + PeiServicesMock, + PeiServicesLocatePpi ( + BufferEq (&gAdvancedLoggerPpiGuid, sizeof (EFI_GUID)), + Eq (0), + IsNull (), + NotNull () + ) + ) + .WillOnce ( + DoAll ( + SetArgPointee<3>(ByRef (gALPpi)), + Return (EFI_SUCCESS) + ) + ); + + // Expect the call to AdvancedLoggerWritePpi + EXPECT_CALL ( + AdvancedLoggerPpiMock, + gAL_AdvancedLoggerWritePpi ( + Eq (DebugLevel), + BufferEq (Buffer, numBytesZero), + Eq (NumberOfBytes) + ) + ) + .WillOnce ( + Return () + ); + + AdvancedLoggerWrite (DebugLevel, Buffer, NumberOfBytes); +} + +/* Attempting to write 0 bytes - should be caught/handled by the protocol */ +TEST_F (AdvancedLoggerWriteTestPei, AdvLoggerWriteZeroBytes) { + UINTN NumberOfBytesZero = 0; + + // Expect the call to LocatePpi to return success, "found" AdvancedLoggerPpi (mocked) + EXPECT_CALL ( + PeiServicesMock, + PeiServicesLocatePpi ( + BufferEq (&gAdvancedLoggerPpiGuid, sizeof (EFI_GUID)), + Eq (0), + IsNull (), + NotNull () + ) + ) + .WillOnce ( + DoAll ( + SetArgPointee<3>(ByRef (gALPpi)), + Return (EFI_SUCCESS) + ) + ); + + // Expect the call to AdvancedLoggerWritePpi + EXPECT_CALL ( + AdvancedLoggerPpiMock, + gAL_AdvancedLoggerWritePpi ( + Eq (DebugLevel), + BufferEq (Buffer, NumberOfBytes), + Eq (NumberOfBytesZero) + ) + ) + .WillOnce ( + Return () + ); + + AdvancedLoggerWrite (DebugLevel, Buffer, NumberOfBytesZero); +} + +/* Passing a mismatched signature. Asserts are disabled so execution will continue */ +TEST_F (AdvancedLoggerWriteTestPei, AdvLoggerWriteFailMismatchedSignature) { + // Expect the call to LocatePpi to return success, "found" AdvancedLoggerPpi (mocked) + gALPpi->Signature = SIGNATURE_32 ('T', 'E', 'S', 'T'); + gALPpi->Version = ADVANCED_LOGGER_PPI_VERSION + 1; + + EXPECT_CALL ( + PeiServicesMock, + PeiServicesLocatePpi ( + BufferEq (&gAdvancedLoggerPpiGuid, sizeof (EFI_GUID)), + Eq (0), + IsNull (), + NotNull () + ) + ) + .WillOnce ( + DoAll ( + SetArgPointee<3>(ByRef (gALPpi)), + Return (EFI_SUCCESS) + ) + ); + + // TODO - why do we still expect a call to AdvancedLoggerWritePpi? shouldn't we exit? + // Or are we expecting the call to AdvancedLoggerWritePpi to check the signature and fail? + + // Expect the call to AdvancedLoggerWritePpi + EXPECT_CALL ( + AdvancedLoggerPpiMock, + gAL_AdvancedLoggerWritePpi ( + Eq (DebugLevel), + BufferEq (Buffer, NumberOfBytes), + Eq (NumberOfBytes) + ) + ) + .WillOnce ( + Return () + ); + + AdvancedLoggerWrite (DebugLevel, Buffer, NumberOfBytes); +} + +int +main ( + int argc, + char *argv[] + ) +{ + InitGoogleTest (&argc, argv); + return RUN_ALL_TESTS (); +} diff --git a/AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.inf b/AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.inf new file mode 100644 index 0000000000..5ce7d0ce51 --- /dev/null +++ b/AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.inf @@ -0,0 +1,42 @@ +## @file AdvancedLoggerPeiLibGoogleTest.inf +# +# Google Test for PEI instance of the Advanced Logger library. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.26 + BASE_NAME = AdvancedLoggerPeiLibGoogleTest + FILE_GUID = 95196693-DA35-4775-887C-1FF9C65D5054 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# + +[Sources] + AdvancedLoggerPeiLibGoogleTest.cpp + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + AdvLoggerPkg/AdvLoggerPkg.dec + +[LibraryClasses] + GoogleTestLib + AdvancedLoggerLib + +[Ppis] + gAdvancedLoggerPpiGuid ## CONSUMES + +[Pcd] + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerHdwPortDebugPrintErrorLevel ## SOMETIMES_CONSUMES + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /EHsc diff --git a/AdvLoggerPkg/Test/AdvLoggerHostTest.dsc b/AdvLoggerPkg/Test/AdvLoggerHostTest.dsc index ebe57dc610..d6fc1430a6 100644 --- a/AdvLoggerPkg/Test/AdvLoggerHostTest.dsc +++ b/AdvLoggerPkg/Test/AdvLoggerHostTest.dsc @@ -50,3 +50,8 @@ AdvLoggerPkg/AdvLoggerOsConnectorPrm/Library/AdvLoggerOsConnectorPrmConfigLib/GoogleTest/AdvLoggerPrmConfigLibGoogleTest.inf AdvLoggerPkg/AdvLoggerOsConnectorPrm/GoogleTest/AdvLoggerOsConnectorPrmGoogleTest.inf AdvLoggerPkg/Library/AdvancedLoggerLib/Dxe/GoogleTest/AdvancedLoggerDxeLibGoogleTest.inf + AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/GoogleTest/AdvancedLoggerPeiLibGoogleTest.inf { + + AdvancedLoggerLib|AdvLoggerPkg/Library/AdvancedLoggerLib/Pei/AdvancedLoggerLib.inf + PeiServicesLib|MdePkg/Test/Mock/Library/GoogleTest/MockPeiServicesLib/MockPeiServicesLib.inf + } diff --git a/AdvLoggerPkg/Test/Mock/Include/GoogleTest/Ppi/MockAdvancedLogger.h b/AdvLoggerPkg/Test/Mock/Include/GoogleTest/Ppi/MockAdvancedLogger.h new file mode 100644 index 0000000000..709fcf3a3f --- /dev/null +++ b/AdvLoggerPkg/Test/Mock/Include/GoogleTest/Ppi/MockAdvancedLogger.h @@ -0,0 +1,69 @@ +/** @file MockAdvancedLogger.h + This file declares a mock of the Advanced Logger Ppi. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef MOCK_ADVANCED_LOGGER_PPI_H_ +#define MOCK_ADVANCED_LOGGER_PPI_H_ + +#include +#include + +extern "C" { + #include + #include +} + +struct MockAdvancedLoggerPpi { + MOCK_INTERFACE_DECLARATION (MockAdvancedLoggerPpi); + + MOCK_FUNCTION_DECLARATION ( + VOID, + gAL_AdvancedLoggerWritePpi, + (IN UINTN ErrorLevel, + IN CONST CHAR8 *Buffer, + IN UINTN NumberOfBytes) + ); + + MOCK_FUNCTION_DECLARATION ( + VOID, + gAL_AdvancedLoggerPrintPpi, + (IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + IN VA_LIST VaListMarker) + ); + + MOCK_FUNCTION_DECLARATION ( + VOID, + gAL_AdvancedLoggerAssertPpi, + (IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description) + ); +}; + +// +// Mock function definitions in header file to prevent need of cpp file and +// make it easier to consume in tests. +// This is only suitable for protocol mocks. +// +MOCK_INTERFACE_DEFINITION (MockAdvancedLoggerPpi); +MOCK_FUNCTION_DEFINITION (MockAdvancedLoggerPpi, gAL_AdvancedLoggerWritePpi, 3, EFIAPI); +MOCK_FUNCTION_DEFINITION (MockAdvancedLoggerPpi, gAL_AdvancedLoggerPrintPpi, 3, EFIAPI); +MOCK_FUNCTION_DEFINITION (MockAdvancedLoggerPpi, gAL_AdvancedLoggerAssertPpi, 3, EFIAPI); + +ADVANCED_LOGGER_PPI advancedLoggerPpiInstance = { + ADVANCED_LOGGER_PPI_SIGNATURE, // UINT32 + ADVANCED_LOGGER_PPI_VERSION, // UINT32 + gAL_AdvancedLoggerWritePpi, // ADVANCED_LOGGER_WRITE_PPI + gAL_AdvancedLoggerPrintPpi, // ADVANCED_LOGGER_PRINT_PPI + gAL_AdvancedLoggerAssertPpi // ADVANCED_LOGGER_ASSERT_PPI +}; + +extern "C" { + ADVANCED_LOGGER_PPI *gALPpi = &advancedLoggerPpiInstance; +} + +#endif // MOCK_ADVANCED_LOGGER_PPI_H_