EvaluateDependencyUnitTest.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /** @file
  2. Unit tests of EvaluateDependency API in FmpDependencyLib.
  3. Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
  4. Copyright (c) Microsoft Corporation.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Uefi.h>
  8. #include <Library/BaseLib.h>
  9. #include <Library/BaseMemoryLib.h>
  10. #include <Library/DebugLib.h>
  11. #include <Library/FmpDependencyLib.h>
  12. #include <Library/MemoryAllocationLib.h>
  13. #include <Library/UnitTestLib.h>
  14. #define UNIT_TEST_APP_NAME "FmpDependencyLib Unit Test Application"
  15. #define UNIT_TEST_APP_VERSION "1.0"
  16. typedef struct {
  17. UINT8 *Dependencies;
  18. UINTN DependenciesSize;
  19. BOOLEAN ExpectedResult;
  20. } BASIC_TEST_CONTEXT;
  21. //
  22. // Image Type ID of FMP device A
  23. //
  24. #define IMAGE_TYPE_ID_1 { 0x97144DFA, 0xEB8E, 0xD14D, {0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42}}
  25. //
  26. // Image Type ID of FMP device B
  27. //
  28. #define IMAGE_TYPE_ID_2 { 0xA42A7370, 0x433A, 0x684D, {0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3}}
  29. //
  30. // Device A's version is 0x00000002
  31. // Device B's version is 0x00000003
  32. //
  33. static FMP_DEPEX_CHECK_VERSION_DATA mFmpVersions[] = {
  34. { IMAGE_TYPE_ID_1, 0x00000002 },
  35. { IMAGE_TYPE_ID_2, 0x00000003 }
  36. };
  37. // Valid Dependency Expression 1: (Version(A) > 0x00000001) && (Version(B) >= 0x00000003)
  38. static UINT8 mExpression1[] = {
  39. EFI_FMP_DEP_PUSH_VERSION, 0x01, 0x00, 0x00, 0x00,
  40. EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97,0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,
  41. EFI_FMP_DEP_GT,
  42. EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00,
  43. EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4,0x3A, 0x43, 0x4D, 0x68, 0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3,
  44. EFI_FMP_DEP_GTE,
  45. EFI_FMP_DEP_AND,
  46. EFI_FMP_DEP_END
  47. };
  48. // Valid Dependency Expression 2: (Version(A) < 0x00000002) || (Version(B) <= 0x00000003)
  49. static UINT8 mExpression2[] = {
  50. EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
  51. EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97,0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,
  52. EFI_FMP_DEP_LT,
  53. EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00,
  54. EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4,0x3A, 0x43, 0x4D, 0x68, 0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3,
  55. EFI_FMP_DEP_LTE,
  56. EFI_FMP_DEP_OR,
  57. EFI_FMP_DEP_END
  58. };
  59. // Valid Dependency Expression 3: !(Version(A) == 0x0000002)
  60. static UINT8 mExpression3[] = {
  61. EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
  62. EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97,0x8E,0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,
  63. EFI_FMP_DEP_EQ,
  64. EFI_FMP_DEP_NOT,
  65. EFI_FMP_DEP_END
  66. };
  67. // Valid Dependency Expression 4: "Test" TRUE && FALSE
  68. static UINT8 mExpression4[] = {
  69. EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', '\0',
  70. EFI_FMP_DEP_TRUE,
  71. EFI_FMP_DEP_FALSE,
  72. EFI_FMP_DEP_AND,
  73. EFI_FMP_DEP_END
  74. };
  75. // Invalid Dependency Expression 1: Invalid Op-code
  76. static UINT8 mExpression5[] = { EFI_FMP_DEP_TRUE, 0xAA, EFI_FMP_DEP_END };
  77. // Invalid Dependency Expression 2: String doesn't end with '\0'
  78. static UINT8 mExpression6[] = { EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', EFI_FMP_DEP_TRUE, EFI_FMP_DEP_END };
  79. // Invalid Dependency Expression 3: GUID is in invalid size
  80. static UINT8 mExpression7[] = {
  81. EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
  82. EFI_FMP_DEP_PUSH_GUID, 0xAA, 0xBB, 0xCC, 0xDD,
  83. EFI_FMP_DEP_GTE,
  84. EFI_FMP_DEP_END
  85. };
  86. // Invalid Dependency Expression 4: Version is in invalid size
  87. static UINT8 mExpression8[] = {
  88. EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00,
  89. EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB,0x25,0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53,
  90. EFI_FMP_DEP_GTE,
  91. EFI_FMP_DEP_END
  92. };
  93. // Invalid Dependency Expression 5: Operand and operator mismatch
  94. static UINT8 mExpression9[] = { EFI_FMP_DEP_TRUE, EFI_FMP_DEP_FALSE, EFI_FMP_DEP_GTE, EFI_FMP_DEP_END };
  95. // Invalid Dependency Expression 6: GUID is NOT FOUND
  96. static UINT8 mExpression10[] = {
  97. EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
  98. EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC,0x9E,0xCD, 0x5E, 0xE2, 0x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53,
  99. EFI_FMP_DEP_GT,
  100. EFI_FMP_DEP_END
  101. };
  102. // Invalid Dependency Expression 7: Stack underflow
  103. static UINT8 mExpression11[] = {
  104. EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
  105. EFI_FMP_DEP_GT,
  106. EFI_FMP_DEP_END
  107. };
  108. // ------------------------------------------------Test Depex------Depex Size----------------Expected Result
  109. static BASIC_TEST_CONTEXT mBasicTestTrue1 = { mExpression1, sizeof (mExpression1), TRUE };
  110. static BASIC_TEST_CONTEXT mBasicTestTrue2 = { mExpression2, sizeof (mExpression2), TRUE };
  111. static BASIC_TEST_CONTEXT mBasicTestFalse1 = { mExpression3, sizeof (mExpression3), FALSE };
  112. static BASIC_TEST_CONTEXT mBasicTestFalse2 = { mExpression4, sizeof (mExpression4), FALSE };
  113. static BASIC_TEST_CONTEXT mBasicTestInvalid1 = { mExpression1, sizeof (mExpression1) - 1, FALSE };
  114. static BASIC_TEST_CONTEXT mBasicTestInvalid2 = { mExpression5, sizeof (mExpression5), FALSE };
  115. static BASIC_TEST_CONTEXT mBasicTestInvalid3 = { mExpression6, sizeof (mExpression6), FALSE };
  116. static BASIC_TEST_CONTEXT mBasicTestInvalid4 = { mExpression7, sizeof (mExpression7), FALSE };
  117. static BASIC_TEST_CONTEXT mBasicTestInvalid5 = { mExpression8, sizeof (mExpression8), FALSE };
  118. static BASIC_TEST_CONTEXT mBasicTestInvalid6 = { mExpression9, sizeof (mExpression9), FALSE };
  119. static BASIC_TEST_CONTEXT mBasicTestInvalid7 = { mExpression10, sizeof (mExpression10), FALSE };
  120. static BASIC_TEST_CONTEXT mBasicTestInvalid8 = { mExpression11, sizeof (mExpression11), FALSE };
  121. /**
  122. Unit test for EvaluateDependency() API of the FmpDependencyLib.
  123. @param[in] Context [Optional] An optional parameter that enables:
  124. 1) test-case reuse with varied parameters and
  125. 2) test-case re-entry for Target tests that need a
  126. reboot. This parameter is a VOID* and it is the
  127. responsibility of the test author to ensure that the
  128. contents are well understood by all test cases that may
  129. consume it.
  130. @retval UNIT_TEST_PASSED The Unit test has completed and the test
  131. case was successful.
  132. @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
  133. **/
  134. STATIC
  135. UNIT_TEST_STATUS
  136. EFIAPI
  137. EvaluateDependencyTest (
  138. IN UNIT_TEST_CONTEXT Context
  139. )
  140. {
  141. BASIC_TEST_CONTEXT *TestContext;
  142. BOOLEAN EvaluationResult;
  143. UINT32 LastAttemptStatus;
  144. TestContext = (BASIC_TEST_CONTEXT *)Context;
  145. EvaluationResult = EvaluateDependency (
  146. (EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies,
  147. TestContext->DependenciesSize,
  148. mFmpVersions,
  149. sizeof (mFmpVersions)/sizeof (FMP_DEPEX_CHECK_VERSION_DATA),
  150. &LastAttemptStatus
  151. );
  152. UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult);
  153. return UNIT_TEST_PASSED;
  154. }
  155. /**
  156. Initialize the unit test framework, suite, and unit tests for the
  157. EvaluateDependency API in FmpDependencyLib and run the unit tests.
  158. @retval EFI_SUCCESS All test cases were dispatched.
  159. @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
  160. initialize the unit tests.
  161. **/
  162. STATIC
  163. EFI_STATUS
  164. EFIAPI
  165. UnitTestingEntry (
  166. VOID
  167. )
  168. {
  169. EFI_STATUS Status;
  170. UNIT_TEST_FRAMEWORK_HANDLE Fw;
  171. UNIT_TEST_SUITE_HANDLE DepexEvalTests;
  172. Fw = NULL;
  173. DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
  174. //
  175. // Start setting up the test framework for running the tests.
  176. //
  177. Status = InitUnitTestFramework (&Fw, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
  178. if (EFI_ERROR (Status)) {
  179. DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
  180. goto EXIT;
  181. }
  182. //
  183. // Populate the Unit Test Suite.
  184. //
  185. Status = CreateUnitTestSuite (&DepexEvalTests, Fw, "Evaluate Dependency Test", "FmpDependencyLib.EvaluateDependency", NULL, NULL);
  186. if (EFI_ERROR (Status)) {
  187. DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for DepexEvalTests\n"));
  188. goto EXIT;
  189. }
  190. AddTestCase (DepexEvalTests, "Evaluate to True - 1", "Test1", EvaluateDependencyTest, NULL, NULL, &mBasicTestTrue1);
  191. AddTestCase (DepexEvalTests, "Evaluate to True - 2", "Test2", EvaluateDependencyTest, NULL, NULL, &mBasicTestTrue2);
  192. AddTestCase (DepexEvalTests, "Evaluate to False - 1", "Test3", EvaluateDependencyTest, NULL, NULL, &mBasicTestFalse1);
  193. AddTestCase (DepexEvalTests, "Evaluate to False - 2", "Test4", EvaluateDependencyTest, NULL, NULL, &mBasicTestFalse2);
  194. AddTestCase (DepexEvalTests, "Error: Non-END-terminated expression", "Test5", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid1);
  195. AddTestCase (DepexEvalTests, "Error: UNKNOWN Op-Code", "Test6", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid2);
  196. AddTestCase (DepexEvalTests, "Error: Non-Null-terminated string", "Test7", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid3);
  197. AddTestCase (DepexEvalTests, "Error: GUID size is not 16", "Test8", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid4);
  198. AddTestCase (DepexEvalTests, "Error: Version size is not 4", "Test9", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid5);
  199. AddTestCase (DepexEvalTests, "Error: Operand and operator mismatch", "Test10", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid6);
  200. AddTestCase (DepexEvalTests, "Error: GUID is NOT FOUND", "Test11", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid7);
  201. AddTestCase (DepexEvalTests, "Error: Stack Underflow", "Test12", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid8);
  202. //
  203. // Execute the tests.
  204. //
  205. Status = RunAllTestSuites (Fw);
  206. EXIT:
  207. if (Fw) {
  208. FreeUnitTestFramework (Fw);
  209. }
  210. return Status;
  211. }
  212. /**
  213. Standard UEFI entry point for target based unit test execution from UEFI Shell.
  214. **/
  215. EFI_STATUS
  216. EFIAPI
  217. FmpDependencyLibUnitTestAppEntry (
  218. IN EFI_HANDLE ImageHandle,
  219. IN EFI_SYSTEM_TABLE *SystemTable
  220. )
  221. {
  222. return UnitTestingEntry ();
  223. }
  224. /**
  225. Standard POSIX C entry point for host based unit test execution.
  226. **/
  227. int
  228. main (
  229. int argc,
  230. char *argv[]
  231. )
  232. {
  233. return UnitTestingEntry ();
  234. }