pdr: Add APIs for creating and locating remote PDRs

In the current state, the tree_find() and tree_add() utilities work by
replacing the existing container ID that comes from the remote
endpoints. But we need the remote container ID when we do the PDR
normalization (merging) in BMC.

Two boolean properties are introduced:

* is_remote: used to indicate if the entity is BMC owned or of remote
  endpoint owned.

* is_update_container_id: used to indicate if the container id of the
  entity needs to be updated or not.

We handle 3 different combinations,

1. Both are false - when it is the parent node in the tree
   example: - https://github.com/ibm-openbmc/pldm/blob/1050/
   libpldmresponder/pdr_state_sensor.hpp#L136

2. is_remote is false and update_container_id is true - when it is
   a BMC entity but we have a container id change needed.
   example: - https://github.com/ibm-openbmc/pldm/blob/1050/
   libpldmresponder/fru.cpp#L130

3. is_remote is true and update_container_id is false - In IBM
   PLDM stack talks to two different remote firmware implementations
   over PLDM, and we had a conflicting requirement to not merge the
   container ID from one endpoint but merge the container ID from
   another endpoint. Example: -https://github.com/ibm-openbmc/
   pldm/blob/1050/host-bmc/host_pdr_handler.cpp#L509

Change-Id: I8541b76aa46ba23172ffbc4d72e686909b7147fc
Signed-off-by: Pavithra Barithaya <pavithra.b@ibm.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/tests/libpldm_pdr_test.cpp b/tests/libpldm_pdr_test.cpp
index 6b99d5e..72860d7 100644
--- a/tests/libpldm_pdr_test.cpp
+++ b/tests/libpldm_pdr_test.cpp
@@ -748,6 +748,91 @@
     pldm_entity_association_tree_destroy(tree);
 }
 
+#if LIBPLDM_API_TESTING
+TEST(EntityAssociationPDR, findAndAddRemotePDR)
+{
+    //         Tree - 1
+    //
+    //        11521(1,0)
+    //             |
+    //          45 (1,1)
+    //             |
+    //          64 (1,2)
+    //             |
+    //    ------------------
+    //    |                 |
+    //  67(0,3)           67(1,3)
+    //    |                 |
+    // 135(0,4)          135(0,5)
+    //    |                 |
+    // 32903(0,6)         32903(0,7)
+
+    pldm_entity entities[9]{};
+    entities[0].entity_type = 11521;
+    entities[1].entity_type = 45;
+    entities[2].entity_type = 64;
+    entities[3].entity_type = 67;
+    entities[4].entity_type = 67;
+    entities[5].entity_type = 135;
+    entities[5].entity_container_id = 2;
+    entities[6].entity_type = 135;
+    entities[6].entity_container_id = 3;
+    entities[7].entity_type = 32903;
+    entities[8].entity_type = 32903;
+    auto tree = pldm_entity_association_tree_init();
+    auto l1 = pldm_entity_association_tree_add_entity(
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
+        false, true, 0xFFFF);
+    EXPECT_NE(l1, nullptr);
+    auto l2 = pldm_entity_association_tree_add_entity(
+        tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xFFFF);
+    EXPECT_NE(l2, nullptr);
+    auto l3 = pldm_entity_association_tree_add_entity(
+        tree, &entities[2], 0xFFFF, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        true, 0xFFFF);
+    EXPECT_NE(l3, nullptr);
+    auto l4a = pldm_entity_association_tree_add_entity(
+        tree, &entities[3], 0, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xFFFF);
+    EXPECT_NE(l4a, nullptr);
+    auto l4b = pldm_entity_association_tree_add_entity(
+        tree, &entities[4], 1, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+        0xFFFF);
+    EXPECT_NE(l4b, nullptr);
+    auto l5a = pldm_entity_association_tree_add_entity(
+        tree, &entities[5], 0, l4a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xFFFF);
+    EXPECT_NE(l5a, nullptr);
+    auto l5b = pldm_entity_association_tree_add_entity(
+        tree, &entities[6], 0, l4b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xFFFF);
+    EXPECT_NE(l5b, nullptr);
+    pldm_entity entity{};
+    entity.entity_type = 135;
+    entity.entity_instance_num = 0;
+    entity.entity_container_id = 2;
+    auto result1 = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_EQ(result1, l5a);
+    EXPECT_EQ(entities[5].entity_container_id, 2);
+    auto l6a = pldm_entity_association_tree_add_entity(
+        tree, &entities[7], 0, result1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xFFFF);
+    EXPECT_NE(l6a, nullptr);
+    entity.entity_type = 135;
+    entity.entity_instance_num = 0;
+    entity.entity_container_id = 3;
+    auto result2 = pldm_entity_association_tree_find(tree, &entity);
+    EXPECT_NE(result2, l5b);
+    EXPECT_EQ(entities[6].entity_container_id, 3);
+    auto l7a = pldm_entity_association_tree_add_entity(
+        tree, &entities[8], 0, result2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
+        false, 0xFFFF);
+    EXPECT_EQ(l7a, nullptr);
+    pldm_entity_association_tree_destroy(tree);
+}
+#endif
+
 TEST(EntityAssociationPDR, testSpecialTrees)
 {
     pldm_entity entities[3]{};