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