Handle entity association records from host

- Get the PDRs from host, traverse the entity association structure
  and construct the D-Bus object path according to the entity type ID
  and container type ID.

- eg:
 /xyz/openbmc_project/inventory/system1/chassis1/io_board1/powersupply1
 /xyz/openbmc_project/inventory/system1/chassis1/io_board1/powersupply2
 /xyz/openbmc_project/inventory/system1/chassis2/io_board2/powersupply1
 /xyz/openbmc_project/inventory/system1/chassis2/io_board2/powersupply2

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I1c606ea943624f2601be4f5f6b5c30d1bf71cd11
diff --git a/host-bmc/test/meson.build b/host-bmc/test/meson.build
index 7ccfef7..d19d4ef 100644
--- a/host-bmc/test/meson.build
+++ b/host-bmc/test/meson.build
@@ -2,12 +2,18 @@
           sources: [ '../dbus_to_host_effecters.cpp' ],
           include_directories: '../../requester')
 
+test_sources = [
+  '../../common/utils.cpp',
+]
+
 tests = [
   'dbus_to_host_effecter_test',
+  'utils_test',
 ]
 
 foreach t : tests
   test(t, executable(t.underscorify(), t + '.cpp',
+                     test_sources,
                      implicit_include_directories: false,
                      link_args: dynamic_linker,
                      build_rpath: get_option('oe-sdk').enabled() ? rpath : '',
diff --git a/host-bmc/test/utils_test.cpp b/host-bmc/test/utils_test.cpp
new file mode 100644
index 0000000..45653ec
--- /dev/null
+++ b/host-bmc/test/utils_test.cpp
@@ -0,0 +1,98 @@
+#include "libpldm/pdr.h"
+
+#include "common/utils.hpp"
+
+#include <filesystem>
+
+#include <gtest/gtest.h>
+
+namespace fs = std::filesystem;
+using namespace pldm;
+using namespace pldm::utils;
+
+TEST(EntityAssociation, addObjectPathEntityAssociations1)
+{
+    pldm_entity entities[41]{};
+
+    entities[0].entity_type = 45;
+    entities[0].entity_container_id = 0;
+
+    entities[1].entity_type = 64;
+    entities[1].entity_container_id = 1;
+
+    entities[2].entity_type = 67;
+    entities[2].entity_container_id = 2;
+    entities[3].entity_type = 67;
+    entities[3].entity_container_id = 2;
+
+    entities[4].entity_type = 135;
+    entities[4].entity_container_id = 3;
+    entities[5].entity_type = 135;
+    entities[5].entity_container_id = 3;
+    entities[6].entity_type = 135;
+    entities[6].entity_container_id = 3;
+    entities[7].entity_type = 135;
+    entities[7].entity_container_id = 3;
+
+    auto tree = pldm_entity_association_tree_init();
+
+    auto l1 = pldm_entity_association_tree_add(tree, &entities[0], 1, nullptr,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+
+    auto l2 = pldm_entity_association_tree_add(tree, &entities[1], 1, l1,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+
+    auto l3a = pldm_entity_association_tree_add(
+        tree, &entities[2], 0, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l3b = pldm_entity_association_tree_add(
+        tree, &entities[3], 1, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+
+    auto l4a = pldm_entity_association_tree_add(
+        tree, &entities[4], 0, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l4b = pldm_entity_association_tree_add(
+        tree, &entities[5], 1, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+
+    auto l5a = pldm_entity_association_tree_add(
+        tree, &entities[6], 0, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l5b = pldm_entity_association_tree_add(
+        tree, &entities[7], 1, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+
+    EntityAssociations entityAssociations = {
+        {l1, l2}, {l2, l3a, l3b}, {l3a, l4a, l4b}, {l3b, l5a, l5b}};
+
+    ObjectPathMaps retObjectMaps = {
+        {"/xyz/openbmc_project/inventory/chassis1", l1},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1", l2},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1/dcm0", l3a},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1/dcm1", l3b},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1/dcm0/cpu0", l4a},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1/dcm0/cpu1", l4b},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1/dcm1/cpu0", l5a},
+        {"/xyz/openbmc_project/inventory/chassis1/motherboard1/dcm1/cpu1", l5b},
+    };
+
+    ObjectPathMaps objPathMap;
+    updateEntityAssociation(entityAssociations, tree, objPathMap);
+
+    EXPECT_EQ(objPathMap.size(), retObjectMaps.size());
+
+    int index = 0;
+    for (auto& obj : objPathMap)
+    {
+        if (retObjectMaps.contains(obj.first))
+        {
+            index++;
+            pldm_entity entity = pldm_entity_extract(obj.second);
+            pldm_entity retEntity =
+                pldm_entity_extract(retObjectMaps[obj.first]);
+            EXPECT_EQ(entity.entity_type, retEntity.entity_type);
+            EXPECT_EQ(entity.entity_instance_num,
+                      retEntity.entity_instance_num);
+            EXPECT_EQ(pldm_entity_node_get_remote_container_id(obj.second),
+                      pldm_entity_node_get_remote_container_id(
+                          retObjectMaps[obj.first]));
+        }
+    }
+    EXPECT_EQ(index, retObjectMaps.size());
+    pldm_entity_association_tree_destroy(tree);
+}