]> git.proxmox.com Git - mirror_edk2.git/blobdiff - FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c
FmpDevicePkg/Test: Add FmpDependencyLib unit test
[mirror_edk2.git] / FmpDevicePkg / Test / UnitTest / Library / FmpDependencyLib / EvaluateDependencyUnitTest.c
diff --git a/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c
new file mode 100644 (file)
index 0000000..f8ccdd9
--- /dev/null
@@ -0,0 +1,270 @@
+/** @file\r
+  Unit tests of EvaluateDependency API in FmpDependencyLib.\r
+\r
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/FmpDependencyLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UnitTestLib.h>\r
+\r
+#define UNIT_TEST_APP_NAME     "FmpDependencyLib Unit Test Application"\r
+#define UNIT_TEST_APP_VERSION  "1.0"\r
+\r
+typedef struct {\r
+    UINT8       *Dependencies;\r
+    UINTN       DependenciesSize;\r
+    BOOLEAN     ExpectedResult;\r
+} BASIC_TEST_CONTEXT;\r
+\r
+//\r
+// Image Type ID of FMP device A\r
+//\r
+#define IMAGE_TYPE_ID_1   { 0x97144DFA, 0xEB8E, 0xD14D, {0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42}}\r
+\r
+//\r
+// Image Type ID of FMP device B\r
+//\r
+#define IMAGE_TYPE_ID_2   { 0xA42A7370, 0x433A, 0x684D, {0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3}}\r
+\r
+//\r
+// Device A's version is 0x00000002\r
+// Device B's version is 0x00000003\r
+//\r
+static FMP_DEPEX_CHECK_VERSION_DATA mFmpVersions[] = {\r
+  {IMAGE_TYPE_ID_1, 0x00000002},\r
+  {IMAGE_TYPE_ID_2, 0x00000003}\r
+};\r
+\r
+// Valid Dependency Expression 1: (Version(A) > 0x00000001) && (Version(B) >= 0x00000003)\r
+static UINT8 mExpression1[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x01, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,\r
+  EFI_FMP_DEP_GT,\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4, 0x3A, 0x43, 0x4D, 0x68, 0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3,\r
+  EFI_FMP_DEP_GTE,\r
+  EFI_FMP_DEP_AND,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Valid Dependency Expression 2: (Version(A) < 0x00000002) || (Version(B) <= 0x00000003)\r
+static UINT8 mExpression2[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,\r
+  EFI_FMP_DEP_LT,\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4, 0x3A, 0x43, 0x4D, 0x68, 0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3,\r
+  EFI_FMP_DEP_LTE,\r
+  EFI_FMP_DEP_OR,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Valid Dependency Expression 3: !(Version(A) == 0x0000002)\r
+static UINT8 mExpression3[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,\r
+  EFI_FMP_DEP_EQ,\r
+  EFI_FMP_DEP_NOT,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Valid Dependency Expression 4: "Test" TRUE && FALSE\r
+static UINT8 mExpression4[] = {\r
+  EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', '\0',\r
+  EFI_FMP_DEP_TRUE,\r
+  EFI_FMP_DEP_FALSE,\r
+  EFI_FMP_DEP_AND,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Invalid Dependency Expression 1: Invalid Op-code\r
+static UINT8 mExpression5[] = {EFI_FMP_DEP_TRUE, 0xAA, EFI_FMP_DEP_END};\r
+\r
+// Invalid Dependency Expression 2: String doesn't end with '\0'\r
+static UINT8 mExpression6[] = {EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', EFI_FMP_DEP_TRUE, EFI_FMP_DEP_END};\r
+\r
+// Invalid Dependency Expression 3: GUID is in invalid size\r
+static UINT8 mExpression7[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0xAA, 0xBB, 0xCC, 0xDD,\r
+  EFI_FMP_DEP_GTE,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Invalid Dependency Expression 4: Version is in invalid size\r
+static UINT8 mExpression8[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53,\r
+  EFI_FMP_DEP_GTE,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Invalid Dependency Expression 5: Operand and operator mismatch\r
+static UINT8 mExpression9[] = {EFI_FMP_DEP_TRUE, EFI_FMP_DEP_FALSE, EFI_FMP_DEP_GTE, EFI_FMP_DEP_END};\r
+\r
+// Invalid Dependency Expression 6: GUID is NOT FOUND\r
+static UINT8 mExpression10[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53,\r
+  EFI_FMP_DEP_GT,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// Invalid Dependency Expression 7: Stack underflow\r
+static UINT8 mExpression11[] = {\r
+  EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,\r
+  EFI_FMP_DEP_GT,\r
+  EFI_FMP_DEP_END\r
+};\r
+\r
+// ------------------------------------------------Test Depex------Depex Size----------------Expected Result\r
+static BASIC_TEST_CONTEXT   mBasicTestTrue1      = {mExpression1,  sizeof(mExpression1),     TRUE};\r
+static BASIC_TEST_CONTEXT   mBasicTestTrue2      = {mExpression2,  sizeof(mExpression2),     TRUE};\r
+static BASIC_TEST_CONTEXT   mBasicTestFalse1     = {mExpression3,  sizeof(mExpression3),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestFalse2     = {mExpression4,  sizeof(mExpression4),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid1   = {mExpression1,  sizeof(mExpression1) - 1, FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid2   = {mExpression5,  sizeof(mExpression5),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid3   = {mExpression6,  sizeof(mExpression6),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid4   = {mExpression7,  sizeof(mExpression7),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid5   = {mExpression8,  sizeof(mExpression8),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid6   = {mExpression9,  sizeof(mExpression9),     FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid7   = {mExpression10, sizeof(mExpression10),    FALSE};\r
+static BASIC_TEST_CONTEXT   mBasicTestInvalid8   = {mExpression11, sizeof(mExpression11),    FALSE};\r
+\r
+/**\r
+  Unit test for EvaluateDependency() API of the FmpDependencyLib.\r
+\r
+  @param[in]  Context    [Optional] An optional parameter that enables:\r
+                         1) test-case reuse with varied parameters and\r
+                         2) test-case re-entry for Target tests that need a\r
+                         reboot.  This parameter is a VOID* and it is the\r
+                         responsibility of the test author to ensure that the\r
+                         contents are well understood by all test cases that may\r
+                         consume it.\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+**/\r
+STATIC\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+EvaluateDependencyTest (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  BASIC_TEST_CONTEXT  *TestContext;\r
+  BOOLEAN             EvaluationResult;\r
+\r
+  TestContext = (BASIC_TEST_CONTEXT *)Context;\r
+\r
+  EvaluationResult = EvaluateDependency (\r
+                       (EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies,\r
+                       TestContext->DependenciesSize,\r
+                       mFmpVersions,\r
+                       sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION_DATA)\r
+                     );\r
+\r
+  UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Initialize the unit test framework, suite, and unit tests for the\r
+  EvaluateDependency API in FmpDependencyLib and run the unit tests.\r
+\r
+  @retval  EFI_SUCCESS           All test cases were dispatched.\r
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to\r
+                                 initialize the unit tests.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestingEntry (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  UNIT_TEST_FRAMEWORK_HANDLE  Fw;\r
+  UNIT_TEST_SUITE_HANDLE      DepexEvalTests;\r
+\r
+  Fw = NULL;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));\r
+\r
+  //\r
+  // Start setting up the test framework for running the tests.\r
+  //\r
+  Status = InitUnitTestFramework (&Fw, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);\r
+  if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));\r
+      goto EXIT;\r
+  }\r
+\r
+  //\r
+  // Populate the Unit Test Suite.\r
+  //\r
+  Status = CreateUnitTestSuite (&DepexEvalTests, Fw, "Evaluate Dependency Test", "FmpDependencyLib.EvaluateDependency", NULL, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for DepexEvalTests\n"));\r
+    goto EXIT;\r
+  }\r
+\r
+  AddTestCase (DepexEvalTests, "Evaluate to True - 1", "Test1", EvaluateDependencyTest, NULL, NULL, &mBasicTestTrue1);\r
+  AddTestCase (DepexEvalTests, "Evaluate to True - 2", "Test2", EvaluateDependencyTest, NULL, NULL, &mBasicTestTrue2);\r
+  AddTestCase (DepexEvalTests, "Evaluate to False - 1", "Test3", EvaluateDependencyTest, NULL, NULL, &mBasicTestFalse1);\r
+  AddTestCase (DepexEvalTests, "Evaluate to False - 2", "Test4", EvaluateDependencyTest, NULL, NULL, &mBasicTestFalse2);\r
+  AddTestCase (DepexEvalTests, "Error: Non-END-terminated expression", "Test5", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid1);\r
+  AddTestCase (DepexEvalTests, "Error: UNKNOWN Op-Code", "Test6", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid2);\r
+  AddTestCase (DepexEvalTests, "Error: Non-Null-terminated string", "Test7", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid3);\r
+  AddTestCase (DepexEvalTests, "Error: GUID size is not 16", "Test8", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid4);\r
+  AddTestCase (DepexEvalTests, "Error: Version size is not 4", "Test9", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid5);\r
+  AddTestCase (DepexEvalTests, "Error: Operand and operator mismatch", "Test10", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid6);\r
+  AddTestCase (DepexEvalTests, "Error: GUID is NOT FOUND", "Test11", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid7);\r
+  AddTestCase (DepexEvalTests, "Error: Stack Underflow", "Test12", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid8);\r
+\r
+  //\r
+  // Execute the tests.\r
+  //\r
+  Status = RunAllTestSuites (Fw);\r
+\r
+EXIT:\r
+  if (Fw) {\r
+    FreeUnitTestFramework (Fw);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Standard UEFI entry point for target based unit test execution from UEFI Shell.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FmpDependencyLibUnitTestAppEntry (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  return UnitTestingEntry ();\r
+}\r
+\r
+/**\r
+  Standard POSIX C entry point for host based unit test execution.\r
+**/\r
+int\r
+main (\r
+  int argc,\r
+  char *argv[]\r
+  )\r
+{\r
+  return UnitTestingEntry ();\r
+}\r