[edk2-devel] [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test module

Albecki, Mateusz posted 2 patches 2 years, 4 months ago
[edk2-devel] [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test module
Posted by Albecki, Mateusz 2 years, 4 months ago
This commit adds host-based unit tests for device path lib.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>

Signed-off-by: Mateusz Albecki <mateusz.albecki@intel.com>
---
 MdePkg/MdePkg.ci.yaml                         |   5 +-
 MdePkg/Test/MdePkgHostTest.dsc                |   2 +
 .../Library/DevicePathLib/TestDevicePathLib.c | 638 ++++++++++++++++++
 .../Library/DevicePathLib/TestDevicePathLib.h |  26 +
 .../DevicePathLib/TestDevicePathLibHost.inf   |  33 +
 .../TestDevicePathStringConversions.c         | 370 ++++++++++
 6 files changed, 1073 insertions(+), 1 deletion(-)
 create mode 100644 MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
 create mode 100644 MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
 create mode 100644 MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
 create mode 100644 MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c

diff --git a/MdePkg/MdePkg.ci.yaml b/MdePkg/MdePkg.ci.yaml
index c3faf4913d..45f4fb537b 100644
--- a/MdePkg/MdePkg.ci.yaml
+++ b/MdePkg/MdePkg.ci.yaml
@@ -74,7 +74,10 @@
             "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",
             "Library/BaseFdtLib",
             "Library/MipiSysTLib/mipi_syst.h",
-            "Include/Register/Amd/SmramSaveStateMap.h"
+            "Include/Register/Amd/SmramSaveStateMap.h",
+            "Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c",
+            "Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h",
+            "Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c"
         ]
     },
     ## options defined ci/Plugin/CompilerPlugin
diff --git a/MdePkg/Test/MdePkgHostTest.dsc b/MdePkg/Test/MdePkgHostTest.dsc
index 529ea69024..b92b564d43 100644
--- a/MdePkg/Test/MdePkgHostTest.dsc
+++ b/MdePkg/Test/MdePkgHostTest.dsc
@@ -21,6 +21,7 @@
 
 [LibraryClasses]
   SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.inf
 
 [Components]
   #
@@ -29,6 +30,7 @@
   MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost.inf
   MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost.inf
   MdePkg/Test/GoogleTest/Library/BaseSafeIntLib/GoogleTestBaseSafeIntLib.inf
+  MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
 
   #
   # Build HOST_APPLICATION Libraries
