TianoCore EDK2 master
Loading...
Searching...
No Matches
UnitTestLib.c
1
9#include <Uefi.h>
10#include <Library/UnitTestLib.h>
11#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
17
22VOID
23UpdateTestFromSave (
25 IN UNIT_TEST_SAVE_HEADER *SavedState
26 );
27
41BOOLEAN
42IsFrameworkShortNameValid (
43 IN CHAR8 *ShortTitleString
44 )
45{
46 // TODO: Finish this function.
47 return TRUE;
48}
49
51CHAR8 *
52AllocateAndCopyString (
53 IN CHAR8 *StringToCopy
54 )
55{
56 CHAR8 *NewString;
57 UINTN NewStringLength;
58
60 NewStringLength = AsciiStrnLenS (StringToCopy, UNIT_TEST_MAX_STRING_LENGTH) + 1;
61 NewString = AllocatePool (NewStringLength * sizeof (CHAR8));
62 if (NewString != NULL) {
63 AsciiStrCpyS (NewString, NewStringLength, StringToCopy);
64 }
65
66 return NewString;
67}
68
70VOID
71SetFrameworkFingerprint (
72 OUT UINT8 *Fingerprint,
73 IN UNIT_TEST_FRAMEWORK *Framework
74 )
75{
76 UINT32 NewFingerprint;
77
78 // For this one we'll just use the title and version as the unique fingerprint.
79 NewFingerprint = CalculateCrc32 (Framework->Title, (AsciiStrLen (Framework->Title) * sizeof (CHAR8)));
80 NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Framework->VersionString, (AsciiStrLen (Framework->VersionString) * sizeof (CHAR8)));
81
82 CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE);
83 return;
84}
85
87VOID
88SetSuiteFingerprint (
89 OUT UINT8 *Fingerprint,
90 IN UNIT_TEST_FRAMEWORK *Framework,
91 IN UNIT_TEST_SUITE *Suite
92 )
93{
94 UINT32 NewFingerprint;
95
96 // For this one, we'll use the fingerprint from the framework, and the title of the suite.
97 NewFingerprint = CalculateCrc32 (&Framework->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
98 NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Suite->Title, (AsciiStrLen (Suite->Title) * sizeof (CHAR8)));
99 NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Suite->Name, (AsciiStrLen (Suite->Name) * sizeof (CHAR8)));
100
101 CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE);
102 return;
103}
104
105STATIC
106VOID
107SetTestFingerprint (
108 OUT UINT8 *Fingerprint,
109 IN UNIT_TEST_SUITE *Suite,
111 )
112{
113 UINT32 NewFingerprint;
114
115 // For this one, we'll use the fingerprint from the suite, and the description and classname of the test.
116 NewFingerprint = CalculateCrc32 (&Suite->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
117 NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Test->Description, (AsciiStrLen (Test->Description) * sizeof (CHAR8)));
118 NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Test->Name, (AsciiStrLen (Test->Name) * sizeof (CHAR8)));
119
120 CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE);
121 return;
122}
123
124STATIC
125BOOLEAN
126CompareFingerprints (
127 IN UINT8 *FingerprintA,
128 IN UINT8 *FingerprintB
129 )
130{
131 return (CompareMem (FingerprintA, FingerprintB, UNIT_TEST_FINGERPRINT_SIZE) == 0);
132}
133
149EFIAPI
151 IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
152 )
153{
154 // TODO: Finish this function.
155 return EFI_SUCCESS;
156}
157
158STATIC
160FreeUnitTestSuiteEntry (
162 )
163{
164 // TODO: Finish this function.
165 return EFI_SUCCESS;
166}
167
168STATIC
170FreeUnitTestTestEntry (
171 IN UNIT_TEST_LIST_ENTRY *TestEntry
172 )
173{
174 // TODO: Finish this function.
175 return EFI_SUCCESS;
176}
177
203EFIAPI
205 OUT UNIT_TEST_FRAMEWORK_HANDLE *FrameworkHandle,
206 IN CHAR8 *Title,
207 IN CHAR8 *ShortTitle,
208 IN CHAR8 *VersionString
209 )
210{
211 EFI_STATUS Status;
212 UNIT_TEST_FRAMEWORK_HANDLE NewFrameworkHandle;
213 UNIT_TEST_FRAMEWORK *NewFramework;
214 UINTN SaveStateSize;
215
216 Status = EFI_SUCCESS;
217 NewFramework = NULL;
218
219 //
220 // First, check all pointers and make sure nothing's broked.
221 //
222 if ((FrameworkHandle == NULL) || (Title == NULL) ||
223 (ShortTitle == NULL) || (VersionString == NULL))
224 {
225 return EFI_INVALID_PARAMETER;
226 }
227
228 //
229 // Next, determine whether all of the strings are good to use.
230 //
231 if (!IsFrameworkShortNameValid (ShortTitle)) {
232 return EFI_INVALID_PARAMETER;
233 }
234
235 //
236 // Next, set aside some space to start messing with the framework.
237 //
238 NewFramework = AllocateZeroPool (sizeof (UNIT_TEST_FRAMEWORK));
239 if (NewFramework == NULL) {
240 return EFI_OUT_OF_RESOURCES;
241 }
242
243 //
244 // Next, set up all the test data.
245 //
246 NewFrameworkHandle = (UNIT_TEST_FRAMEWORK_HANDLE)NewFramework;
247 NewFramework->Title = AllocateAndCopyString (Title);
248 NewFramework->ShortTitle = AllocateAndCopyString (ShortTitle);
249 NewFramework->VersionString = AllocateAndCopyString (VersionString);
250 NewFramework->Log = NULL;
251 NewFramework->CurrentTest = NULL;
252 NewFramework->SavedState = NULL;
253 if ((NewFramework->Title == NULL) ||
254 (NewFramework->ShortTitle == NULL) ||
255 (NewFramework->VersionString == NULL))
256 {
257 Status = EFI_OUT_OF_RESOURCES;
258 goto Exit;
259 }
260
261 InitializeListHead (&(NewFramework->TestSuiteList));
262
263 //
264 // Create the framework fingerprint.
265 //
266 SetFrameworkFingerprint (&NewFramework->Fingerprint[0], NewFramework);
267
268 //
269 // If there is a persisted context, load it now.
270 //
271 if (DoesCacheExist (NewFrameworkHandle)) {
272 Status = LoadUnitTestCache (NewFrameworkHandle, (VOID **)(&NewFramework->SavedState), &SaveStateSize);
273 if (EFI_ERROR (Status)) {
274 //
275 // Don't actually report it as an error, but emit a warning.
276 //
277 DEBUG ((DEBUG_ERROR, "%a - Cache was detected, but failed to load.\n", __func__));
278 Status = EFI_SUCCESS;
279 }
280 }
281
282Exit:
283 //
284 // If we're good, then let's copy the framework.
285 //
286 if (!EFI_ERROR (Status)) {
287 *FrameworkHandle = NewFrameworkHandle;
288 } else {
289 //
290 // Otherwise, we need to undo this horrible thing that we've done.
291 //
292 FreeUnitTestFramework (NewFrameworkHandle);
293 }
294
295 return Status;
296}
297
325EFIAPI
327 OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle,
328 IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
329 IN CHAR8 *Title,
330 IN CHAR8 *Name,
331 IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL,
332 IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL
333 )
334{
335 EFI_STATUS Status;
336 UNIT_TEST_SUITE_LIST_ENTRY *NewSuiteEntry;
337 UNIT_TEST_FRAMEWORK *Framework;
338
339 Status = EFI_SUCCESS;
340 Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
341
342 //
343 // First, let's check to make sure that our parameters look good.
344 //
345 if ((SuiteHandle == NULL) || (Framework == NULL) || (Title == NULL) || (Name == NULL)) {
346 return EFI_INVALID_PARAMETER;
347 }
348
349 //
350 // Create the new entry.
351 //
352 NewSuiteEntry = AllocateZeroPool (sizeof (UNIT_TEST_SUITE_LIST_ENTRY));
353 if (NewSuiteEntry == NULL) {
354 return EFI_OUT_OF_RESOURCES;
355 }
356
357 //
358 // Copy the fields we think we need.
359 //
360 NewSuiteEntry->UTS.NumTests = 0;
361 NewSuiteEntry->UTS.Title = AllocateAndCopyString (Title);
362 NewSuiteEntry->UTS.Name = AllocateAndCopyString (Name);
363 NewSuiteEntry->UTS.Setup = Setup;
364 NewSuiteEntry->UTS.Teardown = Teardown;
365 NewSuiteEntry->UTS.ParentFramework = FrameworkHandle;
366 InitializeListHead (&(NewSuiteEntry->Entry)); // List entry for sibling suites.
367 InitializeListHead (&(NewSuiteEntry->UTS.TestCaseList)); // List entry for child tests.
368 if (NewSuiteEntry->UTS.Title == NULL) {
369 Status = EFI_OUT_OF_RESOURCES;
370 goto Exit;
371 }
372
373 if (NewSuiteEntry->UTS.Name == NULL) {
374 Status = EFI_OUT_OF_RESOURCES;
375 goto Exit;
376 }
377
378 //
379 // Create the suite fingerprint.
380 //
381 SetSuiteFingerprint (&NewSuiteEntry->UTS.Fingerprint[0], Framework, &NewSuiteEntry->UTS);
382
383Exit:
384 //
385 // If everything is going well, add the new suite to the tail list for the framework.
386 //
387 if (!EFI_ERROR (Status)) {
388 InsertTailList (&(Framework->TestSuiteList), (LIST_ENTRY *)NewSuiteEntry);
389 *SuiteHandle = (UNIT_TEST_SUITE_HANDLE)(&NewSuiteEntry->UTS);
390 } else {
391 //
392 // Otherwise, make with the destruction.
393 //
394 FreeUnitTestSuiteEntry (NewSuiteEntry);
395 }
396
397 return Status;
398}
399
425EFIAPI
427 IN UNIT_TEST_SUITE_HANDLE SuiteHandle,
428 IN CHAR8 *Description,
429 IN CHAR8 *Name,
430 IN UNIT_TEST_FUNCTION Function,
431 IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL,
432 IN UNIT_TEST_CLEANUP CleanUp OPTIONAL,
433 IN UNIT_TEST_CONTEXT Context OPTIONAL
434 )
435{
436 EFI_STATUS Status;
437 UNIT_TEST_LIST_ENTRY *NewTestEntry;
438 UNIT_TEST_FRAMEWORK *ParentFramework;
439 UNIT_TEST_SUITE *Suite;
440
441 Status = EFI_SUCCESS;
442 Suite = (UNIT_TEST_SUITE *)SuiteHandle;
443
444 //
445 // First, let's check to make sure that our parameters look good.
446 //
447 if ((Suite == NULL) || (Description == NULL) || (Name == NULL) || (Function == NULL)) {
448 return EFI_INVALID_PARAMETER;
449 }
450
451 ParentFramework = (UNIT_TEST_FRAMEWORK *)Suite->ParentFramework;
452 //
453 // Create the new entry.
454 NewTestEntry = AllocateZeroPool (sizeof (UNIT_TEST_LIST_ENTRY));
455 if (NewTestEntry == NULL) {
456 return EFI_OUT_OF_RESOURCES;
457 }
458
459 //
460 // Copy the fields we think we need.
461 NewTestEntry->UT.Description = AllocateAndCopyString (Description);
462 NewTestEntry->UT.Name = AllocateAndCopyString (Name);
463 NewTestEntry->UT.FailureType = FAILURETYPE_NOFAILURE;
464 NewTestEntry->UT.FailureMessage[0] = '\0';
465 NewTestEntry->UT.Log = NULL;
466 NewTestEntry->UT.Prerequisite = Prerequisite;
467 NewTestEntry->UT.CleanUp = CleanUp;
468 NewTestEntry->UT.RunTest = Function;
469 NewTestEntry->UT.Context = Context;
470 NewTestEntry->UT.Result = UNIT_TEST_PENDING;
471 NewTestEntry->UT.ParentSuite = SuiteHandle;
472 InitializeListHead (&(NewTestEntry->Entry)); // List entry for sibling tests.
473 if (NewTestEntry->UT.Description == NULL) {
474 Status = EFI_OUT_OF_RESOURCES;
475 goto Exit;
476 }
477
478 if (NewTestEntry->UT.Name == NULL) {
479 Status = EFI_OUT_OF_RESOURCES;
480 goto Exit;
481 }
482
483 //
484 // Create the test fingerprint.
485 //
486 SetTestFingerprint (&NewTestEntry->UT.Fingerprint[0], Suite, &NewTestEntry->UT);
487
488 // TODO: Make sure that duplicate fingerprints cannot be created.
489
490 //
491 // If there is saved test data, update this record.
492 //
493 if (ParentFramework->SavedState != NULL) {
494 UpdateTestFromSave (&NewTestEntry->UT, ParentFramework->SavedState);
495 }
496
497Exit:
498 //
499 // If everything is going well, add the new suite to the tail list for the framework.
500 //
501 if (!EFI_ERROR (Status)) {
502 InsertTailList (&(Suite->TestCaseList), (LIST_ENTRY *)NewTestEntry);
503 Suite->NumTests++;
504 } else {
505 //
506 // Otherwise, make with the destruction.
507 //
508 FreeUnitTestTestEntry (NewTestEntry);
509 }
510
511 return Status;
512}
513
514STATIC
515VOID
516UpdateTestFromSave (
518 IN UNIT_TEST_SAVE_HEADER *SavedState
519 )
520{
521 UNIT_TEST_SAVE_TEST *CurrentTest;
522 UNIT_TEST_SAVE_TEST *MatchingTest;
523 UINT8 *FloatingPointer;
524 UNIT_TEST_SAVE_CONTEXT *SavedContext;
525 UINTN Index;
526
527 //
528 // First, evaluate the inputs.
529 //
530 if ((Test == NULL) || (SavedState == NULL)) {
531 return;
532 }
533
534 if (SavedState->TestCount == 0) {
535 return;
536 }
537
538 //
539 // Next, determine whether a matching test can be found.
540 // Start at the beginning.
541 //
542 MatchingTest = NULL;
543 FloatingPointer = (UINT8 *)SavedState + sizeof (*SavedState);
544 for (Index = 0; Index < SavedState->TestCount; Index++) {
545 CurrentTest = (UNIT_TEST_SAVE_TEST *)FloatingPointer;
546 if (CompareFingerprints (&Test->Fingerprint[0], &CurrentTest->Fingerprint[0])) {
547 MatchingTest = CurrentTest;
548 //
549 // If there's a saved context, it's important that we iterate through the entire list.
550 //
551 if (!SavedState->HasSavedContext) {
552 break;
553 }
554 }
555
556 //
557 // If we didn't find it, we have to increment to the next test.
558 //
559 FloatingPointer = (UINT8 *)CurrentTest + CurrentTest->Size;
560 }
561
562 //
563 // If a matching test was found, copy the status.
564 //
565 if (MatchingTest) {
566 //
567 // Override the test status with the saved status.
568 //
569 Test->Result = MatchingTest->Result;
570
571 Test->FailureType = MatchingTest->FailureType;
573 &Test->FailureMessage[0],
575 &MatchingTest->FailureMessage[0],
577 );
578
579 //
580 // If there is a log string associated, grab that.
581 // We can tell that there's a log string because the "size" will be larger than
582 // the structure size.
583 // IMPORTANT NOTE: There are security implications here.
584 // This data is user-supplied and we're about to play kinda
585 // fast and loose with data buffers.
586 //
587 if (MatchingTest->Size > sizeof (UNIT_TEST_SAVE_TEST)) {
588 UnitTestLogInit (Test, (UINT8 *)MatchingTest->Log, MatchingTest->Size - sizeof (UNIT_TEST_SAVE_TEST));
589 }
590 }
591
592 //
593 // If the saved context exists and matches this test, grab it, too.
594 //
595 if (SavedState->HasSavedContext) {
596 //
597 // If there was a saved context, the "matching test" loop will have placed the FloatingPointer
598 // at the beginning of the context structure.
599 //
600 SavedContext = (UNIT_TEST_SAVE_CONTEXT *)FloatingPointer;
601 if (((SavedContext->Size - sizeof (UNIT_TEST_SAVE_CONTEXT)) > 0) &&
602 CompareFingerprints (&Test->Fingerprint[0], &SavedContext->Fingerprint[0]))
603 {
604 //
605 // Override the test context with the saved context.
606 //
607 Test->Context = (VOID *)SavedContext->Data;
608 }
609 }
610}
611
612STATIC
614SerializeState (
615 IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
616 IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL,
617 IN UINTN ContextToSaveSize
618 )
619{
620 UNIT_TEST_FRAMEWORK *Framework;
621 UNIT_TEST_SAVE_HEADER *Header;
622 LIST_ENTRY *SuiteListHead;
623 LIST_ENTRY *Suite;
624 LIST_ENTRY *TestListHead;
626 UINT32 TestCount;
627 UINT32 TotalSize;
628 UINTN LogSize;
629 UNIT_TEST_SAVE_TEST *TestSaveData;
630 UNIT_TEST_SAVE_CONTEXT *TestSaveContext;
631 UNIT_TEST *UnitTest;
632 UINT8 *FloatingPointer;
633
634 Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
635 Header = NULL;
636
637 //
638 // First, let's not make assumptions about the parameters.
639 //
640 if ((Framework == NULL) ||
641 ((ContextToSave != NULL) && (ContextToSaveSize == 0)) ||
642 (ContextToSaveSize > MAX_UINT32))
643 {
644 return NULL;
645 }
646
647 //
648 // Next, we've gotta figure out the resources that will be required to serialize the
649 // the framework state so that we can persist it.
650 // To start with, we're gonna need a header.
651 //
652 TotalSize = sizeof (UNIT_TEST_SAVE_HEADER);
653 //
654 // Now we need to figure out how many tests there are.
655 //
656 TestCount = 0;
657 //
658 // Iterate all suites.
659 //
660 SuiteListHead = &Framework->TestSuiteList;
661 for (Suite = GetFirstNode (SuiteListHead); Suite != SuiteListHead; Suite = GetNextNode (SuiteListHead, Suite)) {
662 //
663 // Iterate all tests within the suite.
664 //
665 TestListHead = &((UNIT_TEST_SUITE_LIST_ENTRY *)Suite)->UTS.TestCaseList;
666 for (Test = GetFirstNode (TestListHead); Test != TestListHead; Test = GetNextNode (TestListHead, Test)) {
667 UnitTest = &((UNIT_TEST_LIST_ENTRY *)Test)->UT;
668 //
669 // Account for the size of a test structure.
670 //
671 TotalSize += sizeof (UNIT_TEST_SAVE_TEST);
672 //
673 // If there's a log, make sure to account for the log size.
674 //
675 if (UnitTest->Log != NULL) {
676 //
677 // The +1 is for the NULL character. Can't forget the NULL character.
678 //
679 LogSize = (AsciiStrLen (UnitTest->Log) + 1) * sizeof (CHAR8);
680 ASSERT (LogSize < MAX_UINT32);
681 TotalSize += (UINT32)LogSize;
682 }
683
684 //
685 // Increment the test count.
686 //
687 TestCount++;
688 }
689 }
690
691 //
692 // If there are no tests, we're done here.
693 //
694 if (TestCount == 0) {
695 return NULL;
696 }
697
698 //
699 // Add room for the context, if there is one.
700 //
701 if (ContextToSave != NULL) {
702 TotalSize += sizeof (UNIT_TEST_SAVE_CONTEXT) + (UINT32)ContextToSaveSize;
703 }
704
705 //
706 // Now that we know the size, we need to allocate space for the serialized output.
707 //
708 Header = AllocateZeroPool (TotalSize);
709 if (Header == NULL) {
710 return NULL;
711 }
712
713 //
714 // Alright, let's start setting up some data.
715 //
716 Header->Version = UNIT_TEST_PERSISTENCE_LIB_VERSION;
717 Header->SaveStateSize = TotalSize;
718 CopyMem (&Header->Fingerprint[0], &Framework->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
719 CopyMem (&Header->StartTime, &Framework->StartTime, sizeof (EFI_TIME));
720 Header->TestCount = TestCount;
721 Header->HasSavedContext = FALSE;
722
723 //
724 // Start adding all of the test cases.
725 // Set the floating pointer to the start of the current test save buffer.
726 //
727 FloatingPointer = (UINT8 *)Header + sizeof (UNIT_TEST_SAVE_HEADER);
728 //
729 // Iterate all suites.
730 //
731 SuiteListHead = &Framework->TestSuiteList;
732 for (Suite = GetFirstNode (SuiteListHead); Suite != SuiteListHead; Suite = GetNextNode (SuiteListHead, Suite)) {
733 //
734 // Iterate all tests within the suite.
735 //
736 TestListHead = &((UNIT_TEST_SUITE_LIST_ENTRY *)Suite)->UTS.TestCaseList;
737 for (Test = GetFirstNode (TestListHead); Test != TestListHead; Test = GetNextNode (TestListHead, Test)) {
738 TestSaveData = (UNIT_TEST_SAVE_TEST *)FloatingPointer;
739 UnitTest = &((UNIT_TEST_LIST_ENTRY *)Test)->UT;
740
741 //
742 // Save the fingerprint.
743 //
744 CopyMem (&TestSaveData->Fingerprint[0], &UnitTest->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
745
746 //
747 // Save the result.
748 //
749 TestSaveData->Result = UnitTest->Result;
750 TestSaveData->FailureType = UnitTest->FailureType;
751 AsciiStrnCpyS (&TestSaveData->FailureMessage[0], UNIT_TEST_MAX_STRING_LENGTH, &UnitTest->FailureMessage[0], UNIT_TEST_MAX_STRING_LENGTH);
752
753 //
754 // If there is a log, save the log.
755 //
756 FloatingPointer += sizeof (UNIT_TEST_SAVE_TEST);
757 if (UnitTest->Log != NULL) {
758 //
759 // The +1 is for the NULL character. Can't forget the NULL character.
760 //
761 LogSize = (AsciiStrLen (UnitTest->Log) + 1) * sizeof (CHAR8);
762 CopyMem (FloatingPointer, UnitTest->Log, LogSize);
763 FloatingPointer += LogSize;
764 }
765
766 //
767 // Update the size once the structure is complete.
768 // NOTE: Should this be a straight cast without validation?
769 //
770 TestSaveData->Size = (UINT32)(FloatingPointer - (UINT8 *)TestSaveData);
771 }
772 }
773
774 //
775 // If there is a context to save, let's do that now.
776 //
777 if ((ContextToSave != NULL) && (Framework->CurrentTest != NULL)) {
778 TestSaveContext = (UNIT_TEST_SAVE_CONTEXT *)FloatingPointer;
779 TestSaveContext->Size = (UINT32)ContextToSaveSize + sizeof (UNIT_TEST_SAVE_CONTEXT);
780 CopyMem (&TestSaveContext->Fingerprint[0], &Framework->CurrentTest->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
781 CopyMem (((UINT8 *)TestSaveContext + sizeof (UNIT_TEST_SAVE_CONTEXT)), ContextToSave, ContextToSaveSize);
782 Header->HasSavedContext = TRUE;
783 }
784
785 return Header;
786}
787
817EFIAPI
819 IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL,
820 IN UINTN ContextToSaveSize
821 )
822{
823 EFI_STATUS Status;
824 UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle;
825 UNIT_TEST_SAVE_HEADER *Header;
826
827 Header = NULL;
828 FrameworkHandle = GetActiveFrameworkHandle ();
829 if (FrameworkHandle == NULL) {
830 DEBUG ((DEBUG_ERROR, "%a - Could not save state! FrameworkHandle not initialized\n", __func__));
831 return EFI_DEVICE_ERROR;
832 }
833
834 //
835 // Return a unique error code if the framework is not set.
836 //
837 if (FrameworkHandle == NULL) {
838 return EFI_NOT_FOUND;
839 }
840
841 //
842 // First, let's not make assumptions about the parameters.
843 //
844 if (((ContextToSave != NULL) && (ContextToSaveSize == 0)) ||
845 (ContextToSaveSize > MAX_UINT32))
846 {
847 return EFI_INVALID_PARAMETER;
848 }
849
850 //
851 // Now, let's package up all the data for saving.
852 //
853 Header = SerializeState (FrameworkHandle, ContextToSave, ContextToSaveSize);
854 if (Header == NULL) {
855 return EFI_OUT_OF_RESOURCES;
856 }
857
858 //
859 // All that should be left to do is save it using the associated persistence lib.
860 //
861 Status = SaveUnitTestCache (FrameworkHandle, Header, Header->SaveStateSize);
862 if (EFI_ERROR (Status)) {
863 DEBUG ((DEBUG_ERROR, "%a - Could not save state! %r\n", __func__, Status));
864 Status = EFI_DEVICE_ERROR;
865 }
866
867 //
868 // Free data that was used.
869 //
870 FreePool (Header);
871
872 return Status;
873}
UINT64 UINTN
UINTN EFIAPI AsciiStrnLenS(IN CONST CHAR8 *String, IN UINTN MaxSize)
Definition: SafeString.c:1696
RETURN_STATUS EFIAPI AsciiStrnCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:1875
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
UINT32 EFIAPI CalculateCrc32(IN VOID *Buffer, IN UINTN Length)
Definition: CheckSum.c:600
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1797
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STRING_ID NewString(IN CHAR16 *String, IN EFI_HII_HANDLE HiiHandle)
Definition: Setup.c:981
INTN EFIAPI Test(CONST VOID *b1, CONST VOID *b2)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
#define UNIT_TEST_FINGERPRINT_SIZE
#define UNIT_TEST_MAX_STRING_LENGTH
EFI_STATUS EFIAPI SaveFrameworkState(IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL, IN UINTN ContextToSaveSize)
Definition: UnitTestLib.c:818
UNIT_TEST_STATUS(EFIAPI * UNIT_TEST_PREREQUISITE)(IN UNIT_TEST_CONTEXT Context)
Definition: UnitTestLib.h:103
VOID * UNIT_TEST_CONTEXT
Definition: UnitTestLib.h:54
VOID(EFIAPI * UNIT_TEST_SUITE_TEARDOWN)(VOID)
Definition: UnitTestLib.h:158
EFI_STATUS EFIAPI CreateUnitTestSuite(OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle, IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, IN CHAR8 *Title, IN CHAR8 *Name, IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL, IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL)
Definition: UnitTestLib.c:326
EFI_STATUS EFIAPI FreeUnitTestFramework(IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle)
Definition: UnitTestLib.c:150
EFI_STATUS EFIAPI AddTestCase(IN UNIT_TEST_SUITE_HANDLE SuiteHandle, IN CHAR8 *Description, IN CHAR8 *Name, IN UNIT_TEST_FUNCTION Function, IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL, IN UNIT_TEST_CLEANUP CleanUp OPTIONAL, IN UNIT_TEST_CONTEXT Context OPTIONAL)
Definition: UnitTestLib.c:426
VOID(EFIAPI * UNIT_TEST_SUITE_SETUP)(VOID)
Definition: UnitTestLib.h:144
EFI_STATUS EFIAPI InitUnitTestFramework(OUT UNIT_TEST_FRAMEWORK_HANDLE *FrameworkHandle, IN CHAR8 *Title, IN CHAR8 *ShortTitle, IN CHAR8 *VersionString)
Definition: UnitTestLib.c:204
UNIT_TEST_STATUS(EFIAPI * UNIT_TEST_FUNCTION)(IN UNIT_TEST_CONTEXT Context)
Definition: UnitTestLib.h:77
VOID(EFIAPI * UNIT_TEST_CLEANUP)(IN UNIT_TEST_CONTEXT Context)
Definition: UnitTestLib.h:130
EFI_STATUS EFIAPI SaveUnitTestCache(IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, IN VOID *SaveData, IN UINTN SaveStateSize)
EFI_STATUS EFIAPI LoadUnitTestCache(IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, OUT VOID **SaveData, OUT UINTN *SaveStateSize)
BOOLEAN EFIAPI DoesCacheExist(IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle)