RunTestsCmocka.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /** @file
  2. UnitTestLib APIs to run unit tests using cmocka
  3. Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdarg.h>
  9. #include <stddef.h>
  10. #include <setjmp.h>
  11. #include <cmocka.h>
  12. #include <Uefi.h>
  13. #include <UnitTestFrameworkTypes.h>
  14. #include <Library/UnitTestLib.h>
  15. #include <Library/BaseLib.h>
  16. #include <Library/BaseMemoryLib.h>
  17. #include <Library/MemoryAllocationLib.h>
  18. #include <Library/DebugLib.h>
  19. STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle = NULL;
  20. UNIT_TEST_FRAMEWORK_HANDLE
  21. GetActiveFrameworkHandle (
  22. VOID
  23. )
  24. {
  25. ASSERT (mFrameworkHandle != NULL);
  26. return mFrameworkHandle;
  27. }
  28. //
  29. // The currently active test suite
  30. //
  31. UNIT_TEST_SUITE *mActiveUnitTestSuite = NULL;
  32. void
  33. CmockaUnitTestFunctionRunner (
  34. void **state
  35. )
  36. {
  37. UNIT_TEST *UnitTest;
  38. UNIT_TEST_SUITE *Suite;
  39. UNIT_TEST_FRAMEWORK *Framework;
  40. UnitTest = (UNIT_TEST *)(*state);
  41. Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite);
  42. Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework);
  43. if (UnitTest->RunTest == NULL) {
  44. UnitTest->Result = UNIT_TEST_SKIPPED;
  45. } else {
  46. UnitTest->Result = UNIT_TEST_RUNNING;
  47. Framework->CurrentTest = UnitTest;
  48. UnitTest->Result = UnitTest->RunTest (UnitTest->Context);
  49. Framework->CurrentTest = NULL;
  50. }
  51. }
  52. int
  53. CmockaUnitTestSetupFunctionRunner (
  54. void **state
  55. )
  56. {
  57. UNIT_TEST *UnitTest;
  58. UNIT_TEST_SUITE *Suite;
  59. UNIT_TEST_FRAMEWORK *Framework;
  60. UNIT_TEST_STATUS Result;
  61. UnitTest = (UNIT_TEST *)(*state);
  62. Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite);
  63. Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework);
  64. if (UnitTest->Prerequisite == NULL) {
  65. return 0;
  66. }
  67. Framework->CurrentTest = UnitTest;
  68. Result = UnitTest->Prerequisite (UnitTest->Context);
  69. Framework->CurrentTest = NULL;
  70. //
  71. // Return 0 for success. Non-zero for error.
  72. //
  73. return (int)Result;
  74. }
  75. int
  76. CmockaUnitTestTeardownFunctionRunner (
  77. void **state
  78. )
  79. {
  80. UNIT_TEST *UnitTest;
  81. UNIT_TEST_SUITE *Suite;
  82. UNIT_TEST_FRAMEWORK *Framework;
  83. UnitTest = (UNIT_TEST *)(*state);
  84. Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite);
  85. Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework);
  86. if (UnitTest->CleanUp != NULL) {
  87. Framework->CurrentTest = UnitTest;
  88. UnitTest->CleanUp (UnitTest->Context);
  89. Framework->CurrentTest = NULL;
  90. }
  91. //
  92. // Print out the log messages - This is a partial solution as it
  93. // does not get the log into the XML. Need cmocka changes to support
  94. // stdout and stderr in their xml format
  95. //
  96. if (UnitTest->Log != NULL) {
  97. print_message ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description);
  98. print_message ("Log Output Start\n");
  99. print_message ("%s", UnitTest->Log);
  100. print_message ("Log Output End\n");
  101. }
  102. //
  103. // Return 0 for success. Non-zero for error.
  104. //
  105. return 0;
  106. }
  107. int
  108. CmockaUnitTestSuiteSetupFunctionRunner (
  109. void **state
  110. )
  111. {
  112. if (mActiveUnitTestSuite == NULL) {
  113. return -1;
  114. }
  115. if (mActiveUnitTestSuite->Setup == NULL) {
  116. return 0;
  117. }
  118. mActiveUnitTestSuite->Setup ();
  119. //
  120. // Always succeed
  121. //
  122. return 0;
  123. }
  124. int
  125. CmockaUnitTestSuiteTeardownFunctionRunner (
  126. void **state
  127. )
  128. {
  129. if (mActiveUnitTestSuite == NULL) {
  130. return -1;
  131. }
  132. if (mActiveUnitTestSuite->Teardown == NULL) {
  133. return 0;
  134. }
  135. mActiveUnitTestSuite->Teardown ();
  136. //
  137. // Always succeed
  138. //
  139. return 0;
  140. }
  141. STATIC
  142. EFI_STATUS
  143. RunTestSuite (
  144. IN UNIT_TEST_SUITE *Suite
  145. )
  146. {
  147. UNIT_TEST_LIST_ENTRY *TestEntry;
  148. UNIT_TEST *UnitTest;
  149. struct CMUnitTest *Tests;
  150. UINTN Index;
  151. TestEntry = NULL;
  152. if (Suite == NULL) {
  153. return EFI_INVALID_PARAMETER;
  154. }
  155. DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
  156. DEBUG ((DEBUG_VERBOSE, "RUNNING TEST SUITE: %a\n", Suite->Title));
  157. DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
  158. //
  159. // Allocate buffer of CMUnitTest entries
  160. //
  161. Tests = AllocateZeroPool (Suite->NumTests * sizeof (struct CMUnitTest));
  162. ASSERT (Tests != NULL);
  163. //
  164. // Populate buffer of CMUnitTest entries
  165. //
  166. Index = 0;
  167. for (TestEntry = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->TestCaseList));
  168. (LIST_ENTRY *)TestEntry != &(Suite->TestCaseList);
  169. TestEntry = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->TestCaseList), (LIST_ENTRY *)TestEntry))
  170. {
  171. UnitTest = &TestEntry->UT;
  172. Tests[Index].name = UnitTest->Description;
  173. Tests[Index].test_func = CmockaUnitTestFunctionRunner;
  174. Tests[Index].setup_func = CmockaUnitTestSetupFunctionRunner;
  175. Tests[Index].teardown_func = CmockaUnitTestTeardownFunctionRunner;
  176. Tests[Index].initial_state = UnitTest;
  177. Index++;
  178. }
  179. ASSERT (Index == Suite->NumTests);
  180. //
  181. // Run all unit tests in a test suite
  182. //
  183. mActiveUnitTestSuite = Suite;
  184. _cmocka_run_group_tests (
  185. Suite->Title,
  186. Tests,
  187. Suite->NumTests,
  188. CmockaUnitTestSuiteSetupFunctionRunner,
  189. CmockaUnitTestSuiteTeardownFunctionRunner
  190. );
  191. mActiveUnitTestSuite = NULL;
  192. FreePool (Tests);
  193. return EFI_SUCCESS;
  194. }
  195. /**
  196. Execute all unit test cases in all unit test suites added to a Framework.
  197. Once a unit test framework is initialized and all unit test suites and unit
  198. test cases are registered, this function will cause the unit test framework to
  199. dispatch all unit test cases in sequence and record the results for reporting.
  200. @param[in] FrameworkHandle A handle to the current running framework that
  201. dispatched the test. Necessary for recording
  202. certain test events with the framework.
  203. @retval EFI_SUCCESS All test cases were dispatched.
  204. @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
  205. **/
  206. EFI_STATUS
  207. EFIAPI
  208. RunAllTestSuites (
  209. IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
  210. )
  211. {
  212. UNIT_TEST_FRAMEWORK *Framework;
  213. UNIT_TEST_SUITE_LIST_ENTRY *Suite;
  214. EFI_STATUS Status;
  215. Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
  216. Suite = NULL;
  217. if (Framework == NULL) {
  218. return EFI_INVALID_PARAMETER;
  219. }
  220. DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
  221. DEBUG ((DEBUG_VERBOSE, "------------ RUNNING ALL TEST SUITES --------------\n"));
  222. DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
  223. mFrameworkHandle = FrameworkHandle;
  224. //
  225. // Iterate all suites
  226. //
  227. for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList);
  228. (LIST_ENTRY *)Suite != &Framework->TestSuiteList;
  229. Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite))
  230. {
  231. Status = RunTestSuite (&(Suite->UTS));
  232. if (EFI_ERROR (Status)) {
  233. DEBUG ((DEBUG_ERROR, "Test Suite Failed with Error. %r\n", Status));
  234. }
  235. }
  236. mFrameworkHandle = NULL;
  237. return EFI_SUCCESS;
  238. }