diff --git a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
new file mode 100644
index 0000000000..687497278c
--- /dev/null
+++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
@@ -0,0 +1,638 @@
+/** @file
+  UEFI OS based application for unit testing the DevicePathLib.
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "TestDevicePathLib.h"
+
+#define UNIT_TEST_NAME     "DevicePathLib Unit Test Application"
+#define UNIT_TEST_VERSION  "0.1"
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH        AcpiPath;
+  PCI_DEVICE_PATH             PciPathRootPort;
+  PCI_DEVICE_PATH             PciPathEndPoint;
+  USB_DEVICE_PATH             UsbPath;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} TEST_COMPLEX_DEVICE_PATH;
+
+GLOBAL_REMOVE_IF_UNREFERENCED TEST_COMPLEX_DEVICE_PATH  mComplexDevicePath = {
+  { // ACPI device path with root bridge EISA_PNP_ID
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0x0A03),
+    0
+  },
+  { // PCI device path - root port (0x2:0x0)
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_PCI_DP,
+      {
+        (UINT8)(sizeof (PCI_DEVICE_PATH)),
+        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
+      }
+    },
+    0x2,
+    0x0
+  },
+  { // PCI device path - endpoint (0x0:0x0)
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_PCI_DP,
+      {
+        (UINT8)(sizeof (PCI_DEVICE_PATH)),
+        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
+      }
+    },
+    0x0,
+    0x0
+  },
+  { // USB interface
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_USB_DP,
+      {
+        (UINT8)(sizeof (USB_DEVICE_PATH)),
+        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,
+    2
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
+      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
+    }
+  }
+};
+
+CONST GLOBAL_REMOVE_IF_UNREFERENCED CHAR16  *mComplexDevicePathString = L"PciRoot(0x0)/Pci(0x0,0x2)/Pci(0x0,0x0)/USB(0x0,0x2)";
+
+CONST GLOBAL_REMOVE_IF_UNREFERENCED CHAR16  *mPciEndPointPathString = L"Pci(0x0, 0x0)";
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH        AcpiPath;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} TEST_SIMPLE_DEVICE_PATH;
+
+GLOBAL_REMOVE_IF_UNREFERENCED TEST_SIMPLE_DEVICE_PATH  mSimpleDevicePath = {
+  { // ACPI device path with root bridge EISA_PNP_ID
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0x0A03),
+    0
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
+      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
+    }
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED TEST_SIMPLE_DEVICE_PATH  mInvalidSimpleDevicePath = {
+  { // ACPI device path with root bridge EISA_PNP_ID
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        0,
+        0
+      }
+    },
+    EISA_PNP_ID (0x0A03),
+    0
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
+      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
+    }
+  }
+};
+
+typedef struct {
+  TEST_SIMPLE_DEVICE_PATH     *SimpleDevicePath;
+  TEST_SIMPLE_DEVICE_PATH     *InvalidDevicePath;
+  TEST_COMPLEX_DEVICE_PATH    *ComplexDevicePath;
+} SIMPLE_TEST_SUITE_CONTEXT;
+
+UNIT_TEST_STATUS
+EFIAPI
+TestIsDevicePathValid (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  BOOLEAN                    IsValid;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->SimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH));
+  UT_ASSERT_TRUE (IsValid);
+
+  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath, sizeof (TEST_COMPLEX_DEVICE_PATH));
+  UT_ASSERT_TRUE (IsValid);
+
+  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath, 0);
+  UT_ASSERT_TRUE (IsValid);
+
+  // Device path can't be NULL
+  IsValid = IsDevicePathValid (NULL, 0);
+  UT_ASSERT_FALSE (IsValid);
+
+  // MaxSize can't be less then the size of the device path
+  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->SimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH) - 1);
+  UT_ASSERT_FALSE (IsValid);
+
+  // If MaxSize != 0 it must be bigger then EFI_DEVICE_PATH_PROTOCOL
+  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->SimpleDevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL) - 1);
+  UT_ASSERT_FALSE (IsValid);
+
+  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->InvalidDevicePath, 0);
+  UT_ASSERT_FALSE (IsValid);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestDevicePathType (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINT8                      Type;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  // Test 2 types just in case the implementation is returning constant value
+  // NOTE: passing NULL to this function causes NULL pointer dereference.
+  Type = DevicePathType (&TestContext->ComplexDevicePath->AcpiPath);
+  UT_ASSERT_EQUAL (Type, ACPI_DEVICE_PATH);
+
+  Type = DevicePathType (&TestContext->ComplexDevicePath->PciPathRootPort);
+  UT_ASSERT_EQUAL (Type, HARDWARE_DEVICE_PATH);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestDevicePathSubType (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINT8                      SubType;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  // Test 2 sub types just in case the implementation is returning constant value
+  // NOTE: passing NULL to this function causes NULL pointer dereference.
+  SubType = DevicePathSubType (&TestContext->ComplexDevicePath->AcpiPath);
+  UT_ASSERT_EQUAL (SubType, ACPI_DP);
+
+  SubType = DevicePathSubType (&TestContext->ComplexDevicePath->PciPathRootPort);
+  UT_ASSERT_EQUAL (SubType, HW_PCI_DP);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestDevicePathNodeLength (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINTN                      Length;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  // Test 2 nodes just in case the implementation is returning constant value
+  // NOTE: passing NULL to this function causes NULL pointer dereference.
+  Length = DevicePathNodeLength (&TestContext->ComplexDevicePath->AcpiPath);
+  UT_ASSERT_EQUAL (Length, sizeof (ACPI_HID_DEVICE_PATH));
+
+  Length = DevicePathNodeLength (&TestContext->ComplexDevicePath->PciPathRootPort);
+  UT_ASSERT_EQUAL (Length, sizeof (PCI_DEVICE_PATH));
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestNextDevicePathNode (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  VOID                       *Node;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  Node = &mComplexDevicePath;
+  Node = NextDevicePathNode (Node);
+  UT_ASSERT_MEM_EQUAL (Node, &TestContext->ComplexDevicePath->PciPathRootPort, DevicePathNodeLength (Node));
+
+  Node = NextDevicePathNode (Node);
+  UT_ASSERT_MEM_EQUAL (Node, &TestContext->ComplexDevicePath->PciPathEndPoint, DevicePathNodeLength (Node));
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestIsDevicePathEndType (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  BOOLEAN                    IsEndType;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  IsEndType = IsDevicePathEndType (&TestContext->ComplexDevicePath->PciPathRootPort);
+  UT_ASSERT_FALSE (IsEndType);
+
+  IsEndType = IsDevicePathEndType (&TestContext->ComplexDevicePath->End);
+  UT_ASSERT_TRUE (IsEndType);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestIsDevicePathEnd (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  BOOLEAN                    IsEnd;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  IsEnd = IsDevicePathEnd (&TestContext->ComplexDevicePath->PciPathRootPort);
+  UT_ASSERT_FALSE (IsEnd);
+
+  IsEnd = IsDevicePathEnd (&TestContext->ComplexDevicePath->End);
+  UT_ASSERT_TRUE (IsEnd);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestSetDevicePathNodeLength (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  DevPath;
+
+  // NOTE: Node == NULL or NodeLength >= 0x10000 NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)
+  // are all invalid parameters. However there are only ASSERTS added to catch them so there is no
+  // way to test it.
+  SetDevicePathNodeLength (&DevPath, sizeof (EFI_DEVICE_PATH_PROTOCOL));
+  UT_ASSERT_EQUAL (DevicePathNodeLength (&DevPath), sizeof (EFI_DEVICE_PATH_PROTOCOL));
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestSetDevicePathEndNode (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  EndNode;
+
+  SetDevicePathEndNode (&EndNode);
+  UT_ASSERT_EQUAL (EndNode.Type, END_DEVICE_PATH_TYPE);
+  UT_ASSERT_EQUAL (EndNode.SubType, END_ENTIRE_DEVICE_PATH_SUBTYPE);
+  UT_ASSERT_EQUAL (DevicePathNodeLength (&EndNode), END_DEVICE_PATH_LENGTH);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestGetDevicePathSize (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  UINTN                      Size;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  Size = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->SimpleDevicePath);
+  UT_ASSERT_EQUAL (Size, sizeof (TEST_SIMPLE_DEVICE_PATH));
+
+  Size = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath);
+  UT_ASSERT_EQUAL (Size, sizeof (TEST_COMPLEX_DEVICE_PATH));
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestDuplicateDevicePath (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL   *Duplicate;
+  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
+
+  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
+
+  Duplicate = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath);
+  UT_ASSERT_EQUAL (GetDevicePathSize (Duplicate), GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath));
+  UT_ASSERT_MEM_EQUAL (Duplicate, TestContext->ComplexDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath));
+  FreePool (Duplicate);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestAppendDevicePath (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Appended;
+  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
+
+  Appended = AppendDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&mComplexDevicePath);
+  NextNode = NextDevicePathNode (Appended);
+  UT_ASSERT_MEM_EQUAL (NextNode, &mSimpleDevicePath.AcpiPath, sizeof (ACPI_HID_DEVICE_PATH));
+  FreePool (Appended);
+
+  // If one of the paths is invalid result device path should be NULL
+  Appended = AppendDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&mInvalidSimpleDevicePath);
+  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
+
+  Appended = AppendDevicePath (NULL, NULL);
+  UT_ASSERT_EQUAL (Appended->Type, END_DEVICE_PATH_TYPE);
+  UT_ASSERT_EQUAL (Appended->SubType, END_ENTIRE_DEVICE_PATH_SUBTYPE);
+  UT_ASSERT_EQUAL (DevicePathNodeLength (Appended), END_DEVICE_PATH_LENGTH);
+  FreePool (Appended);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestAppendDevicePathNode (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Appended;
+  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
+  BOOLEAN                   IsValid;
+  ACPI_HID_DEVICE_PATH      AcpiPath =
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0x0AAB),
+    0
+  };
+
+  Appended = AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&AcpiPath);
+  NextNode = NextDevicePathNode (Appended);
+  UT_ASSERT_MEM_EQUAL (NextNode, &AcpiPath, sizeof (ACPI_HID_DEVICE_PATH));
+  FreePool (Appended);
+
+  Appended = AppendDevicePathNode (NULL, (EFI_DEVICE_PATH_PROTOCOL *)&AcpiPath);
+  UT_ASSERT_MEM_EQUAL (Appended, &AcpiPath, sizeof (ACPI_HID_DEVICE_PATH));
+  IsValid = IsDevicePathValid (Appended, 0);
+  UT_ASSERT_TRUE (IsValid);
+  FreePool (Appended);
+
+  Appended = AppendDevicePathNode (NULL, NULL);
+  UT_ASSERT_EQUAL (Appended->Type, END_DEVICE_PATH_TYPE);
+  UT_ASSERT_EQUAL (Appended->SubType, END_ENTIRE_DEVICE_PATH_SUBTYPE);
+  UT_ASSERT_EQUAL (DevicePathNodeLength (Appended), END_DEVICE_PATH_LENGTH);
+  FreePool (Appended);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestAppendDevicePathInstance (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Appended;
+  EFI_DEVICE_PATH_PROTOCOL  *NextInstance;
+  EFI_DEVICE_PATH_PROTOCOL  *NextInstanceRet;
+  BOOLEAN                   IsMultiInstance;
+  UINTN                     Size;
+
+  Appended        = AppendDevicePathInstance ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&mComplexDevicePath);
+  IsMultiInstance = IsDevicePathMultiInstance (Appended);
+  UT_ASSERT_TRUE (IsMultiInstance);
+  UT_ASSERT_MEM_EQUAL (Appended, &mSimpleDevicePath, sizeof (ACPI_DEVICE_PATH));
+  NextInstance    = Appended;
+  NextInstanceRet = GetNextDevicePathInstance (&NextInstance, &Size);
+  UT_ASSERT_MEM_EQUAL (NextInstance, &mComplexDevicePath, Size);
+  FreePool (Appended);
+  FreePool (NextInstanceRet);
+
+  Appended = AppendDevicePathInstance (NULL, (EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath);
+  UT_ASSERT_MEM_EQUAL (Appended, &mSimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH));
+  FreePool (Appended);
+
+  Appended = AppendDevicePathInstance (NULL, NULL);
+  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
+  FreePool (Appended);
+
+  Appended = AppendDevicePathInstance ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&mInvalidSimpleDevicePath);
+  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
+  FreePool (Appended);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestDevicePathFromHandle (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_HANDLE                Handle;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     FakeHandle;
+
+  Handle     = NULL;
+  DevicePath = DevicePathFromHandle (Handle);
+  UT_ASSERT_EQUAL ((uintptr_t)DevicePath, (uintptr_t)NULL);
+
+  Handle     = (EFI_HANDLE)&FakeHandle;
+  DevicePath = DevicePathFromHandle (Handle);
+  UT_ASSERT_EQUAL ((uintptr_t)DevicePath, (uintptr_t)NULL);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestCreateDeviceNode (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevNode;
+
+  DevNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH));
+  UT_ASSERT_EQUAL (DevNode->Type, HARDWARE_DEVICE_PATH);
+  UT_ASSERT_EQUAL (DevNode->SubType, HW_PCI_DP);
+  UT_ASSERT_EQUAL (DevicePathNodeLength (DevNode), sizeof (PCI_DEVICE_PATH));
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestFileDevicePath (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_HANDLE            Handle;
+  FILEPATH_DEVICE_PATH  *DevicePath;
+  CONST CHAR16          *TestFilePath = L"FS0:/Boot/EFI/BootMgr.efi";
+
+  Handle     = NULL;
+  DevicePath = (FILEPATH_DEVICE_PATH *)FileDevicePath (Handle, TestFilePath);
+  UT_ASSERT_NOT_NULL (DevicePath);
+  UT_ASSERT_EQUAL (DevicePath->Header.Type, MEDIA_DEVICE_PATH);
+  UT_ASSERT_EQUAL (DevicePath->Header.Type, MEDIA_FILEPATH_DP);
+  UT_ASSERT_MEM_EQUAL (DevicePath->PathName, TestFilePath, StrSize (TestFilePath));
+
+  return UNIT_TEST_PASSED;
+}
+
+/**
+
+  Main fuction sets up the unit test environment
+
+**/
+EFI_STATUS
+EFIAPI
+UefiTestMain (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  UNIT_TEST_FRAMEWORK_HANDLE  Framework;
+  UNIT_TEST_SUITE_HANDLE      DevicePathSimpleTestSuite;
+  UNIT_TEST_SUITE_HANDLE      DevicePathAppendTestSuite;
+  UNIT_TEST_SUITE_HANDLE      DevicePathFileTestSuite;
+  SIMPLE_TEST_SUITE_CONTEXT   SimpleTestContext;
+
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
+
+  Framework                 = NULL;
+  DevicePathSimpleTestSuite = NULL;
+  DevicePathAppendTestSuite = NULL;
+  DevicePathFileTestSuite   = NULL;
+
+  Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+    goto EXIT;
+  }
+
+  Status = CreateUnitTestSuite (&DevicePathSimpleTestSuite, Framework, "Simple device path operations test suite", "Common.DevicePath.SimpleOps", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to create simple device path test suite\n"));
+    goto EXIT;
+  }
+
+  SimpleTestContext.SimpleDevicePath  = &mSimpleDevicePath;
+  SimpleTestContext.InvalidDevicePath = &mInvalidSimpleDevicePath;
+  SimpleTestContext.ComplexDevicePath = &mComplexDevicePath;
+
+  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathValid", "TestIsDevicePathValid", TestIsDevicePathValid, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathType", "TestDevicePathType", TestDevicePathType, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathSubType", "TestDevicePathSubType", TestDevicePathSubType, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathNodeLength", "TestDevicePathNodeLength", TestDevicePathNodeLength, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test NextDevicePathNode", "TestNextDevicePathNode", TestNextDevicePathNode, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathEndType", "TestIsDevicePathEndType", TestIsDevicePathEndType, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathEnd", "TestIsDevicePathEnd", TestIsDevicePathEnd, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test SetDevicePathNodeLength", "TestSetDevicePathNodeLength", TestSetDevicePathNodeLength, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test GetDevicePathSize", "TestGetDevicePathSize", TestGetDevicePathSize, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test CreateDeviceNode", "TestCreateDeviceNode", TestCreateDeviceNode, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathSimpleTestSuite, "Test SetDevicePathEndNode", "TestSetDevicePathEndNode", TestSetDevicePathEndNode, NULL, NULL, &SimpleTestContext);
+  AddTestCase (DevicePathAppendTestSuite, "Test DuplicateDevicePath", "TestDuplicateDevicePath", TestDuplicateDevicePath, NULL, NULL, &SimpleTestContext);
+
+  Status = CreateUnitTestSuite (&DevicePathAppendTestSuite, Framework, "Device path append operations test suite", "Common.DevicePath.Append", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to create append device path test suite\n"));
+    goto EXIT;
+  }
+
+  AddTestCase (DevicePathAppendTestSuite, "Test AppendDevicePath", "TestAppendDevicePath", TestAppendDevicePath, NULL, NULL, NULL);
+  AddTestCase (DevicePathAppendTestSuite, "Test AppendDevicePathNode", "TestAppendDevicePathNode", TestAppendDevicePathNode, NULL, NULL, NULL);
+  AddTestCase (DevicePathAppendTestSuite, "Test AppendDevicePathInstance", "TestAppendDevicePathInstance", TestAppendDevicePathInstance, NULL, NULL, NULL);
+
+  Status = CreateDevicePathStringConversionsTestSuite (Framework);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to create conversions test suite\n"));
+    goto EXIT;
+  }
+
+  Status = CreateUnitTestSuite (&DevicePathFileTestSuite, Framework, "Device path file operations test suite", "Common.DevicePath.FileDevPath", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to create device path file test suite\n"));
+    goto EXIT;
+  }
+
+  AddTestCase (DevicePathFileTestSuite, "Test DevicePathFromHandle", "TestDevicePathFromHandle", TestDevicePathFromHandle, NULL, NULL, NULL);
+  AddTestCase (DevicePathFileTestSuite, "Test FileDevicePath", "TestFileDevicePath", TestFileDevicePath, NULL, NULL, NULL);
+
+  Status = RunAllTestSuites (Framework);
+
+EXIT:
+  if (Framework != NULL) {
+    FreeUnitTestFramework (Framework);
+  }
+
+  return Status;
+}
+
+int
+main (
+  int   argc,
+  char  *argv[]
+  )
+{
+  return UefiTestMain ();
+}
diff --git a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
new file mode 100644
index 0000000000..4a0c3d4c43
--- /dev/null
+++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
@@ -0,0 +1,26 @@
+/** @file
+  UEFI OS based application for unit testing the DevicePathLib.
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __TEST_DEVICE_PATH_LIB_H__
+#define __TEST_DEVICE_PATH_LIB_H__
+
+#include <PiPei.h>
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UnitTestLib.h>
+#include <Protocol/DevicePath.h>
+#include <Library/DevicePathLib.h>
+#include <stdint.h>
+
+EFI_STATUS
+CreateDevicePathStringConversionsTestSuite (
+  IN UNIT_TEST_FRAMEWORK_HANDLE  Framework
+  );
+
+#endif
diff --git a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
new file mode 100644
index 0000000000..9f9c36946a
--- /dev/null
+++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
@@ -0,0 +1,33 @@
+## @file
+# Host OS based Application that Unit Tests the UefiDevicePathLib
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION     = 0x00010005
+  BASE_NAME       = TestDevicePathLibHost
+  MODULE_UNI_FILE = TestDevicePathLib.uni
+  FILE_GUID       = F1505A0E-D71F-4431-99BE-736776842E38
+  MODULE_TYPE     = HOST_APPLICATION
+  VERSION_STRING  = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  TestDevicePathLib.c
+  TestDevicePathStringConversions.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  DevicePathLib
+  UnitTestLib
diff --git a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c
new file mode 100644
index 0000000000..4ea25ec142
--- /dev/null
+++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c
@@ -0,0 +1,370 @@
+/** @file
+  UEFI OS based application for unit testing the DevicePathLib.
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestDevicePathLib.h"
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL    *DevPath;
+  CONST CHAR16                *DevPathString;
+} DEVICE_PATH_CONVERSIONS_TEST_CONTEXT;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCI_DEVICE_PATH  mPciDevicePathNode =
+{
+  // PCI device path - root port (0x2:0x0)
+  {
+    HARDWARE_DEVICE_PATH,
+    HW_PCI_DP,
+    {
+      (UINT8)(sizeof (PCI_DEVICE_PATH)),
+      (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
+    }
+  },
+  0x2,
+  0x0
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED ACPI_HID_DEVICE_PATH  mAcpiPciRootHidDevicePathNode =
+{
+  // ACPI PCI root - PciRoot(0x0)
+  {
+    ACPI_DEVICE_PATH,
+    ACPI_DP,
+    {
+      (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+      (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+    }
+  },
+  EISA_PNP_ID (0x0A03),
+  0
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED ACPI_HID_DEVICE_PATH  mAcpiNonPciRootHidDevicePathNode =
+{
+  // Random ACPI device - ACPI(PNPB0C0, 1)
+  {
+    ACPI_DEVICE_PATH,
+    ACPI_DP,
+    {
+      (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+      (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+    }
+  },
+  EISA_PNP_ID (0xB0C0),
+  1
+};
+
+#define HID_STR_SIZE  8
+#define CID_STR_SIZE  8
+#define UID_STR_SIZE  8
+
+typedef struct {
+  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
+  CHAR8                            HidStr[HID_STR_SIZE];
+  CHAR8                            CidStr[CID_STR_SIZE];
+  CHAR8                            UidStr[UID_STR_SIZE];
+} ACPI_EXTENDED_HID_DEVICE_PATH_FULL;
+
+GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXTENDED_HID_DEVICE_PATH_FULL  mAcpiExtendedDevicePathFull =
+{
+  // ACPI Extended HID PciRoot device node
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_EXTENDED_DP,
+      {
+        (UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_FULL)),
+        (UINT8)((sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_FULL)) >> 8)
+      }
+    },
+    0,
+    0,
+    0,
+  },
+  { 'P', 'N', 'P', 'B', '0', 'C', '0', '\0' }, // HIDSTR
+  { 'P', 'N', 'P', '0', '0', '0', '1', '\0' }, // CIDSTR
+  { 'U', 'I', 'D', '0', '0', '0', '0', '\0' } // UIDSTR
+};
+
+typedef struct {
+  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
+  CHAR8                            HidStr[HID_STR_SIZE];
+} ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL;
+
+GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL  mAcpiExtendedDevicePathPartial =
+{
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_EXTENDED_DP,
+      {
+        (UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL)),
+        (UINT8)((sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL)) >> 8)
+      }
+    },
+    0,
+    2,
+    0,
+  },
+  { 'P', 'N', 'P', 'B', '0', '\0', '\0', '\0' }, // HIDSTR
+};
+
+typedef struct {
+  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
+  CHAR8                            UidStr[UID_STR_SIZE];
+} ACPI_EXPANDED_DEVICE_PATH;
+
+GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXPANDED_DEVICE_PATH  mAcpiExpandedDevicePathUidOnly =
+{
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_EXTENDED_DP,
+      {
+        (UINT8)(sizeof (ACPI_EXPANDED_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_EXPANDED_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0xAAAA),
+    0,
+    0,
+  },
+  { '\0', 'U', 'I', 'D', '0', '0', '\0', '\0' } // UIDSTR
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXPANDED_DEVICE_PATH  mAcpiExpandedDevicePathUidOnlyWithCid =
+{
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_EXTENDED_DP,
+      {
+        (UINT8)(sizeof (ACPI_EXPANDED_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_EXPANDED_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0xAAAA),
+    0,
+    EISA_PNP_ID (0xAADD),
+  },
+  { '\0', 'U', 'I', 'D', '0', '0', '\0', '\0' } // UIDSTR
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  mDevPathNodeToFromTextContext[] = {
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mPciDevicePathNode,
+    L"Pci(0x0,0x2)"
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiPciRootHidDevicePathNode,
+    L"PciRoot(0x0)"
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiNonPciRootHidDevicePathNode,
+    L"Acpi(PNPB0C0,0x1)"
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExtendedDevicePathFull,
+    L"AcpiEx(@@@0000,@@@0000,0x0,PNPB0C0,UID0000,PNP0001)"
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExtendedDevicePathPartial,
+    L"AcpiEx(@@@0000,@@@0000,0x2,PNPB0,,)"
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExpandedDevicePathUidOnly,
+    L"AcpiExp(PNPAAAA,0,UID00)"
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExpandedDevicePathUidOnlyWithCid,
+    L"AcpiExp(PNPAAAA,PNPAADD,UID00)"
+  }
+};
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH        AcpiPath;
+  PCI_DEVICE_PATH             PciPathRootPort;
+  PCI_DEVICE_PATH             PciPathEndPoint;
+  USB_DEVICE_PATH             UsbPath;
+  EFI_DEVICE_PATH_PROTOCOL    End;
+} TEST_CONVERSIONS_DEVICE_PATH;
+
+GLOBAL_REMOVE_IF_UNREFERENCED TEST_CONVERSIONS_DEVICE_PATH  mConversionsDevicePath = {
+  { // ACPI device path with root bridge EISA_PNP_ID
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0x0A03),
+    0
+  },
+  { // PCI device path - root port (0x2:0x0)
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_PCI_DP,
+      {
+        (UINT8)(sizeof (PCI_DEVICE_PATH)),
+        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
+      }
+    },
+    0x2,
+    0x0
+  },
+  { // PCI device path - endpoint (0x0:0x0)
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_PCI_DP,
+      {
+        (UINT8)(sizeof (PCI_DEVICE_PATH)),
+        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
+      }
+    },
+    0x0,
+    0x0
+  },
+  { // USB interface
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_USB_DP,
+      {
+        (UINT8)(sizeof (USB_DEVICE_PATH)),
+        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+      }
+    },
+    0,
+    2
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
+      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
+    }
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  mDevPathToFromTextContext[] = {
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *)&mConversionsDevicePath,
+    L"PciRoot(0x0)/Pci(0x0,0x2)/Pci(0x0,0x0)/USB(0x0,0x2)"
+  }
+};
+
+UNIT_TEST_STATUS
+EFIAPI
+TestConvertDevicePathToText (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  CHAR16                                *DevPathString;
+  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
+
+  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
+
+  DevPathString = ConvertDevicePathToText (TestContext->DevPath, FALSE, FALSE);
+  UT_ASSERT_EQUAL (StrLen (DevPathString), StrLen (TestContext->DevPathString));
+  UT_ASSERT_MEM_EQUAL (DevPathString, TestContext->DevPathString, StrLen (TestContext->DevPathString));
+  FreePool (DevPathString);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestConvertTextToDevicePath (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL              *ConvertedDevPath;
+  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
+
+  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
+
+  ConvertedDevPath = ConvertTextToDevicePath (TestContext->DevPathString);
+  UT_ASSERT_EQUAL (GetDevicePathSize (ConvertedDevPath), GetDevicePathSize (TestContext->DevPath));
+  UT_ASSERT_MEM_EQUAL (ConvertedDevPath, TestContext->DevPath, GetDevicePathSize (TestContext->DevPath));
+  FreePool (ConvertedDevPath);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestConvertDeviceNodeToText (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  CHAR16                                *DevPathNodeString;
+  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
+
+  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
+
+  DevPathNodeString = ConvertDeviceNodeToText (TestContext->DevPath, FALSE, FALSE);
+  UT_ASSERT_EQUAL (StrLen (DevPathNodeString), StrLen (TestContext->DevPathString));
+  UT_ASSERT_MEM_EQUAL (DevPathNodeString, TestContext->DevPathString, StrLen (TestContext->DevPathString));
+  FreePool (DevPathNodeString);
+
+  return UNIT_TEST_PASSED;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestConvertTextToDeviceNode (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL              *DevPath;
+  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
+
+  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
+
+  DevPath = ConvertTextToDeviceNode (TestContext->DevPathString);
+  UT_ASSERT_EQUAL (DevicePathNodeLength (DevPath), DevicePathNodeLength (TestContext->DevPath));
+  UT_ASSERT_MEM_EQUAL (DevPath, TestContext->DevPath, DevicePathNodeLength (TestContext->DevPath));
+  FreePool (DevPath);
+
+  return UNIT_TEST_PASSED;
+}
+
+EFI_STATUS
+CreateDevicePathStringConversionsTestSuite (
+  IN UNIT_TEST_FRAMEWORK_HANDLE  Framework
+  )
+{
+  EFI_STATUS              Status;
+  UNIT_TEST_SUITE_HANDLE  DevicePathTextConversionSuite = NULL;
+  UINTN                   Index;
+
+  Status = CreateUnitTestSuite (&DevicePathTextConversionSuite, Framework, "Device path text conversion operations test suite", "Common.DevicePath.TextConversions", NULL, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to create device path text conversions test suite\n"));
+    return Status;
+  }
+
+  for (Index = 0; Index < ARRAY_SIZE (mDevPathNodeToFromTextContext); Index++) {
+    AddTestCase (DevicePathTextConversionSuite, "Test ConvertDeviceNodeToText", "TestConvertDeviceNodeToText", TestConvertDeviceNodeToText, NULL, NULL, &mDevPathNodeToFromTextContext[Index]);
+  }
+
+  for (Index = 0; Index < ARRAY_SIZE (mDevPathNodeToFromTextContext); Index++) {
+    AddTestCase (DevicePathTextConversionSuite, "Test ConvertTextToDeviceNode", "TestConvertTextToDeviceNode", TestConvertTextToDeviceNode, NULL, NULL, &mDevPathNodeToFromTextContext[Index]);
+  }
+
+  for (Index = 0; Index < ARRAY_SIZE (mDevPathToFromTextContext); Index++) {
+    AddTestCase (DevicePathTextConversionSuite, "Test ConvertDevicePathToText", "TestConvertDevicePathToText", TestConvertDevicePathToText, NULL, NULL, &mDevPathToFromTextContext[Index]);
+  }
+
+  for (Index = 0; Index < ARRAY_SIZE (mDevPathToFromTextContext); Index++) {
+    AddTestCase (DevicePathTextConversionSuite, "Test ConvertTextToDevicePath", "TestConvertTextToDevicePath", TestConvertTextToDevicePath, NULL, NULL, &mDevPathToFromTextContext[Index]);
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.39.2

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109126): https://edk2.groups.io/g/devel/message/109126
Mute This Topic: https://groups.io/mt/101619981/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test module
Posted by Michael D Kinney 2 years, 3 months ago
Reviewed-by: Michael D Kinney <Michael.d.kinney@intel.com>

> -----Original Message-----
> From: Albecki, Mateusz <mateusz.albecki@intel.com>
> Sent: Wednesday, September 27, 2023 8:51 AM
> To: devel@edk2.groups.io
> Cc: Albecki, Mateusz <mateusz.albecki@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>;
> Liu, Zhiguang <zhiguang.liu@intel.com>
> Subject: [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test module
> 
> This commit adds host-based unit tests for device path lib.
> 
> 
> 
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> 
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> 
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> 
> 
> 
> Signed-off-by: Mateusz Albecki <mateusz.albecki@intel.com>
> 
> ---
> 
>  MdePkg/MdePkg.ci.yaml                         |   5 +-
> 
>  MdePkg/Test/MdePkgHostTest.dsc                |   2 +
> 
>  .../Library/DevicePathLib/TestDevicePathLib.c | 638
> ++++++++++++++++++
> 
>  .../Library/DevicePathLib/TestDevicePathLib.h |  26 +
> 
>  .../DevicePathLib/TestDevicePathLibHost.inf   |  33 +
> 
>  .../TestDevicePathStringConversions.c         | 370 ++++++++++
> 
>  6 files changed, 1073 insertions(+), 1 deletion(-)
> 
>  create mode 100644
> MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> 
>  create mode 100644
> MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> 
>  create mode 100644
> MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> 
>  create mode 100644
> MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConvers
> ions.c
> 
> 
> 
> diff --git a/MdePkg/MdePkg.ci.yaml b/MdePkg/MdePkg.ci.yaml
> 
> index c3faf4913d..45f4fb537b 100644
> 
> --- a/MdePkg/MdePkg.ci.yaml
> 
> +++ b/MdePkg/MdePkg.ci.yaml
> 
> @@ -74,7 +74,10 @@
> 
> 
> "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",
> 
>              "Library/BaseFdtLib",
> 
>              "Library/MipiSysTLib/mipi_syst.h",
> 
> -            "Include/Register/Amd/SmramSaveStateMap.h"
> 
> +            "Include/Register/Amd/SmramSaveStateMap.h",
> 
> +
> "Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c",
> 
> +
> "Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h",
> 
> +
> "Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c
> "
> 
>          ]
> 
>      },
> 
>      ## options defined ci/Plugin/CompilerPlugin
> 
> diff --git a/MdePkg/Test/MdePkgHostTest.dsc
> b/MdePkg/Test/MdePkgHostTest.dsc
> 
> index 529ea69024..b92b564d43 100644
> 
> --- a/MdePkg/Test/MdePkgHostTest.dsc
> 
> +++ b/MdePkg/Test/MdePkgHostTest.dsc
> 
> @@ -21,6 +21,7 @@
> 
> 
> 
>  [LibraryClasses]
> 
>    SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> 
> +
> DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.i
> nf
> 
> 
> 
>  [Components]
> 
>    #
> 
> @@ -29,6 +30,7 @@
> 
> 
> MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost.inf
> 
>    MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost.inf
> 
> 
> MdePkg/Test/GoogleTest/Library/BaseSafeIntLib/GoogleTestBaseSafeIntLib
> .inf
> 
> +
> MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> 
> 
> 
>    #
> 
>    # Build HOST_APPLICATION Libraries
> 
> diff --git
> a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> 
> new file mode 100644
> 
> index 0000000000..687497278c
> 
> --- /dev/null
> 
> +++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> 
> @@ -0,0 +1,638 @@
> 
> +/** @file
> 
> +  UEFI OS based application for unit testing the DevicePathLib.
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +
> 
> +#include "TestDevicePathLib.h"
> 
> +
> 
> +#define UNIT_TEST_NAME     "DevicePathLib Unit Test Application"
> 
> +#define UNIT_TEST_VERSION  "0.1"
> 
> +
> 
> +typedef struct {
> 
> +  ACPI_HID_DEVICE_PATH        AcpiPath;
> 
> +  PCI_DEVICE_PATH             PciPathRootPort;
> 
> +  PCI_DEVICE_PATH             PciPathEndPoint;
> 
> +  USB_DEVICE_PATH             UsbPath;
> 
> +  EFI_DEVICE_PATH_PROTOCOL    End;
> 
> +} TEST_COMPLEX_DEVICE_PATH;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED TEST_COMPLEX_DEVICE_PATH
> mComplexDevicePath = {
> 
> +  { // ACPI device path with root bridge EISA_PNP_ID
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0x0A03),
> 
> +    0
> 
> +  },
> 
> +  { // PCI device path - root port (0x2:0x0)
> 
> +    {
> 
> +      HARDWARE_DEVICE_PATH,
> 
> +      HW_PCI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0x2,
> 
> +    0x0
> 
> +  },
> 
> +  { // PCI device path - endpoint (0x0:0x0)
> 
> +    {
> 
> +      HARDWARE_DEVICE_PATH,
> 
> +      HW_PCI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0x0,
> 
> +    0x0
> 
> +  },
> 
> +  { // USB interface
> 
> +    {
> 
> +      MESSAGING_DEVICE_PATH,
> 
> +      MSG_USB_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (USB_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0,
> 
> +    2
> 
> +  },
> 
> +  {
> 
> +    END_DEVICE_PATH_TYPE,
> 
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> 
> +    {
> 
> +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> 
> +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> 
> +    }
> 
> +  }
> 
> +};
> 
> +
> 
> +CONST GLOBAL_REMOVE_IF_UNREFERENCED CHAR16  *mComplexDevicePathString
> = L"PciRoot(0x0)/Pci(0x0,0x2)/Pci(0x0,0x0)/USB(0x0,0x2)";
> 
> +
> 
> +CONST GLOBAL_REMOVE_IF_UNREFERENCED CHAR16  *mPciEndPointPathString =
> L"Pci(0x0, 0x0)";
> 
> +
> 
> +typedef struct {
> 
> +  ACPI_HID_DEVICE_PATH        AcpiPath;
> 
> +  EFI_DEVICE_PATH_PROTOCOL    End;
> 
> +} TEST_SIMPLE_DEVICE_PATH;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED TEST_SIMPLE_DEVICE_PATH
> mSimpleDevicePath = {
> 
> +  { // ACPI device path with root bridge EISA_PNP_ID
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0x0A03),
> 
> +    0
> 
> +  },
> 
> +  {
> 
> +    END_DEVICE_PATH_TYPE,
> 
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> 
> +    {
> 
> +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> 
> +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> 
> +    }
> 
> +  }
> 
> +};
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED TEST_SIMPLE_DEVICE_PATH
> mInvalidSimpleDevicePath = {
> 
> +  { // ACPI device path with root bridge EISA_PNP_ID
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_DP,
> 
> +      {
> 
> +        0,
> 
> +        0
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0x0A03),
> 
> +    0
> 
> +  },
> 
> +  {
> 
> +    END_DEVICE_PATH_TYPE,
> 
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> 
> +    {
> 
> +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> 
> +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> 
> +    }
> 
> +  }
> 
> +};
> 
> +
> 
> +typedef struct {
> 
> +  TEST_SIMPLE_DEVICE_PATH     *SimpleDevicePath;
> 
> +  TEST_SIMPLE_DEVICE_PATH     *InvalidDevicePath;
> 
> +  TEST_COMPLEX_DEVICE_PATH    *ComplexDevicePath;
> 
> +} SIMPLE_TEST_SUITE_CONTEXT;
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestIsDevicePathValid (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  BOOLEAN                    IsValid;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->SimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH));
> 
> +  UT_ASSERT_TRUE (IsValid);
> 
> +
> 
> +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->ComplexDevicePath, sizeof (TEST_COMPLEX_DEVICE_PATH));
> 
> +  UT_ASSERT_TRUE (IsValid);
> 
> +
> 
> +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->ComplexDevicePath, 0);
> 
> +  UT_ASSERT_TRUE (IsValid);
> 
> +
> 
> +  // Device path can't be NULL
> 
> +  IsValid = IsDevicePathValid (NULL, 0);
> 
> +  UT_ASSERT_FALSE (IsValid);
> 
> +
> 
> +  // MaxSize can't be less then the size of the device path
> 
> +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->SimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH) -
> 1);
> 
> +  UT_ASSERT_FALSE (IsValid);
> 
> +
> 
> +  // If MaxSize != 0 it must be bigger then EFI_DEVICE_PATH_PROTOCOL
> 
> +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->SimpleDevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL) -
> 1);
> 
> +  UT_ASSERT_FALSE (IsValid);
> 
> +
> 
> +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->InvalidDevicePath, 0);
> 
> +  UT_ASSERT_FALSE (IsValid);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestDevicePathType (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  UINT8                      Type;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  // Test 2 types just in case the implementation is returning
> constant value
> 
> +  // NOTE: passing NULL to this function causes NULL pointer
> dereference.
> 
> +  Type = DevicePathType (&TestContext->ComplexDevicePath->AcpiPath);
> 
> +  UT_ASSERT_EQUAL (Type, ACPI_DEVICE_PATH);
> 
> +
> 
> +  Type = DevicePathType (&TestContext->ComplexDevicePath-
> >PciPathRootPort);
> 
> +  UT_ASSERT_EQUAL (Type, HARDWARE_DEVICE_PATH);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestDevicePathSubType (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  UINT8                      SubType;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  // Test 2 sub types just in case the implementation is returning
> constant value
> 
> +  // NOTE: passing NULL to this function causes NULL pointer
> dereference.
> 
> +  SubType = DevicePathSubType (&TestContext->ComplexDevicePath-
> >AcpiPath);
> 
> +  UT_ASSERT_EQUAL (SubType, ACPI_DP);
> 
> +
> 
> +  SubType = DevicePathSubType (&TestContext->ComplexDevicePath-
> >PciPathRootPort);
> 
> +  UT_ASSERT_EQUAL (SubType, HW_PCI_DP);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestDevicePathNodeLength (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  UINTN                      Length;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  // Test 2 nodes just in case the implementation is returning
> constant value
> 
> +  // NOTE: passing NULL to this function causes NULL pointer
> dereference.
> 
> +  Length = DevicePathNodeLength (&TestContext->ComplexDevicePath-
> >AcpiPath);
> 
> +  UT_ASSERT_EQUAL (Length, sizeof (ACPI_HID_DEVICE_PATH));
> 
> +
> 
> +  Length = DevicePathNodeLength (&TestContext->ComplexDevicePath-
> >PciPathRootPort);
> 
> +  UT_ASSERT_EQUAL (Length, sizeof (PCI_DEVICE_PATH));
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestNextDevicePathNode (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  VOID                       *Node;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  Node = &mComplexDevicePath;
> 
> +  Node = NextDevicePathNode (Node);
> 
> +  UT_ASSERT_MEM_EQUAL (Node, &TestContext->ComplexDevicePath-
> >PciPathRootPort, DevicePathNodeLength (Node));
> 
> +
> 
> +  Node = NextDevicePathNode (Node);
> 
> +  UT_ASSERT_MEM_EQUAL (Node, &TestContext->ComplexDevicePath-
> >PciPathEndPoint, DevicePathNodeLength (Node));
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestIsDevicePathEndType (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  BOOLEAN                    IsEndType;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  IsEndType = IsDevicePathEndType (&TestContext->ComplexDevicePath-
> >PciPathRootPort);
> 
> +  UT_ASSERT_FALSE (IsEndType);
> 
> +
> 
> +  IsEndType = IsDevicePathEndType (&TestContext->ComplexDevicePath-
> >End);
> 
> +  UT_ASSERT_TRUE (IsEndType);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestIsDevicePathEnd (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  BOOLEAN                    IsEnd;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  IsEnd = IsDevicePathEnd (&TestContext->ComplexDevicePath-
> >PciPathRootPort);
> 
> +  UT_ASSERT_FALSE (IsEnd);
> 
> +
> 
> +  IsEnd = IsDevicePathEnd (&TestContext->ComplexDevicePath->End);
> 
> +  UT_ASSERT_TRUE (IsEnd);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestSetDevicePathNodeLength (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL  DevPath;
> 
> +
> 
> +  // NOTE: Node == NULL or NodeLength >= 0x10000 NodeLength < sizeof
> (EFI_DEVICE_PATH_PROTOCOL)
> 
> +  // are all invalid parameters. However there are only ASSERTS added
> to catch them so there is no
> 
> +  // way to test it.
> 
> +  SetDevicePathNodeLength (&DevPath, sizeof
> (EFI_DEVICE_PATH_PROTOCOL));
> 
> +  UT_ASSERT_EQUAL (DevicePathNodeLength (&DevPath), sizeof
> (EFI_DEVICE_PATH_PROTOCOL));
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestSetDevicePathEndNode (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL  EndNode;
> 
> +
> 
> +  SetDevicePathEndNode (&EndNode);
> 
> +  UT_ASSERT_EQUAL (EndNode.Type, END_DEVICE_PATH_TYPE);
> 
> +  UT_ASSERT_EQUAL (EndNode.SubType, END_ENTIRE_DEVICE_PATH_SUBTYPE);
> 
> +  UT_ASSERT_EQUAL (DevicePathNodeLength (&EndNode),
> END_DEVICE_PATH_LENGTH);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestGetDevicePathSize (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  UINTN                      Size;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  Size = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext-
> >SimpleDevicePath);
> 
> +  UT_ASSERT_EQUAL (Size, sizeof (TEST_SIMPLE_DEVICE_PATH));
> 
> +
> 
> +  Size = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext-
> >ComplexDevicePath);
> 
> +  UT_ASSERT_EQUAL (Size, sizeof (TEST_COMPLEX_DEVICE_PATH));
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestDuplicateDevicePath (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL   *Duplicate;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> 
> +
> 
> +  Duplicate = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext->ComplexDevicePath);
> 
> +  UT_ASSERT_EQUAL (GetDevicePathSize (Duplicate), GetDevicePathSize
> ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath));
> 
> +  UT_ASSERT_MEM_EQUAL (Duplicate, TestContext->ComplexDevicePath,
> GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext-
> >ComplexDevicePath));
> 
> +  FreePool (Duplicate);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestAppendDevicePath (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *Appended;
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
> 
> +
> 
> +  Appended = AppendDevicePath ((EFI_DEVICE_PATH_PROTOCOL
> *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL
> *)&mComplexDevicePath);
> 
> +  NextNode = NextDevicePathNode (Appended);
> 
> +  UT_ASSERT_MEM_EQUAL (NextNode, &mSimpleDevicePath.AcpiPath, sizeof
> (ACPI_HID_DEVICE_PATH));
> 
> +  FreePool (Appended);
> 
> +
> 
> +  // If one of the paths is invalid result device path should be NULL
> 
> +  Appended = AppendDevicePath ((EFI_DEVICE_PATH_PROTOCOL
> *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL
> *)&mInvalidSimpleDevicePath);
> 
> +  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
> 
> +
> 
> +  Appended = AppendDevicePath (NULL, NULL);
> 
> +  UT_ASSERT_EQUAL (Appended->Type, END_DEVICE_PATH_TYPE);
> 
> +  UT_ASSERT_EQUAL (Appended->SubType,
> END_ENTIRE_DEVICE_PATH_SUBTYPE);
> 
> +  UT_ASSERT_EQUAL (DevicePathNodeLength (Appended),
> END_DEVICE_PATH_LENGTH);
> 
> +  FreePool (Appended);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestAppendDevicePathNode (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *Appended;
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
> 
> +  BOOLEAN                   IsValid;
> 
> +  ACPI_HID_DEVICE_PATH      AcpiPath =
> 
> +  {
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0x0AAB),
> 
> +    0
> 
> +  };
> 
> +
> 
> +  Appended = AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
> *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&AcpiPath);
> 
> +  NextNode = NextDevicePathNode (Appended);
> 
> +  UT_ASSERT_MEM_EQUAL (NextNode, &AcpiPath, sizeof
> (ACPI_HID_DEVICE_PATH));
> 
> +  FreePool (Appended);
> 
> +
> 
> +  Appended = AppendDevicePathNode (NULL, (EFI_DEVICE_PATH_PROTOCOL
> *)&AcpiPath);
> 
> +  UT_ASSERT_MEM_EQUAL (Appended, &AcpiPath, sizeof
> (ACPI_HID_DEVICE_PATH));
> 
> +  IsValid = IsDevicePathValid (Appended, 0);
> 
> +  UT_ASSERT_TRUE (IsValid);
> 
> +  FreePool (Appended);
> 
> +
> 
> +  Appended = AppendDevicePathNode (NULL, NULL);
> 
> +  UT_ASSERT_EQUAL (Appended->Type, END_DEVICE_PATH_TYPE);
> 
> +  UT_ASSERT_EQUAL (Appended->SubType,
> END_ENTIRE_DEVICE_PATH_SUBTYPE);
> 
> +  UT_ASSERT_EQUAL (DevicePathNodeLength (Appended),
> END_DEVICE_PATH_LENGTH);
> 
> +  FreePool (Appended);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestAppendDevicePathInstance (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *Appended;
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *NextInstance;
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *NextInstanceRet;
> 
> +  BOOLEAN                   IsMultiInstance;
> 
> +  UINTN                     Size;
> 
> +
> 
> +  Appended        = AppendDevicePathInstance
> ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath,
> (EFI_DEVICE_PATH_PROTOCOL *)&mComplexDevicePath);
> 
> +  IsMultiInstance = IsDevicePathMultiInstance (Appended);
> 
> +  UT_ASSERT_TRUE (IsMultiInstance);
> 
> +  UT_ASSERT_MEM_EQUAL (Appended, &mSimpleDevicePath, sizeof
> (ACPI_DEVICE_PATH));
> 
> +  NextInstance    = Appended;
> 
> +  NextInstanceRet = GetNextDevicePathInstance (&NextInstance, &Size);
> 
> +  UT_ASSERT_MEM_EQUAL (NextInstance, &mComplexDevicePath, Size);
> 
> +  FreePool (Appended);
> 
> +  FreePool (NextInstanceRet);
> 
> +
> 
> +  Appended = AppendDevicePathInstance (NULL,
> (EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath);
> 
> +  UT_ASSERT_MEM_EQUAL (Appended, &mSimpleDevicePath, sizeof
> (TEST_SIMPLE_DEVICE_PATH));
> 
> +  FreePool (Appended);
> 
> +
> 
> +  Appended = AppendDevicePathInstance (NULL, NULL);
> 
> +  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
> 
> +  FreePool (Appended);
> 
> +
> 
> +  Appended = AppendDevicePathInstance ((EFI_DEVICE_PATH_PROTOCOL
> *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL
> *)&mInvalidSimpleDevicePath);
> 
> +  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
> 
> +  FreePool (Appended);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestDevicePathFromHandle (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_HANDLE                Handle;
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> 
> +  UINTN                     FakeHandle;
> 
> +
> 
> +  Handle     = NULL;
> 
> +  DevicePath = DevicePathFromHandle (Handle);
> 
> +  UT_ASSERT_EQUAL ((uintptr_t)DevicePath, (uintptr_t)NULL);
> 
> +
> 
> +  Handle     = (EFI_HANDLE)&FakeHandle;
> 
> +  DevicePath = DevicePathFromHandle (Handle);
> 
> +  UT_ASSERT_EQUAL ((uintptr_t)DevicePath, (uintptr_t)NULL);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestCreateDeviceNode (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL  *DevNode;
> 
> +
> 
> +  DevNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof
> (PCI_DEVICE_PATH));
> 
> +  UT_ASSERT_EQUAL (DevNode->Type, HARDWARE_DEVICE_PATH);
> 
> +  UT_ASSERT_EQUAL (DevNode->SubType, HW_PCI_DP);
> 
> +  UT_ASSERT_EQUAL (DevicePathNodeLength (DevNode), sizeof
> (PCI_DEVICE_PATH));
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestFileDevicePath (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_HANDLE            Handle;
> 
> +  FILEPATH_DEVICE_PATH  *DevicePath;
> 
> +  CONST CHAR16          *TestFilePath = L"FS0:/Boot/EFI/BootMgr.efi";
> 
> +
> 
> +  Handle     = NULL;
> 
> +  DevicePath = (FILEPATH_DEVICE_PATH *)FileDevicePath (Handle,
> TestFilePath);
> 
> +  UT_ASSERT_NOT_NULL (DevicePath);
> 
> +  UT_ASSERT_EQUAL (DevicePath->Header.Type, MEDIA_DEVICE_PATH);
> 
> +  UT_ASSERT_EQUAL (DevicePath->Header.Type, MEDIA_FILEPATH_DP);
> 
> +  UT_ASSERT_MEM_EQUAL (DevicePath->PathName, TestFilePath, StrSize
> (TestFilePath));
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +/**
> 
> +
> 
> +  Main fuction sets up the unit test environment
> 
> +
> 
> +**/
> 
> +EFI_STATUS
> 
> +EFIAPI
> 
> +UefiTestMain (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  EFI_STATUS                  Status;
> 
> +  UNIT_TEST_FRAMEWORK_HANDLE  Framework;
> 
> +  UNIT_TEST_SUITE_HANDLE      DevicePathSimpleTestSuite;
> 
> +  UNIT_TEST_SUITE_HANDLE      DevicePathAppendTestSuite;
> 
> +  UNIT_TEST_SUITE_HANDLE      DevicePathFileTestSuite;
> 
> +  SIMPLE_TEST_SUITE_CONTEXT   SimpleTestContext;
> 
> +
> 
> +  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME,
> UNIT_TEST_VERSION));
> 
> +
> 
> +  Framework                 = NULL;
> 
> +  DevicePathSimpleTestSuite = NULL;
> 
> +  DevicePathAppendTestSuite = NULL;
> 
> +  DevicePathFileTestSuite   = NULL;
> 
> +
> 
> +  Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME,
> gEfiCallerBaseName, UNIT_TEST_VERSION);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =
> %r\n", Status));
> 
> +    goto EXIT;
> 
> +  }
> 
> +
> 
> +  Status = CreateUnitTestSuite (&DevicePathSimpleTestSuite,
> Framework, "Simple device path operations test suite",
> "Common.DevicePath.SimpleOps", NULL, NULL);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_ERROR, "Failed to create simple device path test
> suite\n"));
> 
> +    goto EXIT;
> 
> +  }
> 
> +
> 
> +  SimpleTestContext.SimpleDevicePath  = &mSimpleDevicePath;
> 
> +  SimpleTestContext.InvalidDevicePath = &mInvalidSimpleDevicePath;
> 
> +  SimpleTestContext.ComplexDevicePath = &mComplexDevicePath;
> 
> +
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathValid",
> "TestIsDevicePathValid", TestIsDevicePathValid, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathType",
> "TestDevicePathType", TestDevicePathType, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathSubType",
> "TestDevicePathSubType", TestDevicePathSubType, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test
> DevicePathNodeLength", "TestDevicePathNodeLength",
> TestDevicePathNodeLength, NULL, NULL, &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test NextDevicePathNode",
> "TestNextDevicePathNode", TestNextDevicePathNode, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathEndType",
> "TestIsDevicePathEndType", TestIsDevicePathEndType, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathEnd",
> "TestIsDevicePathEnd", TestIsDevicePathEnd, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test
> SetDevicePathNodeLength", "TestSetDevicePathNodeLength",
> TestSetDevicePathNodeLength, NULL, NULL, &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test GetDevicePathSize",
> "TestGetDevicePathSize", TestGetDevicePathSize, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test CreateDeviceNode",
> "TestCreateDeviceNode", TestCreateDeviceNode, NULL, NULL,
> &SimpleTestContext);
> 
> +  AddTestCase (DevicePathSimpleTestSuite, "Test
> SetDevicePathEndNode", "TestSetDevicePathEndNode",
> TestSetDevicePathEndNode, NULL, NULL, &SimpleTestContext);
> 
> +  AddTestCase (DevicePathAppendTestSuite, "Test DuplicateDevicePath",
> "TestDuplicateDevicePath", TestDuplicateDevicePath, NULL, NULL,
> &SimpleTestContext);
> 
> +
> 
> +  Status = CreateUnitTestSuite (&DevicePathAppendTestSuite,
> Framework, "Device path append operations test suite",
> "Common.DevicePath.Append", NULL, NULL);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_ERROR, "Failed to create append device path test
> suite\n"));
> 
> +    goto EXIT;
> 
> +  }
> 
> +
> 
> +  AddTestCase (DevicePathAppendTestSuite, "Test AppendDevicePath",
> "TestAppendDevicePath", TestAppendDevicePath, NULL, NULL, NULL);
> 
> +  AddTestCase (DevicePathAppendTestSuite, "Test
> AppendDevicePathNode", "TestAppendDevicePathNode",
> TestAppendDevicePathNode, NULL, NULL, NULL);
> 
> +  AddTestCase (DevicePathAppendTestSuite, "Test
> AppendDevicePathInstance", "TestAppendDevicePathInstance",
> TestAppendDevicePathInstance, NULL, NULL, NULL);
> 
> +
> 
> +  Status = CreateDevicePathStringConversionsTestSuite (Framework);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_ERROR, "Failed to create conversions test
> suite\n"));
> 
> +    goto EXIT;
> 
> +  }
> 
> +
> 
> +  Status = CreateUnitTestSuite (&DevicePathFileTestSuite, Framework,
> "Device path file operations test suite",
> "Common.DevicePath.FileDevPath", NULL, NULL);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_ERROR, "Failed to create device path file test
> suite\n"));
> 
> +    goto EXIT;
> 
> +  }
> 
> +
> 
> +  AddTestCase (DevicePathFileTestSuite, "Test DevicePathFromHandle",
> "TestDevicePathFromHandle", TestDevicePathFromHandle, NULL, NULL,
> NULL);
> 
> +  AddTestCase (DevicePathFileTestSuite, "Test FileDevicePath",
> "TestFileDevicePath", TestFileDevicePath, NULL, NULL, NULL);
> 
> +
> 
> +  Status = RunAllTestSuites (Framework);
> 
> +
> 
> +EXIT:
> 
> +  if (Framework != NULL) {
> 
> +    FreeUnitTestFramework (Framework);
> 
> +  }
> 
> +
> 
> +  return Status;
> 
> +}
> 
> +
> 
> +int
> 
> +main (
> 
> +  int   argc,
> 
> +  char  *argv[]
> 
> +  )
> 
> +{
> 
> +  return UefiTestMain ();
> 
> +}
> 
> diff --git
> a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> 
> new file mode 100644
> 
> index 0000000000..4a0c3d4c43
> 
> --- /dev/null
> 
> +++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> 
> @@ -0,0 +1,26 @@
> 
> +/** @file
> 
> +  UEFI OS based application for unit testing the DevicePathLib.
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +
> 
> +#ifndef __TEST_DEVICE_PATH_LIB_H__
> 
> +#define __TEST_DEVICE_PATH_LIB_H__
> 
> +
> 
> +#include <PiPei.h>
> 
> +#include <Uefi.h>
> 
> +#include <Library/UefiLib.h>
> 
> +#include <Library/DebugLib.h>
> 
> +#include <Library/MemoryAllocationLib.h>
> 
> +#include <Library/UnitTestLib.h>
> 
> +#include <Protocol/DevicePath.h>
> 
> +#include <Library/DevicePathLib.h>
> 
> +#include <stdint.h>
> 
> +
> 
> +EFI_STATUS
> 
> +CreateDevicePathStringConversionsTestSuite (
> 
> +  IN UNIT_TEST_FRAMEWORK_HANDLE  Framework
> 
> +  );
> 
> +
> 
> +#endif
> 
> diff --git
> a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> 
> new file mode 100644
> 
> index 0000000000..9f9c36946a
> 
> --- /dev/null
> 
> +++
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> 
> @@ -0,0 +1,33 @@
> 
> +## @file
> 
> +# Host OS based Application that Unit Tests the UefiDevicePathLib
> 
> +#
> 
> +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +##
> 
> +
> 
> +[Defines]
> 
> +  INF_VERSION     = 0x00010005
> 
> +  BASE_NAME       = TestDevicePathLibHost
> 
> +  MODULE_UNI_FILE = TestDevicePathLib.uni
> 
> +  FILE_GUID       = F1505A0E-D71F-4431-99BE-736776842E38
> 
> +  MODULE_TYPE     = HOST_APPLICATION
> 
> +  VERSION_STRING  = 1.0
> 
> +
> 
> +#
> 
> +# The following information is for reference only and not required by
> the build tools.
> 
> +#
> 
> +#  VALID_ARCHITECTURES           = IA32 X64
> 
> +#
> 
> +
> 
> +[Sources]
> 
> +  TestDevicePathLib.c
> 
> +  TestDevicePathStringConversions.c
> 
> +
> 
> +[Packages]
> 
> +  MdePkg/MdePkg.dec
> 
> +
> 
> +[LibraryClasses]
> 
> +  BaseLib
> 
> +  DebugLib
> 
> +  DevicePathLib
> 
> +  UnitTestLib
> 
> diff --git
> a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConve
> rsions.c
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConve
> rsions.c
> 
> new file mode 100644
> 
> index 0000000000..4ea25ec142
> 
> --- /dev/null
> 
> +++
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConve
> rsions.c
> 
> @@ -0,0 +1,370 @@
> 
> +/** @file
> 
> +  UEFI OS based application for unit testing the DevicePathLib.
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include "TestDevicePathLib.h"
> 
> +
> 
> +typedef struct {
> 
> +  EFI_DEVICE_PATH_PROTOCOL    *DevPath;
> 
> +  CONST CHAR16                *DevPathString;
> 
> +} DEVICE_PATH_CONVERSIONS_TEST_CONTEXT;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED PCI_DEVICE_PATH  mPciDevicePathNode =
> 
> +{
> 
> +  // PCI device path - root port (0x2:0x0)
> 
> +  {
> 
> +    HARDWARE_DEVICE_PATH,
> 
> +    HW_PCI_DP,
> 
> +    {
> 
> +      (UINT8)(sizeof (PCI_DEVICE_PATH)),
> 
> +      (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> 
> +    }
> 
> +  },
> 
> +  0x2,
> 
> +  0x0
> 
> +};
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_HID_DEVICE_PATH
> mAcpiPciRootHidDevicePathNode =
> 
> +{
> 
> +  // ACPI PCI root - PciRoot(0x0)
> 
> +  {
> 
> +    ACPI_DEVICE_PATH,
> 
> +    ACPI_DP,
> 
> +    {
> 
> +      (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> 
> +      (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> 
> +    }
> 
> +  },
> 
> +  EISA_PNP_ID (0x0A03),
> 
> +  0
> 
> +};
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_HID_DEVICE_PATH
> mAcpiNonPciRootHidDevicePathNode =
> 
> +{
> 
> +  // Random ACPI device - ACPI(PNPB0C0, 1)
> 
> +  {
> 
> +    ACPI_DEVICE_PATH,
> 
> +    ACPI_DP,
> 
> +    {
> 
> +      (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> 
> +      (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> 
> +    }
> 
> +  },
> 
> +  EISA_PNP_ID (0xB0C0),
> 
> +  1
> 
> +};
> 
> +
> 
> +#define HID_STR_SIZE  8
> 
> +#define CID_STR_SIZE  8
> 
> +#define UID_STR_SIZE  8
> 
> +
> 
> +typedef struct {
> 
> +  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
> 
> +  CHAR8                            HidStr[HID_STR_SIZE];
> 
> +  CHAR8                            CidStr[CID_STR_SIZE];
> 
> +  CHAR8                            UidStr[UID_STR_SIZE];
> 
> +} ACPI_EXTENDED_HID_DEVICE_PATH_FULL;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXTENDED_HID_DEVICE_PATH_FULL
> mAcpiExtendedDevicePathFull =
> 
> +{
> 
> +  // ACPI Extended HID PciRoot device node
> 
> +  {
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_EXTENDED_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_FULL)),
> 
> +        (UINT8)((sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_FULL)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0,
> 
> +    0,
> 
> +    0,
> 
> +  },
> 
> +  { 'P', 'N', 'P', 'B', '0', 'C', '0', '\0' }, // HIDSTR
> 
> +  { 'P', 'N', 'P', '0', '0', '0', '1', '\0' }, // CIDSTR
> 
> +  { 'U', 'I', 'D', '0', '0', '0', '0', '\0' } // UIDSTR
> 
> +};
> 
> +
> 
> +typedef struct {
> 
> +  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
> 
> +  CHAR8                            HidStr[HID_STR_SIZE];
> 
> +} ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL
> mAcpiExtendedDevicePathPartial =
> 
> +{
> 
> +  {
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_EXTENDED_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL)),
> 
> +        (UINT8)((sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL)) >>
> 8)
> 
> +      }
> 
> +    },
> 
> +    0,
> 
> +    2,
> 
> +    0,
> 
> +  },
> 
> +  { 'P', 'N', 'P', 'B', '0', '\0', '\0', '\0' }, // HIDSTR
> 
> +};
> 
> +
> 
> +typedef struct {
> 
> +  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
> 
> +  CHAR8                            UidStr[UID_STR_SIZE];
> 
> +} ACPI_EXPANDED_DEVICE_PATH;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXPANDED_DEVICE_PATH
> mAcpiExpandedDevicePathUidOnly =
> 
> +{
> 
> +  {
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_EXTENDED_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_EXPANDED_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (ACPI_EXPANDED_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0xAAAA),
> 
> +    0,
> 
> +    0,
> 
> +  },
> 
> +  { '\0', 'U', 'I', 'D', '0', '0', '\0', '\0' } // UIDSTR
> 
> +};
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXPANDED_DEVICE_PATH
> mAcpiExpandedDevicePathUidOnlyWithCid =
> 
> +{
> 
> +  {
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_EXTENDED_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_EXPANDED_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (ACPI_EXPANDED_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0xAAAA),
> 
> +    0,
> 
> +    EISA_PNP_ID (0xAADD),
> 
> +  },
> 
> +  { '\0', 'U', 'I', 'D', '0', '0', '\0', '\0' } // UIDSTR
> 
> +};
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_CONVERSIONS_TEST_CONTEXT
> mDevPathNodeToFromTextContext[] = {
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mPciDevicePathNode,
> 
> +    L"Pci(0x0,0x2)"
> 
> +  },
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiPciRootHidDevicePathNode,
> 
> +    L"PciRoot(0x0)"
> 
> +  },
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiNonPciRootHidDevicePathNode,
> 
> +    L"Acpi(PNPB0C0,0x1)"
> 
> +  },
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExtendedDevicePathFull,
> 
> +    L"AcpiEx(@@@0000,@@@0000,0x0,PNPB0C0,UID0000,PNP0001)"
> 
> +  },
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExtendedDevicePathPartial,
> 
> +    L"AcpiEx(@@@0000,@@@0000,0x2,PNPB0,,)"
> 
> +  },
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExpandedDevicePathUidOnly,
> 
> +    L"AcpiExp(PNPAAAA,0,UID00)"
> 
> +  },
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL
> *)&mAcpiExpandedDevicePathUidOnlyWithCid,
> 
> +    L"AcpiExp(PNPAAAA,PNPAADD,UID00)"
> 
> +  }
> 
> +};
> 
> +
> 
> +typedef struct {
> 
> +  ACPI_HID_DEVICE_PATH        AcpiPath;
> 
> +  PCI_DEVICE_PATH             PciPathRootPort;
> 
> +  PCI_DEVICE_PATH             PciPathEndPoint;
> 
> +  USB_DEVICE_PATH             UsbPath;
> 
> +  EFI_DEVICE_PATH_PROTOCOL    End;
> 
> +} TEST_CONVERSIONS_DEVICE_PATH;
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED TEST_CONVERSIONS_DEVICE_PATH
> mConversionsDevicePath = {
> 
> +  { // ACPI device path with root bridge EISA_PNP_ID
> 
> +    {
> 
> +      ACPI_DEVICE_PATH,
> 
> +      ACPI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    EISA_PNP_ID (0x0A03),
> 
> +    0
> 
> +  },
> 
> +  { // PCI device path - root port (0x2:0x0)
> 
> +    {
> 
> +      HARDWARE_DEVICE_PATH,
> 
> +      HW_PCI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0x2,
> 
> +    0x0
> 
> +  },
> 
> +  { // PCI device path - endpoint (0x0:0x0)
> 
> +    {
> 
> +      HARDWARE_DEVICE_PATH,
> 
> +      HW_PCI_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0x0,
> 
> +    0x0
> 
> +  },
> 
> +  { // USB interface
> 
> +    {
> 
> +      MESSAGING_DEVICE_PATH,
> 
> +      MSG_USB_DP,
> 
> +      {
> 
> +        (UINT8)(sizeof (USB_DEVICE_PATH)),
> 
> +        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
> 
> +      }
> 
> +    },
> 
> +    0,
> 
> +    2
> 
> +  },
> 
> +  {
> 
> +    END_DEVICE_PATH_TYPE,
> 
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> 
> +    {
> 
> +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> 
> +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> 
> +    }
> 
> +  }
> 
> +};
> 
> +
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_CONVERSIONS_TEST_CONTEXT
> mDevPathToFromTextContext[] = {
> 
> +  {
> 
> +    (EFI_DEVICE_PATH_PROTOCOL *)&mConversionsDevicePath,
> 
> +    L"PciRoot(0x0)/Pci(0x0,0x2)/Pci(0x0,0x0)/USB(0x0,0x2)"
> 
> +  }
> 
> +};
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestConvertDevicePathToText (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  CHAR16                                *DevPathString;
> 
> +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> 
> +
> 
> +  DevPathString = ConvertDevicePathToText (TestContext->DevPath,
> FALSE, FALSE);
> 
> +  UT_ASSERT_EQUAL (StrLen (DevPathString), StrLen (TestContext-
> >DevPathString));
> 
> +  UT_ASSERT_MEM_EQUAL (DevPathString, TestContext->DevPathString,
> StrLen (TestContext->DevPathString));
> 
> +  FreePool (DevPathString);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestConvertTextToDevicePath (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL              *ConvertedDevPath;
> 
> +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> 
> +
> 
> +  ConvertedDevPath = ConvertTextToDevicePath (TestContext-
> >DevPathString);
> 
> +  UT_ASSERT_EQUAL (GetDevicePathSize (ConvertedDevPath),
> GetDevicePathSize (TestContext->DevPath));
> 
> +  UT_ASSERT_MEM_EQUAL (ConvertedDevPath, TestContext->DevPath,
> GetDevicePathSize (TestContext->DevPath));
> 
> +  FreePool (ConvertedDevPath);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestConvertDeviceNodeToText (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  CHAR16                                *DevPathNodeString;
> 
> +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> 
> +
> 
> +  DevPathNodeString = ConvertDeviceNodeToText (TestContext->DevPath,
> FALSE, FALSE);
> 
> +  UT_ASSERT_EQUAL (StrLen (DevPathNodeString), StrLen (TestContext-
> >DevPathString));
> 
> +  UT_ASSERT_MEM_EQUAL (DevPathNodeString, TestContext->DevPathString,
> StrLen (TestContext->DevPathString));
> 
> +  FreePool (DevPathNodeString);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +UNIT_TEST_STATUS
> 
> +EFIAPI
> 
> +TestConvertTextToDeviceNode (
> 
> +  IN UNIT_TEST_CONTEXT  Context
> 
> +  )
> 
> +{
> 
> +  EFI_DEVICE_PATH_PROTOCOL              *DevPath;
> 
> +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> 
> +
> 
> +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> 
> +
> 
> +  DevPath = ConvertTextToDeviceNode (TestContext->DevPathString);
> 
> +  UT_ASSERT_EQUAL (DevicePathNodeLength (DevPath),
> DevicePathNodeLength (TestContext->DevPath));
> 
> +  UT_ASSERT_MEM_EQUAL (DevPath, TestContext->DevPath,
> DevicePathNodeLength (TestContext->DevPath));
> 
> +  FreePool (DevPath);
> 
> +
> 
> +  return UNIT_TEST_PASSED;
> 
> +}
> 
> +
> 
> +EFI_STATUS
> 
> +CreateDevicePathStringConversionsTestSuite (
> 
> +  IN UNIT_TEST_FRAMEWORK_HANDLE  Framework
> 
> +  )
> 
> +{
> 
> +  EFI_STATUS              Status;
> 
> +  UNIT_TEST_SUITE_HANDLE  DevicePathTextConversionSuite = NULL;
> 
> +  UINTN                   Index;
> 
> +
> 
> +  Status = CreateUnitTestSuite (&DevicePathTextConversionSuite,
> Framework, "Device path text conversion operations test suite",
> "Common.DevicePath.TextConversions", NULL, NULL);
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    DEBUG ((DEBUG_ERROR, "Failed to create device path text
> conversions test suite\n"));
> 
> +    return Status;
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < ARRAY_SIZE (mDevPathNodeToFromTextContext);
> Index++) {
> 
> +    AddTestCase (DevicePathTextConversionSuite, "Test
> ConvertDeviceNodeToText", "TestConvertDeviceNodeToText",
> TestConvertDeviceNodeToText, NULL, NULL,
> &mDevPathNodeToFromTextContext[Index]);
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < ARRAY_SIZE (mDevPathNodeToFromTextContext);
> Index++) {
> 
> +    AddTestCase (DevicePathTextConversionSuite, "Test
> ConvertTextToDeviceNode", "TestConvertTextToDeviceNode",
> TestConvertTextToDeviceNode, NULL, NULL,
> &mDevPathNodeToFromTextContext[Index]);
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < ARRAY_SIZE (mDevPathToFromTextContext);
> Index++) {
> 
> +    AddTestCase (DevicePathTextConversionSuite, "Test
> ConvertDevicePathToText", "TestConvertDevicePathToText",
> TestConvertDevicePathToText, NULL, NULL,
> &mDevPathToFromTextContext[Index]);
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < ARRAY_SIZE (mDevPathToFromTextContext);
> Index++) {
> 
> +    AddTestCase (DevicePathTextConversionSuite, "Test
> ConvertTextToDevicePath", "TestConvertTextToDevicePath",
> TestConvertTextToDevicePath, NULL, NULL,
> &mDevPathToFromTextContext[Index]);
> 
> +  }
> 
> +
> 
> +  return EFI_SUCCESS;
> 
> +}
> 
> --
> 
> 2.39.2
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109594): https://edk2.groups.io/g/devel/message/109594
Mute This Topic: https://groups.io/mt/101619981/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/3901457/1787277/102458076/xyzzy [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test module
Posted by Michael D Kinney 2 years, 3 months ago
Merged: https://github.com/tianocore/edk2/pull/4865

Mike

> -----Original Message-----
> From: Kinney, Michael D <michael.d.kinney@intel.com>
> Sent: Friday, October 13, 2023 9:55 AM
> To: Albecki, Mateusz <mateusz.albecki@intel.com>; devel@edk2.groups.io
> Cc: Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang
> <zhiguang.liu@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test
> module
> 
> Reviewed-by: Michael D Kinney <Michael.d.kinney@intel.com>
> 
> > -----Original Message-----
> > From: Albecki, Mateusz <mateusz.albecki@intel.com>
> > Sent: Wednesday, September 27, 2023 8:51 AM
> > To: devel@edk2.groups.io
> > Cc: Albecki, Mateusz <mateusz.albecki@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Gao, Liming
> <gaoliming@byosoft.com.cn>;
> > Liu, Zhiguang <zhiguang.liu@intel.com>
> > Subject: [PATCHv2 2/2] MdePkg/Test: Add DevicePathLib host test
> module
> >
> > This commit adds host-based unit tests for device path lib.
> >
> >
> >
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> >
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> >
> > Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> >
> >
> >
> > Signed-off-by: Mateusz Albecki <mateusz.albecki@intel.com>
> >
> > ---
> >
> >  MdePkg/MdePkg.ci.yaml                         |   5 +-
> >
> >  MdePkg/Test/MdePkgHostTest.dsc                |   2 +
> >
> >  .../Library/DevicePathLib/TestDevicePathLib.c | 638
> > ++++++++++++++++++
> >
> >  .../Library/DevicePathLib/TestDevicePathLib.h |  26 +
> >
> >  .../DevicePathLib/TestDevicePathLibHost.inf   |  33 +
> >
> >  .../TestDevicePathStringConversions.c         | 370 ++++++++++
> >
> >  6 files changed, 1073 insertions(+), 1 deletion(-)
> >
> >  create mode 100644
> > MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> >
> >  create mode 100644
> > MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> >
> >  create mode 100644
> > MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> >
> >  create mode 100644
> >
> MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConvers
> > ions.c
> >
> >
> >
> > diff --git a/MdePkg/MdePkg.ci.yaml b/MdePkg/MdePkg.ci.yaml
> >
> > index c3faf4913d..45f4fb537b 100644
> >
> > --- a/MdePkg/MdePkg.ci.yaml
> >
> > +++ b/MdePkg/MdePkg.ci.yaml
> >
> > @@ -74,7 +74,10 @@
> >
> >
> > "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",
> >
> >              "Library/BaseFdtLib",
> >
> >              "Library/MipiSysTLib/mipi_syst.h",
> >
> > -            "Include/Register/Amd/SmramSaveStateMap.h"
> >
> > +            "Include/Register/Amd/SmramSaveStateMap.h",
> >
> > +
> > "Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c",
> >
> > +
> > "Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h",
> >
> > +
> >
> "Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConversions.c
> > "
> >
> >          ]
> >
> >      },
> >
> >      ## options defined ci/Plugin/CompilerPlugin
> >
> > diff --git a/MdePkg/Test/MdePkgHostTest.dsc
> > b/MdePkg/Test/MdePkgHostTest.dsc
> >
> > index 529ea69024..b92b564d43 100644
> >
> > --- a/MdePkg/Test/MdePkgHostTest.dsc
> >
> > +++ b/MdePkg/Test/MdePkgHostTest.dsc
> >
> > @@ -21,6 +21,7 @@
> >
> >
> >
> >  [LibraryClasses]
> >
> >    SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> >
> > +
> >
> DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.i
> > nf
> >
> >
> >
> >  [Components]
> >
> >    #
> >
> > @@ -29,6 +30,7 @@
> >
> >
> >
> MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost.inf
> >
> >    MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost.inf
> >
> >
> >
> MdePkg/Test/GoogleTest/Library/BaseSafeIntLib/GoogleTestBaseSafeIntLib
> > .inf
> >
> > +
> > MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> >
> >
> >
> >    #
> >
> >    # Build HOST_APPLICATION Libraries
> >
> > diff --git
> > a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> > b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> >
> > new file mode 100644
> >
> > index 0000000000..687497278c
> >
> > --- /dev/null
> >
> > +++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.c
> >
> > @@ -0,0 +1,638 @@
> >
> > +/** @file
> >
> > +  UEFI OS based application for unit testing the DevicePathLib.
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +**/
> >
> > +
> >
> > +#include "TestDevicePathLib.h"
> >
> > +
> >
> > +#define UNIT_TEST_NAME     "DevicePathLib Unit Test Application"
> >
> > +#define UNIT_TEST_VERSION  "0.1"
> >
> > +
> >
> > +typedef struct {
> >
> > +  ACPI_HID_DEVICE_PATH        AcpiPath;
> >
> > +  PCI_DEVICE_PATH             PciPathRootPort;
> >
> > +  PCI_DEVICE_PATH             PciPathEndPoint;
> >
> > +  USB_DEVICE_PATH             UsbPath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    End;
> >
> > +} TEST_COMPLEX_DEVICE_PATH;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED TEST_COMPLEX_DEVICE_PATH
> > mComplexDevicePath = {
> >
> > +  { // ACPI device path with root bridge EISA_PNP_ID
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0x0A03),
> >
> > +    0
> >
> > +  },
> >
> > +  { // PCI device path - root port (0x2:0x0)
> >
> > +    {
> >
> > +      HARDWARE_DEVICE_PATH,
> >
> > +      HW_PCI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0x2,
> >
> > +    0x0
> >
> > +  },
> >
> > +  { // PCI device path - endpoint (0x0:0x0)
> >
> > +    {
> >
> > +      HARDWARE_DEVICE_PATH,
> >
> > +      HW_PCI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0x0,
> >
> > +    0x0
> >
> > +  },
> >
> > +  { // USB interface
> >
> > +    {
> >
> > +      MESSAGING_DEVICE_PATH,
> >
> > +      MSG_USB_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (USB_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0,
> >
> > +    2
> >
> > +  },
> >
> > +  {
> >
> > +    END_DEVICE_PATH_TYPE,
> >
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> >
> > +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> >
> > +    }
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +CONST GLOBAL_REMOVE_IF_UNREFERENCED CHAR16
> *mComplexDevicePathString
> > = L"PciRoot(0x0)/Pci(0x0,0x2)/Pci(0x0,0x0)/USB(0x0,0x2)";
> >
> > +
> >
> > +CONST GLOBAL_REMOVE_IF_UNREFERENCED CHAR16  *mPciEndPointPathString
> =
> > L"Pci(0x0, 0x0)";
> >
> > +
> >
> > +typedef struct {
> >
> > +  ACPI_HID_DEVICE_PATH        AcpiPath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    End;
> >
> > +} TEST_SIMPLE_DEVICE_PATH;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED TEST_SIMPLE_DEVICE_PATH
> > mSimpleDevicePath = {
> >
> > +  { // ACPI device path with root bridge EISA_PNP_ID
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0x0A03),
> >
> > +    0
> >
> > +  },
> >
> > +  {
> >
> > +    END_DEVICE_PATH_TYPE,
> >
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> >
> > +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> >
> > +    }
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED TEST_SIMPLE_DEVICE_PATH
> > mInvalidSimpleDevicePath = {
> >
> > +  { // ACPI device path with root bridge EISA_PNP_ID
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_DP,
> >
> > +      {
> >
> > +        0,
> >
> > +        0
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0x0A03),
> >
> > +    0
> >
> > +  },
> >
> > +  {
> >
> > +    END_DEVICE_PATH_TYPE,
> >
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> >
> > +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> >
> > +    }
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +typedef struct {
> >
> > +  TEST_SIMPLE_DEVICE_PATH     *SimpleDevicePath;
> >
> > +  TEST_SIMPLE_DEVICE_PATH     *InvalidDevicePath;
> >
> > +  TEST_COMPLEX_DEVICE_PATH    *ComplexDevicePath;
> >
> > +} SIMPLE_TEST_SUITE_CONTEXT;
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestIsDevicePathValid (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  BOOLEAN                    IsValid;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->SimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH));
> >
> > +  UT_ASSERT_TRUE (IsValid);
> >
> > +
> >
> > +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->ComplexDevicePath, sizeof
> (TEST_COMPLEX_DEVICE_PATH));
> >
> > +  UT_ASSERT_TRUE (IsValid);
> >
> > +
> >
> > +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->ComplexDevicePath, 0);
> >
> > +  UT_ASSERT_TRUE (IsValid);
> >
> > +
> >
> > +  // Device path can't be NULL
> >
> > +  IsValid = IsDevicePathValid (NULL, 0);
> >
> > +  UT_ASSERT_FALSE (IsValid);
> >
> > +
> >
> > +  // MaxSize can't be less then the size of the device path
> >
> > +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->SimpleDevicePath, sizeof (TEST_SIMPLE_DEVICE_PATH) -
> > 1);
> >
> > +  UT_ASSERT_FALSE (IsValid);
> >
> > +
> >
> > +  // If MaxSize != 0 it must be bigger then
> EFI_DEVICE_PATH_PROTOCOL
> >
> > +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->SimpleDevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL) -
> > 1);
> >
> > +  UT_ASSERT_FALSE (IsValid);
> >
> > +
> >
> > +  IsValid = IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->InvalidDevicePath, 0);
> >
> > +  UT_ASSERT_FALSE (IsValid);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestDevicePathType (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  UINT8                      Type;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  // Test 2 types just in case the implementation is returning
> > constant value
> >
> > +  // NOTE: passing NULL to this function causes NULL pointer
> > dereference.
> >
> > +  Type = DevicePathType (&TestContext->ComplexDevicePath-
> >AcpiPath);
> >
> > +  UT_ASSERT_EQUAL (Type, ACPI_DEVICE_PATH);
> >
> > +
> >
> > +  Type = DevicePathType (&TestContext->ComplexDevicePath-
> > >PciPathRootPort);
> >
> > +  UT_ASSERT_EQUAL (Type, HARDWARE_DEVICE_PATH);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestDevicePathSubType (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  UINT8                      SubType;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  // Test 2 sub types just in case the implementation is returning
> > constant value
> >
> > +  // NOTE: passing NULL to this function causes NULL pointer
> > dereference.
> >
> > +  SubType = DevicePathSubType (&TestContext->ComplexDevicePath-
> > >AcpiPath);
> >
> > +  UT_ASSERT_EQUAL (SubType, ACPI_DP);
> >
> > +
> >
> > +  SubType = DevicePathSubType (&TestContext->ComplexDevicePath-
> > >PciPathRootPort);
> >
> > +  UT_ASSERT_EQUAL (SubType, HW_PCI_DP);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestDevicePathNodeLength (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  UINTN                      Length;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  // Test 2 nodes just in case the implementation is returning
> > constant value
> >
> > +  // NOTE: passing NULL to this function causes NULL pointer
> > dereference.
> >
> > +  Length = DevicePathNodeLength (&TestContext->ComplexDevicePath-
> > >AcpiPath);
> >
> > +  UT_ASSERT_EQUAL (Length, sizeof (ACPI_HID_DEVICE_PATH));
> >
> > +
> >
> > +  Length = DevicePathNodeLength (&TestContext->ComplexDevicePath-
> > >PciPathRootPort);
> >
> > +  UT_ASSERT_EQUAL (Length, sizeof (PCI_DEVICE_PATH));
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestNextDevicePathNode (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  VOID                       *Node;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  Node = &mComplexDevicePath;
> >
> > +  Node = NextDevicePathNode (Node);
> >
> > +  UT_ASSERT_MEM_EQUAL (Node, &TestContext->ComplexDevicePath-
> > >PciPathRootPort, DevicePathNodeLength (Node));
> >
> > +
> >
> > +  Node = NextDevicePathNode (Node);
> >
> > +  UT_ASSERT_MEM_EQUAL (Node, &TestContext->ComplexDevicePath-
> > >PciPathEndPoint, DevicePathNodeLength (Node));
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestIsDevicePathEndType (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  BOOLEAN                    IsEndType;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  IsEndType = IsDevicePathEndType (&TestContext->ComplexDevicePath-
> > >PciPathRootPort);
> >
> > +  UT_ASSERT_FALSE (IsEndType);
> >
> > +
> >
> > +  IsEndType = IsDevicePathEndType (&TestContext->ComplexDevicePath-
> > >End);
> >
> > +  UT_ASSERT_TRUE (IsEndType);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestIsDevicePathEnd (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  BOOLEAN                    IsEnd;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  IsEnd = IsDevicePathEnd (&TestContext->ComplexDevicePath-
> > >PciPathRootPort);
> >
> > +  UT_ASSERT_FALSE (IsEnd);
> >
> > +
> >
> > +  IsEnd = IsDevicePathEnd (&TestContext->ComplexDevicePath->End);
> >
> > +  UT_ASSERT_TRUE (IsEnd);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestSetDevicePathNodeLength (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  DevPath;
> >
> > +
> >
> > +  // NOTE: Node == NULL or NodeLength >= 0x10000 NodeLength <
> sizeof
> > (EFI_DEVICE_PATH_PROTOCOL)
> >
> > +  // are all invalid parameters. However there are only ASSERTS
> added
> > to catch them so there is no
> >
> > +  // way to test it.
> >
> > +  SetDevicePathNodeLength (&DevPath, sizeof
> > (EFI_DEVICE_PATH_PROTOCOL));
> >
> > +  UT_ASSERT_EQUAL (DevicePathNodeLength (&DevPath), sizeof
> > (EFI_DEVICE_PATH_PROTOCOL));
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestSetDevicePathEndNode (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  EndNode;
> >
> > +
> >
> > +  SetDevicePathEndNode (&EndNode);
> >
> > +  UT_ASSERT_EQUAL (EndNode.Type, END_DEVICE_PATH_TYPE);
> >
> > +  UT_ASSERT_EQUAL (EndNode.SubType,
> END_ENTIRE_DEVICE_PATH_SUBTYPE);
> >
> > +  UT_ASSERT_EQUAL (DevicePathNodeLength (&EndNode),
> > END_DEVICE_PATH_LENGTH);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestGetDevicePathSize (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  UINTN                      Size;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  Size = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext-
> > >SimpleDevicePath);
> >
> > +  UT_ASSERT_EQUAL (Size, sizeof (TEST_SIMPLE_DEVICE_PATH));
> >
> > +
> >
> > +  Size = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL
> *)TestContext-
> > >ComplexDevicePath);
> >
> > +  UT_ASSERT_EQUAL (Size, sizeof (TEST_COMPLEX_DEVICE_PATH));
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestDuplicateDevicePath (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL   *Duplicate;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (SIMPLE_TEST_SUITE_CONTEXT *)Context;
> >
> > +
> >
> > +  Duplicate = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
> > *)TestContext->ComplexDevicePath);
> >
> > +  UT_ASSERT_EQUAL (GetDevicePathSize (Duplicate), GetDevicePathSize
> > ((EFI_DEVICE_PATH_PROTOCOL *)TestContext->ComplexDevicePath));
> >
> > +  UT_ASSERT_MEM_EQUAL (Duplicate, TestContext->ComplexDevicePath,
> > GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)TestContext-
> > >ComplexDevicePath));
> >
> > +  FreePool (Duplicate);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestAppendDevicePath (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *Appended;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
> >
> > +
> >
> > +  Appended = AppendDevicePath ((EFI_DEVICE_PATH_PROTOCOL
> > *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL
> > *)&mComplexDevicePath);
> >
> > +  NextNode = NextDevicePathNode (Appended);
> >
> > +  UT_ASSERT_MEM_EQUAL (NextNode, &mSimpleDevicePath.AcpiPath,
> sizeof
> > (ACPI_HID_DEVICE_PATH));
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  // If one of the paths is invalid result device path should be
> NULL
> >
> > +  Appended = AppendDevicePath ((EFI_DEVICE_PATH_PROTOCOL
> > *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL
> > *)&mInvalidSimpleDevicePath);
> >
> > +  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
> >
> > +
> >
> > +  Appended = AppendDevicePath (NULL, NULL);
> >
> > +  UT_ASSERT_EQUAL (Appended->Type, END_DEVICE_PATH_TYPE);
> >
> > +  UT_ASSERT_EQUAL (Appended->SubType,
> > END_ENTIRE_DEVICE_PATH_SUBTYPE);
> >
> > +  UT_ASSERT_EQUAL (DevicePathNodeLength (Appended),
> > END_DEVICE_PATH_LENGTH);
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestAppendDevicePathNode (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *Appended;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
> >
> > +  BOOLEAN                   IsValid;
> >
> > +  ACPI_HID_DEVICE_PATH      AcpiPath =
> >
> > +  {
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0x0AAB),
> >
> > +    0
> >
> > +  };
> >
> > +
> >
> > +  Appended = AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL
> > *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&AcpiPath);
> >
> > +  NextNode = NextDevicePathNode (Appended);
> >
> > +  UT_ASSERT_MEM_EQUAL (NextNode, &AcpiPath, sizeof
> > (ACPI_HID_DEVICE_PATH));
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  Appended = AppendDevicePathNode (NULL, (EFI_DEVICE_PATH_PROTOCOL
> > *)&AcpiPath);
> >
> > +  UT_ASSERT_MEM_EQUAL (Appended, &AcpiPath, sizeof
> > (ACPI_HID_DEVICE_PATH));
> >
> > +  IsValid = IsDevicePathValid (Appended, 0);
> >
> > +  UT_ASSERT_TRUE (IsValid);
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  Appended = AppendDevicePathNode (NULL, NULL);
> >
> > +  UT_ASSERT_EQUAL (Appended->Type, END_DEVICE_PATH_TYPE);
> >
> > +  UT_ASSERT_EQUAL (Appended->SubType,
> > END_ENTIRE_DEVICE_PATH_SUBTYPE);
> >
> > +  UT_ASSERT_EQUAL (DevicePathNodeLength (Appended),
> > END_DEVICE_PATH_LENGTH);
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestAppendDevicePathInstance (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *Appended;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *NextInstance;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *NextInstanceRet;
> >
> > +  BOOLEAN                   IsMultiInstance;
> >
> > +  UINTN                     Size;
> >
> > +
> >
> > +  Appended        = AppendDevicePathInstance
> > ((EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath,
> > (EFI_DEVICE_PATH_PROTOCOL *)&mComplexDevicePath);
> >
> > +  IsMultiInstance = IsDevicePathMultiInstance (Appended);
> >
> > +  UT_ASSERT_TRUE (IsMultiInstance);
> >
> > +  UT_ASSERT_MEM_EQUAL (Appended, &mSimpleDevicePath, sizeof
> > (ACPI_DEVICE_PATH));
> >
> > +  NextInstance    = Appended;
> >
> > +  NextInstanceRet = GetNextDevicePathInstance (&NextInstance,
> &Size);
> >
> > +  UT_ASSERT_MEM_EQUAL (NextInstance, &mComplexDevicePath, Size);
> >
> > +  FreePool (Appended);
> >
> > +  FreePool (NextInstanceRet);
> >
> > +
> >
> > +  Appended = AppendDevicePathInstance (NULL,
> > (EFI_DEVICE_PATH_PROTOCOL *)&mSimpleDevicePath);
> >
> > +  UT_ASSERT_MEM_EQUAL (Appended, &mSimpleDevicePath, sizeof
> > (TEST_SIMPLE_DEVICE_PATH));
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  Appended = AppendDevicePathInstance (NULL, NULL);
> >
> > +  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  Appended = AppendDevicePathInstance ((EFI_DEVICE_PATH_PROTOCOL
> > *)&mSimpleDevicePath, (EFI_DEVICE_PATH_PROTOCOL
> > *)&mInvalidSimpleDevicePath);
> >
> > +  UT_ASSERT_EQUAL ((uintptr_t)Appended, (uintptr_t)NULL);
> >
> > +  FreePool (Appended);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestDevicePathFromHandle (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_HANDLE                Handle;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
> >
> > +  UINTN                     FakeHandle;
> >
> > +
> >
> > +  Handle     = NULL;
> >
> > +  DevicePath = DevicePathFromHandle (Handle);
> >
> > +  UT_ASSERT_EQUAL ((uintptr_t)DevicePath, (uintptr_t)NULL);
> >
> > +
> >
> > +  Handle     = (EFI_HANDLE)&FakeHandle;
> >
> > +  DevicePath = DevicePathFromHandle (Handle);
> >
> > +  UT_ASSERT_EQUAL ((uintptr_t)DevicePath, (uintptr_t)NULL);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestCreateDeviceNode (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL  *DevNode;
> >
> > +
> >
> > +  DevNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_PCI_DP,
> sizeof
> > (PCI_DEVICE_PATH));
> >
> > +  UT_ASSERT_EQUAL (DevNode->Type, HARDWARE_DEVICE_PATH);
> >
> > +  UT_ASSERT_EQUAL (DevNode->SubType, HW_PCI_DP);
> >
> > +  UT_ASSERT_EQUAL (DevicePathNodeLength (DevNode), sizeof
> > (PCI_DEVICE_PATH));
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestFileDevicePath (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_HANDLE            Handle;
> >
> > +  FILEPATH_DEVICE_PATH  *DevicePath;
> >
> > +  CONST CHAR16          *TestFilePath =
> L"FS0:/Boot/EFI/BootMgr.efi";
> >
> > +
> >
> > +  Handle     = NULL;
> >
> > +  DevicePath = (FILEPATH_DEVICE_PATH *)FileDevicePath (Handle,
> > TestFilePath);
> >
> > +  UT_ASSERT_NOT_NULL (DevicePath);
> >
> > +  UT_ASSERT_EQUAL (DevicePath->Header.Type, MEDIA_DEVICE_PATH);
> >
> > +  UT_ASSERT_EQUAL (DevicePath->Header.Type, MEDIA_FILEPATH_DP);
> >
> > +  UT_ASSERT_MEM_EQUAL (DevicePath->PathName, TestFilePath, StrSize
> > (TestFilePath));
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +
> >
> > +  Main fuction sets up the unit test environment
> >
> > +
> >
> > +**/
> >
> > +EFI_STATUS
> >
> > +EFIAPI
> >
> > +UefiTestMain (
> >
> > +  VOID
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS                  Status;
> >
> > +  UNIT_TEST_FRAMEWORK_HANDLE  Framework;
> >
> > +  UNIT_TEST_SUITE_HANDLE      DevicePathSimpleTestSuite;
> >
> > +  UNIT_TEST_SUITE_HANDLE      DevicePathAppendTestSuite;
> >
> > +  UNIT_TEST_SUITE_HANDLE      DevicePathFileTestSuite;
> >
> > +  SIMPLE_TEST_SUITE_CONTEXT   SimpleTestContext;
> >
> > +
> >
> > +  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME,
> > UNIT_TEST_VERSION));
> >
> > +
> >
> > +  Framework                 = NULL;
> >
> > +  DevicePathSimpleTestSuite = NULL;
> >
> > +  DevicePathAppendTestSuite = NULL;
> >
> > +  DevicePathFileTestSuite   = NULL;
> >
> > +
> >
> > +  Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME,
> > gEfiCallerBaseName, UNIT_TEST_VERSION);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =
> > %r\n", Status));
> >
> > +    goto EXIT;
> >
> > +  }
> >
> > +
> >
> > +  Status = CreateUnitTestSuite (&DevicePathSimpleTestSuite,
> > Framework, "Simple device path operations test suite",
> > "Common.DevicePath.SimpleOps", NULL, NULL);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to create simple device path test
> > suite\n"));
> >
> > +    goto EXIT;
> >
> > +  }
> >
> > +
> >
> > +  SimpleTestContext.SimpleDevicePath  = &mSimpleDevicePath;
> >
> > +  SimpleTestContext.InvalidDevicePath = &mInvalidSimpleDevicePath;
> >
> > +  SimpleTestContext.ComplexDevicePath = &mComplexDevicePath;
> >
> > +
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathValid",
> > "TestIsDevicePathValid", TestIsDevicePathValid, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathType",
> > "TestDevicePathType", TestDevicePathType, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test DevicePathSubType",
> > "TestDevicePathSubType", TestDevicePathSubType, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test
> > DevicePathNodeLength", "TestDevicePathNodeLength",
> > TestDevicePathNodeLength, NULL, NULL, &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test
> NextDevicePathNode",
> > "TestNextDevicePathNode", TestNextDevicePathNode, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test
> IsDevicePathEndType",
> > "TestIsDevicePathEndType", TestIsDevicePathEndType, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test IsDevicePathEnd",
> > "TestIsDevicePathEnd", TestIsDevicePathEnd, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test
> > SetDevicePathNodeLength", "TestSetDevicePathNodeLength",
> > TestSetDevicePathNodeLength, NULL, NULL, &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test GetDevicePathSize",
> > "TestGetDevicePathSize", TestGetDevicePathSize, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test CreateDeviceNode",
> > "TestCreateDeviceNode", TestCreateDeviceNode, NULL, NULL,
> > &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathSimpleTestSuite, "Test
> > SetDevicePathEndNode", "TestSetDevicePathEndNode",
> > TestSetDevicePathEndNode, NULL, NULL, &SimpleTestContext);
> >
> > +  AddTestCase (DevicePathAppendTestSuite, "Test
> DuplicateDevicePath",
> > "TestDuplicateDevicePath", TestDuplicateDevicePath, NULL, NULL,
> > &SimpleTestContext);
> >
> > +
> >
> > +  Status = CreateUnitTestSuite (&DevicePathAppendTestSuite,
> > Framework, "Device path append operations test suite",
> > "Common.DevicePath.Append", NULL, NULL);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to create append device path test
> > suite\n"));
> >
> > +    goto EXIT;
> >
> > +  }
> >
> > +
> >
> > +  AddTestCase (DevicePathAppendTestSuite, "Test AppendDevicePath",
> > "TestAppendDevicePath", TestAppendDevicePath, NULL, NULL, NULL);
> >
> > +  AddTestCase (DevicePathAppendTestSuite, "Test
> > AppendDevicePathNode", "TestAppendDevicePathNode",
> > TestAppendDevicePathNode, NULL, NULL, NULL);
> >
> > +  AddTestCase (DevicePathAppendTestSuite, "Test
> > AppendDevicePathInstance", "TestAppendDevicePathInstance",
> > TestAppendDevicePathInstance, NULL, NULL, NULL);
> >
> > +
> >
> > +  Status = CreateDevicePathStringConversionsTestSuite (Framework);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to create conversions test
> > suite\n"));
> >
> > +    goto EXIT;
> >
> > +  }
> >
> > +
> >
> > +  Status = CreateUnitTestSuite (&DevicePathFileTestSuite,
> Framework,
> > "Device path file operations test suite",
> > "Common.DevicePath.FileDevPath", NULL, NULL);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to create device path file test
> > suite\n"));
> >
> > +    goto EXIT;
> >
> > +  }
> >
> > +
> >
> > +  AddTestCase (DevicePathFileTestSuite, "Test
> DevicePathFromHandle",
> > "TestDevicePathFromHandle", TestDevicePathFromHandle, NULL, NULL,
> > NULL);
> >
> > +  AddTestCase (DevicePathFileTestSuite, "Test FileDevicePath",
> > "TestFileDevicePath", TestFileDevicePath, NULL, NULL, NULL);
> >
> > +
> >
> > +  Status = RunAllTestSuites (Framework);
> >
> > +
> >
> > +EXIT:
> >
> > +  if (Framework != NULL) {
> >
> > +    FreeUnitTestFramework (Framework);
> >
> > +  }
> >
> > +
> >
> > +  return Status;
> >
> > +}
> >
> > +
> >
> > +int
> >
> > +main (
> >
> > +  int   argc,
> >
> > +  char  *argv[]
> >
> > +  )
> >
> > +{
> >
> > +  return UefiTestMain ();
> >
> > +}
> >
> > diff --git
> > a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> > b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> >
> > new file mode 100644
> >
> > index 0000000000..4a0c3d4c43
> >
> > --- /dev/null
> >
> > +++ b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLib.h
> >
> > @@ -0,0 +1,26 @@
> >
> > +/** @file
> >
> > +  UEFI OS based application for unit testing the DevicePathLib.
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +**/
> >
> > +
> >
> > +#ifndef __TEST_DEVICE_PATH_LIB_H__
> >
> > +#define __TEST_DEVICE_PATH_LIB_H__
> >
> > +
> >
> > +#include <PiPei.h>
> >
> > +#include <Uefi.h>
> >
> > +#include <Library/UefiLib.h>
> >
> > +#include <Library/DebugLib.h>
> >
> > +#include <Library/MemoryAllocationLib.h>
> >
> > +#include <Library/UnitTestLib.h>
> >
> > +#include <Protocol/DevicePath.h>
> >
> > +#include <Library/DevicePathLib.h>
> >
> > +#include <stdint.h>
> >
> > +
> >
> > +EFI_STATUS
> >
> > +CreateDevicePathStringConversionsTestSuite (
> >
> > +  IN UNIT_TEST_FRAMEWORK_HANDLE  Framework
> >
> > +  );
> >
> > +
> >
> > +#endif
> >
> > diff --git
> >
> a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> >
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> >
> > new file mode 100644
> >
> > index 0000000000..9f9c36946a
> >
> > --- /dev/null
> >
> > +++
> >
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathLibHost.inf
> >
> > @@ -0,0 +1,33 @@
> >
> > +## @file
> >
> > +# Host OS based Application that Unit Tests the UefiDevicePathLib
> >
> > +#
> >
> > +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +##
> >
> > +
> >
> > +[Defines]
> >
> > +  INF_VERSION     = 0x00010005
> >
> > +  BASE_NAME       = TestDevicePathLibHost
> >
> > +  MODULE_UNI_FILE = TestDevicePathLib.uni
> >
> > +  FILE_GUID       = F1505A0E-D71F-4431-99BE-736776842E38
> >
> > +  MODULE_TYPE     = HOST_APPLICATION
> >
> > +  VERSION_STRING  = 1.0
> >
> > +
> >
> > +#
> >
> > +# The following information is for reference only and not required
> by
> > the build tools.
> >
> > +#
> >
> > +#  VALID_ARCHITECTURES           = IA32 X64
> >
> > +#
> >
> > +
> >
> > +[Sources]
> >
> > +  TestDevicePathLib.c
> >
> > +  TestDevicePathStringConversions.c
> >
> > +
> >
> > +[Packages]
> >
> > +  MdePkg/MdePkg.dec
> >
> > +
> >
> > +[LibraryClasses]
> >
> > +  BaseLib
> >
> > +  DebugLib
> >
> > +  DevicePathLib
> >
> > +  UnitTestLib
> >
> > diff --git
> >
> a/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConve
> > rsions.c
> >
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConve
> > rsions.c
> >
> > new file mode 100644
> >
> > index 0000000000..4ea25ec142
> >
> > --- /dev/null
> >
> > +++
> >
> b/MdePkg/Test/UnitTest/Library/DevicePathLib/TestDevicePathStringConve
> > rsions.c
> >
> > @@ -0,0 +1,370 @@
> >
> > +/** @file
> >
> > +  UEFI OS based application for unit testing the DevicePathLib.
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include "TestDevicePathLib.h"
> >
> > +
> >
> > +typedef struct {
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    *DevPath;
> >
> > +  CONST CHAR16                *DevPathString;
> >
> > +} DEVICE_PATH_CONVERSIONS_TEST_CONTEXT;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED PCI_DEVICE_PATH  mPciDevicePathNode =
> >
> > +{
> >
> > +  // PCI device path - root port (0x2:0x0)
> >
> > +  {
> >
> > +    HARDWARE_DEVICE_PATH,
> >
> > +    HW_PCI_DP,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (PCI_DEVICE_PATH)),
> >
> > +      (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> >
> > +    }
> >
> > +  },
> >
> > +  0x2,
> >
> > +  0x0
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_HID_DEVICE_PATH
> > mAcpiPciRootHidDevicePathNode =
> >
> > +{
> >
> > +  // ACPI PCI root - PciRoot(0x0)
> >
> > +  {
> >
> > +    ACPI_DEVICE_PATH,
> >
> > +    ACPI_DP,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> >
> > +      (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> >
> > +    }
> >
> > +  },
> >
> > +  EISA_PNP_ID (0x0A03),
> >
> > +  0
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_HID_DEVICE_PATH
> > mAcpiNonPciRootHidDevicePathNode =
> >
> > +{
> >
> > +  // Random ACPI device - ACPI(PNPB0C0, 1)
> >
> > +  {
> >
> > +    ACPI_DEVICE_PATH,
> >
> > +    ACPI_DP,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> >
> > +      (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> >
> > +    }
> >
> > +  },
> >
> > +  EISA_PNP_ID (0xB0C0),
> >
> > +  1
> >
> > +};
> >
> > +
> >
> > +#define HID_STR_SIZE  8
> >
> > +#define CID_STR_SIZE  8
> >
> > +#define UID_STR_SIZE  8
> >
> > +
> >
> > +typedef struct {
> >
> > +  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
> >
> > +  CHAR8                            HidStr[HID_STR_SIZE];
> >
> > +  CHAR8                            CidStr[CID_STR_SIZE];
> >
> > +  CHAR8                            UidStr[UID_STR_SIZE];
> >
> > +} ACPI_EXTENDED_HID_DEVICE_PATH_FULL;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXTENDED_HID_DEVICE_PATH_FULL
> > mAcpiExtendedDevicePathFull =
> >
> > +{
> >
> > +  // ACPI Extended HID PciRoot device node
> >
> > +  {
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_EXTENDED_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_FULL)),
> >
> > +        (UINT8)((sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_FULL)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0,
> >
> > +    0,
> >
> > +    0,
> >
> > +  },
> >
> > +  { 'P', 'N', 'P', 'B', '0', 'C', '0', '\0' }, // HIDSTR
> >
> > +  { 'P', 'N', 'P', '0', '0', '0', '1', '\0' }, // CIDSTR
> >
> > +  { 'U', 'I', 'D', '0', '0', '0', '0', '\0' } // UIDSTR
> >
> > +};
> >
> > +
> >
> > +typedef struct {
> >
> > +  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
> >
> > +  CHAR8                            HidStr[HID_STR_SIZE];
> >
> > +} ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL
> > mAcpiExtendedDevicePathPartial =
> >
> > +{
> >
> > +  {
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_EXTENDED_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL)),
> >
> > +        (UINT8)((sizeof (ACPI_EXTENDED_HID_DEVICE_PATH_PARTIAL)) >>
> > 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0,
> >
> > +    2,
> >
> > +    0,
> >
> > +  },
> >
> > +  { 'P', 'N', 'P', 'B', '0', '\0', '\0', '\0' }, // HIDSTR
> >
> > +};
> >
> > +
> >
> > +typedef struct {
> >
> > +  ACPI_EXTENDED_HID_DEVICE_PATH    AcpiEx;
> >
> > +  CHAR8                            UidStr[UID_STR_SIZE];
> >
> > +} ACPI_EXPANDED_DEVICE_PATH;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXPANDED_DEVICE_PATH
> > mAcpiExpandedDevicePathUidOnly =
> >
> > +{
> >
> > +  {
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_EXTENDED_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_EXPANDED_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (ACPI_EXPANDED_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0xAAAA),
> >
> > +    0,
> >
> > +    0,
> >
> > +  },
> >
> > +  { '\0', 'U', 'I', 'D', '0', '0', '\0', '\0' } // UIDSTR
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED ACPI_EXPANDED_DEVICE_PATH
> > mAcpiExpandedDevicePathUidOnlyWithCid =
> >
> > +{
> >
> > +  {
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_EXTENDED_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_EXPANDED_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (ACPI_EXPANDED_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0xAAAA),
> >
> > +    0,
> >
> > +    EISA_PNP_ID (0xAADD),
> >
> > +  },
> >
> > +  { '\0', 'U', 'I', 'D', '0', '0', '\0', '\0' } // UIDSTR
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_CONVERSIONS_TEST_CONTEXT
> > mDevPathNodeToFromTextContext[] = {
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mPciDevicePathNode,
> >
> > +    L"Pci(0x0,0x2)"
> >
> > +  },
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiPciRootHidDevicePathNode,
> >
> > +    L"PciRoot(0x0)"
> >
> > +  },
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiNonPciRootHidDevicePathNode,
> >
> > +    L"Acpi(PNPB0C0,0x1)"
> >
> > +  },
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExtendedDevicePathFull,
> >
> > +    L"AcpiEx(@@@0000,@@@0000,0x0,PNPB0C0,UID0000,PNP0001)"
> >
> > +  },
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExtendedDevicePathPartial,
> >
> > +    L"AcpiEx(@@@0000,@@@0000,0x2,PNPB0,,)"
> >
> > +  },
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiExpandedDevicePathUidOnly,
> >
> > +    L"AcpiExp(PNPAAAA,0,UID00)"
> >
> > +  },
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL
> > *)&mAcpiExpandedDevicePathUidOnlyWithCid,
> >
> > +    L"AcpiExp(PNPAAAA,PNPAADD,UID00)"
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +typedef struct {
> >
> > +  ACPI_HID_DEVICE_PATH        AcpiPath;
> >
> > +  PCI_DEVICE_PATH             PciPathRootPort;
> >
> > +  PCI_DEVICE_PATH             PciPathEndPoint;
> >
> > +  USB_DEVICE_PATH             UsbPath;
> >
> > +  EFI_DEVICE_PATH_PROTOCOL    End;
> >
> > +} TEST_CONVERSIONS_DEVICE_PATH;
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED TEST_CONVERSIONS_DEVICE_PATH
> > mConversionsDevicePath = {
> >
> > +  { // ACPI device path with root bridge EISA_PNP_ID
> >
> > +    {
> >
> > +      ACPI_DEVICE_PATH,
> >
> > +      ACPI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    EISA_PNP_ID (0x0A03),
> >
> > +    0
> >
> > +  },
> >
> > +  { // PCI device path - root port (0x2:0x0)
> >
> > +    {
> >
> > +      HARDWARE_DEVICE_PATH,
> >
> > +      HW_PCI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0x2,
> >
> > +    0x0
> >
> > +  },
> >
> > +  { // PCI device path - endpoint (0x0:0x0)
> >
> > +    {
> >
> > +      HARDWARE_DEVICE_PATH,
> >
> > +      HW_PCI_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (PCI_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (PCI_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0x0,
> >
> > +    0x0
> >
> > +  },
> >
> > +  { // USB interface
> >
> > +    {
> >
> > +      MESSAGING_DEVICE_PATH,
> >
> > +      MSG_USB_DP,
> >
> > +      {
> >
> > +        (UINT8)(sizeof (USB_DEVICE_PATH)),
> >
> > +        (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
> >
> > +      }
> >
> > +    },
> >
> > +    0,
> >
> > +    2
> >
> > +  },
> >
> > +  {
> >
> > +    END_DEVICE_PATH_TYPE,
> >
> > +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> >
> > +    {
> >
> > +      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
> >
> > +      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
> >
> > +    }
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_CONVERSIONS_TEST_CONTEXT
> > mDevPathToFromTextContext[] = {
> >
> > +  {
> >
> > +    (EFI_DEVICE_PATH_PROTOCOL *)&mConversionsDevicePath,
> >
> > +    L"PciRoot(0x0)/Pci(0x0,0x2)/Pci(0x0,0x0)/USB(0x0,0x2)"
> >
> > +  }
> >
> > +};
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestConvertDevicePathToText (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  CHAR16                                *DevPathString;
> >
> > +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> >
> > +
> >
> > +  DevPathString = ConvertDevicePathToText (TestContext->DevPath,
> > FALSE, FALSE);
> >
> > +  UT_ASSERT_EQUAL (StrLen (DevPathString), StrLen (TestContext-
> > >DevPathString));
> >
> > +  UT_ASSERT_MEM_EQUAL (DevPathString, TestContext->DevPathString,
> > StrLen (TestContext->DevPathString));
> >
> > +  FreePool (DevPathString);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestConvertTextToDevicePath (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL              *ConvertedDevPath;
> >
> > +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> >
> > +
> >
> > +  ConvertedDevPath = ConvertTextToDevicePath (TestContext-
> > >DevPathString);
> >
> > +  UT_ASSERT_EQUAL (GetDevicePathSize (ConvertedDevPath),
> > GetDevicePathSize (TestContext->DevPath));
> >
> > +  UT_ASSERT_MEM_EQUAL (ConvertedDevPath, TestContext->DevPath,
> > GetDevicePathSize (TestContext->DevPath));
> >
> > +  FreePool (ConvertedDevPath);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestConvertDeviceNodeToText (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  CHAR16                                *DevPathNodeString;
> >
> > +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> >
> > +
> >
> > +  DevPathNodeString = ConvertDeviceNodeToText (TestContext-
> >DevPath,
> > FALSE, FALSE);
> >
> > +  UT_ASSERT_EQUAL (StrLen (DevPathNodeString), StrLen (TestContext-
> > >DevPathString));
> >
> > +  UT_ASSERT_MEM_EQUAL (DevPathNodeString, TestContext-
> >DevPathString,
> > StrLen (TestContext->DevPathString));
> >
> > +  FreePool (DevPathNodeString);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +UNIT_TEST_STATUS
> >
> > +EFIAPI
> >
> > +TestConvertTextToDeviceNode (
> >
> > +  IN UNIT_TEST_CONTEXT  Context
> >
> > +  )
> >
> > +{
> >
> > +  EFI_DEVICE_PATH_PROTOCOL              *DevPath;
> >
> > +  DEVICE_PATH_CONVERSIONS_TEST_CONTEXT  *TestContext;
> >
> > +
> >
> > +  TestContext = (DEVICE_PATH_CONVERSIONS_TEST_CONTEXT *)Context;
> >
> > +
> >
> > +  DevPath = ConvertTextToDeviceNode (TestContext->DevPathString);
> >
> > +  UT_ASSERT_EQUAL (DevicePathNodeLength (DevPath),
> > DevicePathNodeLength (TestContext->DevPath));
> >
> > +  UT_ASSERT_MEM_EQUAL (DevPath, TestContext->DevPath,
> > DevicePathNodeLength (TestContext->DevPath));
> >
> > +  FreePool (DevPath);
> >
> > +
> >
> > +  return UNIT_TEST_PASSED;
> >
> > +}
> >
> > +
> >
> > +EFI_STATUS
> >
> > +CreateDevicePathStringConversionsTestSuite (
> >
> > +  IN UNIT_TEST_FRAMEWORK_HANDLE  Framework
> >
> > +  )
> >
> > +{
> >
> > +  EFI_STATUS              Status;
> >
> > +  UNIT_TEST_SUITE_HANDLE  DevicePathTextConversionSuite = NULL;
> >
> > +  UINTN                   Index;
> >
> > +
> >
> > +  Status = CreateUnitTestSuite (&DevicePathTextConversionSuite,
> > Framework, "Device path text conversion operations test suite",
> > "Common.DevicePath.TextConversions", NULL, NULL);
> >
> > +  if (EFI_ERROR (Status)) {
> >
> > +    DEBUG ((DEBUG_ERROR, "Failed to create device path text
> > conversions test suite\n"));
> >
> > +    return Status;
> >
> > +  }
> >
> > +
> >
> > +  for (Index = 0; Index < ARRAY_SIZE
> (mDevPathNodeToFromTextContext);
> > Index++) {
> >
> > +    AddTestCase (DevicePathTextConversionSuite, "Test
> > ConvertDeviceNodeToText", "TestConvertDeviceNodeToText",
> > TestConvertDeviceNodeToText, NULL, NULL,
> > &mDevPathNodeToFromTextContext[Index]);
> >
> > +  }
> >
> > +
> >
> > +  for (Index = 0; Index < ARRAY_SIZE
> (mDevPathNodeToFromTextContext);
> > Index++) {
> >
> > +    AddTestCase (DevicePathTextConversionSuite, "Test
> > ConvertTextToDeviceNode", "TestConvertTextToDeviceNode",
> > TestConvertTextToDeviceNode, NULL, NULL,
> > &mDevPathNodeToFromTextContext[Index]);
> >
> > +  }
> >
> > +
> >
> > +  for (Index = 0; Index < ARRAY_SIZE (mDevPathToFromTextContext);
> > Index++) {
> >
> > +    AddTestCase (DevicePathTextConversionSuite, "Test
> > ConvertDevicePathToText", "TestConvertDevicePathToText",
> > TestConvertDevicePathToText, NULL, NULL,
> > &mDevPathToFromTextContext[Index]);
> >
> > +  }
> >
> > +
> >
> > +  for (Index = 0; Index < ARRAY_SIZE (mDevPathToFromTextContext);
> > Index++) {
> >
> > +    AddTestCase (DevicePathTextConversionSuite, "Test
> > ConvertTextToDevicePath", "TestConvertTextToDevicePath",
> > TestConvertTextToDevicePath, NULL, NULL,
> > &mDevPathToFromTextContext[Index]);
> >
> > +  }
> >
> > +
> >
> > +  return EFI_SUCCESS;
> >
> > +}
> >
> > --
> >
> > 2.39.2
> >
> >



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109817): https://edk2.groups.io/g/devel/message/109817
Mute This Topic: https://groups.io/mt/101619981/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/3901457/1787277/102458076/xyzzy [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-