Log.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /**
  2. Implemnet UnitTestLib log services
  3. Copyright (c) Microsoft Corporation.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <PiDxe.h>
  7. #include <UnitTestFrameworkTypes.h>
  8. #include <Library/UnitTestLib.h>
  9. #include <Library/BaseLib.h>
  10. #include <Library/BaseMemoryLib.h>
  11. #include <Library/MemoryAllocationLib.h>
  12. #include <Library/DebugLib.h>
  13. #include <Library/PrintLib.h>
  14. #include <Library/PcdLib.h>
  15. #define UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH (512)
  16. #define UNIT_TEST_MAX_LOG_BUFFER SIZE_16KB
  17. struct _UNIT_TEST_LOG_PREFIX_STRING {
  18. UNIT_TEST_STATUS LogLevel;
  19. CHAR8 *String;
  20. };
  21. struct _UNIT_TEST_LOG_PREFIX_STRING mLogPrefixStrings[] = {
  22. { UNIT_TEST_LOG_LEVEL_ERROR, "[ERROR] " },
  23. { UNIT_TEST_LOG_LEVEL_WARN, "[WARNING] " },
  24. { UNIT_TEST_LOG_LEVEL_INFO, "[INFO] " },
  25. { UNIT_TEST_LOG_LEVEL_VERBOSE, "[VERBOSE] " }
  26. };
  27. //
  28. // Unit-Test Log helper functions
  29. //
  30. STATIC
  31. CONST CHAR8 *
  32. GetStringForStatusLogPrefix (
  33. IN UINTN LogLevel
  34. )
  35. {
  36. UINTN Index;
  37. CHAR8 *Result;
  38. Result = NULL;
  39. for (Index = 0; Index < ARRAY_SIZE (mLogPrefixStrings); Index++) {
  40. if (mLogPrefixStrings[Index].LogLevel == LogLevel) {
  41. Result = mLogPrefixStrings[Index].String;
  42. break;
  43. }
  44. }
  45. return Result;
  46. }
  47. STATIC
  48. EFI_STATUS
  49. AddStringToUnitTestLog (
  50. IN OUT UNIT_TEST *UnitTest,
  51. IN CONST CHAR8 *String
  52. )
  53. {
  54. EFI_STATUS Status;
  55. //
  56. // Make sure that you're cooking with gas.
  57. //
  58. if ((UnitTest == NULL) || (String == NULL)) {
  59. return EFI_INVALID_PARAMETER;
  60. }
  61. // If this is the first log for the test allocate log space
  62. if (UnitTest->Log == NULL) {
  63. UnitTestLogInit (UnitTest, NULL, 0);
  64. }
  65. if (UnitTest->Log == NULL) {
  66. DEBUG ((DEBUG_ERROR, "Failed to allocate space for unit test log\n"));
  67. ASSERT (UnitTest->Log != NULL);
  68. return EFI_OUT_OF_RESOURCES;
  69. }
  70. Status = AsciiStrnCatS (
  71. UnitTest->Log,
  72. UNIT_TEST_MAX_LOG_BUFFER / sizeof (CHAR8),
  73. String,
  74. UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH
  75. );
  76. if (EFI_ERROR (Status)) {
  77. DEBUG ((DEBUG_ERROR, "Failed to add unit test log string. Status = %r\n", Status));
  78. return Status;
  79. }
  80. return EFI_SUCCESS;
  81. }
  82. /**
  83. This function is responsible for initializing the log buffer for a single test. It can
  84. be used internally, but may also be consumed by the test framework to add pre-existing
  85. data to a log before it's used.
  86. @param[in,out] TestHandle A handle to the test being initialized.
  87. @param[in] Buffer [Optional] A pointer to pre-existing log data that should
  88. be used to initialize the log. Should include a NULL terminator.
  89. @param[in] BufferSize [Optional] The size of the pre-existing log data.
  90. **/
  91. VOID
  92. EFIAPI
  93. UnitTestLogInit (
  94. IN OUT UNIT_TEST *Test,
  95. IN UINT8 *Buffer OPTIONAL,
  96. IN UINTN BufferSize OPTIONAL
  97. )
  98. {
  99. //
  100. // Make sure that you're cooking with gas.
  101. //
  102. if (Test == NULL) {
  103. DEBUG ((DEBUG_ERROR, "%a called with invalid Test parameter\n", __FUNCTION__));
  104. return;
  105. }
  106. //
  107. // If this is the first log for the test allocate log space
  108. //
  109. if (Test->Log == NULL) {
  110. Test->Log = AllocateZeroPool (UNIT_TEST_MAX_LOG_BUFFER);
  111. }
  112. //
  113. // check again to make sure allocate worked
  114. //
  115. if (Test->Log == NULL) {
  116. DEBUG ((DEBUG_ERROR, "Failed to allocate memory for the log\n"));
  117. return;
  118. }
  119. if ((Buffer != NULL) && (BufferSize > 0) && (BufferSize <= UNIT_TEST_MAX_LOG_BUFFER)) {
  120. CopyMem (Test->Log, Buffer, BufferSize);
  121. }
  122. }
  123. /**
  124. Test logging function that records a messages in the test framework log.
  125. Record is associated with the currently executing test case.
  126. @param[in] ErrorLevel The error level of the unit test log message.
  127. @param[in] Format Formatting string following the format defined in the
  128. MdePkg/Include/Library/PrintLib.h.
  129. @param[in] ... Print args.
  130. **/
  131. VOID
  132. EFIAPI
  133. UnitTestLog (
  134. IN UINTN ErrorLevel,
  135. IN CONST CHAR8 *Format,
  136. ...
  137. )
  138. {
  139. UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle;
  140. CHAR8 NewFormatString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH];
  141. CHAR8 LogString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH];
  142. CONST CHAR8 *LogTypePrefix;
  143. VA_LIST Marker;
  144. FrameworkHandle = GetActiveFrameworkHandle ();
  145. LogTypePrefix = NULL;
  146. //
  147. // Make sure that this unit test log level is enabled.
  148. //
  149. if ((ErrorLevel & (UINTN)PcdGet32 (PcdUnitTestLogLevel)) == 0) {
  150. return;
  151. }
  152. //
  153. // If we need to define a new format string...
  154. // well... get to it.
  155. //
  156. LogTypePrefix = GetStringForStatusLogPrefix (ErrorLevel);
  157. if (LogTypePrefix != NULL) {
  158. AsciiSPrint (NewFormatString, sizeof (NewFormatString), "%a%a", LogTypePrefix, Format);
  159. } else {
  160. AsciiStrCpyS (NewFormatString, sizeof (NewFormatString), Format);
  161. }
  162. //
  163. // Convert the message to an ASCII String
  164. //
  165. VA_START (Marker, Format);
  166. AsciiVSPrint (LogString, sizeof (LogString), NewFormatString, Marker);
  167. VA_END (Marker);
  168. //
  169. // Finally, add the string to the log.
  170. //
  171. AddStringToUnitTestLog (((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest, LogString);
  172. }