VirtualBox

Ignore:
Timestamp:
Sep 27, 2023 1:34:02 PM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159276
Message:

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
18 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Include/Library/GoogleTestLib.h

    r99404 r101291  
    1111
    1212#include <gtest/gtest.h>
     13#include <gmock/gmock.h>
     14#include <cstring>
     15
     16extern "C" {
     17#include <Uefi.h>
     18}
     19
     20//////////////////////////////////////////////////////////////////////////////
     21// Below are the action extensions to GoogleTest and gmock for EDK2 types.
     22// These actions are intended to be used in EXPECT_CALL (and related gmock
     23// macros) to support assignments to output arguments in the expected call.
     24//
     25
     26// Action to support pointer types to a buffer (such as UINT8* or VOID*)
     27ACTION_TEMPLATE (
     28  SetArgBuffer,
     29  HAS_1_TEMPLATE_PARAMS (size_t, ArgNum),
     30  AND_2_VALUE_PARAMS (Buffer, ByteSize)
     31  ) {
     32  auto  ArgBuffer = std::get<ArgNum>(args);
     33
     34  std::memcpy (ArgBuffer, Buffer, ByteSize);
     35}
     36
     37//////////////////////////////////////////////////////////////////////////////
     38// Below are the matcher extensions to GoogleTest and gmock for EDK2 types.
     39// These matchers are intended to be used in EXPECT_CALL (and related gmock
     40// macros) to support comparisons to input arguments in the expected call.
     41//
     42// Note that these matchers can also be used in the EXPECT_THAT or ASSERT_THAT
     43// macros to compare whether two values are equal.
     44//
     45
     46// Matcher to support pointer types to a buffer (such as UINT8* or VOID* or
     47// any structure pointer)
     48MATCHER_P2 (
     49  BufferEq,
     50  Buffer,
     51  ByteSize,
     52  std::string ("buffer data to ") + (negation ? "not " : "") + "be the same"
     53  ) {
     54  UINT8  *Actual   = (UINT8 *)arg;
     55  UINT8  *Expected = (UINT8 *)Buffer;
     56
     57  for (size_t i = 0; i < ByteSize; i++) {
     58    if (Actual[i] != Expected[i]) {
     59      *result_listener << "byte at offset " << i
     60      << " does not match expected. [" << std::hex
     61      << "Actual: 0x" << std::setw (2) << std::setfill ('0')
     62      << (unsigned int)Actual[i] << ", "
     63      << "Expected: 0x" << std::setw (2) << std::setfill ('0')
     64      << (unsigned int)Expected[i] << "]";
     65      return false;
     66    }
     67  }
     68
     69  *result_listener << "all bytes match";
     70  return true;
     71}
     72
     73// Matcher to support CHAR16* type
     74MATCHER_P (
     75  Char16StrEq,
     76  String,
     77  std::string ("strings to ") + (negation ? "not " : "") + "be the same"
     78  ) {
     79  CHAR16  *Actual   = (CHAR16 *)arg;
     80  CHAR16  *Expected = (CHAR16 *)String;
     81
     82  for (size_t i = 0; Actual[i] != 0; i++) {
     83    if (Actual[i] != Expected[i]) {
     84      *result_listener << "character at offset " << i
     85      << " does not match expected. [" << std::hex
     86      << "Actual: 0x" << std::setw (4) << std::setfill ('0')
     87      << Actual[i];
     88
     89      if (std::isprint (Actual[i])) {
     90        *result_listener << " ('" << (char)Actual[i] << "')";
     91      }
     92
     93      *result_listener << ", Expected: 0x" << std::setw (4) << std::setfill ('0')
     94      << Expected[i];
     95
     96      if (std::isprint (Expected[i])) {
     97        *result_listener << " ('" << (char)Expected[i] << "')";
     98      }
     99
     100      *result_listener << "]";
     101
     102      return false;
     103    }
     104  }
     105
     106  *result_listener << "strings match";
     107  return true;
     108}
    13109
    14110#endif
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf

    r99404 r101291  
    1717
    1818#
    19 #  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
     19#  VALID_ARCHITECTURES           = IA32 X64
    2020#
    2121
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf

    r99404 r101291  
    88
    99[Defines]
    10   INF_VERSION     = 0x00010005
     10  INF_VERSION     = 0x00010018
    1111  BASE_NAME       = GoogleTestLib
    1212  MODULE_UNI_FILE = GoogleTestLib.uni
    1313  FILE_GUID       = A90E4751-AD30-43CC-980B-01E356B49ADF
    14   MODULE_TYPE     = BASE
     14  MODULE_TYPE     = HOST_APPLICATION
    1515  VERSION_STRING  = 0.1
    16   LIBRARY_CLASS   = GoogleTestLib|HOST_APPLICATION
     16  LIBRARY_CLASS   = GoogleTestLib
    1717
    1818#
    19 #  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
     19#  VALID_ARCHITECTURES           = IA32 X64
    2020#
    2121
    2222[Sources]
    2323  googletest/googletest/src/gtest-all.cc
     24  googletest/googlemock/src/gmock-all.cc
    2425
    2526[Packages]
     27  MdePkg/MdePkg.dec
    2628  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
    2729
    2830[BuildOptions]
    29   MSFT:*_*_*_CC_FLAGS     == /c /EHsc /Zi
    30   MSFT:NOOPT_*_*_CC_FLAGS =  /Od
    31 
    32   GCC:*_*_*_CC_FLAGS     == -g -c
    33 
    34   GCC:NOOPT_*_*_CC_FLAGS =  -O0
    35   GCC:*_*_IA32_CC_FLAGS  =  -m32
    36   GCC:*_*_X64_CC_FLAGS   =  -m64
     31  MSFT:*_*_*_CC_FLAGS   == /c /EHsc /Zi /Od
     32  GCC:*_*_IA32_CC_FLAGS == -g -c -fshort-wchar -O0 -m32
     33  GCC:*_*_X64_CC_FLAGS  == -g -c -fshort-wchar -O0 -m64
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni

    r99404 r101291  
    22// This module provides GoogleTest Library implementation.
    33//
    4 // This module provides GoogleTest Library implementation.
    5 //
    64// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
    7 //
    85// SPDX-License-Identifier: BSD-2-Clause-Patent
    96//
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.c

    r99404 r101291  
    6262  DpEnd = AppendDevicePathNode (NULL, NULL);
    6363  if (DpEnd == NULL) {
    64     DEBUG ((DEBUG_ERROR, "%a: Unable to create device path.  DpEnd is NULL.\n", __FUNCTION__));
     64    DEBUG ((DEBUG_ERROR, "%a: Unable to create device path.  DpEnd is NULL.\n", __func__));
    6565    Status = EFI_OUT_OF_RESOURCES;
    6666    goto CLEANUP;
     
    7373         );
    7474  if (Dp == NULL) {
    75     DEBUG ((DEBUG_ERROR, "%a: Unable to create device path.  Dp is NULL.\n", __FUNCTION__));
     75    DEBUG ((DEBUG_ERROR, "%a: Unable to create device path.  Dp is NULL.\n", __func__));
    7676    Status = EFI_OUT_OF_RESOURCES;
    7777    goto CLEANUP;
     
    8989             );
    9090  if (EFI_ERROR (Status)) {
    91     DEBUG ((DEBUG_ERROR, "%a: Error creating load option.  Status = %r\n", __FUNCTION__, Status));
     91    DEBUG ((DEBUG_ERROR, "%a: Error creating load option.  Status = %r\n", __func__, Status));
    9292    goto CLEANUP;
    9393  }
    9494
    9595  NewOptionValid = TRUE;
    96   DEBUG ((DEBUG_VERBOSE, "%a: Generic USB Class Device boot option created.\n", __FUNCTION__));
     96  DEBUG ((DEBUG_VERBOSE, "%a: Generic USB Class Device boot option created.\n", __func__));
    9797  Status = EfiBootManagerLoadOptionToVariable (&NewOption);
    9898  if (EFI_ERROR (Status)) {
    99     DEBUG ((DEBUG_ERROR, "%a: Error Saving boot option NV variable. Status = %r\n", __FUNCTION__, Status));
     99    DEBUG ((DEBUG_ERROR, "%a: Error Saving boot option NV variable. Status = %r\n", __func__, Status));
    100100    goto CLEANUP;
    101101  }
     
    112112                  );
    113113
    114   DEBUG ((DEBUG_VERBOSE, "%a - Set BootNext Status (%r)\n", __FUNCTION__, Status));
     114  DEBUG ((DEBUG_VERBOSE, "%a - Set BootNext Status (%r)\n", __func__, Status));
    115115
    116116CLEANUP:
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestLib/Log.c

    r99404 r101291  
    119119  //
    120120  if (Test == NULL) {
    121     DEBUG ((DEBUG_ERROR, "%a called with invalid Test parameter\n", __FUNCTION__));
     121    DEBUG ((DEBUG_ERROR, "%a called with invalid Test parameter\n", __func__));
    122122    return;
    123123  }
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.c

    r99404 r101291  
    275275      // Don't actually report it as an error, but emit a warning.
    276276      //
    277       DEBUG ((DEBUG_ERROR, "%a - Cache was detected, but failed to load.\n", __FUNCTION__));
     277      DEBUG ((DEBUG_ERROR, "%a - Cache was detected, but failed to load.\n", __func__));
    278278      Status = EFI_SUCCESS;
    279279    }
     
    857857  Status = SaveUnitTestCache (FrameworkHandle, Header, Header->SaveStateSize);
    858858  if (EFI_ERROR (Status)) {
    859     DEBUG ((DEBUG_ERROR, "%a - Could not save state! %r\n", __FUNCTION__, Status));
     859    DEBUG ((DEBUG_ERROR, "%a - Could not save state! %r\n", __func__, Status));
    860860    Status = EFI_DEVICE_ERROR;
    861861  }
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.c

    r99404 r101291  
    1717#include <Library/DevicePathLib.h>
    1818#include <Library/ShellLib.h>
     19#include <Library/UefiLib.h>
    1920#include <Protocol/LoadedImage.h>
    2021#include <UnitTestFrameworkTypes.h>
     
    2223#define CACHE_FILE_SUFFIX  L"_Cache.dat"
    2324
     25CHAR16  *mCachePath = NULL;
     26
    2427/**
    25   Generate the device path to the cache file.
     28  Generate the file name and path to the cache file.
    2629
    2730  @param[in]  FrameworkHandle  A pointer to the framework that is being persisted.
     
    3235**/
    3336STATIC
    34 EFI_DEVICE_PATH_PROTOCOL *
    35 GetCacheFileDevicePath (
     37CHAR16 *
     38GetCacheFileName (
    3639  IN UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle
    3740  )
     
    4548  UINTN                      DirectorySlashOffset;
    4649  UINTN                      CacheFilePathLength;
    47   EFI_DEVICE_PATH_PROTOCOL   *CacheFileDevicePath;
    48 
    49   Framework           = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
    50   AppPath             = NULL;
    51   CacheFilePath       = NULL;
    52   TestName            = NULL;
    53   CacheFileDevicePath = NULL;
     50
     51  Framework     = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
     52  AppPath       = NULL;
     53  CacheFilePath = NULL;
     54  TestName      = NULL;
    5455
    5556  //
     
    6263                  );
    6364  if (EFI_ERROR (Status)) {
    64     DEBUG ((DEBUG_WARN, "%a - Failed to locate DevicePath for loaded image. %r\n", __FUNCTION__, Status));
     65    DEBUG ((DEBUG_WARN, "%a - Failed to locate DevicePath for loaded image. %r\n", __func__, Status));
    6566    return NULL;
    6667  }
     
    8687  //     if (PathRemoveLastItem (FileNameCopy)) {
    8788  //
    88   AppPath              = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE); // NOTE: This must be freed.
    89   DirectorySlashOffset = StrLen (AppPath);
    90   //
    91   // Make sure we didn't get any weird data.
    92   //
    93   if (DirectorySlashOffset == 0) {
    94     DEBUG ((DEBUG_ERROR, "%a - Weird 0-length string when processing app path.\n", __FUNCTION__));
    95     goto Exit;
    96   }
    97 
    98   //
    99   // Now that we know we have a decent string, let's take a deeper look.
    100   //
    101   do {
    102     if (AppPath[DirectorySlashOffset] == L'\\') {
    103       break;
    104     }
    105 
    106     DirectorySlashOffset--;
    107   } while (DirectorySlashOffset > 0);
    108 
    109   //
    110   // After that little maneuver, DirectorySlashOffset should be pointing at the last '\' in AppString.
    111   // That would be the path to the parent directory that the test app is executing from.
    112   // Let's check and make sure that's right.
    113   //
    114   if (AppPath[DirectorySlashOffset] != L'\\') {
    115     DEBUG ((DEBUG_ERROR, "%a - Could not find a single directory separator in app path.\n", __FUNCTION__));
    116     goto Exit;
     89  if (mCachePath == NULL) {
     90    AppPath = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE); // NOTE: This must be freed.
     91    if (AppPath == NULL) {
     92      goto Exit;
     93    }
     94
     95    DirectorySlashOffset = StrLen (AppPath);
     96    //
     97    // Make sure we didn't get any weird data.
     98    //
     99    if (DirectorySlashOffset == 0) {
     100      DEBUG ((DEBUG_ERROR, "%a - Weird 0-length string when processing app path.\n", __func__));
     101      goto Exit;
     102    }
     103
     104    //
     105    // Now that we know we have a decent string, let's take a deeper look.
     106    //
     107    do {
     108      if (AppPath[DirectorySlashOffset] == L'\\') {
     109        break;
     110      }
     111
     112      DirectorySlashOffset--;
     113    } while (DirectorySlashOffset > 0);
     114
     115    //
     116    // After that little maneuver, DirectorySlashOffset should be pointing at the last '\' in AppString.
     117    // That would be the path to the parent directory that the test app is executing from.
     118    // Let's check and make sure that's right.
     119    //
     120    if (AppPath[DirectorySlashOffset] != L'\\') {
     121      DEBUG ((DEBUG_ERROR, "%a - Could not find a single directory separator in app path.\n", __func__));
     122      goto Exit;
     123    }
     124  } else {
     125    AppPath = FullyQualifyPath (mCachePath); // NOTE: This must be freed.
     126    if (AppPath == NULL) {
     127      goto Exit;
     128    }
     129
     130    DirectorySlashOffset = StrLen (AppPath);
     131
     132    if (AppPath[DirectorySlashOffset - 1] != L'\\') {
     133      // Set the slash if user did not specify it on the newly allocated pool
     134      AppPath = ReallocatePool (
     135                  (DirectorySlashOffset + 1) * sizeof (CHAR16),
     136                  (DirectorySlashOffset + 2) * sizeof (CHAR16),
     137                  AppPath
     138                  );
     139      AppPath[DirectorySlashOffset]     = L'\\';
     140      AppPath[DirectorySlashOffset + 1] = L'\0';
     141    } else {
     142      // Otherwise the user input is good enough to go, mostly
     143      DirectorySlashOffset--;
     144    }
    117145  }
    118146
     
    136164  StrCatS (CacheFilePath, CacheFilePathLength, CACHE_FILE_SUFFIX);                   // Copy the file suffix.
    137165
    138   //
    139   // Finally, try to create the device path for the thing thing.
    140   //
    141   CacheFileDevicePath = FileDevicePath (LoadedImage->DeviceHandle, CacheFilePath);
    142 
    143166Exit:
    144167  //
     
    149172  }
    150173
    151   if (CacheFilePath != NULL) {
    152     FreePool (CacheFilePath);
    153   }
    154 
    155174  if (TestName != NULL) {
    156175    FreePool (TestName);
    157176  }
    158177
    159   return CacheFileDevicePath;
     178  return CacheFilePath;
    160179}
    161180
     
    176195  )
    177196{
    178   EFI_DEVICE_PATH_PROTOCOL  *FileDevicePath;
    179   EFI_STATUS                Status;
    180   SHELL_FILE_HANDLE         FileHandle;
     197  CHAR16             *FileName;
     198  EFI_STATUS         Status;
     199  SHELL_FILE_HANDLE  FileHandle;
    181200
    182201  //
    183202  // NOTE: This devpath is allocated and must be freed.
    184203  //
    185   FileDevicePath = GetCacheFileDevicePath (FrameworkHandle);
     204  FileName = GetCacheFileName (FrameworkHandle);
     205  if (FileName == NULL) {
     206    return FALSE;
     207  }
    186208
    187209  //
     
    189211  // reading, it exists.  Otherwise, probably not.
    190212  //
    191   Status = ShellOpenFileByDevicePath (
    192              &FileDevicePath,
     213  Status = ShellOpenFileByName (
     214             FileName,
    193215             &FileHandle,
    194216             EFI_FILE_MODE_READ,
     
    199221  }
    200222
    201   if (FileDevicePath != NULL) {
    202     FreePool (FileDevicePath);
    203   }
    204 
    205   DEBUG ((DEBUG_VERBOSE, "%a - Returning %d\n", __FUNCTION__, !EFI_ERROR (Status)));
     223  if (FileName != NULL) {
     224    FreePool (FileName);
     225  }
     226
     227  DEBUG ((DEBUG_VERBOSE, "%a - Returning %d\n", __func__, !EFI_ERROR (Status)));
    206228
    207229  return (!EFI_ERROR (Status));
     
    230252  )
    231253{
    232   EFI_DEVICE_PATH_PROTOCOL  *FileDevicePath;
    233   EFI_STATUS                Status;
    234   SHELL_FILE_HANDLE         FileHandle;
    235   UINTN                     WriteCount;
     254  CHAR16             *FileName;
     255  EFI_STATUS         Status;
     256  SHELL_FILE_HANDLE  FileHandle;
     257  UINTN              WriteCount;
    236258
    237259  //
     
    246268  // NOTE: This devpath is allocated and must be freed.
    247269  //
    248   FileDevicePath = GetCacheFileDevicePath (FrameworkHandle);
     270  FileName = GetCacheFileName (FrameworkHandle);
     271  if (FileName == NULL) {
     272    return EFI_INVALID_PARAMETER;
     273  }
    249274
    250275  //
    251276  // First lets open the file if it exists so we can delete it...This is the work around for truncation
    252277  //
    253   Status = ShellOpenFileByDevicePath (
    254              &FileDevicePath,
     278  Status = ShellOpenFileByName (
     279             FileName,
    255280             &FileHandle,
    256281             (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE),
     
    264289    Status = ShellDeleteFile (&FileHandle);
    265290    if (EFI_ERROR (Status)) {
    266       DEBUG ((DEBUG_ERROR, "%a failed to delete file %r\n", __FUNCTION__, Status));
     291      DEBUG ((DEBUG_ERROR, "%a failed to delete file %r\n", __func__, Status));
    267292    }
    268293  }
     
    271296  // Now that we know the path to the file... let's open it for writing.
    272297  //
    273   Status = ShellOpenFileByDevicePath (
    274              &FileDevicePath,
     298  Status = ShellOpenFileByName (
     299             FileName,
    275300             &FileHandle,
    276301             (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE),
     
    278303             );
    279304  if (EFI_ERROR (Status)) {
    280     DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __FUNCTION__, Status));
     305    DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __func__, Status));
    281306    goto Exit;
    282307  }
     
    286311  //
    287312  WriteCount = SaveStateSize;
    288   DEBUG ((DEBUG_INFO, "%a - Writing %d bytes to file...\n", __FUNCTION__, WriteCount));
     313  DEBUG ((DEBUG_INFO, "%a - Writing %d bytes to file...\n", __func__, WriteCount));
    289314  Status = ShellWriteFile (
    290315             FileHandle,
     
    294319
    295320  if (EFI_ERROR (Status) || (WriteCount != SaveStateSize)) {
    296     DEBUG ((DEBUG_ERROR, "%a - Writing to file failed! %r\n", __FUNCTION__, Status));
     321    DEBUG ((DEBUG_ERROR, "%a - Writing to file failed! %r\n", __func__, Status));
    297322  } else {
    298     DEBUG ((DEBUG_INFO, "%a - SUCCESS!\n", __FUNCTION__));
     323    DEBUG ((DEBUG_INFO, "%a - SUCCESS!\n", __func__));
    299324  }
    300325
     
    305330
    306331Exit:
    307   if (FileDevicePath != NULL) {
    308     FreePool (FileDevicePath);
     332  if (FileName != NULL) {
     333    FreePool (FileName);
    309334  }
    310335
     
    335360  )
    336361{
    337   EFI_STATUS                Status;
    338   EFI_DEVICE_PATH_PROTOCOL  *FileDevicePath;
    339   SHELL_FILE_HANDLE         FileHandle;
    340   BOOLEAN                   IsFileOpened;
    341   UINT64                    LargeFileSize;
    342   UINTN                     FileSize;
    343   VOID                      *Buffer;
     362  EFI_STATUS         Status;
     363  CHAR16             *FileName;
     364  SHELL_FILE_HANDLE  FileHandle;
     365  BOOLEAN            IsFileOpened;
     366  UINT64             LargeFileSize;
     367  UINTN              FileSize;
     368  VOID               *Buffer;
    344369
    345370  IsFileOpened = FALSE;
     
    357382  // NOTE: This devpath is allocated and must be freed.
    358383  //
    359   FileDevicePath = GetCacheFileDevicePath (FrameworkHandle);
     384  FileName = GetCacheFileName (FrameworkHandle);
     385  if (FileName == NULL) {
     386    return EFI_INVALID_PARAMETER;
     387  }
    360388
    361389  //
    362390  // Now that we know the path to the file... let's open it for writing.
    363391  //
    364   Status = ShellOpenFileByDevicePath (
    365              &FileDevicePath,
     392  Status = ShellOpenFileByName (
     393             FileName,
    366394             &FileHandle,
    367395             EFI_FILE_MODE_READ,
     
    369397             );
    370398  if (EFI_ERROR (Status)) {
    371     DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __FUNCTION__, Status));
     399    DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __func__, Status));
    372400    goto Exit;
    373401  } else {
     
    380408  Status = ShellGetFileSize (FileHandle, &LargeFileSize);
    381409  if (EFI_ERROR (Status)) {
    382     DEBUG ((DEBUG_ERROR, "%a - Failed to determine file size! %r\n", __FUNCTION__, Status));
     410    DEBUG ((DEBUG_ERROR, "%a - Failed to determine file size! %r\n", __func__, Status));
    383411    goto Exit;
    384412  }
     
    391419  Buffer         = AllocatePool (FileSize);
    392420  if (Buffer == NULL) {
    393     DEBUG ((DEBUG_ERROR, "%a - Failed to allocate a pool to hold the file contents! %r\n", __FUNCTION__, Status));
     421    DEBUG ((DEBUG_ERROR, "%a - Failed to allocate a pool to hold the file contents! %r\n", __func__, Status));
    394422    Status = EFI_OUT_OF_RESOURCES;
    395423    goto Exit;
     
    401429  Status = ShellReadFile (FileHandle, &FileSize, Buffer);
    402430  if (EFI_ERROR (Status)) {
    403     DEBUG ((DEBUG_ERROR, "%a - Failed to read the file contents! %r\n", __FUNCTION__, Status));
     431    DEBUG ((DEBUG_ERROR, "%a - Failed to read the file contents! %r\n", __func__, Status));
    404432  }
    405433
     
    408436  // Free allocated buffers
    409437  //
    410   if (FileDevicePath != NULL) {
    411     FreePool (FileDevicePath);
     438  if (FileName != NULL) {
     439    FreePool (FileName);
    412440  }
    413441
     
    427455  return Status;
    428456}
     457
     458/**
     459  Shell based UnitTestPersistenceLib library constructor.
     460
     461  @param[in]  ImageHandle  The firmware allocated handle for the EFI image.
     462  @param[in]  SystemTable  A pointer to the EFI System Table.
     463
     464  @retval EFI_SUCCESS      The constructor finished successfully.
     465  @retval Others           Error codes returned from gBS->HandleProtocol.
     466 **/
     467EFI_STATUS
     468EFIAPI
     469UnitTestPersistenceLibConstructor (
     470  IN EFI_HANDLE        ImageHandle,
     471  IN EFI_SYSTEM_TABLE  *SystemTable
     472  )
     473{
     474  UINTN                          Index;
     475  UINTN                          Argc;
     476  CHAR16                         **Argv;
     477  EFI_STATUS                     Status;
     478  EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters;
     479
     480  Status = gBS->HandleProtocol (
     481                  gImageHandle,
     482                  &gEfiShellParametersProtocolGuid,
     483                  (VOID **)&ShellParameters
     484                  );
     485  if (EFI_ERROR (Status)) {
     486    ASSERT_EFI_ERROR (Status);
     487    goto Done;
     488  }
     489
     490  Argc = ShellParameters->Argc;
     491  Argv = ShellParameters->Argv;
     492
     493  Status = EFI_SUCCESS;
     494  if ((Argc > 1) && (Argv != NULL)) {
     495    // This might be our cue, check for whether we need to do anything
     496    for (Index = 1; Index < Argc; Index++) {
     497      if (StrCmp (Argv[Index], L"--CachePath") == 0) {
     498        // Need to update the potential cache path to designated path
     499        if (Index < Argc - 1) {
     500          mCachePath = Argv[Index + 1];
     501        } else {
     502          Print (L"  --CachePath <Path of where to save unit test cache files, i.e. FS0:TestFolder>\n");
     503        }
     504      }
     505    }
     506  }
     507
     508Done:
     509  return Status;
     510}
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c

    r99404 r101291  
    103103  // Return last entry if no match found.
    104104  //
    105   DEBUG ((DEBUG_INFO, "%a Failure Type does not have string defined 0x%X\n", __FUNCTION__, (UINT32)Failure));
     105  DEBUG ((DEBUG_INFO, "%a Failure Type does not have string defined 0x%X\n", __func__, (UINT32)Failure));
    106106  return mFailureTypeStrings[Index].String;
    107107}
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.c

    r99404 r101291  
    2626  Length = UnicodeVSPrintAsciiFormat (String, sizeof (String), Format, Marker);
    2727  if (Length == 0) {
    28     DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __FUNCTION__));
     28    DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __func__));
    2929  } else {
    3030    gST->ConOut->OutputString (gST->ConOut, String);
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.c

    r99404 r101291  
    2525  Length = AsciiVSPrint (String, sizeof (String), Format, Marker);
    2626  if (Length == 0) {
    27     DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __FUNCTION__));
     27    DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __func__));
    2828  } else {
    2929    DEBUG ((DEBUG_INFO, String));
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/ReadMe.md

    r99404 r101291  
    2121
    2222The second unit test framework supported by the UnitTestFrameworkPkg is
    23 [GoogleTest](http://google.github.io/googletest/) that can be used to implement host-based unit tests.
    24 Use of GoogleTest for target-based unit tests of EDK II components is not supported. If a
    25 host-based unit test requires mocked interfaces, then the Framework with cmocka support should be
    26 used instead. Enabling support for mocked interfaces with GoogleTest is being actively investigated.
     23[GoogleTest](http://google.github.io/googletest/) and can be used to implement host-based unit tests.
    2724[GoogleTest on GitHub](https://github.com/google/googletest) is included in the UnitTestFrameworkPkg
    28 as a submodule.
     25as a submodule. Use of GoogleTest for target-based unit tests of EDK II components is not supported.
     26Host-based unit tests that require mocked interfaces can use the mocking infrastructure included with
     27GoogleTest called [gMock](https://github.com/google/googletest/tree/main/googlemock). Note that the
     28gMock framework does not directly support mocking of free (C style) functions, so the FunctionMockLib
     29(containing a set of macros that wrap gMock's MOCK_METHOD macro) was created within the
     30UnitTestFrameworkPkg to enable this support. The details and usage of these macros in the
     31FunctionMockLib are described later.
    2932
    3033GoogleTest requires less overhead to register test suites and test cases compared to the Framework.
     
    3437that may be used to implement, run, and debug unit tests implemented using GoogleTest.
    3538
    36 If a component can be tested with host-based unit tests without support for mocked interfaces,
    37 then GoogleTest is recommended. The MdePkg contains a port of the BaseSafeIntLib unit tests in
    38 the GoogleTest style so the differences between GoogleTest and Framework unit tests can be reviewed.
    39 The paths to the BaseSafeIntLib unit tests are:
    40 
    41 * MdePkg\Test\UnitTest\Library\BaseSafeIntLib
    42 * MdePkg\Test\GoogleTest\Library\BaseSafeIntLib
     39If a component can be tested with host-based unit tests, then GoogleTest is recommended. The MdePkg
     40contains a port of the BaseSafeIntLib unit tests in the GoogleTest style so the differences between
     41GoogleTest and Framework unit tests can be reviewed. The paths to the BaseSafeIntLib unit tests are:
     42
     43* `MdePkg/Test/UnitTest/Library/BaseSafeIntLib`
     44* `MdePkg/Test/GoogleTest/Library/BaseSafeIntLib`
     45
     46Furthermore, the SecurityPkg contains unit tests for the SecureBootVariableLib using mocks in both
     47the Framework/cmocka and GoogleTest/gMock style so the differences between cmocka and gMock can be
     48reviewed. The paths to the SecureBootVariableLib unit tests are:
     49
     50* `SecurityPkg/Library/SecureBootVariableLib/UnitTest`
     51* `SecurityPkg/Library/SecureBootVariableLib/GoogleTest`
    4352
    4453## Framework and GoogleTest Feature Comparison
     
    5766| Type-Parameterized Tests    |    NO     |    YES     |
    5867| Timeout Support             |    NO     |    YES     |
    59 | Mocking Support             |   Cmocka  |     NO     |
     68| Mocking Support             |   Cmocka  |   gMock    |
    6069| JUNIT XML Reports           |    YES    |    YES     |
    6170| Execute subset of tests     |    NO     |    YES     |
     
    105114how to check for expected conditions in test cases and a bit of the logging characteristics.
    106115
    107 Most of these examples will refer to the SampleUnitTestUefiShell app found in this package.
     116Most of these examples will refer to the `SampleUnitTestUefiShell` app found in this package.
    108117
    109118### Framework Requirements - INF
     
    114123you should be good to go.
    115124
    116 See this example in 'SampleUnitTestUefiShell.inf'...
     125See this example in `SampleUnitTestUefiShell.inf`...
    117126
    118127```
     
    128137```
    129138
    130 Also, if you want you test to automatically be picked up by the Test Runner plugin, you will need
     139Also, if you want your test to automatically be picked up by the Test Runner plugin, you will need
    131140to make sure that the module `BASE_NAME` contains the word `Test`...
    132141
     
    136145```
    137146
     147### Framework Requirements - DSC
     148
     149In our DSC file, we'll need to bring in the INF file that was just created into the `[Components]`
     150section so that the unit tests will be built.
     151
     152See this example in `UnitTestFrameworkPkg.dsc`...
     153
     154```
     155[Components]
     156  UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf
     157```
     158
     159Also, based on the type of tests that are being created, the associated DSC include file from the
     160UnitTestFrameworkPkg for Host or Target based tests should also be included at the top of the DSC
     161file.
     162
     163```
     164!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
     165```
     166
     167Lastly, in the case that the test build has specific dependent libraries associated with it,
     168they should be added in the \<LibraryClasses\> sub-section for the INF file in the
     169`[Components]` section of the DSC file.
     170
     171See this example in `SecurityPkgHostTest.dsc`...
     172
     173```
     174[Components]
     175  SecurityPkg/Library/SecureBootVariableLib/UnitTest/SecureBootVariableLibUnitTest.inf {
     176    <LibraryClasses>
     177      SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
     178      UefiRuntimeServicesTableLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf
     179      PlatformPKProtectionLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
     180      UefiLib|SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
     181  }
     182```
     183
    138184### Framework Requirements - Code
    139185
     
    144190```
    145191
    146 Now that we've got that squared away, let's look at our 'Main()'' routine (or DriverEntryPoint() or whatever).
     192Now that we've got that squared away, let's look at our 'Main()' routine (or DriverEntryPoint() or whatever).
    147193
    148194### Framework Configuration
     
    158204These strings are copied internally to the Framework, so using stack-allocated or literal strings is fine.
    159205
    160 In the 'SampleUnitTestUefiShell' app, the module name is used as the short name, so the initialization looks like this.
     206In the `SampleUnitTestUefiShell` app, the module name is used as the short name, so the initialization looks like this.
    161207
    162208```c
     
    185231`UNIT_TEST_SUITE_SETUP` and `UNIT_TEST_SUITE_TEARDOWN`.
    186232
    187 Looking at 'SampleUnitTestUefiShell' app, you can see that the first test suite is created as below...
     233Looking at `SampleUnitTestUefiShell` app, you can see that the first test suite is created as below...
    188234
    189235```c
     
    219265pointer, so it could be a simple value, or it could be a complex structure. If unneeded, pass `NULL`.
    220266
    221 In 'SampleUnitTestUefiShell' app, the first test case is added using the code below...
     267In `SampleUnitTestUefiShell` app, the first test case is added using the code below...
    222268
    223269```c
     
    283329https://api.cmocka.org/
    284330
     331## GoogleTest Libraries
     332
     333### GoogleTestLib
     334
     335GoogleTestLib is the core library used for GoogleTest in EDK II. This library is mainly a wrapper
     336around the GoogleTest and gMock header and source files. So all the standard
     337[GoogleTest](http://google.github.io/googletest/) and
     338[gMock](https://github.com/google/googletest/tree/main/googlemock) documentation for writing tests
     339and using mocks applies.
     340
     341Additionally, to support the use of some primitive types that are not directly supported by
     342GoogleTest and gMock (but are needed to allow gMock to be used in EDK II), some custom gMock
     343actions and matchers were added to GoogleTestLib. These customizations are briefly described in
     344the following tables.
     345
     346#### Custom Actions
     347
     348| Action Name | Similar gMock Generic Action | Usage |
     349|:--- |:--- |:--- |
     350| `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()` |
     351
     352#### Custom Matchers
     353
     354| Matcher Name | Similar gMock Generic Matcher | Usage |
     355|:--- |:--- |:--- |
     356| `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. |
     357| `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. |
     358
     359### FunctionMockLib
     360
     361FunctionMockLib is the library that allows gMock to be used with free (C style) functions. This
     362library contains a set of macros that wrap gMock's MOCK_METHOD macro to enable the standard gMock
     363capabilities to be used with free functions. The details of how this is implemented is outside the
     364scope of this document, but a brief description of each of the public macros in FunctionMockLib is
     365described below. A full example of how to use these macros to create a mock is described in a
     366later section.
     367
     368In total there are six public macros in FunctionMockLib. Four of the macros are related to creating
     369the mock functions, and the other two macros are related to creating an interface that is necessary
     370to contain the mock functions and connect them into the gMock framework.
     371
     372The macros used to create the interface are...
     3731. `MOCK_INTERFACE_DECLARATION(MOCK)`
     3742. `MOCK_INTERFACE_DEFINITION(MOCK)`
     375
     376These macros both take one argument which is the name of the interface for the mock. The
     377`MOCK_INTERFACE_DECLARATION` macro is used to declare the interface in the `.h` file and the
     378`MOCK_INTERFACE_DEFINITION` macro is used to define the interface in the `.cpp` file. For
     379example, to create a mock for the `UefiLib`, a `MockUefiLib.h` file would be created and the
     380below code would be added to it.
     381
     382```cpp
     383struct MockUefiLib {
     384  MOCK_INTERFACE_DECLARATION(MockUefiLib);
     385};
     386```
     387
     388Additionally, the below code would be written into a `MockUefiLib.cpp` file.
     389
     390```cpp
     391MOCK_INTERFACE_DEFINITION(MockUefiLib);
     392```
     393
     394The macros used to create the mock functions are...
     3951. `MOCK_FUNCTION_DECLARATION(RET_TYPE, FUNC, ARGS)`
     3962. `MOCK_FUNCTION_DEFINITION(MOCK, FUNC, NUM_ARGS, CALL_TYPE)`
     3973. `MOCK_FUNCTION_INTERNAL_DECLARATION(RET_TYPE, FUNC, ARGS)`
     3984. `MOCK_FUNCTION_INTERNAL_DEFINITION(MOCK, FUNC, NUM_ARGS, CALL_TYPE)`
     399
     400You will notice that there are two sets of macros: one to mock external functions and
     401another to mock internal functions. Each set of macros has the exact same arguments, but
     402they are used for slightly different use cases. The details of these different use cases
     403is described in detail in a later section. For now, we will focus on the usage of the macro
     404arguments since that is common between them.
     405
     406The `MOCK_FUNCTION_DECLARATION` macro is used to declare the mock function in the `.h` file,
     407and it takes three arguments: return type, function name, and argument list. The
     408`MOCK_FUNCTION_DEFINITION` macro is used to define the mock function in the `.cpp` file,
     409and it takes four arguments: name of the interface for the mock, function name, number of
     410arguments the function takes, and calling convention type of the function. For example, to
     411continue with the `UefiLib` mock example above, the `GetVariable2` and `GetEfiGlobalVariable2`
     412functions are declared in `UefiLib.h` as shown below.
     413
     414```cpp
     415EFI_STATUS
     416EFIAPI
     417GetVariable2 (
     418  IN CONST CHAR16    *Name,
     419  IN CONST EFI_GUID  *Guid,
     420  OUT VOID           **Value,
     421  OUT UINTN          *Size OPTIONAL
     422  );
     423
     424EFI_STATUS
     425EFIAPI
     426GetEfiGlobalVariable2 (
     427  IN CONST CHAR16  *Name,
     428  OUT VOID         **Value,
     429  OUT UINTN        *Size OPTIONAL
     430  );
     431```
     432
     433To declare mocks for these functions within the previously created `MockUefiLib` interface,
     434the below code would be added to the `MockUefiLib.h` file. Note that the previously added
     435interface declaration is also included in the code below for context.
     436
     437```cpp
     438struct MockUefiLib {
     439  MOCK_INTERFACE_DECLARATION (MockUefiLib);
     440
     441  MOCK_FUNCTION_DECLARATION (
     442    EFI_STATUS,
     443    GetVariable2,
     444    (IN CONST CHAR16    *Name,
     445     IN CONST EFI_GUID  *Guid,
     446     OUT VOID           **Value,
     447     OUT UINTN          *Size OPTIONAL)
     448    );
     449
     450  MOCK_FUNCTION_DECLARATION (
     451    EFI_STATUS,
     452    GetEfiGlobalVariable2,
     453    (IN CONST CHAR16  *Name,
     454     OUT VOID         **Value,
     455     OUT UINTN        *Size OPTIONAL)
     456    );
     457};
     458```
     459
     460Additionally, the below code would be added into the `MockUefiLib.cpp` file to provide
     461the definitions for these mock functions. Again, the previously added interface
     462definition is also included in the code below for context.
     463
     464```cpp
     465MOCK_INTERFACE_DEFINITION(MockUefiLib);
     466
     467MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, EFIAPI);
     468MOCK_FUNCTION_DEFINITION(MockUefiLib, GetEfiGlobalVariable2, 3, EFIAPI);
     469```
     470
     471That concludes the basic overview on how to use the macros, but a more detailed
     472description on how to name the mocks, where to put the files, how to build the
     473mocks, and how to use the mocks is described in detail later.
     474
     475### SubhookLib
     476
     477SubhookLib is the library used by FunctionMockLib to implement the macros to
     478mock internal functions: `MOCK_FUNCTION_INTERNAL_DECLARATION` and
     479`MOCK_FUNCTION_INTERNAL_DEFINITION`. These macros require the additional
     480functionality provided by SubhookLib because they create mock functions
     481for functions that are already defined and compiled within the module being
     482tested. More detail on this is provided in a later section, but for now it is
     483sufficient to know that the SubhookLib allows a second definition of the
     484function to be compiled into the test application and then hooked to during a
     485test.
     486
     487This library is mainly a wrapper around the
     488[subhook](https://github.com/Zeex/subhook) header and source files. It is
     489important to note that the use of the mock function macros and the creation
     490of mock functions requires no knowledge about the SubhookLib. The SubhookLib
     491library is entirely hidden and encapsulated within FunctionMockLib, and it
     492is only mentioned here to provide a complete explanation on all the libraries
     493used in the implementation.
     494
     495## FunctionMockLib Mocks
     496
     497This section describes the details on how to use the mock function macros in
     498FunctionMockLib to create mock functions, name them, organize their files,
     499and build them so that they can be used within GoogleTest tests. The usage
     500of the mock functions is detailed in a later section while this section
     501simply details how to create them, build them, and where to put them.
     502
     503### FunctionMockLib Mocks - External vs. Internal
     504
     505The first question to ask when creating a mock function is if the function being
     506mocked is external or internal to the module being tested. This is very important
     507because the macros in FunctionMockLib used to create the mock function are named
     508differently for these two use cases. Fortunately, the arguments to these macros
     509and the usage of the mock functions within the tests are exactly the same.
     510However, because of the different underlying implementations, two different sets
     511of macros are used.
     512
     513A more detailed description of when to use the external vs. internal mock function
     514macros is in the following sections, but the quick summary is as follows.
     515
     516* External mock function macros are used to mock functions that are outside the
     517module being tested and use link-time replacement.
     518* Internal mock function macros are used to mock functions that are inside the
     519module being tested and use run-time replacement.
     520
     521The below table shows which macros to use in these two use cases. However, note that
     522for the creation of the interface, the same macros are used in both cases.
     523
     524| Mock Function Use Case | Mock Interface Macros | Mock Function Macros |
     525|:--- |:--- |:--- |
     526| External mock functions | `MOCK_INTERFACE_DECLARATION`</br>`MOCK_INTERFACE_DEFINITION` | `MOCK_FUNCTION_DECLARATION`</br>`MOCK_FUNCTION_DEFINITION` |
     527| Internal mock functions | `MOCK_INTERFACE_DECLARATION`</br>`MOCK_INTERFACE_DEFINITION` | `MOCK_FUNCTION_INTERNAL_DECLARATION`</br>`MOCK_FUNCTION_INTERNAL_DEFINITION` |
     528
     529#### FunctionMockLib Mocks - External mock function
     530
     531The external mock function macros are used to create mock function definitions
     532for a library, global service, or protocol that is defined outside of the module
     533being tested. These mock function definitions are linked into the test application
     534instead of linking in the design function definitions. In other words, the
     535external mock function macros use link-time replacement of the design functions.
     536
     537The `.h/.cpp` files for these mock functions are created within the package
     538directory where the library, global table, or protocol that is being mocked is
     539declared. These files are compiled into their own separate library (using
     540an INF file) that can be shared and linked into many test applications, but more
     541on that later.
     542
     543#### FunctionMockLib Mocks - Internal mock function
     544
     545The internal mock function macros are used to create mock function definitions
     546for functions that are defined within the module being tested. These mock
     547function definitions are compiled into the test application along with the design
     548function definitions. This is possible because the mock functions are given a
     549slightly different name during compilation. Then during test execution, the
     550design function is hooked and replaced with the mock function. In other words,
     551the internal mock function macros use run-time replacement of the design
     552functions.
     553
     554The `.h/.cpp` files for these mock functions are created within the GoogleTest
     555directory containing the specific tests that are using them. These files are
     556compiled directly in the GoogleTest INF file that builds the test application,
     557and they are not shared outside of that GoogleTest directory, but more on that
     558later.
     559
     560### FunctionMockLib Mocks - Declaration
     561
     562The declaration of mock functions using the FunctionMockLib macros are done
     563in header files. The name of the header file is determined by the interface
     564(such as a library or a protocol) that is being created for the mock functions.
     565The rules for naming the file are shown in the table below.
     566
     567| Interface Type | Header File Name |
     568| :--- | :--- |
     569| Library | Mock\<LibraryName\>Lib.h |
     570| Global Table (e.g. gRT, gBS, etc.) | Mock\<GlobalTableLibraryName\>Lib.h |
     571| Protocol | Mock\<ProtocolName\>Protocol.h |
     572
     573The below table shows examples for file names with each of the above cases.
     574
     575| Interface Type | Interface Name | Header File Name |
     576| :--- | :--- | :--- |
     577| Library | UefiLib | MockUefiLib.h |
     578| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MockUefiRuntimeServicesTableLib.h |
     579| Protocol | EFI_USB_IO_PROTOCOL | MockEfiUsbIoProtocol.h |
     580
     581Once the header file name is known, the file needs to be created in the proper
     582location. For internal mock functions, the location is simply the same
     583GoogleTest directory that contains the INF file that builds the test application.
     584For external mock functions, the location is within the `Test` directory under the
     585package where the library, global table, or protocol that is being mocked is
     586declared. The exact location depends on the interface type and is shown in the
     587below table.
     588
     589| Interface Type | Header File Location |
     590| :--- | :--- |
     591| Library | \<PackageName\>/Test/Mock/Include/GoogleTest/Library |
     592| Global Table (e.g. gRT, gBS, etc.) | \<PackageName\>/Test/Mock/Include/GoogleTest/Library |
     593| Protocol | \<PackageName\>/Test/Mock/Include/GoogleTest/Protocol |
     594
     595The below table shows examples for file locations with each of the above cases.
     596
     597| Interface Type | Interface Name | Header File Location |
     598| :--- | :--- | :--- |
     599| Library | UefiLib | MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiLib.h |
     600| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h |
     601| Protocol | EFI_USB_IO_PROTOCOL | MdePkg/Test/Mock/Include/GoogleTest/Protocol/MockEfiUsbIoProtocol.h |
     602
     603Now that the file location is known, the contents can be added to it. After the
     604standard `#ifndef` for a header file is added at the top of the file, the
     605`GoogleTestLib.h` and `FunctionMockLib.h` files are always added. Following these
     606includes other EDK II related include files are added and must be wrapped in
     607`extern "C" {}` because they are C include files. Failure to do this will cause
     608link errors to occur. Note that a `#include` of the interface being mocked must
     609also be added. This causes the declarations of the functions being mocked to be
     610included in the compilation and allows the compilation to verify that the function
     611signatures of the mock and design functions are identical.
     612
     613After all the needed includes have been added in the file , a `struct` is declared
     614using the same name as the header file (which was determined using the rules
     615above). Within this structure declaration a `MOCK_INTERFACE_DECLARATION` is
     616added along with a `MOCK_FUNCTION_DECLARATION` (or a
     617`MOCK_FUNCTION_INTERNAL_DECLARATION` if this interface is for internal mock
     618functions) for each function in the interface. To build on the examples above,
     619the complete `MockUefiLib.h` file would be as shown below. Note that for brevity
     620only the `GetVariable2` and `GetEfiGlobalVariable2` declarations are included in
     621the example.
     622
     623```cpp
     624#ifndef MOCK_UEFI_LIB_H_
     625#define MOCK_UEFI_LIB_H_
     626
     627#include <Library/GoogleTestLib.h>
     628#include <Library/FunctionMockLib.h>
     629extern "C" {
     630  #include <Uefi.h>
     631  #include <Library/UefiLib.h>
     632}
     633
     634struct MockUefiLib {
     635  MOCK_INTERFACE_DECLARATION (MockUefiLib);
     636
     637  MOCK_FUNCTION_DECLARATION (
     638    EFI_STATUS,
     639    GetVariable2,
     640    (IN CONST CHAR16    *Name,
     641     IN CONST EFI_GUID  *Guid,
     642     OUT VOID           **Value,
     643     OUT UINTN          *Size OPTIONAL)
     644    );
     645
     646  MOCK_FUNCTION_DECLARATION (
     647    EFI_STATUS,
     648    GetEfiGlobalVariable2,
     649    (IN CONST CHAR16  *Name,
     650     OUT VOID         **Value,
     651     OUT UINTN        *Size OPTIONAL)
     652    );
     653};
     654
     655#endif
     656```
     657
     658In the case of libraries, the function names in the mock declarations
     659align exactly with the function names in the design. However, in the
     660case of global tables and protocols, to eliminate possible function
     661name collisions, the names are adjusted slightly in the mock
     662declarations as shown in the below table.
     663
     664| Mock Function Use Case | Design Function Name | Mock Function Name |
     665| :--- | :--- | :--- |
     666| Library | GetVariable2 | GetVariable2  |
     667| Global Table (e.g. gRT, gBS, etc.) | gRT->GetVariable | gRT_GetVariable |
     668| Protocol | UsbIoProtocol->UsbPortReset | UsbIoProtocol_UsbPortReset |
     669
     670Lastly, when creating mock functions, there are two limitations to be
     671aware of in gMock that extend into FunctionMockLib.
     672
     6731. gMock does not support mocking functions that have more than 15 arguments.
     6742. gMock does not support mocking variadic functions.
     675
     676With those limitations in mind, that completes the mock function
     677declarations, and now the mock function definitions for those declarations
     678can be created.
     679
     680### FunctionMockLib Mocks - Definition
     681
     682The definition of mock functions using the FunctionMockLib macros are done
     683in source files. The name of the source file is determined by the interface
     684(such as a library or a protocol) that is being created for the mock functions.
     685The rules for naming the file align with the naming of the file for declarations
     686and are shown in the table below.
     687
     688| Interface Type | Source File Name |
     689| :--- | :--- |
     690| Library | Mock\<LibraryName\>Lib.cpp |
     691| Global Table (e.g. gRT, gBS, etc.) | Mock\<GlobalTableLibraryName\>Lib.cpp |
     692| Protocol | Mock\<ProtocolName\>Protocol.cpp |
     693
     694The below table shows examples for file names with each of the above cases.
     695
     696| Interface Type | Interface Name | Source File Name |
     697| :--- | :--- | :--- |
     698| Library | UefiLib | MockUefiLib.cpp |
     699| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MockUefiRuntimeServicesTableLib.cpp |
     700| Protocol | EFI_USB_IO_PROTOCOL | MockEfiUsbIoProtocol.cpp |
     701
     702Once the source file name is known, the file needs to be created in the proper
     703location. The location of the source file is aligned with the location for the
     704header file. For internal mock functions, the location is simply the same
     705GoogleTest directory that contains the INF file that builds the test application.
     706For external mock functions, the location is within the `Test` directory under the
     707package where the library, global table, or protocol that is being mocked is
     708declared. The exact location depends on the interface type and is shown in the
     709below table.
     710
     711| Interface Type | Source File Location |
     712| :--- | :--- |
     713| Library | \<PackageName\>/Test/Mock/Library/GoogleTest/Mock\<LibraryName\>Lib |
     714| Global Table (e.g. gRT, gBS, etc.) | \<PackageName\>/Test/Mock/Library/GoogleTest/Mock\<GlobalTableLibraryName\>Lib |
     715| Protocol | \<PackageName\>/Test/Mock/Library/GoogleTest/Mock\<ProtocolName\>Protocol |
     716
     717The below table shows examples for file locations with each of the above cases.
     718
     719| Interface Type | Interface Name | Source File Location |
     720| :--- | :--- | :--- |
     721| Library | UefiLib | MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.cpp |
     722| Global Table (e.g. gRT, gBS, etc.) | UefiRuntimeServicesTableLib | MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp |
     723| Protocol | EFI_USB_IO_PROTOCOL | MdePkg/Test/Mock/Library/GoogleTest/MockEfiUsbIoProtocol/MockEfiUsbIoProtocol.cpp |
     724
     725Now that the file location is known, the contents can be added to it. At the top
     726of the file, the header file containing the mock function declarations is always
     727added. After this `#include`, the interface definition is created using
     728`MOCK_INTERFACE_DEFINITION` with the interface name that was used in the mock
     729function declaration header file. A `MOCK_FUNCTION_DEFINITION` is then added (or
     730a `MOCK_FUNCTION_INTERNAL_DEFINITION` if this interface is for internal mock
     731functions) for each function that was declared in the interface. To build on the
     732prior declaration examples, the complete `MockUefiLib.cpp` file would be as shown
     733below. Note that for brevity only the `GetVariable2` and `GetEfiGlobalVariable2`
     734definitions are included in the example.
     735
     736```cpp
     737#include <GoogleTest/Library/MockUefiLib.h>
     738
     739MOCK_INTERFACE_DEFINITION(MockUefiLib);
     740
     741MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, EFIAPI);
     742MOCK_FUNCTION_DEFINITION(MockUefiLib, GetEfiGlobalVariable2, 3, EFIAPI);
     743```
     744
     745When creating the defintions, there are a few things to keep in mind.
     746
     747First, when using `MOCK_FUNCTION_DEFINITION`, some functions being mocked do
     748not specify a calling convention. In this case, it is fine to leave the last
     749argument of `MOCK_FUNCTION_DEFINITION` empty. For example, if `GetVariable2`
     750did not specify the `EFIAPI` calling convention in its declaration, then the
     751below code would be used for the mock function definition.
     752
     753```cpp
     754MOCK_FUNCTION_DEFINITION(MockUefiLib, GetVariable2, 4, );
     755```
     756
     757Second, the function name used in `MOCK_FUNCTION_DEFINITION` must align with
     758the function name used in the associated `MOCK_FUNCTION_DECLARATION` in the
     759header file.
     760
     761Last, if the interface is mocking a global table or protocol, then the structure
     762of function pointers for that interface must also be defined within the source
     763file as a `static` structure with the mock function definitions being assigned
     764to the associated entries in the structure. The address of this `static`
     765structure is then assigned to the global table or protocol pointer. Note that
     766this pointer must be wrapped in `extern "C" {}` because it needs C style
     767linkage. Failure to do this will cause link errors to occur. For example, when
     768creating the definition of the mock for the global runtime services table, the
     769complete `MockUefiRuntimeServicesTableLib.cpp` file would be as shown below.
     770Note that for brevity only the `GetVariable` and `SetVariable` definitions are
     771included in the example.
     772
     773```cpp
     774#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
     775
     776MOCK_INTERFACE_DEFINITION(MockUefiRuntimeServicesTableLib);
     777
     778MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_GetVariable, 5, EFIAPI);
     779MOCK_FUNCTION_DEFINITION(MockUefiRuntimeServicesTableLib, gRT_SetVariable, 5, EFIAPI);
     780
     781static EFI_RUNTIME_SERVICES localRt = {
     782  {0},              // EFI_TABLE_HEADER
     783
     784  NULL,             // EFI_GET_TIME
     785  NULL,             // EFI_SET_TIME
     786  NULL,             // EFI_GET_WAKEUP_TIME
     787  NULL,             // EFI_SET_WAKEUP_TIME
     788
     789  NULL,             // EFI_SET_VIRTUAL_ADDRESS_MAP
     790  NULL,             // EFI_CONVERT_POINTER
     791
     792  gRT_GetVariable,  // EFI_GET_VARIABLE
     793  NULL,             // EFI_GET_NEXT_VARIABLE_NAME
     794  gRT_SetVariable,  // EFI_SET_VARIABLE
     795
     796  NULL,             // EFI_GET_NEXT_HIGH_MONO_COUNT
     797  NULL,             // EFI_RESET_SYSTEM
     798
     799  NULL,             // EFI_UPDATE_CAPSULE
     800  NULL,             // EFI_QUERY_CAPSULE_CAPABILITIES
     801
     802  NULL,             // EFI_QUERY_VARIABLE_INFO
     803};
     804
     805extern "C" {
     806  EFI_RUNTIME_SERVICES* gRT = &localRt;
     807}
     808```
     809
     810That completes the mock function definitions. So now these mock function
     811definitions can be compiled.
     812
     813### FunctionMockLib Mocks - Build
     814
     815The building of mock functions using FunctionMockLib is done slightly
     816differently for external and internal function mocks. External mock
     817functions are built using their own separate INF file and internal mock
     818functions are built as source files directly referenced in the GoogleTest
     819INF file that builds the test application.
     820
     821#### FunctionMockLib Mocks - Build External Mock Functions
     822
     823The building of external mock functions is done using their own separate INF
     824file which is placed in the same location as the associated source file
     825containing the mock function definitions. The name of the INF file is exactly
     826the same as the mock function definitions file, but uses the `.inf` extension
     827rather than `.cpp`.
     828
     829Within the `.inf` file the `BASE_NAME` should be set to the same name as the
     830file (minus the extension), the `MODULE_TYPE` should be set to
     831`HOST_APPLICATION`, and the `LIBRARY_CLASS` should be the same as the
     832`BASE_NAME` but without the `Mock` prefix.
     833
     834The `[Sources]` section will contain the single mock function definition
     835source file, the `[Packages]` section will contain all the necessary DEC
     836files to compile the mock functions (which at a minimum will include the
     837`UnitTestFrameworkPkg.dec` file), the `[LibraryClasses]` section will contain
     838the `GoogleTestLib`, and the `[BuildOptions]` will need to append the `/EHsc`
     839compilation flag to all MSFT builds to enable proper use of the C++ exception
     840handler. Below is the complete `MockUefiLib.inf` as an example.
     841
     842```
     843[Defines]
     844  INF_VERSION                    = 0x00010005
     845  BASE_NAME                      = MockUefiLib
     846  FILE_GUID                      = 47211F7A-6D90-4DFB-BDF9-610B69197C2E
     847  MODULE_TYPE                    = HOST_APPLICATION
     848  VERSION_STRING                 = 1.0
     849  LIBRARY_CLASS                  = UefiLib
     850
     851#
     852# The following information is for reference only and not required by the build tools.
     853#
     854#  VALID_ARCHITECTURES           = IA32 X64
     855#
     856
     857[Sources]
     858  MockUefiLib.cpp
     859
     860[Packages]
     861  MdePkg/MdePkg.dec
     862  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
     863
     864[LibraryClasses]
     865  GoogleTestLib
     866
     867[BuildOptions]
     868  MSFT:*_*_*_CC_FLAGS = /EHsc
     869```
     870
     871To ensure that this specific set of mock functions are always buildable even
     872if no test uses it yet, this created INF file needs to be added into the
     873`[Components]` section of the associated `Test` DSC file for the package in
     874which this INF file resides. For example, the above `MockUefiLib.inf` would
     875need to be added to the `MdePkg/Test/MdePkgHostTest.dsc` file as shown below.
     876
     877```
     878[Components]
     879  MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
     880```
     881
     882This created INF file will also be referenced within the necessary `Test` DSC
     883files in order to include the mock function definitions in the test
     884applications which use this set of mock functions, but more on that later.
     885
     886One small additional requirement is that if this INF file is added into a
     887package that does not yet have any other external mock functions in it, then
     888that package's DEC file will need to have the mock include directory (more
     889specifically the `Test/Mock/Include` directory) added to its `[Includes]`
     890section so that test files who want to use the mock functions will be able to
     891locate the mock function header file. For example, if `MockUefiLib.inf` were
     892the first mock added to the `MdePkg`, then the below snippet would need to be
     893added to the `MdePkg.dec` file.
     894
     895```
     896[Includes]
     897  Test/Mock/Include
     898```
     899
     900#### FunctionMockLib Mocks - Build Internal Mock Functions
     901
     902The building of internal mock functions is done using the GoogleTest INF file
     903that already needs to exist to build the test application. This is easy to
     904manage since the source and header files for the internal mock functions are
     905also located in the same GoogleTest directory as the GoogleTest INF file that
     906will reference them.
     907
     908The only additions that are required to the GoogleTest INF file are that the
     909mock function definitions file be added to the `[Sources]` section, the
     910`UnitTestFrameworkPkg.dec` file be added to the `[Packages]` section, and the
     911`GoogleTestLib` and `SubhookLib` be added to the `[LibraryClasses]` section.
     912Below is a minimal contrived example for a `MyModuleGoogleTest.inf` that uses a
     913`MockMyModuleInternalFunctions.cpp` source file for its internal mock functions.
     914
     915```
     916[Defines]
     917  INF_VERSION         = 0x00010017
     918  BASE_NAME           = MyModuleGoogleTest
     919  FILE_GUID           = 814B09B9-2D51-4786-8A77-2E10CD1C55F3
     920  VERSION_STRING      = 1.0
     921  MODULE_TYPE         = HOST_APPLICATION
     922
     923#
     924# The following information is for reference only and not required by the build tools.
     925#
     926#  VALID_ARCHITECTURES           = IA32 X64
     927#
     928
     929[Sources]
     930  MyModuleGoogleTest.cpp
     931  MockMyModuleInternalFunctions.cpp
     932
     933[Packages]
     934  MdePkg/MdePkg.dec
     935  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
     936
     937[LibraryClasses]
     938  GoogleTestLib
     939  SubhookLib
     940```
     941
    285942## GoogleTest Samples
    286943
     
    292949needing a target.
    293950
     951There is also a sample unit test provided as both an example of how to write a unit test with
     952mock functions and leverage some of the gMock features. This sample can be found in the
     953`SecurityPkg/Library/SecureBootVariableLib/GoogleTest` directory.
     954
     955It too is provided for the HOST_APPLICATION build type, which can be run on a host system without
     956needing a target.
     957
    294958## GoogleTest Usage
    295959
     
    298962how to check for expected conditions in test cases and a bit of the logging characteristics.
    299963
    300 Most of these examples will refer to the SampleGoogleTestHost app found in this package.
     964Most of these examples will refer to the `SampleGoogleTestHost` app found in this package, but
     965the examples related to mock functions will refer to the `SecureBootVariableLibGoogleTest` app
     966found in the `SecurityPkg`.
    301967
    302968### GoogleTest Requirements - INF
    303969
    304 In our INF file, we'll need to bring in the `GoogleTest` library. Conveniently, the interface
    305 header for the `GoogleTest` is in `UnitTestFrameworkPkg`, so you shouldn't need to depend on any other
     970In our INF file, we'll need to bring in the `GoogleTestLib` library. Conveniently, the interface
     971header for the `GoogleTestLib` is in `UnitTestFrameworkPkg`, so you shouldn't need to depend on any other
    306972packages. As long as your DSC file knows where to find the lib implementation that you want to use,
    307973you should be good to go.
    308974
    309 See this example in 'SampleGoogleTestHost.inf'...
     975See this example in `SampleGoogleTestHost.inf`...
    310976
    311977```
     
    320986```
    321987
    322 Also, if you want you test to automatically be picked up by the Test Runner plugin, you will need
     988Also, if you want your test to automatically be picked up by the Test Runner plugin, you will need
    323989to make sure that the module `BASE_NAME` contains the word `Test`...
    324990
     
    328994```
    329995
     996### GoogleTest Requirements - DSC
     997
     998In our DSC file, we'll need to bring in the INF file that was just created into the `[Components]`
     999section so that the unit tests will be built.
     1000
     1001See this example in `UnitTestFrameworkPkgHostTest.dsc`...
     1002
     1003```
     1004[Components]
     1005  UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTest/SampleGoogleTestHost.inf
     1006```
     1007
     1008Also, based on the type of tests that are being created, the associated DSC include file from the
     1009UnitTestFrameworkPkg for Host or Target based tests should also be included at the top of the DSC
     1010file.
     1011
     1012```
     1013!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
     1014```
     1015
     1016Lastly, in the case that the test build has specific dependent libraries associated with it,
     1017they should be added in the \<LibraryClasses\> sub-section for the INF file in the
     1018`[Components]` section of the DSC file. Note that it is within this sub-section where you can
     1019control whether the design or mock version of a component is linked into the test exectuable.
     1020
     1021See this example in `SecurityPkgHostTest.dsc` where the `SecureBootVariableLib` design is
     1022being tested using mock versions of `UefiRuntimeServicesTableLib`, `PlatformPKProtectionLib`,
     1023and `UefiLib`...
     1024
     1025```
     1026[Components]
     1027  SecurityPkg/Library/SecureBootVariableLib/GoogleTest/SecureBootVariableLibGoogleTest.inf {
     1028    <LibraryClasses>
     1029      SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
     1030      UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
     1031      PlatformPKProtectionLib|SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
     1032      UefiLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiLib/MockUefiLib.inf
     1033  }
     1034```
     1035
    3301036### GoogleTest Requirements - Code
    3311037
    332 Not to state the obvious, but let's make sure we have the following include before getting too far along...
    333 
    334 ```
    335 #include <gtest/gtest.h>
     1038GoogleTest applications are implemented in C++, so make sure that your test file has
     1039a `.cpp` extension. With that behind us, not to state the obvious, but let's make sure
     1040we have the following includes before getting too far along in the file...
     1041
     1042```cpp
     1043#include <Library/GoogleTestLib.h>
    3361044extern "C" {
    3371045  #include <Uefi.h>
     
    3411049```
    3421050
    343 GoogleTest applications are implemented in C++. The first include brings in the
    344 GoogleTest definitions. Other EDK II related include files must be wrapped in
    345 `extern "C" {}` because they are C include files. Link failures will occur if
    346 this is not done.
    347 
    348 Now that we've got that squared away, let's look at our 'Main()'' routine (or DriverEntryPoint() or whatever).
     1051The first include brings in the GoogleTest definitions. Other EDK II related include
     1052files must be wrapped in `extern "C" {}` because they are C include files. Link
     1053failures will occur if this is not done.
     1054
     1055Also, when using GoogleTest it is helpful to add a `using` declaration for its
     1056`testing` namespace. This `using` statement greatly reduces the amount of code you
     1057need to write in the tests when referencing the utilities within the `testing`
     1058namespace. For example, instead of writing `::testing::Return` or `::testing::Test`,
     1059you can just write `Return` or `Test` respectively, and these types of references
     1060occur numerous times within the tests.
     1061
     1062Lastly, in the case that tests within a GoogleTest application require the usage of
     1063mock functions, it is also necessary to include the header files for those interfaces
     1064as well. As an example, the `SecureBootVariableLibGoogleTest` uses the mock versions
     1065of `UefiLib` and `UefiRuntimeServicesTableLib`. So its test file contains the below
     1066includes. Note that the `using` declaration mentioned above is also shown in the code
     1067below for completeness of the example.
     1068
     1069```cpp
     1070#include <Library/GoogleTestLib.h>
     1071#include <GoogleTest/Library/MockUefiLib.h>
     1072#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
     1073
     1074extern "C" {
     1075  #include <Uefi.h>
     1076  ...
     1077}
     1078
     1079using namespace testing;
     1080```
     1081
     1082Now that we've got that squared away, let's look at our 'Main()' routine (or DriverEntryPoint() or whatever).
    3491083
    3501084### GoogleTest Configuration
     
    3531087be registered. Instead, the test cases declare the test suite name and test
    3541088case name as part of their implementation. The only requirement for GoogleTest
    355 is to have a `main()` function that initialize the GoogleTest infrastructure and
    356 call the service `RUN_ALL_TESTS()` to run all the unit tests.
    357 
    358 ```c
     1089is to have a `main()` function that initializes the GoogleTest infrastructure
     1090and calls the service `RUN_ALL_TESTS()` to run all the unit tests.
     1091
     1092```cpp
    3591093int main(int argc, char* argv[]) {
    3601094  testing::InitGoogleTest(&argc, argv);
     
    3631097```
    3641098
     1099However, while GoogleTest does not require test suites or test cases to be
     1100registered, there is still one rule within EDK II that currently needs to be
     1101followed. This rule is that all tests for a given GoogleTest application must
     1102be contained within the same source file that contains the `main()` function
     1103shown above. These tests can be written directly in the file or a `#include`
     1104can be used to add them into the file indirectly.
     1105
     1106The reason for this is due to EDK II taking the host application INF file and
     1107first compiling all of its source files into a static library. This static
     1108library is then linked into the final host application. The problem with this
     1109method is that only the tests in the object file containing the `main()`
     1110function are linked into the final host application. This is because the other
     1111tests are contained in their own object files within the static library and
     1112they have no symbols in them that the final host application depends on, so
     1113those object files are not linked into the final host application.
     1114
    3651115### GoogleTest - A Simple Test Case
    3661116
    367 We'll look at the below test case from 'SampleGoogleTestHost'...
    368 
    369 ```c
     1117Below is a sample test case from `SampleGoogleTestHost`.
     1118
     1119```cpp
    3701120TEST(SimpleMathTests, OnePlusOneShouldEqualTwo) {
    3711121  UINTN  A;
     
    3941144_Note_ that this early return can have implications for memory leakage.
    3951145
    396 There is no return status from a GooglTest unit test. If no assertions are
     1146For most `ASSERT` macros in GoogleTest there is also an equivalent `EXPECT` macro. Both macro versions
     1147will ultimately cause the `TEST` to fail if the check fails. However, the difference between the two
     1148macro versions is that when the check fails, the `ASSERT` version immediately returns from the `TEST`
     1149while the `EXPECT` version continues running the `TEST`.
     1150
     1151There is no return status from a GooglTest unit test. If no assertions (or expectations) are
    3971152triggered then the unit test has a passing status.
     1153
     1154### GoogleTest - A gMock Test Case
     1155
     1156Below is a sample test case from `SecureBootVariableLibGoogleTest`. Although
     1157actually, the test case is not written exactly like this in the test file, but
     1158more on that in a bit.
     1159
     1160```cpp
     1161TEST(SetSecureBootModeTest, SetVarError) {
     1162  MockUefiRuntimeServicesTableLib RtServicesMock;
     1163  UINT8                           SecureBootMode;
     1164  EFI_STATUS                      Status;
     1165
     1166  // Any random magic number can be used for these tests
     1167  SecureBootMode = 0xAB;
     1168
     1169  EXPECT_CALL(RtServicesMock, gRT_SetVariable)
     1170    .WillOnce(Return(EFI_INVALID_PARAMETER));
     1171
     1172  Status = SetSecureBootMode(SecureBootMode);
     1173  EXPECT_EQ(Status, EFI_INVALID_PARAMETER);
     1174}
     1175```
     1176
     1177Keep in mind that this test is written to verify that `SetSecureBootMode()` will
     1178return `EFI_INVALID_PARAMETER` when the call to `gRT->SetVariable()` within the
     1179implementation of `SetSecureBootMode()` returns `EFI_INVALID_PARAMETER`. With that
     1180in mind, let's discuss how a mock function is used to accomplish this in the test.
     1181
     1182In this test case, the `MockUefiRuntimeServicesTableLib` interface is instantiated as
     1183`RtServicesMock` which enables its associated mock functions. These interface
     1184instantiations that contain the mock functions are very important for mock function
     1185based unit tests because without these instantiations, the mock functions within that
     1186interface will not exist and can not be used.
     1187
     1188The next line of interest is the `EXPECT_CALL`, which is a standard part of the gMock
     1189framework. This macro is telling the test that a call is expected to occur to a
     1190specific function on a specific interface. The first argument is the name of the
     1191interface object that was instantiated in this test, and the second argument is the
     1192name of the mock function within that interface that is expected to be called. The
     1193`WillOnce(Return(EFI_INVALID_PARAMETER))` associated with this `EXPECT_CALL` states
     1194that the `gRT_SetVariable()` function (remember from earlier in this documentation
     1195that this refers to the `gRT->SetVariable()` function) will be called once during
     1196this test, and when it does get called, we want it to return `EFI_INVALID_PARAMETER`.
     1197
     1198Once this `EXPECT_CALL` has been setup, the call to `SetSecureBootMode()` occurs in
     1199the test, and its return value is saved in `Status` so that it can be tested. Based
     1200on the `EXPECT_CALL` that was setup earlier, when `SetSecureBootMode()` internally
     1201calls `gRT->SetVariable()`, it returns `EFI_INVALID_PARAMETER`. This value should
     1202then be returned by `SetSecureBootMode()`, and the
     1203`EXPECT_EQ(Status, EFI_INVALID_PARAMETER)` verifies this is the case.
     1204
     1205There is much more that can be done with `EXPECT_CALL` and mock functions, but we
     1206will leave those details to be explained in the gMock documentation.
     1207
     1208Now it was mentioned earlier that this test case is not written exactly like this
     1209in the test file, and the next section describes how this test is slightly
     1210refactored to reduce the total amount of code in the entire test suite.
     1211
     1212### GoogleTest - A gMock Test Case (refactored)
     1213
     1214The sample test case from `SecureBootVariableLibGoogleTest` in the prior section is
     1215actually written as shown below.
     1216
     1217```cpp
     1218class SetSecureBootModeTest : public Test {
     1219  protected:
     1220    MockUefiRuntimeServicesTableLib RtServicesMock;
     1221    UINT8       SecureBootMode;
     1222    EFI_STATUS  Status;
     1223
     1224    void SetUp() override {
     1225      // Any random magic number can be used for these tests
     1226      SecureBootMode = 0xAB;
     1227    }
     1228};
     1229
     1230TEST_F(SetSecureBootModeTest, SetVarError) {
     1231  EXPECT_CALL(RtServicesMock, gRT_SetVariable)
     1232    .WillOnce(Return(EFI_INVALID_PARAMETER));
     1233
     1234  Status = SetSecureBootMode(SecureBootMode);
     1235  EXPECT_EQ(Status, EFI_INVALID_PARAMETER);
     1236}
     1237```
     1238
     1239This code may at first seem more complicated, but you will notice that the code
     1240with in it is still the same. There is still a `MockUefiRuntimeServicesTableLib`
     1241instantiation, there is still a `SecureBootMode` and `Status` variable defined,
     1242there is still an `EXPECT_CALL`, and etc. However, the benefit of constructing
     1243the test this way is that the new `TEST_F()` requires less code than the prior
     1244`TEST()`.
     1245
     1246This is made possible by the usage of what GoogleTest calls a _test fixture_.
     1247This concept of a test fixture allows multiple tests to use (or more specifically
     1248inherit from a base class) a common set of variables and initial conditions.
     1249Notice that using `TEST_F()` requires the first argument to be a name that aligns
     1250with a test fixture (in this case `SetSecureBootModeTest`), and the second
     1251argument is the name of the test (just like in the `TEST()` macro).
     1252
     1253All `TEST_F()` tests that use a specific test fixture can be thought of as having
     1254all of that test fixture's variables automatically defined in the test as well as
     1255having that text fixture's `SetUp()` function called before entering the test.
     1256
     1257This means that another `TEST_F()` can be written without needing to worry about
     1258defining a bunch of variables or instantiating a bunch of interfaces for mock
     1259functions. For example, the below test (also in `SecureBootVariableLibGoogleTest`)
     1260uses the same test fixture and makes use of its `RtServicesMock`, `Status`, and
     1261`SecureBootMode` variables.
     1262
     1263```cpp
     1264TEST_F(SetSecureBootModeTest, PropogateModeToSetVar) {
     1265  EXPECT_CALL(RtServicesMock,
     1266    gRT_SetVariable(
     1267      Char16StrEq(EFI_CUSTOM_MODE_NAME),
     1268      BufferEq(&gEfiCustomModeEnableGuid, sizeof(EFI_GUID)),
     1269      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
     1270      sizeof(SecureBootMode),
     1271      BufferEq(&SecureBootMode, sizeof(SecureBootMode))))
     1272    .WillOnce(Return(EFI_SUCCESS));
     1273
     1274  Status = SetSecureBootMode(SecureBootMode);
     1275  EXPECT_EQ(Status, EFI_SUCCESS);
     1276}
     1277```
     1278
     1279The biggest benefit is that the `TEST_F()` code can now focus on what is being
     1280tested and not worry about any repetitive setup. There is more that can be done
     1281with test fixtures, but we will leave those details to be explained in the
     1282gMock documentation.
     1283
     1284Now, as for what is in the above test, it is slightly more complicated than the
     1285first test. So let's explain this added complexity and what it is actually
     1286testing. In this test, there is still an `EXPECT_CALL` for the
     1287`gRT_SetVariable()` function. However, in this test we are stating that we
     1288expect the input arguments passed to `gRT_SetVariable()` be specific values.
     1289The order they are provided in the `EXPECT_CALL` align with the order of the
     1290arguments in the `gRT_SetVariable()` function. In this case the order of the
     1291`gRT_SetVariable()` arguments is as shown below.
     1292
     1293```cpp
     1294IN  CHAR16                       *VariableName,
     1295IN  EFI_GUID                     *VendorGuid,
     1296IN  UINT32                       Attributes,
     1297IN  UINTN                        DataSize,
     1298IN  VOID                         *Data
     1299```
     1300
     1301So in the `EXPECT_CALL` we are stating that the call to `gRT_SetVariable()`
     1302will be made with the below input argument values.
     1303
     13041. `VariableName` is equal to the `EFI_CUSTOM_MODE_NAME` string
     13052. `VendorGuid` is equal to the `gEfiCustomModeEnableGuid` GUID (which has a byte length of `sizeof(EFI_GUID)`)
     13063. `Attributes` is equal to `EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS`
     13074. `DataSize` is equal to `sizeof(SecureBootMode)`
     13085. `Data` is equal to `SecureBootMode` (which has a byte length of `sizeof(SecureBootMode)`)
     1309
     1310If any one of these input arguments does not match in the actual call to
     1311`gRT_SetVariable()` in the design, then the test will fail. There is much more
     1312that can be done with `EXPECT_CALL` and mock functions, but again we will
     1313leave those details to be explained in the gMock documentation.
    3981314
    3991315### GoogleTest - More Complex Cases
     
    5881504Host based Unit Tests will automatically enable coverage data.
    5891505
    590 For Windows, This is primarily leverage for pipeline builds, but this can be leveraged locally using the
     1506For Windows, this is primarily leveraged for pipeline builds, but this can be leveraged locally using the
    5911507OpenCppCoverage windows tool to parse coverage data to cobertura xml format.
    5921508
     
    6081524
    6091525
    610 For Linux, This is primarily leveraged for pipeline builds, but this can be leveraged locally using the
     1526For Linux, this is primarily leveraged for pipeline builds, but this can be leveraged locally using the
    6111527lcov linux tool, and parsed using the lcov_cobertura python tool to parse it to cobertura xml format.
    6121528
     
    6551571Code/Test                                   | Location
    6561572---------                                   | --------
    657 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`
    658 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/`
     1573Host-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`
     1574Host-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/`
    6591575Host-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.
    6601576Non-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.
     
    7141630        GeneralPurposeLibHostUnitTest.inf
    7151631
     1632    Mock/
     1633      Include/
     1634        GoogleTest/
     1635          Library/
     1636            MockGeneralPurposeLib.h
     1637
     1638      Library/
     1639        GoogleTest/
     1640          MockGeneralPurposeLib/
     1641            MockGeneralPurposeLib.cpp
     1642            MockGeneralPurposeLib.inf
     1643
    7161644  <Package>Pkg.dsc          # Standard Modules and any Target-Based Test Apps (including in Test/)
    717 
    7181645```
    7191646
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTest.dsc

    r99404 r101291  
    3333  #
    3434  UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
     35  UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
    3536  UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
    3637  UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
    3738  UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
     39  UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
    3840  UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml

    r99404 r101291  
    8080        "IgnoreFiles": [             # use gitignore syntax to ignore errors in matching files
    8181            "Library/CmockaLib/cmocka/**/*.*",  # not going to spell check a submodule
    82             "Library/GoogleTestLib/googletest/**/*.*"  # not going to spell check a submodule
     82            "Library/GoogleTestLib/googletest/**/*.*",  # not going to spell check a submodule
     83            "Library/SubhookLib/subhook/**/*.*"  # not going to spell check a submodule
    8384        ],
    8485        "ExtendWords": [             # words to extend to the dictionary for this package
     86            "Pointee",
     87            "gmock",
     88            "GMOCK",
     89            "DSUBHOOK",
    8590            "testcase",
    8691            "testsuites",
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec

    r99404 r101291  
    2121  Library/GoogleTestLib/googletest/googletest/include
    2222  Library/GoogleTestLib/googletest/googlemock/include
     23  Library/SubhookLib/subhook
    2324
    2425[Includes.Common.Private]
     
    2627  Library/CmockaLib/cmocka/include/cmockery
    2728  Library/GoogleTestLib/googletest/googletest
     29  Library/GoogleTestLib/googletest/googlemock
    2830
    2931[LibraryClasses]
     
    3537  #
    3638  GoogleTestLib|Include/Library/GoogleTestLib.h
     39  SubhookLib|Include/Library/SubhookLib.h
     40  FunctionMockLib|Include/Library/FunctionMockLib.h
    3741
    3842[LibraryClasses.Common.Private]
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc

    r99404 r101291  
    3636  UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
    3737  UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf
     38  UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf
    3839
    3940  UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf
  • trunk/src/VBox/Devices/EFI/FirmwareNew/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc

    r99404 r101291  
    1616  CmockaLib|UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf
    1717  GoogleTestLib|UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf
     18  SubhookLib|UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf
     19  FunctionMockLib|UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf
    1820  UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf
    1921  DebugLib|UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf
    2022  MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
    2123  UefiBootServicesTableLib|UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf
     24  PeiServicesTablePointerLib|UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf
    2225
    2326[BuildOptions]
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette