Add entity instance as an input parameter to pldm_pdr_tree_add()

- The intent behind this commit is to allow other projects that are
  consuming the libpldm(like openpower/hostboot) to create the
  entities with custom entity instance numbers while creating
  the entity association PDR's.

- If the entity instance number value is 0xFFFF or its parent is
  NULL, then use the existing logic.

- If the entity instance number value is not 0xFFFF and the parent is
  not NULL, should be verify whether the entity exists, if it exists,
  return the entity, otherwise add the entity to the tree.

Tested: Built pldm successfully and Unit Test passes.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: If9b0ac9c1dac3147ed6f95a3e027d155fe2a38c6
diff --git a/libpldm/pdr.c b/libpldm/pdr.c
index d8c0f77..d887917 100644
--- a/libpldm/pdr.c
+++ b/libpldm/pdr.c
@@ -373,12 +373,23 @@
 	return start;
 }
 
-pldm_entity_node *
-pldm_entity_association_tree_add(pldm_entity_association_tree *tree,
-				 pldm_entity *entity, pldm_entity_node *parent,
-				 uint8_t association_type)
+pldm_entity_node *pldm_entity_association_tree_add(
+    pldm_entity_association_tree *tree, pldm_entity *entity,
+    uint16_t entity_instance_number, pldm_entity_node *parent,
+    uint8_t association_type)
 {
 	assert(tree != NULL);
+	assert(entity != NULL);
+
+	if (entity_instance_number != 0xFFFF && parent != NULL) {
+		pldm_entity node;
+		node.entity_type = entity->entity_type;
+		node.entity_instance_num = entity_instance_number;
+		if (pldm_is_current_parent_child(parent, &node)) {
+			return NULL;
+		}
+	}
+
 	assert(association_type == PLDM_ENTITY_ASSOCIAION_PHYSICAL ||
 	       association_type == PLDM_ENTITY_ASSOCIAION_LOGICAL);
 	pldm_entity_node *node = malloc(sizeof(pldm_entity_node));
@@ -387,7 +398,8 @@
 	node->first_child = NULL;
 	node->next_sibling = NULL;
 	node->entity.entity_type = entity->entity_type;
-	node->entity.entity_instance_num = 1;
+	node->entity.entity_instance_num =
+	    entity_instance_number != 0xFFFF ? entity_instance_number : 1;
 	node->association_type = association_type;
 
 	if (tree->root == NULL) {
@@ -409,7 +421,9 @@
 		if (prev->entity.entity_type == entity->entity_type) {
 			assert(prev->entity.entity_instance_num != UINT16_MAX);
 			node->entity.entity_instance_num =
-			    prev->entity.entity_instance_num + 1;
+			    entity_instance_number != 0xFFFF
+				? entity_instance_number
+				: prev->entity.entity_instance_num + 1;
 		}
 		prev->next_sibling = node;
 		node->parent = prev->parent;
diff --git a/libpldm/pdr.h b/libpldm/pdr.h
index 8d827dc..021a6d1 100644
--- a/libpldm/pdr.h
+++ b/libpldm/pdr.h
@@ -223,16 +223,19 @@
  *  @param[in/out] entity - pointer to the entity to be added. Input has the
  *                          entity type. On output, instance number and the
  *                          container id are populated.
+ *  @param[in] entity_instance_number - entity instance number, we can use the
+ *                                      entity instance number of the entity by
+ *                                      default if its value is equal 0xFFFF.
  *  @param[in] parent - pointer to the node that should be the parent of input
  *                      entity. If this is NULL, then the entity is the root
  *  @param[in] association_type - relation with the parent : logical or physical
  *
  *  @return pldm_entity_node* - opaque pointer to added entity
  */
-pldm_entity_node *
-pldm_entity_association_tree_add(pldm_entity_association_tree *tree,
-				 pldm_entity *entity, pldm_entity_node *parent,
-				 uint8_t association_type);
+pldm_entity_node *pldm_entity_association_tree_add(
+    pldm_entity_association_tree *tree, pldm_entity *entity,
+    uint16_t entity_instance_number, pldm_entity_node *parent,
+    uint8_t association_type);
 
 /** @brief Visit and note each entity in the entity association tree
  *
diff --git a/libpldm/tests/libpldm_pdr_test.cpp b/libpldm/tests/libpldm_pdr_test.cpp
index b7fb59a..8c070a3 100644
--- a/libpldm/tests/libpldm_pdr_test.cpp
+++ b/libpldm/tests/libpldm_pdr_test.cpp
@@ -531,32 +531,32 @@
 
     auto tree = pldm_entity_association_tree_init();
 
-    auto l1 = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
-                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l1, nullptr);
     auto l2a = pldm_entity_association_tree_add(
-        tree, &entities[1], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2a, nullptr);
     auto l2b = pldm_entity_association_tree_add(
-        tree, &entities[2], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2b, nullptr);
     auto l2c = pldm_entity_association_tree_add(
-        tree, &entities[3], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2c, nullptr);
     auto l3a = pldm_entity_association_tree_add(
-        tree, &entities[4], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[4], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3a, nullptr);
     auto l3b = pldm_entity_association_tree_add(
-        tree, &entities[5], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[5], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3b, nullptr);
     auto l3c = pldm_entity_association_tree_add(
-        tree, &entities[6], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[6], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3b, nullptr);
     auto l4a = pldm_entity_association_tree_add(
-        tree, &entities[7], l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[7], 0xFFFF, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l4a, nullptr);
     auto l4b = pldm_entity_association_tree_add(
-        tree, &entities[8], l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[8], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l4b, nullptr);
 
     EXPECT_EQ(pldm_entity_is_node_parent(l1), true);
@@ -676,7 +676,7 @@
     // A
     auto tree = pldm_entity_association_tree_init();
     auto node = pldm_entity_association_tree_add(
-        tree, &entities[0], nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
     size_t num{};
     pldm_entity* out = nullptr;
@@ -690,13 +690,13 @@
 
     // A-A-A
     tree = pldm_entity_association_tree_init();
-    node = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr,
                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
-    node = pldm_entity_association_tree_add(tree, &entities[1], nullptr,
+    node = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, nullptr,
                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
-    node = pldm_entity_association_tree_add(tree, &entities[2], nullptr,
+    node = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, nullptr,
                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
     pldm_entity_association_tree_visit(tree, &out, &num);
@@ -719,14 +719,14 @@
     // |
     // A
     tree = pldm_entity_association_tree_init();
-    node = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr,
                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
     auto node1 = pldm_entity_association_tree_add(
-        tree, &entities[1], node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[1], 0xFFFF, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node1, nullptr);
     auto node2 = pldm_entity_association_tree_add(
-        tree, &entities[2], node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[2], 0xFFFF, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node2, nullptr);
     pldm_entity_association_tree_visit(tree, &out, &num);
     EXPECT_EQ(num, 3u);
@@ -746,16 +746,16 @@
     //   |
     //   A-A
     tree = pldm_entity_association_tree_init();
-    node = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr,
                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
-    node = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
+    node = pldm_entity_association_tree_add(tree, &entities[0], 0xFFFF, nullptr,
                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node, nullptr);
-    node1 = pldm_entity_association_tree_add(tree, &entities[1], node,
+    node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xFFFF, node,
                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node1, nullptr);
-    node2 = pldm_entity_association_tree_add(tree, &entities[2], node,
+    node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, node,
                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(node2, nullptr);
     pldm_entity_association_tree_visit(tree, &out, &num);
@@ -813,44 +813,44 @@
 
     auto tree = pldm_entity_association_tree_init();
 
-    auto l1 = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
-                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l1, nullptr);
     auto l1a = pldm_entity_association_tree_add(
-        tree, &entities[1], nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[1], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l1a, nullptr);
 
     auto l2a = pldm_entity_association_tree_add(
-        tree, &entities[1], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2a, nullptr);
-    auto l2b = pldm_entity_association_tree_add(tree, &entities[2], l1,
+    auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xFFFF, l1,
                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
     EXPECT_NE(l2b, nullptr);
     auto l2c = pldm_entity_association_tree_add(
-        tree, &entities[3], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2c, nullptr);
-    auto l2d = pldm_entity_association_tree_add(tree, &entities[4], l1,
+    auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xFFFF, l1,
                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
     EXPECT_NE(l2d, nullptr);
 
     auto l3a = pldm_entity_association_tree_add(
-        tree, &entities[5], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[5], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3a, nullptr);
     auto l3b = pldm_entity_association_tree_add(
-        tree, &entities[6], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[6], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3b, nullptr);
-    auto l3c = pldm_entity_association_tree_add(tree, &entities[7], l2a,
+    auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xFFFF, l2a,
                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
     EXPECT_NE(l3c, nullptr);
-    auto l3d = pldm_entity_association_tree_add(tree, &entities[8], l2a,
+    auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xFFFF, l2a,
                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
     EXPECT_NE(l3d, nullptr);
 
     auto l4a = pldm_entity_association_tree_add(
-        tree, &entities[9], l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[9], 0xFFFF, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l4a, nullptr);
-    auto l4b = pldm_entity_association_tree_add(tree, &entities[10], l3b,
-                                                PLDM_ENTITY_ASSOCIAION_LOGICAL);
+    auto l4b = pldm_entity_association_tree_add(
+        tree, &entities[10], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL);
     EXPECT_NE(l4b, nullptr);
 
     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
@@ -1110,32 +1110,32 @@
 
     auto tree = pldm_entity_association_tree_init();
 
-    auto l1 = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
-                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l1, nullptr);
     auto l2a = pldm_entity_association_tree_add(
-        tree, &entities[1], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2a, nullptr);
     auto l2b = pldm_entity_association_tree_add(
-        tree, &entities[2], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2b, nullptr);
     auto l2c = pldm_entity_association_tree_add(
-        tree, &entities[3], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2c, nullptr);
     auto l3a = pldm_entity_association_tree_add(
-        tree, &entities[4], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[4], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3a, nullptr);
     auto l3b = pldm_entity_association_tree_add(
-        tree, &entities[5], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[5], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3b, nullptr);
     auto l3c = pldm_entity_association_tree_add(
-        tree, &entities[6], l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[6], 0xFFFF, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l3c, nullptr);
     auto l4a = pldm_entity_association_tree_add(
-        tree, &entities[7], l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[7], 0xFFFF, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l4a, nullptr);
     auto l4b = pldm_entity_association_tree_add(
-        tree, &entities[8], l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[8], 0xFFFF, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l4b, nullptr);
 
     pldm_entity entity{};
@@ -1181,17 +1181,18 @@
 
     auto orgTree = pldm_entity_association_tree_init();
     auto newTree = pldm_entity_association_tree_init();
-    auto l1 = pldm_entity_association_tree_add(orgTree, &entities[0], nullptr,
-                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l1 =
+        pldm_entity_association_tree_add(orgTree, &entities[0], 0xFFFF, nullptr,
+                                         PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l1, nullptr);
     auto l2a = pldm_entity_association_tree_add(
-        orgTree, &entities[1], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        orgTree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2a, nullptr);
     auto l2b = pldm_entity_association_tree_add(
-        orgTree, &entities[2], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        orgTree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2b, nullptr);
     auto l2c = pldm_entity_association_tree_add(
-        orgTree, &entities[3], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        orgTree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2c, nullptr);
     size_t orgNum{};
     pldm_entity* orgOut = nullptr;
@@ -1287,17 +1288,17 @@
     entities[3].entity_type = 3;
 
     auto tree = pldm_entity_association_tree_init();
-    auto l1 = pldm_entity_association_tree_add(tree, &entities[0], nullptr,
-                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto l1 = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l1, nullptr);
     auto l2a = pldm_entity_association_tree_add(
-        tree, &entities[1], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[1], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2a, nullptr);
     auto l2b = pldm_entity_association_tree_add(
-        tree, &entities[2], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[2], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2b, nullptr);
     auto l2c = pldm_entity_association_tree_add(
-        tree, &entities[3], l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+        tree, &entities[3], 0xFFFF, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
     EXPECT_NE(l2c, nullptr);
 
     pldm_entity et1;
@@ -1316,4 +1317,136 @@
     EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3));
 
     pldm_entity_association_tree_destroy(tree);
-}
\ No newline at end of file
+}
+
+TEST(EntityAssociationPDR, testEntityInstanceNumber)
+{
+    pldm_entity entities[9]{};
+
+    entities[0].entity_type = 1;
+    entities[1].entity_type = 2;
+    entities[2].entity_type = 2;
+    entities[3].entity_type = 2;
+    entities[4].entity_type = 2;
+    entities[5].entity_type = 2;
+    entities[6].entity_type = 2;
+    entities[7].entity_type = 3;
+    entities[8].entity_type = 3;
+
+    auto tree = pldm_entity_association_tree_init();
+    auto repo = pldm_pdr_init();
+
+    uint16_t terminusHdl{};
+    uint16_t entityType{};
+    uint16_t entityInstanceNum{};
+    uint16_t containerId{};
+
+    auto node = pldm_entity_association_tree_add(
+        tree, &entities[0], 0xFFFF, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_NE(node, nullptr);
+
+    auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto first = pldm_pdr_add_fru_record_set(
+        repo, 1, 1, entities[1].entity_type, entities[1].entity_instance_num,
+        entities[1].entity_container_id);
+    EXPECT_NE(l1, nullptr);
+    EXPECT_EQ(entities[1].entity_instance_num, 63);
+    EXPECT_EQ(first, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 1, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 63);
+
+    auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto second = pldm_pdr_add_fru_record_set(
+        repo, 1, 2, entities[2].entity_type, entities[2].entity_instance_num,
+        entities[2].entity_container_id);
+    EXPECT_NE(l2, nullptr);
+    EXPECT_EQ(entities[2].entity_instance_num, 37);
+    EXPECT_EQ(second, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 2, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 37);
+
+    auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto third = pldm_pdr_add_fru_record_set(
+        repo, 1, 3, entities[3].entity_type, entities[3].entity_instance_num,
+        entities[3].entity_container_id);
+    EXPECT_NE(l3, nullptr);
+    EXPECT_EQ(entities[3].entity_instance_num, 44);
+    EXPECT_EQ(third, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 3, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 44);
+
+    auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto fourth = pldm_pdr_add_fru_record_set(
+        repo, 1, 4, entities[4].entity_type, entities[4].entity_instance_num,
+        entities[4].entity_container_id);
+    EXPECT_NE(l4, nullptr);
+    EXPECT_EQ(entities[4].entity_instance_num, 89);
+    EXPECT_EQ(fourth, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 4, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 89);
+
+    auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xFFFF, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto fifth = pldm_pdr_add_fru_record_set(
+        repo, 1, 5, entities[5].entity_type, entities[5].entity_instance_num,
+        entities[5].entity_container_id);
+    EXPECT_NE(l5, nullptr);
+    EXPECT_EQ(entities[5].entity_instance_num, 90);
+    EXPECT_EQ(fifth, pldm_pdr_get_record_handle(
+                         repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                   repo, 5, &terminusHdl, &entityType,
+                                   &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 2);
+    EXPECT_EQ(entityInstanceNum, 90);
+
+    auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    EXPECT_EQ(l6, nullptr);
+
+    auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto seventh = pldm_pdr_add_fru_record_set(
+        repo, 1, 7, entities[7].entity_type, entities[7].entity_instance_num,
+        entities[7].entity_container_id);
+    EXPECT_NE(l7, nullptr);
+    EXPECT_EQ(entities[7].entity_instance_num, 100);
+    EXPECT_EQ(seventh, pldm_pdr_get_record_handle(
+                           repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                     repo, 7, &terminusHdl, &entityType,
+                                     &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 3);
+    EXPECT_EQ(entityInstanceNum, 100);
+
+    auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2,
+                                               PLDM_ENTITY_ASSOCIAION_PHYSICAL);
+    auto eighth = pldm_pdr_add_fru_record_set(
+        repo, 1, 8, entities[8].entity_type, entities[8].entity_instance_num,
+        entities[8].entity_container_id);
+    EXPECT_NE(l8, nullptr);
+    EXPECT_EQ(entities[8].entity_instance_num, 100);
+    EXPECT_EQ(eighth, pldm_pdr_get_record_handle(
+                          repo, pldm_pdr_fru_record_set_find_by_rsi(
+                                    repo, 8, &terminusHdl, &entityType,
+                                    &entityInstanceNum, &containerId)));
+    EXPECT_EQ(entityType, 3);
+    EXPECT_EQ(entityInstanceNum, 100);
+
+    pldm_pdr_destroy(repo);
+    pldm_entity_association_tree_destroy(tree);
+}