123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /**
- UnitTestLib APIs to run unit tests
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Uefi.h>
- #include <Library/UnitTestLib.h>
- #include <Library/BaseLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/DebugLib.h>
- #include <Library/UnitTestResultReportLib.h>
- STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle = NULL;
- BASE_LIBRARY_JUMP_BUFFER gUnitTestJumpBuffer;
- UNIT_TEST_FRAMEWORK_HANDLE
- GetActiveFrameworkHandle (
- VOID
- )
- {
- ASSERT (mFrameworkHandle != NULL);
- return mFrameworkHandle;
- }
- STATIC
- EFI_STATUS
- RunTestSuite (
- IN UNIT_TEST_SUITE *Suite
- )
- {
- UNIT_TEST_LIST_ENTRY *TestEntry;
- UNIT_TEST *Test;
- UNIT_TEST_FRAMEWORK *ParentFramework;
- if (Suite == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- TestEntry = NULL;
- ParentFramework = (UNIT_TEST_FRAMEWORK *)Suite->ParentFramework;
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- DEBUG ((DEBUG_VERBOSE, "RUNNING TEST SUITE: %a\n", Suite->Title));
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- if (Suite->Setup != NULL) {
- Suite->Setup ();
- }
- //
- // Iterate all tests within the suite
- //
- for (TestEntry = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->TestCaseList));
- (LIST_ENTRY *)TestEntry != &(Suite->TestCaseList);
- TestEntry = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->TestCaseList), (LIST_ENTRY *)TestEntry))
- {
- Test = &TestEntry->UT;
- ParentFramework->CurrentTest = Test;
- DEBUG ((DEBUG_VERBOSE, "*********************************************************\n"));
- DEBUG ((DEBUG_VERBOSE, " RUNNING TEST: %a:\n", Test->Description));
- DEBUG ((DEBUG_VERBOSE, "**********************************************************\n"));
- //
- // First, check to see whether the test has already been run.
- // NOTE: This would generally only be the case if a saved state was detected and loaded.
- //
- if ((Test->Result != UNIT_TEST_PENDING) && (Test->Result != UNIT_TEST_RUNNING)) {
- DEBUG ((DEBUG_VERBOSE, "Test was run on a previous pass. Skipping.\n"));
- ParentFramework->CurrentTest = NULL;
- continue;
- }
- //
- // Next, if we're still running, make sure that our test prerequisites are in place.
- if ((Test->Result == UNIT_TEST_PENDING) && (Test->Prerequisite != NULL)) {
- DEBUG ((DEBUG_VERBOSE, "PREREQ\n"));
- if (SetJump (&gUnitTestJumpBuffer) == 0) {
- if (Test->Prerequisite (Test->Context) != UNIT_TEST_PASSED) {
- DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n"));
- Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
- ParentFramework->CurrentTest = NULL;
- continue;
- }
- } else {
- DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n"));
- Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
- ParentFramework->CurrentTest = NULL;
- continue;
- }
- }
- //
- // Now we should be ready to call the actual test.
- // We set the status to UNIT_TEST_RUNNING in case the test needs to reboot
- // or quit. The UNIT_TEST_RUNNING state will allow the test to resume
- // but will prevent the Prerequisite from being dispatched a second time.
- if (SetJump (&gUnitTestJumpBuffer) == 0) {
- Test->Result = UNIT_TEST_RUNNING;
- Test->Result = Test->RunTest (Test->Context);
- } else {
- Test->Result = UNIT_TEST_ERROR_TEST_FAILED;
- }
- //
- // Finally, clean everything up, if need be.
- if (Test->CleanUp != NULL) {
- DEBUG ((DEBUG_VERBOSE, "CLEANUP\n"));
- if (SetJump (&gUnitTestJumpBuffer) == 0) {
- Test->CleanUp (Test->Context);
- }
- }
- //
- // End the test.
- //
- ParentFramework->CurrentTest = NULL;
- }
- if (Suite->Teardown != NULL) {
- Suite->Teardown ();
- }
- return EFI_SUCCESS;
- }
- /**
- Execute all unit test cases in all unit test suites added to a Framework.
- Once a unit test framework is initialized and all unit test suites and unit
- test cases are registered, this function will cause the unit test framework to
- dispatch all unit test cases in sequence and record the results for reporting.
- @param[in] FrameworkHandle A handle to the current running framework that
- dispatched the test. Necessary for recording
- certain test events with the framework.
- @retval EFI_SUCCESS All test cases were dispatched.
- @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
- **/
- EFI_STATUS
- EFIAPI
- RunAllTestSuites (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
- {
- UNIT_TEST_FRAMEWORK *Framework;
- UNIT_TEST_SUITE_LIST_ENTRY *Suite;
- EFI_STATUS Status;
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
- Suite = NULL;
- if (Framework == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- DEBUG ((DEBUG_VERBOSE, "------------ RUNNING ALL TEST SUITES --------------\n"));
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- mFrameworkHandle = FrameworkHandle;
- //
- // Iterate all suites
- //
- for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList);
- (LIST_ENTRY *)Suite != &Framework->TestSuiteList;
- Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite))
- {
- Status = RunTestSuite (&(Suite->UTS));
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Test Suite Failed with Error. %r\n", Status));
- }
- }
- //
- // Save current state so if test is started again it doesn't have to run. It will just report
- //
- SaveFrameworkState (NULL, 0);
- OutputUnitTestFrameworkReport (FrameworkHandle);
- mFrameworkHandle = NULL;
- return EFI_SUCCESS;
- }
|