https://bugzilla.tianocore.org/show_bug.cgi?id=2505 Add the following library instances that are used to build unit tests for host and target environments. * CmockaLib with cmocka submodule to: https://git.cryptomilk.org/projects/cmocka.git * DebugLibPosix - Instance of DebugLib based on POSIX APIs (e.g. printf). * MemoryAllocationLibPosix - Instance of MemoryAllocationLib based on POSIX APIs (e.g. malloc/free). * UnitTestBootLibNull - Null instance of the UnitTestBootLib * UnitTestBootLibUsbClass - UnitTestBootLib instances that supports setting boot next to a USB device. * UnitTestLib - UnitTestLib instance that is designed to work with PEI, DXE, SMM, and UEFI Shell target environments. * UnitTestLibCmocka - UintTestLib instance that uses cmocka APIs and can only be use in a host environment. * UnitTestPersistenceLibNull - Null instance of the UnitTestPersistenceLib * UnitTestPersistenceLibSimpleFileSystem - UnitTestPersistenceLib instance that can safe the unit test framework state to a media device that supports the UEFI Simple File System Protocol. * UnitTestResultReportLibConOut - UnitTestResultReportLib instance that sends report results to the UEFI standard output console. * UnitTestResultReportLibDebugLib - UnitTestResultReportLib instance that sends report results to a DebugLib using DEBUG() macros. Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
		
			
				
	
	
		
			201 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
  Implemnet UnitTestLib log services
 | 
						|
 | 
						|
  Copyright (c) Microsoft Corporation.<BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include <PiDxe.h>
 | 
						|
#include <UnitTestFrameworkTypes.h>
 | 
						|
#include <Library/UnitTestLib.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/PrintLib.h>
 | 
						|
#include <Library/PcdLib.h>
 | 
						|
 | 
						|
#define UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH  (512)
 | 
						|
#define UNIT_TEST_MAX_LOG_BUFFER                SIZE_16KB
 | 
						|
 | 
						|
struct _UNIT_TEST_LOG_PREFIX_STRING {
 | 
						|
  UNIT_TEST_STATUS  LogLevel;
 | 
						|
  CHAR8             *String;
 | 
						|
};
 | 
						|
 | 
						|
struct _UNIT_TEST_LOG_PREFIX_STRING  mLogPrefixStrings[] = {
 | 
						|
  { UNIT_TEST_LOG_LEVEL_ERROR,   "[ERROR]       " },
 | 
						|
  { UNIT_TEST_LOG_LEVEL_WARN,    "[WARNING]     " },
 | 
						|
  { UNIT_TEST_LOG_LEVEL_INFO,    "[INFO]        " },
 | 
						|
  { UNIT_TEST_LOG_LEVEL_VERBOSE, "[VERBOSE]     " }
 | 
						|
};
 | 
						|
 | 
						|
//
 | 
						|
// Unit-Test Log helper functions
 | 
						|
//
 | 
						|
 | 
						|
STATIC
 | 
						|
CONST CHAR8*
 | 
						|
GetStringForStatusLogPrefix (
 | 
						|
  IN UINTN  LogLevel
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Index;
 | 
						|
  CHAR8  *Result;
 | 
						|
 | 
						|
  Result = NULL;
 | 
						|
  for (Index = 0; Index < ARRAY_SIZE (mLogPrefixStrings); Index++) {
 | 
						|
    if (mLogPrefixStrings[Index].LogLevel == LogLevel) {
 | 
						|
      Result = mLogPrefixStrings[Index].String;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return Result;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
AddStringToUnitTestLog (
 | 
						|
  IN OUT UNIT_TEST    *UnitTest,
 | 
						|
  IN     CONST CHAR8  *String
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure that you're cooking with gas.
 | 
						|
  //
 | 
						|
  if (UnitTest == NULL || String == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // If this is the first log for the test allocate log space
 | 
						|
  if (UnitTest->Log == NULL) {
 | 
						|
    UnitTestLogInit (UnitTest, NULL, 0);
 | 
						|
  }
 | 
						|
 | 
						|
  if (UnitTest->Log == NULL) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "Failed to allocate space for unit test log\n"));
 | 
						|
    ASSERT (UnitTest->Log != NULL);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AsciiStrnCatS (
 | 
						|
             UnitTest->Log,
 | 
						|
             UNIT_TEST_MAX_LOG_BUFFER / sizeof (CHAR8),
 | 
						|
             String,
 | 
						|
             UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH
 | 
						|
             );
 | 
						|
  if(EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "Failed to add unit test log string.  Status = %r\n", Status));
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function is responsible for initializing the log buffer for a single test. It can
 | 
						|
  be used internally, but may also be consumed by the test framework to add pre-existing
 | 
						|
  data to a log before it's used.
 | 
						|
 | 
						|
  @param[in,out]  TestHandle    A handle to the test being initialized.
 | 
						|
  @param[in]      Buffer        [Optional] A pointer to pre-existing log data that should
 | 
						|
                                be used to initialize the log. Should include a NULL terminator.
 | 
						|
  @param[in]      BufferSize    [Optional] The size of the pre-existing log data.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
UnitTestLogInit (
 | 
						|
  IN OUT UNIT_TEST  *Test,
 | 
						|
  IN     UINT8      *Buffer,     OPTIONAL
 | 
						|
  IN     UINTN      BufferSize   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Make sure that you're cooking with gas.
 | 
						|
  //
 | 
						|
  if (Test == NULL) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "%a called with invalid Test parameter\n", __FUNCTION__));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If this is the first log for the test allocate log space
 | 
						|
  //
 | 
						|
  if (Test->Log == NULL) {
 | 
						|
    Test->Log = AllocateZeroPool (UNIT_TEST_MAX_LOG_BUFFER);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //check again to make sure allocate worked
 | 
						|
  //
 | 
						|
  if(Test->Log == NULL) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "Failed to allocate memory for the log\n"));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if((Buffer != NULL) && (BufferSize > 0) && ((BufferSize <= UNIT_TEST_MAX_LOG_BUFFER))) {
 | 
						|
    CopyMem (Test->Log, Buffer, BufferSize);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Test logging function that records a messages in the test framework log.
 | 
						|
  Record is associated with the currently executing test case.
 | 
						|
 | 
						|
  @param[in]  ErrorLevel  The error level of the unit test log message.
 | 
						|
  @param[in]  Format      Formatting string following the format defined in the
 | 
						|
                          MdePkg/Include/Library/PrintLib.h.
 | 
						|
  @param[in]  ...         Print args.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
UnitTestLog (
 | 
						|
  IN  UINTN        ErrorLevel,
 | 
						|
  IN  CONST CHAR8  *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle;
 | 
						|
  CHAR8                       NewFormatString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH];
 | 
						|
  CHAR8                       LogString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH];
 | 
						|
  CONST CHAR8                 *LogTypePrefix;
 | 
						|
  VA_LIST                     Marker;
 | 
						|
 | 
						|
  FrameworkHandle = GetActiveFrameworkHandle ();
 | 
						|
 | 
						|
  LogTypePrefix = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure that this unit test log level is enabled.
 | 
						|
  //
 | 
						|
  if ((ErrorLevel & (UINTN)PcdGet32 (PcdUnitTestLogLevel)) == 0) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If we need to define a new format string...
 | 
						|
  // well... get to it.
 | 
						|
  //
 | 
						|
  LogTypePrefix = GetStringForStatusLogPrefix (ErrorLevel);
 | 
						|
  if (LogTypePrefix != NULL) {
 | 
						|
    AsciiSPrint (NewFormatString, sizeof (NewFormatString), "%a%a", LogTypePrefix, Format);
 | 
						|
  } else {
 | 
						|
    AsciiStrCpyS (NewFormatString, sizeof (NewFormatString), Format);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert the message to an ASCII String
 | 
						|
  //
 | 
						|
  VA_START (Marker, Format);
 | 
						|
  AsciiVSPrint (LogString, sizeof (LogString), NewFormatString, Marker);
 | 
						|
  VA_END (Marker);
 | 
						|
 | 
						|
  //
 | 
						|
  // Finally, add the string to the log.
 | 
						|
  //
 | 
						|
  AddStringToUnitTestLog (((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest, LogString);
 | 
						|
}
 |