]> git.proxmox.com Git - mirror_edk2.git/blob - UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c
UnitTestFrameworkPkg/Library: Add library instances
[mirror_edk2.git] / UnitTestFrameworkPkg / Library / UnitTestResultReportLib / UnitTestResultReportLib.c
1 /** @file
2 Implement UnitTestResultReportLib doing plain txt out to console
3
4 Copyright (c) Microsoft Corporation.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 **/
7
8 #include <Uefi.h>
9 #include <Library/UnitTestResultReportLib.h>
10 #include <Library/BaseLib.h>
11 #include <Library/DebugLib.h>
12
13 VOID
14 ReportPrint (
15 IN CONST CHAR8 *Format,
16 ...
17 );
18
19 VOID
20 ReportOutput (
21 IN CONST CHAR8 *Output
22 );
23
24 struct _UNIT_TEST_STATUS_STRING {
25 UNIT_TEST_STATUS Status;
26 CHAR8 *String;
27 };
28
29 struct _UNIT_TEST_FAILURE_TYPE_STRING {
30 FAILURE_TYPE Type;
31 CHAR8 *String;
32 };
33
34 struct _UNIT_TEST_STATUS_STRING mStatusStrings[] = {
35 { UNIT_TEST_PASSED, "PASSED"},
36 { UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, "NOT RUN - PREREQUISITE FAILED"},
37 { UNIT_TEST_ERROR_TEST_FAILED, "FAILED"},
38 { UNIT_TEST_RUNNING, "RUNNING"},
39 { UNIT_TEST_PENDING, "PENDING"},
40 { 0, "**UNKNOWN**"}
41 };
42
43 struct _UNIT_TEST_FAILURE_TYPE_STRING mFailureTypeStrings[] = {
44 { FAILURETYPE_NOFAILURE, "NO FAILURE"},
45 { FAILURETYPE_OTHER, "OTHER FAILURE"},
46 { FAILURETYPE_ASSERTTRUE, "ASSERT_TRUE FAILURE"},
47 { FAILURETYPE_ASSERTFALSE, "ASSERT_FALSE FAILURE"},
48 { FAILURETYPE_ASSERTEQUAL, "ASSERT_EQUAL FAILURE"},
49 { FAILURETYPE_ASSERTNOTEQUAL, "ASSERT_NOTEQUAL FAILURE"},
50 { FAILURETYPE_ASSERTNOTEFIERROR, "ASSERT_NOTEFIERROR FAILURE"},
51 { FAILURETYPE_ASSERTSTATUSEQUAL, "ASSERT_STATUSEQUAL FAILURE"},
52 { FAILURETYPE_ASSERTNOTNULL , "ASSERT_NOTNULL FAILURE"},
53 { 0, "*UNKNOWN* Failure"}
54 };
55
56 //
57 // TEST REPORTING FUNCTIONS
58 //
59
60 STATIC
61 CONST CHAR8*
62 GetStringForUnitTestStatus (
63 IN UNIT_TEST_STATUS Status
64 )
65 {
66 UINTN Index;
67
68 for (Index = 0; Index < ARRAY_SIZE (mStatusStrings); Index++) {
69 if (mStatusStrings[Index].Status == Status) {
70 //
71 // Return string from matching entry
72 //
73 return mStatusStrings[Index].String;
74 }
75 }
76 //
77 // Return last entry if no match found.
78 //
79 return mStatusStrings[Index].String;
80 }
81
82 STATIC
83 CONST CHAR8*
84 GetStringForFailureType (
85 IN FAILURE_TYPE Failure
86 )
87 {
88 UINTN Index;
89
90 for (Index = 0; Index < ARRAY_SIZE (mFailureTypeStrings); Index++) {
91 if (mFailureTypeStrings[Index].Type == Failure) {
92 //
93 // Return string from matching entry
94 //
95 return mFailureTypeStrings[Index].String;
96 }
97 }
98 //
99 // Return last entry if no match found.
100 //
101 DEBUG((DEBUG_INFO, "%a Failure Type does not have string defined 0x%X\n", __FUNCTION__, (UINT32)Failure));
102 return mFailureTypeStrings[Index].String;
103 }
104
105 /*
106 Method to print the Unit Test run results
107
108 @retval Success
109 */
110 EFI_STATUS
111 EFIAPI
112 OutputUnitTestFrameworkReport (
113 IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
114 )
115 {
116 UNIT_TEST_FRAMEWORK *Framework;
117 INTN Passed;
118 INTN Failed;
119 INTN NotRun;
120 UNIT_TEST_SUITE_LIST_ENTRY *Suite;
121 UNIT_TEST_LIST_ENTRY *Test;
122 INTN SPassed;
123 INTN SFailed;
124 INTN SNotRun;
125
126 Passed = 0;
127 Failed = 0;
128 NotRun = 0;
129 Suite = NULL;
130
131 Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
132 if (Framework == NULL) {
133 return EFI_INVALID_PARAMETER;
134 }
135
136 ReportPrint ("---------------------------------------------------------\n");
137 ReportPrint ("------------- UNIT TEST FRAMEWORK RESULTS ---------------\n");
138 ReportPrint ("---------------------------------------------------------\n");
139
140 //print the version and time
141
142 //
143 // Iterate all suites
144 //
145 for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY*)GetFirstNode(&Framework->TestSuiteList);
146 (LIST_ENTRY*)Suite != &Framework->TestSuiteList;
147 Suite = (UNIT_TEST_SUITE_LIST_ENTRY*)GetNextNode(&Framework->TestSuiteList, (LIST_ENTRY*)Suite)) {
148
149 Test = NULL;
150 SPassed = 0;
151 SFailed = 0;
152 SNotRun = 0;
153
154 ReportPrint ("/////////////////////////////////////////////////////////\n");
155 ReportPrint (" SUITE: %a\n", Suite->UTS.Title);
156 ReportPrint (" PACKAGE: %a\n", Suite->UTS.Name);
157 ReportPrint ("/////////////////////////////////////////////////////////\n");
158
159 //
160 // Iterate all tests within the suite
161 //
162 for (Test = (UNIT_TEST_LIST_ENTRY*)GetFirstNode(&(Suite->UTS.TestCaseList));
163 (LIST_ENTRY*)Test != &(Suite->UTS.TestCaseList);
164 Test = (UNIT_TEST_LIST_ENTRY*)GetNextNode(&(Suite->UTS.TestCaseList), (LIST_ENTRY*)Test)) {
165
166 ReportPrint ("*********************************************************\n");
167 ReportPrint (" CLASS NAME: %a\n", Test->UT.Name);
168 ReportPrint (" TEST: %a\n", Test->UT.Description);
169 ReportPrint (" STATUS: %a\n", GetStringForUnitTestStatus (Test->UT.Result));
170 ReportPrint (" FAILURE: %a\n", GetStringForFailureType (Test->UT.FailureType));
171 ReportPrint (" FAILURE MESSAGE:\n%a\n", Test->UT.FailureMessage);
172
173 if (Test->UT.Log != NULL) {
174 ReportPrint (" LOG:\n");
175 ReportOutput (Test->UT.Log);
176 }
177
178 switch (Test->UT.Result) {
179 case UNIT_TEST_PASSED:
180 SPassed++;
181 break;
182 case UNIT_TEST_ERROR_TEST_FAILED:
183 SFailed++;
184 break;
185 case UNIT_TEST_PENDING: // Fall through...
186 case UNIT_TEST_RUNNING: // Fall through...
187 case UNIT_TEST_ERROR_PREREQUISITE_NOT_MET:
188 SNotRun++;
189 break;
190 default:
191 break;
192 }
193 ReportPrint ("**********************************************************\n");
194 } //End Test iteration
195
196 ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
197 ReportPrint ("Suite Stats\n");
198 ReportPrint (" Passed: %d (%d%%)\n", SPassed, (SPassed * 100)/(SPassed+SFailed+SNotRun));
199 ReportPrint (" Failed: %d (%d%%)\n", SFailed, (SFailed * 100) / (SPassed + SFailed + SNotRun));
200 ReportPrint (" Not Run: %d (%d%%)\n", SNotRun, (SNotRun * 100) / (SPassed + SFailed + SNotRun));
201 ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" );
202
203 Passed += SPassed; //add to global counters
204 Failed += SFailed; //add to global counters
205 NotRun += SNotRun; //add to global counters
206 }//End Suite iteration
207
208 ReportPrint ("=========================================================\n");
209 ReportPrint ("Total Stats\n");
210 ReportPrint (" Passed: %d (%d%%)\n", Passed, (Passed * 100) / (Passed + Failed + NotRun));
211 ReportPrint (" Failed: %d (%d%%)\n", Failed, (Failed * 100) / (Passed + Failed + NotRun));
212 ReportPrint (" Not Run: %d (%d%%)\n", NotRun, (NotRun * 100) / (Passed + Failed + NotRun));
213 ReportPrint ("=========================================================\n" );
214
215 return EFI_SUCCESS;
216 }