xref: /openbmc/libpldm/tests/dsp/pdr.cpp (revision bc40dd5a64f5b375ba86a0ab6b2ed3e7863e2f5b)
1 #include <endian.h>
2 #include <libpldm/pdr.h>
3 #include <libpldm/platform.h>
4 #include <msgbuf.h>
5 
6 #include <array>
7 #include <cstdint>
8 #include <cstdlib>
9 #include <cstring>
10 #include <vector>
11 
12 #include <gtest/gtest.h>
13 
14 typedef struct pldm_association_pdr_test
15 {
16     uint32_t record_handle;
17     uint8_t version;
18     uint8_t type;
19     uint16_t record_change_num;
20     uint16_t length;
21     uint16_t container_id;
22     uint8_t association_type;
23     uint8_t num_children;
24 
operator ==pldm_association_pdr_test25     inline bool operator==(pldm_association_pdr_test pdr) const
26     {
27         return (record_handle == pdr.record_handle) && (type == pdr.type) &&
28                (length == pdr.length) && (container_id == pdr.container_id) &&
29                (association_type == pdr.association_type) &&
30                (num_children == pdr.num_children);
31     }
32 } pldm_association_pdr_test;
33 
34 typedef struct pldm_entity_test
35 {
36     uint16_t entity_type;
37     uint16_t entity_instance_num;
38     uint16_t entity_container_id;
39 
operator ==pldm_entity_test40     inline bool operator==(pldm_entity_test entity) const
41     {
42         return (entity_type == entity.entity_type) &&
43                (entity_instance_num == entity.entity_instance_num) &&
44                (entity_container_id == entity.entity_container_id);
45     }
46 } pldm_entity_test;
47 
getEntity(struct pldm_msgbuf * buf,pldm_entity_test & entity)48 static void getEntity(struct pldm_msgbuf* buf, pldm_entity_test& entity)
49 {
50     pldm_msgbuf_extract_uint16(buf, entity.entity_type);
51     pldm_msgbuf_extract_uint16(buf, entity.entity_instance_num);
52     pldm_msgbuf_extract_uint16(buf, entity.entity_container_id);
53 }
54 
55 static void
getAssociationPdrDetails(struct pldm_msgbuf * buf,pldm_association_pdr_test & association_pdr_test)56     getAssociationPdrDetails(struct pldm_msgbuf* buf,
57                              pldm_association_pdr_test& association_pdr_test)
58 {
59     pldm_msgbuf_extract_uint32(buf, association_pdr_test.record_handle);
60     pldm_msgbuf_extract_uint8(buf, association_pdr_test.version);
61     pldm_msgbuf_extract_uint8(buf, association_pdr_test.type);
62     pldm_msgbuf_extract_uint16(buf, association_pdr_test.record_change_num);
63     pldm_msgbuf_extract_uint16(buf, association_pdr_test.length);
64 
65     pldm_msgbuf_extract_uint16(buf, association_pdr_test.container_id);
66     pldm_msgbuf_extract_uint8(buf, association_pdr_test.association_type);
67 }
68 
69 static void
verifyEntityAssociationPdr(struct pldm_msgbuf * buf,const pldm_association_pdr_test & association_pdr,const pldm_entity_test & container_entity1,const pldm_entity_test & child_entity1)70     verifyEntityAssociationPdr(struct pldm_msgbuf* buf,
71                                const pldm_association_pdr_test& association_pdr,
72                                const pldm_entity_test& container_entity1,
73                                const pldm_entity_test& child_entity1)
74 {
75     struct pldm_entity_test container_entity = {};
76     struct pldm_entity_test child_entity = {};
77     pldm_association_pdr_test association_pdr_test{};
78 
79     getAssociationPdrDetails(buf, association_pdr_test);
80     getEntity(buf, container_entity);
81     pldm_msgbuf_extract_uint8(buf, association_pdr_test.num_children);
82     getEntity(buf, child_entity);
83 
84     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
85 
86     EXPECT_TRUE(association_pdr_test == association_pdr);
87     EXPECT_TRUE(container_entity == container_entity1);
88     EXPECT_TRUE(child_entity == child_entity1);
89 }
90 
TEST(PDRAccess,testInit)91 TEST(PDRAccess, testInit)
92 {
93     auto repo = pldm_pdr_init();
94     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
95     EXPECT_EQ(pldm_pdr_get_repo_size(repo), 0u);
96     pldm_pdr_destroy(repo);
97 }
98 
TEST(PDRUpdate,testAdd)99 TEST(PDRUpdate, testAdd)
100 {
101     auto repo = pldm_pdr_init();
102 
103     std::array<uint8_t, 10> data{};
104     uint32_t handle = 0;
105     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
106               0);
107     EXPECT_EQ(handle, 1u);
108     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
109     EXPECT_EQ(pldm_pdr_get_repo_size(repo), data.size());
110 
111     handle = 0;
112     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
113               0);
114     EXPECT_EQ(handle, 2u);
115 
116     handle = 0;
117     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
118               0);
119     EXPECT_EQ(handle, 3u);
120 
121     handle = 0xdeeddeedu;
122     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
123               0);
124     EXPECT_EQ(handle, 0xdeeddeed);
125     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
126     EXPECT_EQ(pldm_pdr_get_repo_size(repo), data.size() * 4u);
127 
128     pldm_pdr_destroy(repo);
129 }
130 
TEST(PDRRemoveByTerminus,testRemoveByTerminus)131 TEST(PDRRemoveByTerminus, testRemoveByTerminus)
132 {
133     std::array<uint8_t, 10> data{};
134 
135     auto repo = pldm_pdr_init();
136 
137     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
138     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
139     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
140     pldm_pdr_destroy(repo);
141 
142     repo = pldm_pdr_init();
143     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 2, NULL), 0);
144     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
145     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
146     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
147     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
148     pldm_pdr_destroy(repo);
149 
150     repo = pldm_pdr_init();
151     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
152     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 2, NULL), 0);
153     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 2, NULL), 0);
154     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
155     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 2);
156     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
157     pldm_pdr_destroy(repo);
158 
159     repo = pldm_pdr_init();
160     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
161     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 2, NULL), 0);
162     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
163     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
164     pldm_pdr_remove_remote_pdrs(repo);
165     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
166     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
167     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
168     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 2);
169     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
170     pldm_pdr_destroy(repo);
171 }
172 
TEST(PDRUpdate,testRemove)173 TEST(PDRUpdate, testRemove)
174 {
175     std::array<uint8_t, 10> data{};
176 
177     auto repo = pldm_pdr_init();
178     pldm_pdr_remove_remote_pdrs(repo);
179     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
180     pldm_pdr_destroy(repo);
181 
182     repo = pldm_pdr_init();
183     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
184     pldm_pdr_remove_remote_pdrs(repo);
185     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
186     pldm_pdr_destroy(repo);
187 
188     repo = pldm_pdr_init();
189     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
190     pldm_pdr_remove_remote_pdrs(repo);
191     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
192     pldm_pdr_destroy(repo);
193 
194     repo = pldm_pdr_init();
195     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
196     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
197     pldm_pdr_remove_remote_pdrs(repo);
198     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
199     pldm_pdr_destroy(repo);
200 
201     repo = pldm_pdr_init();
202     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
203     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
204     pldm_pdr_remove_remote_pdrs(repo);
205     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
206     pldm_pdr_destroy(repo);
207 
208     repo = pldm_pdr_init();
209     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
210     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
211     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
212     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
213     pldm_pdr_remove_remote_pdrs(repo);
214     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
215     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
216     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
217     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
218     pldm_pdr_destroy(repo);
219 
220     repo = pldm_pdr_init();
221     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
222     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
223     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
224     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
225     pldm_pdr_remove_remote_pdrs(repo);
226     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
227     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
228     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
229     EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
230     pldm_pdr_destroy(repo);
231 
232     repo = pldm_pdr_init();
233     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
234     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
235     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
236     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
237     pldm_pdr_remove_remote_pdrs(repo);
238     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
239     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
240     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
241     EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
242     pldm_pdr_destroy(repo);
243 
244     repo = pldm_pdr_init();
245     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
246     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
247     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
248     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
249     pldm_pdr_remove_remote_pdrs(repo);
250     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
251     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
252     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
253     EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
254     pldm_pdr_destroy(repo);
255 
256     repo = pldm_pdr_init();
257     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
258     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
259     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
260     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
261     pldm_pdr_remove_remote_pdrs(repo);
262     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
263     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
264     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
265     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
266     pldm_pdr_destroy(repo);
267 
268     repo = pldm_pdr_init();
269     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
270     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
271     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
272     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
273     pldm_pdr_remove_remote_pdrs(repo);
274     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
275     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
276     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
277     EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
278     pldm_pdr_destroy(repo);
279 
280     repo = pldm_pdr_init();
281     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
282     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
283     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
284     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
285     pldm_pdr_remove_remote_pdrs(repo);
286     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
287     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
288     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
289     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
290     pldm_pdr_destroy(repo);
291 
292     repo = pldm_pdr_init();
293     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
294     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
295     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
296     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
297     pldm_pdr_remove_remote_pdrs(repo);
298     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
299     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
300     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
301     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
302     pldm_pdr_destroy(repo);
303 
304     repo = pldm_pdr_init();
305     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
306     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
307     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
308     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
309     pldm_pdr_remove_remote_pdrs(repo);
310     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
311     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
312     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
313     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
314     pldm_pdr_destroy(repo);
315 
316     repo = pldm_pdr_init();
317     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
318     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
319     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
320     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
321     pldm_pdr_remove_remote_pdrs(repo);
322     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
323     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
324     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
325     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
326     pldm_pdr_destroy(repo);
327 
328     repo = pldm_pdr_init();
329     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
330     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
331     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
332     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
333     pldm_pdr_remove_remote_pdrs(repo);
334     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
335     uint32_t handle = 0;
336     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
337               0);
338     EXPECT_EQ(handle, 3u);
339     handle = 0;
340     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle),
341               0);
342     EXPECT_EQ(handle, 4u);
343     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
344     pldm_pdr_destroy(repo);
345 }
346 
TEST(PDRAccess,testGet)347 TEST(PDRAccess, testGet)
348 {
349     auto repo = pldm_pdr_init();
350 
351     std::array<uint32_t, 10> in{100, 345, 3, 6, 89, 0, 11, 45, 23434, 123123};
352     uint32_t handle = 1;
353     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
354     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in.data()),
355                            sizeof(in), false, 1, &handle),
356               0);
357     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
358     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in));
359     uint32_t size{};
360     uint32_t nextRecHdl{};
361     uint8_t* outData = nullptr;
362     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
363     EXPECT_NE(hdl, nullptr);
364     EXPECT_EQ(size, sizeof(in));
365     EXPECT_EQ(nextRecHdl, 0u);
366     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
367     outData = nullptr;
368 
369     auto hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
370     EXPECT_EQ(hdl, hdl2);
371     EXPECT_NE(hdl, nullptr);
372     EXPECT_EQ(size, sizeof(in));
373     EXPECT_EQ(nextRecHdl, 0u);
374     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
375     outData = nullptr;
376 
377     hdl = pldm_pdr_find_record(repo, htole32(0xdeaddead), &outData, &size,
378                                &nextRecHdl);
379     EXPECT_EQ(hdl, nullptr);
380     EXPECT_EQ(size, 0u);
381     EXPECT_EQ(nextRecHdl, 0u);
382     EXPECT_EQ(outData, nullptr);
383     outData = nullptr;
384 
385     std::array<uint32_t, 10> in2{1000, 3450, 30,  60,     890,
386                                  0,    110,  450, 234034, 123123};
387     handle = 2;
388     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
389     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
390                            sizeof(in2), false, 1, &handle),
391               0);
392     handle = 3;
393     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
394     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
395                            sizeof(in2), false, 1, &handle),
396               0);
397     handle = 4;
398     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
399     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
400                            sizeof(in2), true, 1, &handle),
401               0);
402     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
403     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4);
404     hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
405     EXPECT_NE(hdl, nullptr);
406     EXPECT_EQ(size, sizeof(in));
407     EXPECT_EQ(nextRecHdl, 2u);
408     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
409     outData = nullptr;
410     hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
411     EXPECT_EQ(hdl, hdl2);
412     EXPECT_NE(hdl, nullptr);
413     EXPECT_EQ(size, sizeof(in));
414     EXPECT_EQ(nextRecHdl, 2u);
415     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
416     outData = nullptr;
417     hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
418     EXPECT_NE(hdl, nullptr);
419     EXPECT_EQ(size, sizeof(in2));
420     EXPECT_EQ(nextRecHdl, 3u);
421     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
422     outData = nullptr;
423     hdl = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
424     EXPECT_NE(hdl, nullptr);
425     EXPECT_EQ(pldm_pdr_record_is_remote(hdl), false);
426     EXPECT_EQ(size, sizeof(in2));
427     EXPECT_EQ(nextRecHdl, 4u);
428     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
429     outData = nullptr;
430     hdl = pldm_pdr_find_record(repo, 4, &outData, &size, &nextRecHdl);
431     EXPECT_NE(hdl, nullptr);
432     EXPECT_EQ(pldm_pdr_record_is_remote(hdl), true);
433     EXPECT_EQ(size, sizeof(in2));
434     EXPECT_EQ(nextRecHdl, 0u);
435     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
436     outData = nullptr;
437 
438     pldm_pdr_destroy(repo);
439 }
440 
TEST(PDRAccess,testGetNext)441 TEST(PDRAccess, testGetNext)
442 {
443     auto repo = pldm_pdr_init();
444 
445     std::array<uint32_t, 10> in{100, 345, 3, 6, 89, 0, 11, 45, 23434, 123123};
446     uint32_t handle = 1;
447     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
448     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in.data()),
449                            sizeof(in), false, 1, &handle),
450               0);
451     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
452     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in));
453     uint32_t size{};
454     uint32_t nextRecHdl{};
455     uint8_t* outData = nullptr;
456     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
457     EXPECT_NE(hdl, nullptr);
458     EXPECT_EQ(size, sizeof(in));
459     EXPECT_EQ(nextRecHdl, 0u);
460     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
461     outData = nullptr;
462 
463     std::array<uint32_t, 10> in2{1000, 3450, 30,  60,     890,
464                                  0,    110,  450, 234034, 123123};
465     handle = 2;
466     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
467     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
468                            sizeof(in2), false, 1, &handle),
469               0);
470     handle = 3;
471     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
472     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
473                            sizeof(in2), false, 1, &handle),
474               0);
475     handle = 4;
476     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
477     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
478                            sizeof(in2), false, 1, &handle),
479               0);
480     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
481     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4);
482     hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
483     EXPECT_NE(hdl, nullptr);
484     EXPECT_EQ(size, sizeof(in2));
485     EXPECT_EQ(nextRecHdl, 3u);
486     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
487     outData = nullptr;
488     hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
489     EXPECT_NE(hdl, nullptr);
490     EXPECT_EQ(size, sizeof(in2));
491     EXPECT_EQ(nextRecHdl, 4u);
492     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
493     outData = nullptr;
494     hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
495     EXPECT_NE(hdl, nullptr);
496     EXPECT_EQ(size, sizeof(in2));
497     EXPECT_EQ(nextRecHdl, 0u);
498     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
499     outData = nullptr;
500 
501     pldm_pdr_destroy(repo);
502 }
503 
TEST(PDRAccess,testFindByType)504 TEST(PDRAccess, testFindByType)
505 {
506     auto repo = pldm_pdr_init();
507 
508     std::array<uint8_t, sizeof(pldm_pdr_hdr)> data{};
509     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
510     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(data.data());
511     hdr->type = 1;
512     uint32_t first = 0;
513     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &first),
514               0);
515     hdr->type = 2;
516     uint32_t second = 0;
517     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &second),
518               0);
519     hdr->type = 3;
520     uint32_t third = 0;
521     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &third),
522               0);
523     hdr->type = 4;
524     uint32_t fourth = 0;
525     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &fourth),
526               0);
527 
528     uint8_t* outData = nullptr;
529     uint32_t size{};
530     auto firstRec =
531         pldm_pdr_find_record_by_type(repo, 1, nullptr, &outData, &size);
532     EXPECT_EQ(pldm_pdr_get_record_handle(repo, firstRec), first);
533     outData = nullptr;
534     auto secondRec =
535         pldm_pdr_find_record_by_type(repo, 2, nullptr, &outData, &size);
536     EXPECT_EQ(pldm_pdr_get_record_handle(repo, secondRec), second);
537     outData = nullptr;
538     auto thirdRec =
539         pldm_pdr_find_record_by_type(repo, 3, nullptr, &outData, &size);
540     EXPECT_EQ(pldm_pdr_get_record_handle(repo, thirdRec), third);
541     outData = nullptr;
542     auto fourthRec =
543         pldm_pdr_find_record_by_type(repo, 4, nullptr, &outData, &size);
544     EXPECT_EQ(pldm_pdr_get_record_handle(repo, fourthRec), fourth);
545     outData = nullptr;
546     auto fifthRec =
547         pldm_pdr_find_record_by_type(repo, 5, nullptr, &outData, &size);
548     EXPECT_EQ(fifthRec, nullptr);
549     EXPECT_EQ(outData, nullptr);
550     EXPECT_EQ(size, 0u);
551 
552     auto rec =
553         pldm_pdr_find_record_by_type(repo, 3, secondRec, &outData, &size);
554     EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), third);
555     outData = nullptr;
556     rec = pldm_pdr_find_record_by_type(repo, 4, secondRec, &outData, &size);
557     EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), fourth);
558     outData = nullptr;
559     rec = pldm_pdr_find_record_by_type(repo, 2, firstRec, &outData, &size);
560     EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), second);
561     outData = nullptr;
562 
563     pldm_pdr_destroy(repo);
564 }
565 
TEST(PDRUpdate,testAddFruRecordSet)566 TEST(PDRUpdate, testAddFruRecordSet)
567 {
568     auto repo = pldm_pdr_init();
569 
570     uint32_t handle = 0;
571     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 10, 1, 0, 100, &handle), 0);
572     EXPECT_EQ(handle, 1u);
573     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
574     EXPECT_EQ(pldm_pdr_get_repo_size(repo),
575               sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
576     uint32_t size{};
577     uint32_t nextRecHdl{};
578     uint8_t* outData = nullptr;
579     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
580     EXPECT_NE(hdl, nullptr);
581     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
582     EXPECT_EQ(nextRecHdl, 0u);
583     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
584     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
585     EXPECT_EQ(hdr->version, 1u);
586     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
587     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
588     EXPECT_EQ(hdr->record_handle, htole32(1));
589     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
590     pldm_pdr_fru_record_set* fru = reinterpret_cast<pldm_pdr_fru_record_set*>(
591         outData + sizeof(pldm_pdr_hdr));
592     EXPECT_EQ(fru->terminus_handle, htole16(1));
593     EXPECT_EQ(fru->fru_rsi, htole16(10));
594     EXPECT_EQ(fru->entity_type, htole16(1));
595     EXPECT_EQ(fru->entity_instance_num, htole16(0));
596     EXPECT_EQ(fru->container_id, htole16(100));
597     outData = nullptr;
598 
599     handle = 0;
600     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 2, 11, 2, 1, 101, &handle), 0);
601     EXPECT_EQ(handle, 2u);
602     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
603     EXPECT_EQ(pldm_pdr_get_repo_size(repo),
604               2 * (sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set)));
605     hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
606     EXPECT_NE(hdl, nullptr);
607     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
608     EXPECT_EQ(nextRecHdl, 0u);
609     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
610     hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
611     EXPECT_EQ(hdr->version, 1u);
612     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
613     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
614     EXPECT_EQ(hdr->record_handle, htole32(2));
615     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
616     fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
617                                                      sizeof(pldm_pdr_hdr));
618     EXPECT_EQ(fru->terminus_handle, htole16(2));
619     EXPECT_EQ(fru->fru_rsi, htole16(11));
620     EXPECT_EQ(fru->entity_type, htole16(2));
621     EXPECT_EQ(fru->entity_instance_num, htole16(1));
622     EXPECT_EQ(fru->container_id, htole16(101));
623     outData = nullptr;
624 
625     hdl = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
626     EXPECT_NE(hdl, nullptr);
627     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
628     EXPECT_EQ(nextRecHdl, 2u);
629     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
630     hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
631     EXPECT_EQ(hdr->version, 1u);
632     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
633     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
634     EXPECT_EQ(hdr->record_handle, htole32(1));
635     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
636     fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
637                                                      sizeof(pldm_pdr_hdr));
638     EXPECT_EQ(fru->terminus_handle, htole16(1));
639     EXPECT_EQ(fru->fru_rsi, htole16(10));
640     EXPECT_EQ(fru->entity_type, htole16(1));
641     EXPECT_EQ(fru->entity_instance_num, htole16(0));
642     EXPECT_EQ(fru->container_id, htole16(100));
643     outData = nullptr;
644 
645     pldm_pdr_destroy(repo);
646 }
647 
TEST(PDRUpdate,tesFindtFruRecordSet)648 TEST(PDRUpdate, tesFindtFruRecordSet)
649 {
650     auto repo = pldm_pdr_init();
651 
652     uint16_t terminusHdl{};
653     uint16_t entityType{};
654     uint16_t entityInstanceNum{};
655     uint16_t containerId{};
656     uint32_t first = 1;
657     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 1, 1, 0, 100, &first), 0);
658     uint32_t second = 2;
659     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 2, 1, 1, 100, &second), 0);
660     uint32_t third = 3;
661     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 3, 1, 2, 100, &third), 0);
662     EXPECT_EQ(first, pldm_pdr_get_record_handle(
663                          repo, pldm_pdr_fru_record_set_find_by_rsi(
664                                    repo, 1, &terminusHdl, &entityType,
665                                    &entityInstanceNum, &containerId)));
666     EXPECT_EQ(second, pldm_pdr_get_record_handle(
667                           repo, pldm_pdr_fru_record_set_find_by_rsi(
668                                     repo, 2, &terminusHdl, &entityType,
669                                     &entityInstanceNum, &containerId)));
670     EXPECT_EQ(third, pldm_pdr_get_record_handle(
671                          repo, pldm_pdr_fru_record_set_find_by_rsi(
672                                    repo, 3, &terminusHdl, &entityType,
673                                    &entityInstanceNum, &containerId)));
674     EXPECT_EQ(terminusHdl, 1u);
675     EXPECT_EQ(entityType, 1u);
676     EXPECT_EQ(entityInstanceNum, 2u);
677     EXPECT_EQ(containerId, 100u);
678     EXPECT_EQ(nullptr, pldm_pdr_fru_record_set_find_by_rsi(
679                            repo, 4, &terminusHdl, &entityType,
680                            &entityInstanceNum, &containerId));
681 
682     pldm_pdr_destroy(repo);
683 }
684 
685 #ifdef LIBPLDM_API_TESTING
TEST(PDRUpdate,testFindLastInRange)686 TEST(PDRUpdate, testFindLastInRange)
687 {
688     auto repo = pldm_pdr_init();
689 
690     std::array<uint8_t, 10> data{};
691     uint32_t handle1 = 0;
692     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle1),
693               0);
694     uint32_t handle2 = 23;
695     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle2),
696               0);
697     uint32_t handle3 = 77;
698     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle3),
699               0);
700     uint32_t handle4 = 16777325;
701     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle4),
702               0);
703     uint32_t handle5 = 16777344;
704     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle5),
705               0);
706 
707     auto rec1 = pldm_pdr_find_last_in_range(repo, 0, 100);
708     auto rec2 = pldm_pdr_find_last_in_range(repo, 16777300, 33554431);
709     EXPECT_NE(rec1, nullptr);
710     EXPECT_NE(rec2, nullptr);
711     EXPECT_NE(handle1, pldm_pdr_get_record_handle(repo, rec1));
712     EXPECT_NE(handle2, pldm_pdr_get_record_handle(repo, rec1));
713     EXPECT_EQ(handle3, pldm_pdr_get_record_handle(repo, rec1));
714     EXPECT_NE(handle4, pldm_pdr_get_record_handle(repo, rec2));
715     EXPECT_EQ(handle5, pldm_pdr_get_record_handle(repo, rec2));
716 
717     pldm_pdr_destroy(repo);
718 }
719 #endif
720 
721 #ifdef LIBPLDM_API_TESTING
TEST(PDRAccess,testGetTerminusHandle)722 TEST(PDRAccess, testGetTerminusHandle)
723 {
724 
725     auto repo = pldm_pdr_init();
726 
727     pldm_pdr_hdr hdr;
728 
729     hdr.type = 1;
730     uint16_t firstTerminusHandle = 1;
731     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
732     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<const uint8_t*>(&hdr),
733                            sizeof(hdr), false, firstTerminusHandle, NULL),
734               0);
735 
736     hdr.type = 2;
737     uint16_t secondTerminusHandle = 2;
738     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
739     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<const uint8_t*>(&hdr),
740                            sizeof(hdr), true, secondTerminusHandle, NULL),
741               0);
742 
743     hdr.type = 3;
744     uint16_t thirdTerminusHandle = 3;
745     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
746     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<const uint8_t*>(&hdr),
747                            sizeof(hdr), true, thirdTerminusHandle, NULL),
748               0);
749 
750     uint8_t* outData = nullptr;
751     uint32_t size{};
752 
753     auto firstRec =
754         pldm_pdr_find_record_by_type(repo, 1, nullptr, &outData, &size);
755     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, firstRec),
756               firstTerminusHandle);
757     outData = nullptr;
758 
759     auto secondRec =
760         pldm_pdr_find_record_by_type(repo, 2, nullptr, &outData, &size);
761     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, secondRec),
762               secondTerminusHandle);
763     outData = nullptr;
764 
765     auto thirdRec =
766         pldm_pdr_find_record_by_type(repo, 3, nullptr, &outData, &size);
767     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, thirdRec),
768               thirdTerminusHandle);
769     outData = nullptr;
770 
771     pldm_pdr_destroy(repo);
772 }
773 #endif
774 
TEST(EntityAssociationPDR,testInit)775 TEST(EntityAssociationPDR, testInit)
776 {
777     auto tree = pldm_entity_association_tree_init();
778     EXPECT_NE(tree, nullptr);
779     pldm_entity_association_tree_destroy(tree);
780 }
781 
TEST(EntityAssociationPDR,testBuild)782 TEST(EntityAssociationPDR, testBuild)
783 {
784     //        1
785     //        |
786     //        2--3--4
787     //        |
788     //        5--6--7
789     //        |  |
790     //        9  8
791 
792     pldm_entity entities[9]{};
793 
794     entities[0].entity_type = 1;
795     entities[1].entity_type = 2;
796     entities[2].entity_type = 2;
797     entities[3].entity_type = 3;
798     entities[4].entity_type = 4;
799     entities[5].entity_type = 5;
800     entities[6].entity_type = 5;
801     entities[7].entity_type = 6;
802     entities[8].entity_type = 7;
803 
804     auto tree = pldm_entity_association_tree_init();
805 
806     auto l1 = pldm_entity_association_tree_add(
807         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
808     EXPECT_NE(l1, nullptr);
809     auto l2a = pldm_entity_association_tree_add(
810         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
811     EXPECT_NE(l2a, nullptr);
812     auto l2b = pldm_entity_association_tree_add(
813         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
814     EXPECT_NE(l2b, nullptr);
815     auto l2c = pldm_entity_association_tree_add(
816         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
817     EXPECT_NE(l2c, nullptr);
818     auto l3a = pldm_entity_association_tree_add(
819         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
820     EXPECT_NE(l3a, nullptr);
821     auto l3b = pldm_entity_association_tree_add(
822         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
823     EXPECT_NE(l3b, nullptr);
824     auto l3c = pldm_entity_association_tree_add(
825         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
826     EXPECT_NE(l3b, nullptr);
827     auto l4a = pldm_entity_association_tree_add(
828         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
829     EXPECT_NE(l4a, nullptr);
830     auto l4b = pldm_entity_association_tree_add(
831         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
832     EXPECT_NE(l4b, nullptr);
833 
834     EXPECT_EQ(pldm_entity_is_node_parent(l1), true);
835     EXPECT_EQ(pldm_entity_is_node_parent(l2a), true);
836     EXPECT_EQ(pldm_entity_is_node_parent(l3a), true);
837     EXPECT_EQ(pldm_entity_is_node_parent(l3b), true);
838 
839     EXPECT_EQ(pldm_entity_is_node_parent(l2b), false);
840     EXPECT_EQ(pldm_entity_is_node_parent(l2c), false);
841     EXPECT_EQ(pldm_entity_is_node_parent(l3c), false);
842     EXPECT_EQ(pldm_entity_is_node_parent(l4a), false);
843     EXPECT_EQ(pldm_entity_is_node_parent(l4b), false);
844 
845     EXPECT_EQ(pldm_entity_is_exist_parent(l1), false);
846 
847     pldm_entity nodeL1 = pldm_entity_extract(l1);
848     pldm_entity parentL2a = pldm_entity_get_parent(l2a);
849     pldm_entity parentL2b = pldm_entity_get_parent(l2b);
850     pldm_entity parentL2c = pldm_entity_get_parent(l2c);
851     EXPECT_EQ(pldm_entity_is_exist_parent(l2a), true);
852     EXPECT_EQ(pldm_entity_is_exist_parent(l2b), true);
853     EXPECT_EQ(pldm_entity_is_exist_parent(l2c), true);
854     EXPECT_EQ(parentL2a.entity_type, nodeL1.entity_type);
855     EXPECT_EQ(parentL2a.entity_instance_num, nodeL1.entity_instance_num);
856     EXPECT_EQ(parentL2a.entity_container_id, nodeL1.entity_container_id);
857     EXPECT_EQ(parentL2b.entity_type, nodeL1.entity_type);
858     EXPECT_EQ(parentL2b.entity_instance_num, nodeL1.entity_instance_num);
859     EXPECT_EQ(parentL2b.entity_container_id, nodeL1.entity_container_id);
860     EXPECT_EQ(parentL2c.entity_type, nodeL1.entity_type);
861     EXPECT_EQ(parentL2c.entity_instance_num, nodeL1.entity_instance_num);
862     EXPECT_EQ(parentL2c.entity_container_id, nodeL1.entity_container_id);
863 
864     pldm_entity nodeL2a = pldm_entity_extract(l2a);
865     pldm_entity parentL3a = pldm_entity_get_parent(l3a);
866     pldm_entity parentL3b = pldm_entity_get_parent(l3b);
867     pldm_entity parentL3c = pldm_entity_get_parent(l3c);
868     EXPECT_EQ(pldm_entity_is_exist_parent(l3a), true);
869     EXPECT_EQ(pldm_entity_is_exist_parent(l3b), true);
870     EXPECT_EQ(pldm_entity_is_exist_parent(l3c), true);
871     EXPECT_EQ(parentL3a.entity_type, nodeL2a.entity_type);
872     EXPECT_EQ(parentL3a.entity_instance_num, nodeL2a.entity_instance_num);
873     EXPECT_EQ(parentL3a.entity_container_id, nodeL2a.entity_container_id);
874     EXPECT_EQ(parentL3b.entity_type, nodeL2a.entity_type);
875     EXPECT_EQ(parentL3b.entity_instance_num, nodeL2a.entity_instance_num);
876     EXPECT_EQ(parentL3b.entity_container_id, nodeL2a.entity_container_id);
877     EXPECT_EQ(parentL3c.entity_type, nodeL2a.entity_type);
878     EXPECT_EQ(parentL3c.entity_instance_num, nodeL2a.entity_instance_num);
879     EXPECT_EQ(parentL3c.entity_container_id, nodeL2a.entity_container_id);
880 
881     pldm_entity nodeL3a = pldm_entity_extract(l3a);
882     pldm_entity parentL4a = pldm_entity_get_parent(l4a);
883     EXPECT_EQ(pldm_entity_is_exist_parent(l4a), true);
884     EXPECT_EQ(parentL4a.entity_type, nodeL3a.entity_type);
885     EXPECT_EQ(parentL4a.entity_instance_num, nodeL3a.entity_instance_num);
886     EXPECT_EQ(parentL4a.entity_container_id, nodeL3a.entity_container_id);
887 
888     pldm_entity nodeL3b = pldm_entity_extract(l3b);
889     pldm_entity parentL4b = pldm_entity_get_parent(l4b);
890     EXPECT_EQ(pldm_entity_is_exist_parent(l4b), true);
891     EXPECT_EQ(parentL4b.entity_type, nodeL3b.entity_type);
892     EXPECT_EQ(parentL4b.entity_instance_num, nodeL3b.entity_instance_num);
893     EXPECT_EQ(parentL4b.entity_container_id, nodeL3b.entity_container_id);
894 
895     size_t num{};
896     pldm_entity* out = nullptr;
897     pldm_entity_association_tree_visit(tree, &out, &num);
898     EXPECT_EQ(num, 9u);
899 
900     EXPECT_EQ(out[0].entity_type, 1u);
901     EXPECT_EQ(out[0].entity_instance_num, 1u);
902     EXPECT_EQ(out[0].entity_container_id, 0u);
903 
904     EXPECT_EQ(out[1].entity_type, 2u);
905     EXPECT_EQ(out[1].entity_instance_num, 1u);
906     EXPECT_EQ(out[1].entity_container_id, 1u);
907     EXPECT_EQ(out[2].entity_type, 2u);
908     EXPECT_EQ(out[2].entity_instance_num, 2u);
909     EXPECT_EQ(out[2].entity_container_id, 1u);
910     EXPECT_EQ(out[3].entity_type, 3u);
911     EXPECT_EQ(out[3].entity_instance_num, 1u);
912     EXPECT_EQ(out[3].entity_container_id, 1u);
913 
914     EXPECT_EQ(out[4].entity_type, 4u);
915     EXPECT_EQ(out[4].entity_instance_num, 1u);
916     EXPECT_EQ(out[4].entity_container_id, 2u);
917     EXPECT_EQ(out[5].entity_type, 5u);
918     EXPECT_EQ(out[5].entity_instance_num, 1u);
919     EXPECT_EQ(out[5].entity_container_id, 2u);
920     EXPECT_EQ(out[6].entity_type, 5u);
921     EXPECT_EQ(out[6].entity_instance_num, 2u);
922     EXPECT_EQ(out[6].entity_container_id, 2u);
923 
924     EXPECT_EQ(out[7].entity_type, 7u);
925     EXPECT_EQ(out[7].entity_instance_num, 1u);
926     EXPECT_EQ(out[7].entity_container_id, 4u);
927     EXPECT_EQ(out[8].entity_type, 6u);
928     EXPECT_EQ(out[8].entity_instance_num, 1u);
929     EXPECT_EQ(out[8].entity_container_id, 3u);
930 
931     free(out);
932 
933     pldm_entity p1 = pldm_entity_extract(l1);
934     EXPECT_EQ(p1.entity_type, 1u);
935     EXPECT_EQ(p1.entity_instance_num, 1u);
936     EXPECT_EQ(p1.entity_container_id, 0u);
937 
938     pldm_entity p2a = pldm_entity_extract(l2a);
939     EXPECT_EQ(p2a.entity_type, 2u);
940     EXPECT_EQ(p2a.entity_instance_num, 1u);
941     EXPECT_EQ(p2a.entity_container_id, 1u);
942     pldm_entity p2b = pldm_entity_extract(l2b);
943     EXPECT_EQ(p2b.entity_type, 2u);
944     EXPECT_EQ(p2b.entity_instance_num, 2u);
945     EXPECT_EQ(p2b.entity_container_id, 1u);
946     pldm_entity p2c = pldm_entity_extract(l2c);
947     EXPECT_EQ(p2c.entity_type, 3u);
948     EXPECT_EQ(p2c.entity_instance_num, 1u);
949     EXPECT_EQ(p2c.entity_container_id, 1u);
950 
951     pldm_entity p3a = pldm_entity_extract(l3a);
952     EXPECT_EQ(p3a.entity_type, 4u);
953     EXPECT_EQ(p3a.entity_instance_num, 1u);
954     EXPECT_EQ(p3a.entity_container_id, 2u);
955     pldm_entity p3b = pldm_entity_extract(l3b);
956     EXPECT_EQ(p3b.entity_type, 5u);
957     EXPECT_EQ(p3b.entity_instance_num, 1u);
958     EXPECT_EQ(p3b.entity_container_id, 2u);
959     pldm_entity p3c = pldm_entity_extract(l3c);
960     EXPECT_EQ(p3c.entity_type, 5u);
961     EXPECT_EQ(p3c.entity_instance_num, 2u);
962     EXPECT_EQ(p3c.entity_container_id, 2u);
963 
964     pldm_entity p4a = pldm_entity_extract(l4a);
965     EXPECT_EQ(p4a.entity_type, 6u);
966     EXPECT_EQ(p4a.entity_instance_num, 1u);
967     EXPECT_EQ(p4a.entity_container_id, 3u);
968     pldm_entity p4b = pldm_entity_extract(l4b);
969     EXPECT_EQ(p4b.entity_type, 7u);
970     EXPECT_EQ(p4b.entity_instance_num, 1u);
971     EXPECT_EQ(p4b.entity_container_id, 4u);
972 
973     pldm_entity_association_tree_destroy(tree);
974 }
975 
976 #if LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,findAndAddRemotePDR)977 TEST(EntityAssociationPDR, findAndAddRemotePDR)
978 {
979     //         Tree - 1
980     //
981     //        11521(1,0)
982     //             |
983     //          45 (1,1)
984     //             |
985     //          64 (1,2)
986     //             |
987     //    ------------------
988     //    |                 |
989     //  67(0,3)           67(1,3)
990     //    |                 |
991     // 135(0,4)          135(0,5)
992     //    |                 |
993     // 32903(0,6)         32903(0,7)
994 
995     pldm_entity entities[9]{};
996     entities[0].entity_type = 11521;
997     entities[1].entity_type = 45;
998     entities[2].entity_type = 64;
999     entities[3].entity_type = 67;
1000     entities[4].entity_type = 67;
1001     entities[5].entity_type = 135;
1002     entities[5].entity_container_id = 2;
1003     entities[6].entity_type = 135;
1004     entities[6].entity_container_id = 3;
1005     entities[7].entity_type = 32903;
1006     entities[8].entity_type = 32903;
1007     auto tree = pldm_entity_association_tree_init();
1008     auto l1 = pldm_entity_association_tree_add_entity(
1009         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
1010         false, true, 0xffff);
1011     EXPECT_NE(l1, nullptr);
1012     auto l2 = pldm_entity_association_tree_add_entity(
1013         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1014         false, 0xffff);
1015     EXPECT_NE(l2, nullptr);
1016     auto l3 = pldm_entity_association_tree_add_entity(
1017         tree, &entities[2], 0xffff, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1018         true, 0xffff);
1019     EXPECT_NE(l3, nullptr);
1020     auto l4a = pldm_entity_association_tree_add_entity(
1021         tree, &entities[3], 0, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1022         false, 0xffff);
1023     EXPECT_NE(l4a, nullptr);
1024     auto l4b = pldm_entity_association_tree_add_entity(
1025         tree, &entities[4], 1, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
1026         0xffff);
1027     EXPECT_NE(l4b, nullptr);
1028     auto l5a = pldm_entity_association_tree_add_entity(
1029         tree, &entities[5], 0, l4a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1030         false, 0xffff);
1031     EXPECT_NE(l5a, nullptr);
1032     auto l5b = pldm_entity_association_tree_add_entity(
1033         tree, &entities[6], 0, l4b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1034         false, 0xffff);
1035     EXPECT_NE(l5b, nullptr);
1036     pldm_entity entity{};
1037     entity.entity_type = 135;
1038     entity.entity_instance_num = 0;
1039     entity.entity_container_id = 2;
1040     auto result1 = pldm_entity_association_tree_find(tree, &entity);
1041     EXPECT_EQ(result1, l5a);
1042     EXPECT_EQ(entities[5].entity_container_id, 2);
1043     auto l6a = pldm_entity_association_tree_add_entity(
1044         tree, &entities[7], 0, result1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1045         false, 0xffff);
1046     EXPECT_NE(l6a, nullptr);
1047     entity.entity_type = 135;
1048     entity.entity_instance_num = 0;
1049     entity.entity_container_id = 3;
1050     auto result2 = pldm_entity_association_tree_find(tree, &entity);
1051     EXPECT_NE(result2, l5b);
1052     EXPECT_EQ(entities[6].entity_container_id, 3);
1053     auto l7a = pldm_entity_association_tree_add_entity(
1054         tree, &entities[8], 0, result2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1055         false, 0xffff);
1056     EXPECT_EQ(l7a, nullptr);
1057     pldm_entity_association_tree_destroy(tree);
1058 }
1059 #endif
1060 
TEST(EntityAssociationPDR,testSpecialTrees)1061 TEST(EntityAssociationPDR, testSpecialTrees)
1062 {
1063     pldm_entity entities[3]{};
1064 
1065     entities[0].entity_type = 1;
1066     entities[1].entity_type = 2;
1067     entities[2].entity_type = 1;
1068 
1069     // A
1070     auto tree = pldm_entity_association_tree_init();
1071     auto node = pldm_entity_association_tree_add(
1072         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1073     EXPECT_NE(node, nullptr);
1074     size_t num{};
1075     pldm_entity* out = nullptr;
1076     pldm_entity_association_tree_visit(tree, &out, &num);
1077     EXPECT_EQ(num, 1u);
1078     EXPECT_EQ(out[0].entity_type, 1u);
1079     EXPECT_EQ(out[0].entity_instance_num, 1u);
1080     EXPECT_EQ(out[0].entity_container_id, 0u);
1081     free(out);
1082     pldm_entity_association_tree_destroy(tree);
1083 
1084     // A-A-A
1085     tree = pldm_entity_association_tree_init();
1086     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1087                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1088     EXPECT_NE(node, nullptr);
1089     node = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, nullptr,
1090                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1091     EXPECT_NE(node, nullptr);
1092     node = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, nullptr,
1093                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1094     EXPECT_NE(node, nullptr);
1095     pldm_entity_association_tree_visit(tree, &out, &num);
1096     EXPECT_EQ(num, 3u);
1097     EXPECT_EQ(out[0].entity_type, 1u);
1098     EXPECT_EQ(out[0].entity_instance_num, 1u);
1099     EXPECT_EQ(out[0].entity_container_id, 0u);
1100     EXPECT_EQ(out[1].entity_type, 1u);
1101     EXPECT_EQ(out[1].entity_instance_num, 2u);
1102     EXPECT_EQ(out[1].entity_container_id, 0u);
1103     EXPECT_EQ(out[2].entity_type, 2u);
1104     EXPECT_EQ(out[2].entity_instance_num, 1u);
1105     EXPECT_EQ(out[2].entity_container_id, 0u);
1106     free(out);
1107     pldm_entity_association_tree_destroy(tree);
1108 
1109     // A
1110     // |
1111     // A
1112     // |
1113     // A
1114     tree = pldm_entity_association_tree_init();
1115     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1116                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1117     EXPECT_NE(node, nullptr);
1118     auto node1 = pldm_entity_association_tree_add(
1119         tree, &entities[1], 0xffff, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1120     EXPECT_NE(node1, nullptr);
1121     auto node2 = pldm_entity_association_tree_add(
1122         tree, &entities[2], 0xffff, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1123     EXPECT_NE(node2, nullptr);
1124     pldm_entity_association_tree_visit(tree, &out, &num);
1125     EXPECT_EQ(num, 3u);
1126     EXPECT_EQ(out[0].entity_type, 1u);
1127     EXPECT_EQ(out[0].entity_instance_num, 1u);
1128     EXPECT_EQ(out[0].entity_container_id, 0u);
1129     EXPECT_EQ(out[1].entity_type, 2u);
1130     EXPECT_EQ(out[1].entity_instance_num, 1u);
1131     EXPECT_EQ(out[1].entity_container_id, 1u);
1132     EXPECT_EQ(out[2].entity_type, 1u);
1133     EXPECT_EQ(out[2].entity_instance_num, 1u);
1134     EXPECT_EQ(out[2].entity_container_id, 2u);
1135     free(out);
1136     pldm_entity_association_tree_destroy(tree);
1137 
1138     // A-A
1139     //   |
1140     //   A-A
1141     tree = pldm_entity_association_tree_init();
1142     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1143                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1144     EXPECT_NE(node, nullptr);
1145     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1146                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1147     EXPECT_NE(node, nullptr);
1148     node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, node,
1149                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1150     EXPECT_NE(node1, nullptr);
1151     node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, node,
1152                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1153     EXPECT_NE(node2, nullptr);
1154     pldm_entity_association_tree_visit(tree, &out, &num);
1155     EXPECT_EQ(num, 4u);
1156     EXPECT_EQ(out[0].entity_type, 1u);
1157     EXPECT_EQ(out[0].entity_instance_num, 1u);
1158     EXPECT_EQ(out[0].entity_container_id, 0u);
1159     EXPECT_EQ(out[1].entity_type, 1u);
1160     EXPECT_EQ(out[1].entity_instance_num, 2u);
1161     EXPECT_EQ(out[1].entity_container_id, 0u);
1162     EXPECT_EQ(out[2].entity_type, 2u);
1163     EXPECT_EQ(out[2].entity_instance_num, 1u);
1164     EXPECT_EQ(out[2].entity_container_id, 1u);
1165     EXPECT_EQ(out[3].entity_type, 1u);
1166     EXPECT_EQ(out[3].entity_instance_num, 1u);
1167     EXPECT_EQ(out[3].entity_container_id, 1u);
1168     free(out);
1169     pldm_entity_association_tree_destroy(tree);
1170 }
1171 
TEST(EntityAssociationPDR,testPDR)1172 TEST(EntityAssociationPDR, testPDR)
1173 {
1174     // e = entity type, c = container id, i = instance num
1175 
1176     //        INPUT
1177     //        1(e=1)--1a(e=2)
1178     //        |
1179     //        2(e=2)--3(e=2)--4(e=2)--5(e=3)
1180     //        |
1181     //        6(e=4)--7(e=5)--8(e=5)--9(e=5)
1182     //        |       |
1183     //        11(e=6) 10(e=7)
1184 
1185     //        Expected OUTPUT
1186     //        1(e=1,c=0,i=1)
1187     //        |
1188     //        2(e=2,c=1,i=1)--3(e=2,c=1,i=2)--4(e=3,c=1,i=1)--5(e=3,c=1,i=2)
1189     //        |
1190     //        6(e=4,c=2,i=1)--7(e=5,c=2,i=1)--8(e=5,c=2,i=2)--9(e=5,c=2,i=3)
1191     //        |               |
1192     //        10(e=6,c=3,i=1) 11(e=7,c=4,i=1)
1193     pldm_entity entities[11]{};
1194 
1195     entities[0].entity_type = 1;
1196     entities[1].entity_type = 2;
1197     entities[2].entity_type = 3;
1198     entities[3].entity_type = 2;
1199     entities[4].entity_type = 3;
1200     entities[5].entity_type = 4;
1201     entities[6].entity_type = 5;
1202     entities[7].entity_type = 5;
1203     entities[8].entity_type = 5;
1204     entities[9].entity_type = 6;
1205     entities[10].entity_type = 7;
1206 
1207     auto tree = pldm_entity_association_tree_init();
1208 
1209     auto l1 = pldm_entity_association_tree_add(
1210         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1211     EXPECT_NE(l1, nullptr);
1212     auto l1a = pldm_entity_association_tree_add(
1213         tree, &entities[1], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1214     EXPECT_NE(l1a, nullptr);
1215 
1216     auto l2a = pldm_entity_association_tree_add(
1217         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1218     EXPECT_NE(l2a, nullptr);
1219     auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
1220                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1221     EXPECT_NE(l2b, nullptr);
1222     auto l2c = pldm_entity_association_tree_add(
1223         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1224     EXPECT_NE(l2c, nullptr);
1225     auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xffff, l1,
1226                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1227     EXPECT_NE(l2d, nullptr);
1228 
1229     auto l3a = pldm_entity_association_tree_add(
1230         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1231     EXPECT_NE(l3a, nullptr);
1232     auto l3b = pldm_entity_association_tree_add(
1233         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1234     EXPECT_NE(l3b, nullptr);
1235     auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xffff, l2a,
1236                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1237     EXPECT_NE(l3c, nullptr);
1238     auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xffff, l2a,
1239                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1240     EXPECT_NE(l3d, nullptr);
1241 
1242     auto l4a = pldm_entity_association_tree_add(
1243         tree, &entities[9], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1244     EXPECT_NE(l4a, nullptr);
1245     auto l4b = pldm_entity_association_tree_add(
1246         tree, &entities[10], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1247     EXPECT_NE(l4b, nullptr);
1248 
1249     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
1250               2);
1251     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1252               2);
1253     EXPECT_EQ(
1254         pldm_entity_get_num_children(l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 2);
1255     EXPECT_EQ(
1256         pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 0);
1257     EXPECT_EQ(pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1258               1);
1259 
1260     auto repo = pldm_pdr_init();
1261     int rc = pldm_entity_association_pdr_add(tree, repo, false, 1);
1262     ASSERT_EQ(rc, 0);
1263 
1264     EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
1265 
1266     uint32_t currRecHandle{};
1267     uint32_t nextRecHandle{};
1268     uint8_t* data = nullptr;
1269     uint32_t size{};
1270     uint32_t commonSize = sizeof(struct pldm_pdr_hdr) + sizeof(uint16_t) +
1271                           sizeof(uint8_t) + sizeof(pldm_entity) +
1272                           sizeof(uint8_t);
1273 
1274     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1275     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1276                                       l1, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1277                                   sizeof(pldm_entity)));
1278     uint8_t* start = data;
1279     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1280     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1281     EXPECT_EQ(le32toh(hdr->record_handle), 1u);
1282     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1283     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1284     start += sizeof(pldm_pdr_hdr);
1285     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1286     uint16_t* containerId = reinterpret_cast<uint16_t*>(start);
1287     EXPECT_EQ(le16toh(*containerId), 1u);
1288     start += sizeof(uint16_t);
1289     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1290     start += sizeof(uint8_t);
1291     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1292     pldm_entity* entity = reinterpret_cast<pldm_entity*>(start);
1293     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1294     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1295     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1296     start += sizeof(pldm_entity);
1297     EXPECT_EQ(*start,
1298               pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1299     start += sizeof(uint8_t);
1300     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1301     entity = reinterpret_cast<pldm_entity*>(start);
1302     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1303     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1304     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1305     start += sizeof(pldm_entity);
1306     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1307     entity = reinterpret_cast<pldm_entity*>(start);
1308     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1309     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1310     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1311 
1312     currRecHandle = nextRecHandle;
1313 
1314     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1315     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1316                                       l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1317                                   sizeof(pldm_entity)));
1318     start = data;
1319     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1320     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1321     EXPECT_EQ(le32toh(hdr->record_handle), 2u);
1322     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1323     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1324     start += sizeof(pldm_pdr_hdr);
1325     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1326     containerId = reinterpret_cast<uint16_t*>(start);
1327     EXPECT_EQ(le16toh(*containerId), 1u);
1328     start += sizeof(uint16_t);
1329     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1330     start += sizeof(uint8_t);
1331     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1332     entity = reinterpret_cast<pldm_entity*>(start);
1333     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1334     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1335     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1336     start += sizeof(pldm_entity);
1337     EXPECT_EQ(*start, pldm_entity_get_num_children(
1338                           l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1339     start += sizeof(uint8_t);
1340     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1341     entity = reinterpret_cast<pldm_entity*>(start);
1342     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1343     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1344     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1345     start += sizeof(pldm_entity);
1346     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1347     entity = reinterpret_cast<pldm_entity*>(start);
1348     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1349     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1350     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1351 
1352     currRecHandle = nextRecHandle;
1353 
1354     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1355     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1356                                       l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1357                                   sizeof(pldm_entity)));
1358     start = data;
1359     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1360     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1361     EXPECT_EQ(le32toh(hdr->record_handle), 3u);
1362     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1363     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1364     start += sizeof(pldm_pdr_hdr);
1365     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1366     containerId = reinterpret_cast<uint16_t*>(start);
1367     EXPECT_EQ(le16toh(*containerId), 2u);
1368     start += sizeof(uint16_t);
1369     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1370     start += sizeof(uint8_t);
1371     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1372     entity = reinterpret_cast<pldm_entity*>(start);
1373     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1374     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1375     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1376     start += sizeof(pldm_entity);
1377     EXPECT_EQ(*start, pldm_entity_get_num_children(
1378                           l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1379     start += sizeof(uint8_t);
1380     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1381     entity = reinterpret_cast<pldm_entity*>(start);
1382     EXPECT_EQ(le16toh(entity->entity_type), 5);
1383     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1384     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1385     start += sizeof(pldm_entity);
1386     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1387     entity = reinterpret_cast<pldm_entity*>(start);
1388     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1389     EXPECT_EQ(le16toh(entity->entity_instance_num), 3u);
1390     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1391 
1392     currRecHandle = nextRecHandle;
1393 
1394     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1395     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1396                                       l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1397                                   sizeof(pldm_entity)));
1398     start = data;
1399     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1400     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1401     EXPECT_EQ(le32toh(hdr->record_handle), 4u);
1402     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1403     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1404     start += sizeof(pldm_pdr_hdr);
1405     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1406     containerId = reinterpret_cast<uint16_t*>(start);
1407     EXPECT_EQ(le16toh(*containerId), 2u);
1408     start += sizeof(uint16_t);
1409     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1410     start += sizeof(uint8_t);
1411     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1412     entity = reinterpret_cast<pldm_entity*>(start);
1413     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1414     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1415     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1416     start += sizeof(pldm_entity);
1417     EXPECT_EQ(*start, pldm_entity_get_num_children(
1418                           l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1419     start += sizeof(uint8_t);
1420     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1421     entity = reinterpret_cast<pldm_entity*>(start);
1422     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1423     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1424     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1425     start += sizeof(pldm_entity);
1426     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1427     entity = reinterpret_cast<pldm_entity*>(start);
1428     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1429     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1430     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1431 
1432     currRecHandle = nextRecHandle;
1433 
1434     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1435     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1436                                       l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1437                                   sizeof(pldm_entity)));
1438     start = data;
1439     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1440     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1441     EXPECT_EQ(le32toh(hdr->record_handle), 5u);
1442     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1443     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1444     start += sizeof(pldm_pdr_hdr);
1445     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1446     containerId = reinterpret_cast<uint16_t*>(start);
1447     EXPECT_EQ(le16toh(*containerId), 3u);
1448     start += sizeof(uint16_t);
1449     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1450     start += sizeof(uint8_t);
1451     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1452     entity = reinterpret_cast<pldm_entity*>(start);
1453     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1454     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1455     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1456     start += sizeof(pldm_entity);
1457     EXPECT_EQ(*start, pldm_entity_get_num_children(
1458                           l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1459     start += sizeof(uint8_t);
1460     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1461     entity = reinterpret_cast<pldm_entity*>(start);
1462     EXPECT_EQ(le16toh(entity->entity_type), 6u);
1463     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1464     EXPECT_EQ(le16toh(entity->entity_container_id), 3u);
1465 
1466     currRecHandle = nextRecHandle;
1467 
1468     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1469     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1470                                       l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1471                                   sizeof(pldm_entity)));
1472     start = data;
1473     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1474     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1475     EXPECT_EQ(le32toh(hdr->record_handle), 6u);
1476     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1477     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1478     start += sizeof(pldm_pdr_hdr);
1479     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1480     containerId = reinterpret_cast<uint16_t*>(start);
1481     EXPECT_EQ(le16toh(*containerId), 4u);
1482     start += sizeof(uint16_t);
1483     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1484     start += sizeof(uint8_t);
1485     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1486     entity = reinterpret_cast<pldm_entity*>(start);
1487     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1488     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1489     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1490     start += sizeof(pldm_entity);
1491     EXPECT_EQ(*start, pldm_entity_get_num_children(
1492                           l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1493     start += sizeof(uint8_t);
1494     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1495     entity = reinterpret_cast<pldm_entity*>(start);
1496     EXPECT_EQ(le16toh(entity->entity_type), 7u);
1497     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1498     EXPECT_EQ(le16toh(entity->entity_container_id), 4u);
1499 
1500     EXPECT_EQ(nextRecHandle, 0u);
1501 
1502     pldm_pdr_destroy(repo);
1503     pldm_entity_association_tree_destroy(tree);
1504 }
1505 
TEST(EntityAssociationPDR,testPDRWithRecordHandle)1506 TEST(EntityAssociationPDR, testPDRWithRecordHandle)
1507 {
1508     // e = entity type, c = container id, i = instance num
1509 
1510     //        INPUT
1511     //        1(e=1)
1512     //        |
1513     //        2(e=2)--3(e=2)
1514 
1515     //        Expected OUTPUT
1516     //        1(e=1,c=0,i=1)
1517     //        |
1518     //        2(e=2,c=1,i=1)--3(e=2,c=1,i=2)
1519 
1520     pldm_entity entities[3] = {{1, 1, 0}, {2, 1, 1}, {3, 1, 1}};
1521     pldm_entity_test testEntities[3] = {{1, 1, 0}, {2, 1, 1}, {3, 1, 1}};
1522 
1523     auto tree = pldm_entity_association_tree_init();
1524 
1525     auto l1 = pldm_entity_association_tree_add(
1526         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1527     ASSERT_NE(l1, nullptr);
1528 
1529     auto l2a = pldm_entity_association_tree_add(
1530         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1531     ASSERT_NE(l2a, nullptr);
1532     pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
1533                                      PLDM_ENTITY_ASSOCIAION_LOGICAL);
1534     auto repo = pldm_pdr_init();
1535     pldm_entity* l_entities = entities;
1536 
1537     pldm_entity_node* node = nullptr;
1538     pldm_find_entity_ref_in_tree(tree, entities[0], &node);
1539 
1540     ASSERT_NE(node, nullptr);
1541 
1542     int numEntities = 3;
1543     pldm_entity_association_pdr_add_from_node_with_record_handle(
1544         node, repo, &l_entities, numEntities, true, 1, (10));
1545 
1546     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
1547 
1548     uint32_t currRecHandle{};
1549     uint32_t nextRecHandle{};
1550     uint8_t* data = nullptr;
1551     uint32_t size{};
1552 
1553     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1554 
1555     struct pldm_msgbuf _buf;
1556     struct pldm_msgbuf* buf = &_buf;
1557 
1558     auto rc =
1559         pldm_msgbuf_init_errno(buf,
1560                                (sizeof(struct pldm_pdr_hdr) +
1561                                 sizeof(struct pldm_pdr_entity_association)),
1562                                data, size);
1563     ASSERT_EQ(rc, 0);
1564 
1565     pldm_association_pdr_test association_pdr = pldm_association_pdr_test{
1566         10,
1567         1,
1568         PLDM_PDR_ENTITY_ASSOCIATION,
1569         1,
1570         static_cast<uint16_t>(size - sizeof(struct pldm_pdr_hdr)),
1571         1,
1572         PLDM_ENTITY_ASSOCIAION_LOGICAL,
1573         1};
1574 
1575     verifyEntityAssociationPdr(buf, association_pdr, testEntities[0],
1576                                testEntities[2]);
1577 
1578     currRecHandle = nextRecHandle;
1579     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1580     rc = pldm_msgbuf_init_errno(buf,
1581                                 (sizeof(struct pldm_pdr_hdr) +
1582                                  sizeof(struct pldm_pdr_entity_association)),
1583                                 data, size);
1584     ASSERT_EQ(rc, 0);
1585 
1586     pldm_association_pdr_test association_pdr1 = pldm_association_pdr_test{
1587         11,
1588         1,
1589         PLDM_PDR_ENTITY_ASSOCIATION,
1590         1,
1591         static_cast<uint16_t>(size - sizeof(struct pldm_pdr_hdr)),
1592         1,
1593         PLDM_ENTITY_ASSOCIAION_PHYSICAL,
1594         1};
1595 
1596     verifyEntityAssociationPdr(buf, association_pdr1, testEntities[0],
1597                                testEntities[1]);
1598 
1599     pldm_pdr_destroy(repo);
1600     pldm_entity_association_tree_destroy(tree);
1601 }
1602 
TEST(EntityAssociationPDR,testFind)1603 TEST(EntityAssociationPDR, testFind)
1604 {
1605     //        1
1606     //        |
1607     //        2--3--4
1608     //        |
1609     //        5--6--7
1610     //        |  |
1611     //        8  9
1612 
1613     pldm_entity entities[9]{};
1614 
1615     entities[0].entity_type = 1;
1616     entities[1].entity_type = 2;
1617     entities[2].entity_type = 2;
1618     entities[3].entity_type = 3;
1619     entities[4].entity_type = 4;
1620     entities[5].entity_type = 5;
1621     entities[6].entity_type = 5;
1622     entities[7].entity_type = 6;
1623     entities[8].entity_type = 7;
1624 
1625     auto tree = pldm_entity_association_tree_init();
1626 
1627     auto l1 = pldm_entity_association_tree_add(
1628         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1629     EXPECT_NE(l1, nullptr);
1630     auto l2a = pldm_entity_association_tree_add(
1631         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1632     EXPECT_NE(l2a, nullptr);
1633     auto l2b = pldm_entity_association_tree_add(
1634         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1635     EXPECT_NE(l2b, nullptr);
1636     auto l2c = pldm_entity_association_tree_add(
1637         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1638     EXPECT_NE(l2c, nullptr);
1639     auto l3a = pldm_entity_association_tree_add(
1640         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1641     EXPECT_NE(l3a, nullptr);
1642     auto l3b = pldm_entity_association_tree_add(
1643         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1644     EXPECT_NE(l3b, nullptr);
1645     auto l3c = pldm_entity_association_tree_add(
1646         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1647     EXPECT_NE(l3c, nullptr);
1648     auto l4a = pldm_entity_association_tree_add(
1649         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1650     EXPECT_NE(l4a, nullptr);
1651     auto l4b = pldm_entity_association_tree_add(
1652         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1653     EXPECT_NE(l4b, nullptr);
1654 
1655     pldm_entity entity{};
1656 
1657     entity.entity_type = 1;
1658     entity.entity_instance_num = 1;
1659     auto result = pldm_entity_association_tree_find(tree, &entity);
1660     EXPECT_EQ(result, l1);
1661     EXPECT_EQ(entity.entity_container_id, 0);
1662 
1663     entity.entity_type = 2;
1664     entity.entity_instance_num = 1;
1665     result = pldm_entity_association_tree_find(tree, &entity);
1666     EXPECT_EQ(result, l2a);
1667     EXPECT_EQ(entity.entity_container_id, 1);
1668     entity.entity_type = 2;
1669     entity.entity_instance_num = 2;
1670     result = pldm_entity_association_tree_find(tree, &entity);
1671     EXPECT_EQ(result, l2b);
1672     EXPECT_EQ(entity.entity_container_id, 1);
1673     entity.entity_type = 3;
1674     entity.entity_instance_num = 1;
1675     result = pldm_entity_association_tree_find(tree, &entity);
1676     EXPECT_EQ(result, l2c);
1677     EXPECT_EQ(entity.entity_container_id, 1);
1678 
1679     entity.entity_type = 7;
1680     entity.entity_instance_num = 1;
1681     result = pldm_entity_association_tree_find(tree, &entity);
1682     EXPECT_EQ(result, l4b);
1683     EXPECT_EQ(entity.entity_container_id, 4);
1684 
1685     pldm_entity_association_tree_destroy(tree);
1686 }
1687 
1688 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testCopyTree)1689 TEST(EntityAssociationPDR, testCopyTree)
1690 {
1691     pldm_entity entities[4]{};
1692     int rc;
1693 
1694     entities[0].entity_type = 1;
1695     entities[1].entity_type = 2;
1696     entities[2].entity_type = 2;
1697     entities[3].entity_type = 3;
1698 
1699     auto orgTree = pldm_entity_association_tree_init();
1700     auto newTree = pldm_entity_association_tree_init();
1701     auto l1 =
1702         pldm_entity_association_tree_add(orgTree, &entities[0], 0xffff, nullptr,
1703                                          PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1704     EXPECT_NE(l1, nullptr);
1705     auto l2a = pldm_entity_association_tree_add(
1706         orgTree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1707     EXPECT_NE(l2a, nullptr);
1708     auto l2b = pldm_entity_association_tree_add(
1709         orgTree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1710     EXPECT_NE(l2b, nullptr);
1711     auto l2c = pldm_entity_association_tree_add(
1712         orgTree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1713     EXPECT_NE(l2c, nullptr);
1714     size_t orgNum{};
1715     pldm_entity* orgOut = nullptr;
1716     pldm_entity_association_tree_visit(orgTree, &orgOut, &orgNum);
1717     EXPECT_EQ(orgNum, 4u);
1718 
1719     rc = pldm_entity_association_tree_copy_root_check(orgTree, newTree);
1720     ASSERT_EQ(rc, 0);
1721     size_t newNum{};
1722     pldm_entity* newOut = nullptr;
1723     pldm_entity_association_tree_visit(newTree, &newOut, &newNum);
1724     EXPECT_EQ(newNum, orgNum);
1725     EXPECT_EQ(newOut[0].entity_type, 1u);
1726     EXPECT_EQ(newOut[0].entity_instance_num, 1u);
1727     EXPECT_EQ(newOut[0].entity_container_id, 0u);
1728     free(orgOut);
1729     free(newOut);
1730     pldm_entity_association_tree_destroy(orgTree);
1731     pldm_entity_association_tree_destroy(newTree);
1732 }
1733 #endif
1734 
TEST(EntityAssociationPDR,testExtract)1735 TEST(EntityAssociationPDR, testExtract)
1736 {
1737     std::vector<uint8_t> pdr{};
1738     pdr.resize(sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_entity_association) +
1739                sizeof(pldm_entity) * 4);
1740     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1741     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
1742     hdr->type = PLDM_PDR_ENTITY_ASSOCIATION;
1743     hdr->length =
1744         htole16(sizeof(pldm_pdr_entity_association) + sizeof(pldm_entity) * 4);
1745 
1746     pldm_pdr_entity_association* e =
1747         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1748         reinterpret_cast<pldm_pdr_entity_association*>(pdr.data() +
1749                                                        sizeof(pldm_pdr_hdr));
1750     e->container_id = htole16(1);
1751     e->num_children = 5;
1752     e->container.entity_type = htole16(1);
1753     e->container.entity_instance_num = htole16(1);
1754     e->container.entity_container_id = htole16(0);
1755 
1756     pldm_entity* entity = e->children;
1757     entity->entity_type = htole16(2);
1758     entity->entity_instance_num = htole16(1);
1759     entity->entity_container_id = htole16(1);
1760     ++entity;
1761     entity->entity_type = htole16(3);
1762     entity->entity_instance_num = htole16(1);
1763     entity->entity_container_id = htole16(1);
1764     ++entity;
1765     entity->entity_type = htole16(4);
1766     entity->entity_instance_num = htole16(1);
1767     entity->entity_container_id = htole16(1);
1768     ++entity;
1769     entity->entity_type = htole16(5);
1770     entity->entity_instance_num = htole16(1);
1771     entity->entity_container_id = htole16(1);
1772     ++entity;
1773     entity->entity_type = htole16(6);
1774     entity->entity_instance_num = htole16(1);
1775     entity->entity_container_id = htole16(1);
1776 
1777     size_t num{};
1778     pldm_entity* out = nullptr;
1779     pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &num, &out);
1780     EXPECT_EQ(num, (unsigned)e->num_children + 1);
1781     EXPECT_EQ(out[0].entity_type, 1u);
1782     EXPECT_EQ(out[0].entity_instance_num, 1u);
1783     EXPECT_EQ(out[0].entity_container_id, 0u);
1784     EXPECT_EQ(out[1].entity_type, 2u);
1785     EXPECT_EQ(out[1].entity_instance_num, 1u);
1786     EXPECT_EQ(out[1].entity_container_id, 1u);
1787     EXPECT_EQ(out[2].entity_type, 3u);
1788     EXPECT_EQ(out[2].entity_instance_num, 1u);
1789     EXPECT_EQ(out[2].entity_container_id, 1u);
1790     EXPECT_EQ(out[3].entity_type, 4u);
1791     EXPECT_EQ(out[3].entity_instance_num, 1u);
1792     EXPECT_EQ(out[3].entity_container_id, 1u);
1793     EXPECT_EQ(out[4].entity_type, 5u);
1794     EXPECT_EQ(out[4].entity_instance_num, 1u);
1795     EXPECT_EQ(out[4].entity_container_id, 1u);
1796     EXPECT_EQ(out[5].entity_type, 6u);
1797     EXPECT_EQ(out[5].entity_instance_num, 1u);
1798     EXPECT_EQ(out[5].entity_container_id, 1u);
1799 
1800     free(out);
1801 }
1802 
TEST(EntityAssociationPDR,testGetChildren)1803 TEST(EntityAssociationPDR, testGetChildren)
1804 {
1805     pldm_entity entities[4]{};
1806     entities[0].entity_type = 1;
1807     entities[1].entity_type = 2;
1808     entities[2].entity_type = 2;
1809     entities[3].entity_type = 3;
1810 
1811     auto tree = pldm_entity_association_tree_init();
1812     auto l1 = pldm_entity_association_tree_add(
1813         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1814     EXPECT_NE(l1, nullptr);
1815     auto l2a = pldm_entity_association_tree_add(
1816         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1817     EXPECT_NE(l2a, nullptr);
1818     auto l2b = pldm_entity_association_tree_add(
1819         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1820     EXPECT_NE(l2b, nullptr);
1821     auto l2c = pldm_entity_association_tree_add(
1822         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1823     EXPECT_NE(l2c, nullptr);
1824 
1825     pldm_entity et1;
1826     et1.entity_type = 2;
1827     et1.entity_instance_num = 1;
1828     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et1));
1829 
1830     pldm_entity et2;
1831     et2.entity_type = 2;
1832     et2.entity_instance_num = 2;
1833     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et2));
1834 
1835     pldm_entity et3;
1836     et3.entity_type = 2;
1837     et3.entity_instance_num = 3;
1838     EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3));
1839 
1840     pldm_entity_association_tree_destroy(tree);
1841 }
1842 
TEST(EntityAssociationPDR,testEntityInstanceNumber)1843 TEST(EntityAssociationPDR, testEntityInstanceNumber)
1844 {
1845     pldm_entity entities[9]{};
1846 
1847     entities[0].entity_type = 1;
1848     entities[1].entity_type = 2;
1849     entities[2].entity_type = 2;
1850     entities[3].entity_type = 2;
1851     entities[4].entity_type = 2;
1852     entities[5].entity_type = 2;
1853     entities[6].entity_type = 2;
1854     entities[7].entity_type = 3;
1855     entities[8].entity_type = 3;
1856 
1857     auto tree = pldm_entity_association_tree_init();
1858     auto repo = pldm_pdr_init();
1859 
1860     uint16_t terminusHdl{};
1861     uint16_t entityType{};
1862     uint16_t entityInstanceNum{};
1863     uint16_t containerId{};
1864 
1865     auto node = pldm_entity_association_tree_add(
1866         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1867     EXPECT_NE(node, nullptr);
1868 
1869     auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node,
1870                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1871     uint32_t first = 1;
1872     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 1, entities[1].entity_type,
1873                                           entities[1].entity_instance_num,
1874                                           entities[1].entity_container_id,
1875                                           &first),
1876               0);
1877     EXPECT_NE(l1, nullptr);
1878     EXPECT_EQ(entities[1].entity_instance_num, 63);
1879     EXPECT_EQ(first, pldm_pdr_get_record_handle(
1880                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1881                                    repo, 1, &terminusHdl, &entityType,
1882                                    &entityInstanceNum, &containerId)));
1883     EXPECT_EQ(entityType, 2);
1884     EXPECT_EQ(entityInstanceNum, 63);
1885 
1886     auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node,
1887                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1888     uint32_t second = 2;
1889     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 2, entities[2].entity_type,
1890                                           entities[2].entity_instance_num,
1891                                           entities[2].entity_container_id,
1892                                           &second),
1893               0);
1894     EXPECT_NE(l2, nullptr);
1895     EXPECT_EQ(entities[2].entity_instance_num, 37);
1896     EXPECT_EQ(second, pldm_pdr_get_record_handle(
1897                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1898                                     repo, 2, &terminusHdl, &entityType,
1899                                     &entityInstanceNum, &containerId)));
1900     EXPECT_EQ(entityType, 2);
1901     EXPECT_EQ(entityInstanceNum, 37);
1902 
1903     auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node,
1904                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1905     uint32_t third = 3;
1906     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 3, entities[3].entity_type,
1907                                           entities[3].entity_instance_num,
1908                                           entities[3].entity_container_id,
1909                                           &third),
1910               0);
1911     EXPECT_NE(l3, nullptr);
1912     EXPECT_EQ(entities[3].entity_instance_num, 44);
1913     EXPECT_EQ(third, pldm_pdr_get_record_handle(
1914                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1915                                    repo, 3, &terminusHdl, &entityType,
1916                                    &entityInstanceNum, &containerId)));
1917     EXPECT_EQ(entityType, 2);
1918     EXPECT_EQ(entityInstanceNum, 44);
1919 
1920     auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node,
1921                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1922     uint32_t fourth = 4;
1923     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 4, entities[4].entity_type,
1924                                           entities[4].entity_instance_num,
1925                                           entities[4].entity_container_id,
1926                                           &fourth),
1927               0);
1928     EXPECT_NE(l4, nullptr);
1929     EXPECT_EQ(entities[4].entity_instance_num, 89);
1930     EXPECT_EQ(fourth, pldm_pdr_get_record_handle(
1931                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1932                                     repo, 4, &terminusHdl, &entityType,
1933                                     &entityInstanceNum, &containerId)));
1934     EXPECT_EQ(entityType, 2);
1935     EXPECT_EQ(entityInstanceNum, 89);
1936 
1937     auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xffff, node,
1938                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1939     uint32_t fifth = 5;
1940     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 5, entities[5].entity_type,
1941                                           entities[5].entity_instance_num,
1942                                           entities[5].entity_container_id,
1943                                           &fifth),
1944               0);
1945     EXPECT_NE(l5, nullptr);
1946     EXPECT_EQ(entities[5].entity_instance_num, 90);
1947     EXPECT_EQ(fifth, pldm_pdr_get_record_handle(
1948                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1949                                    repo, 5, &terminusHdl, &entityType,
1950                                    &entityInstanceNum, &containerId)));
1951     EXPECT_EQ(entityType, 2);
1952     EXPECT_EQ(entityInstanceNum, 90);
1953 
1954     auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node,
1955                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1956     EXPECT_EQ(l6, nullptr);
1957 
1958     auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1,
1959                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1960     uint32_t seventh = 7;
1961     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 7, entities[7].entity_type,
1962                                           entities[7].entity_instance_num,
1963                                           entities[7].entity_container_id,
1964                                           &seventh),
1965               0);
1966     EXPECT_NE(l7, nullptr);
1967     EXPECT_EQ(entities[7].entity_instance_num, 100);
1968     EXPECT_EQ(seventh, pldm_pdr_get_record_handle(
1969                            repo, pldm_pdr_fru_record_set_find_by_rsi(
1970                                      repo, 7, &terminusHdl, &entityType,
1971                                      &entityInstanceNum, &containerId)));
1972     EXPECT_EQ(entityType, 3);
1973     EXPECT_EQ(entityInstanceNum, 100);
1974 
1975     auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2,
1976                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1977     uint32_t eighth = 8;
1978     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 8, entities[8].entity_type,
1979                                           entities[8].entity_instance_num,
1980                                           entities[8].entity_container_id,
1981                                           &eighth),
1982               0);
1983     EXPECT_NE(l8, nullptr);
1984     EXPECT_EQ(entities[8].entity_instance_num, 100);
1985     EXPECT_EQ(eighth, pldm_pdr_get_record_handle(
1986                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1987                                     repo, 8, &terminusHdl, &entityType,
1988                                     &entityInstanceNum, &containerId)));
1989     EXPECT_EQ(entityType, 3);
1990     EXPECT_EQ(entityInstanceNum, 100);
1991 
1992     pldm_pdr_destroy(repo);
1993     pldm_entity_association_tree_destroy(tree);
1994 }
1995 
1996 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testFindChildContainerID)1997 TEST(EntityAssociationPDR, testFindChildContainerID)
1998 {
1999     pldm_entity entities[3]{};
2000     entities[0].entity_type = 1;
2001     entities[1].entity_type = 2;
2002     entities[2].entity_type = 3;
2003     entities[1].entity_container_id = 2;
2004     entities[1].entity_instance_num = 1;
2005 
2006     auto tree = pldm_entity_association_tree_init();
2007     auto l1 = pldm_entity_association_tree_add_entity(
2008         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
2009         false, true, 0xffff);
2010 
2011     EXPECT_NE(l1, nullptr);
2012     auto l2 = pldm_entity_association_tree_add_entity(
2013         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2014         false, 0xffff);
2015     EXPECT_NE(l2, nullptr);
2016     auto l3 = pldm_entity_association_tree_add_entity(
2017         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2018         true, 0xffff);
2019     EXPECT_NE(l3, nullptr);
2020 
2021     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
2022               2);
2023 
2024     auto repo = pldm_pdr_init();
2025     int rc = pldm_entity_association_pdr_add(tree, repo, false, 1);
2026     ASSERT_EQ(rc, 0);
2027 
2028     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
2029 
2030     uint16_t container_id{};
2031     pldm_pdr_find_child_container_id_index_range_exclude(
2032         repo, 1, 1, 0, 0x01000000, 0x01ffffff, &container_id);
2033     EXPECT_EQ(container_id, 2);
2034 
2035     uint16_t container_id1{};
2036     pldm_pdr_find_child_container_id_index_range_exclude(
2037         repo, 1, 1, 0, 0x00000001, 0x00ffffff, &container_id1);
2038     EXPECT_EQ(container_id1, 0);
2039 
2040     pldm_pdr_destroy(repo);
2041     pldm_entity_association_tree_destroy(tree);
2042 }
2043 #endif
2044 
TEST(EntityAssociationPDR,testNodeAddCheck)2045 TEST(EntityAssociationPDR, testNodeAddCheck)
2046 {
2047     // pldm_entity entities[4]{};
2048     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 4);
2049     entities[0].entity_type = 1;
2050     entities[1].entity_type = 2;
2051     entities[2].entity_type = 2;
2052     entities[3].entity_type = 3;
2053 
2054     auto tree = pldm_entity_association_tree_init();
2055 
2056     auto l1 = pldm_entity_association_tree_add(
2057         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2058     EXPECT_NE(l1, nullptr);
2059     auto l2a = pldm_entity_association_tree_add(
2060         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2061     EXPECT_NE(l2a, nullptr);
2062     auto l2b = pldm_entity_association_tree_add(
2063         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2064     EXPECT_NE(l2b, nullptr);
2065     auto l2c = pldm_entity_association_tree_add(
2066         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2067     EXPECT_NE(l2c, nullptr);
2068 
2069     auto repo = pldm_pdr_init();
2070 
2071     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2072                   l1, repo, &entities, 4, false, 1, 0),
2073               0);
2074     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2075                   l1, repo, &entities, 4, false, 1, 2),
2076               0);
2077     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2078                   l1, repo, &entities, 4, false, 1, 23),
2079               0);
2080     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2081                   l1, repo, &entities, 4, false, 1, 34),
2082               0);
2083 
2084     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
2085 
2086     uint8_t* outData = nullptr;
2087     uint32_t size{};
2088     uint32_t nextRecHdl{};
2089     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
2090     EXPECT_NE(hdl, nullptr);
2091 
2092     outData = nullptr;
2093     auto hdl1 = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
2094     EXPECT_NE(hdl1, nullptr);
2095     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2096     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
2097     EXPECT_EQ(hdr->record_handle, 2);
2098 
2099     outData = nullptr;
2100     auto hdl2 = pldm_pdr_find_record(repo, 23, &outData, &size, &nextRecHdl);
2101     EXPECT_NE(hdl2, nullptr);
2102     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2103     pldm_pdr_hdr* hdr1 = reinterpret_cast<pldm_pdr_hdr*>(outData);
2104     EXPECT_EQ(hdr1->record_handle, 23);
2105 
2106     outData = nullptr;
2107     auto hdl3 = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
2108     EXPECT_EQ(hdl3, nullptr);
2109 
2110     free(entities);
2111     pldm_pdr_destroy(repo);
2112     pldm_entity_association_tree_destroy(tree);
2113 }
2114 
2115 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testAddContainedEntityRemotePDR)2116 TEST(EntityAssociationPDR, testAddContainedEntityRemotePDR)
2117 {
2118     // pldm_entity entities[5]{};
2119     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
2120     entities[0].entity_type = 1;
2121     entities[1].entity_type = 2;
2122     entities[2].entity_type = 3;
2123     entities[3].entity_type = 4;
2124     entities[4].entity_type = 5;
2125 
2126     auto tree = pldm_entity_association_tree_init();
2127     auto l1 = pldm_entity_association_tree_add(
2128         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2129     EXPECT_NE(l1, nullptr);
2130     auto l2a = pldm_entity_association_tree_add(
2131         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2132     EXPECT_NE(l2a, nullptr);
2133     auto l2b = pldm_entity_association_tree_add(
2134         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2135     EXPECT_NE(l2b, nullptr);
2136     auto l2c = pldm_entity_association_tree_add(
2137         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2138     EXPECT_NE(l2c, nullptr);
2139     auto l3a = pldm_entity_association_tree_add(
2140         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2141     EXPECT_NE(l3a, nullptr);
2142 
2143     auto repo = pldm_pdr_init();
2144 
2145     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2146                   l1, repo, &entities, 5, false, 1, 0),
2147               0);
2148     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2149                   l1, repo, &entities, 5, false, 1, 2),
2150               0);
2151     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2152                   l1, repo, &entities, 5, false, 1, 23),
2153               0);
2154     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2155                   l1, repo, &entities, 5, false, 1, 34),
2156               0);
2157     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2158                   l2a, repo, &entities, 5, false, 1, 3),
2159               0);
2160 
2161     pldm_entity entity1[1];
2162     entity1[0].entity_type = 2;
2163 
2164     EXPECT_EQ(pldm_entity_association_pdr_add_contained_entity_to_remote_pdr(
2165                   repo, &entity1[0], 2),
2166               0);
2167 
2168     free(entities);
2169     pldm_pdr_destroy(repo);
2170     pldm_entity_association_tree_destroy(tree);
2171 }
2172 #endif
2173 
2174 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testAddContainedEntityNew)2175 TEST(EntityAssociationPDR, testAddContainedEntityNew)
2176 {
2177     // pldm_entity entities[5]{};
2178     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
2179     entities[0].entity_type = 1;
2180     entities[1].entity_type = 2;
2181     entities[2].entity_type = 3;
2182     entities[3].entity_type = 4;
2183     entities[4].entity_type = 5;
2184 
2185     auto tree = pldm_entity_association_tree_init();
2186     auto l1 = pldm_entity_association_tree_add(
2187         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2188     EXPECT_NE(l1, nullptr);
2189     auto l2a = pldm_entity_association_tree_add(
2190         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2191     EXPECT_NE(l2a, nullptr);
2192     auto l2b = pldm_entity_association_tree_add(
2193         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2194     EXPECT_NE(l2b, nullptr);
2195     auto l2c = pldm_entity_association_tree_add(
2196         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2197     EXPECT_NE(l2c, nullptr);
2198     auto l3a = pldm_entity_association_tree_add(
2199         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2200     EXPECT_NE(l3a, nullptr);
2201 
2202     auto repo = pldm_pdr_init();
2203 
2204     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2205                   l1, repo, &entities, 5, false, 1, 0),
2206               0);
2207     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2208                   l1, repo, &entities, 5, false, 1, 2),
2209               0);
2210     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2211                   l1, repo, &entities, 5, false, 1, 23),
2212               0);
2213     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2214                   l1, repo, &entities, 5, false, 1, 34),
2215               0);
2216     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2217                   l2a, repo, &entities, 5, false, 1, 3),
2218               0);
2219 
2220     uint32_t updated_record_handle = 0;
2221 
2222     pldm_entity entity2[1]{};
2223     entity2[0].entity_type = 4;
2224 
2225     pldm_entity entity3[1]{};
2226     entity3[0].entity_type = 4;
2227 
2228     EXPECT_EQ(pldm_entity_association_pdr_create_new(
2229                   repo, 34, &entity2[0], &entity3[0], &updated_record_handle),
2230               0);
2231 
2232     EXPECT_EQ(updated_record_handle, 35);
2233 
2234     free(entities);
2235     pldm_pdr_destroy(repo);
2236     pldm_entity_association_tree_destroy(tree);
2237 }
2238 #endif
2239 
2240 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testRemoveContainedEntity)2241 TEST(EntityAssociationPDR, testRemoveContainedEntity)
2242 {
2243     struct pldm_entity entities[4] = {
2244         {.entity_type = 1, .entity_instance_num = 1, .entity_container_id = 2},
2245         {.entity_type = 2, .entity_instance_num = 1, .entity_container_id = 2},
2246         {.entity_type = 3, .entity_instance_num = 3, .entity_container_id = 3},
2247         {.entity_type = 4, .entity_instance_num = 1, .entity_container_id = 2}};
2248     struct pldm_entity* base = entities;
2249 
2250     auto tree = pldm_entity_association_tree_init();
2251     auto l1 = pldm_entity_association_tree_add_entity(
2252         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
2253         false, true, 0xffff);
2254 
2255     EXPECT_NE(l1, nullptr);
2256     auto l2 = pldm_entity_association_tree_add_entity(
2257         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2258         false, 0xffff);
2259     EXPECT_NE(l2, nullptr);
2260     auto l3 = pldm_entity_association_tree_add_entity(
2261         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2262         true, 0xffff);
2263     EXPECT_NE(l3, nullptr);
2264     auto l4 = pldm_entity_association_tree_add_entity(
2265         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2266         true, 0xffff);
2267     EXPECT_NE(l4, nullptr);
2268 
2269     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
2270               3);
2271 
2272     auto repo = pldm_pdr_init();
2273 
2274     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2275                   l1, repo, &base, 4, false, 1, 3),
2276               0);
2277 
2278     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
2279 
2280     // Remove first contained entity from the entity association PDR
2281     uint32_t removed_record_handle{};
2282     struct pldm_entity entity[1] = {
2283         {.entity_type = 4, .entity_instance_num = 1, .entity_container_id = 2}};
2284 
2285     EXPECT_EQ(pldm_entity_association_pdr_remove_contained_entity(
2286                   repo, entity, false, &removed_record_handle),
2287               0);
2288     EXPECT_EQ(removed_record_handle, 3);
2289 
2290     // Remove second contained entity from the entity association PDR
2291     removed_record_handle = 0;
2292     EXPECT_EQ(pldm_entity_association_pdr_remove_contained_entity(
2293                   repo, &entities[1], false, &removed_record_handle),
2294               0);
2295     EXPECT_EQ(removed_record_handle, 3);
2296 
2297     // Remove third contained entity from the entity association PDR
2298     removed_record_handle = 0;
2299     EXPECT_EQ(pldm_entity_association_pdr_remove_contained_entity(
2300                   repo, &entities[2], false, &removed_record_handle),
2301               0);
2302     EXPECT_EQ(removed_record_handle, 3);
2303 
2304     // As all the contained entities are removed the entity association PDR
2305     // also gets deleted
2306     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
2307 
2308     pldm_pdr_destroy(repo);
2309     pldm_entity_association_tree_destroy(tree);
2310 }
2311 #endif
2312 
2313 #ifdef LIBPLDM_API_TESTING
TEST(PDRUpdate,testRemoveFruRecord)2314 TEST(PDRUpdate, testRemoveFruRecord)
2315 {
2316     auto repo = pldm_pdr_init();
2317 
2318     uint32_t record_handle = 1;
2319     int rc = pldm_pdr_add_fru_record_set(repo, 1, 1, 1, 0, 100, &record_handle);
2320     EXPECT_EQ(rc, 0);
2321     record_handle = 2;
2322     rc = pldm_pdr_add_fru_record_set(repo, 1, 2, 1, 1, 100, &record_handle);
2323     EXPECT_EQ(rc, 0);
2324     record_handle = 3;
2325     rc = pldm_pdr_add_fru_record_set(repo, 1, 3, 1, 2, 100, &record_handle);
2326     EXPECT_EQ(rc, 0);
2327     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3);
2328 
2329     uint32_t removed_record_handle{};
2330     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 2, false,
2331                                                &removed_record_handle);
2332     EXPECT_EQ(rc, 0);
2333     EXPECT_EQ(removed_record_handle, 2);
2334     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2);
2335 
2336     uint16_t terminusHdl{};
2337     uint16_t entityType{};
2338     uint16_t entityInstanceNum{};
2339     uint16_t containerId{};
2340     auto record = pldm_pdr_fru_record_set_find_by_rsi(
2341         repo, 1, &terminusHdl, &entityType, &entityInstanceNum, &containerId);
2342     EXPECT_NE(record, nullptr);
2343     record_handle = pldm_pdr_get_record_handle(repo, record);
2344     EXPECT_EQ(record_handle, 1);
2345 
2346     record = pldm_pdr_fru_record_set_find_by_rsi(
2347         repo, 3, &terminusHdl, &entityType, &entityInstanceNum, &containerId);
2348     EXPECT_NE(record, nullptr);
2349     record_handle = pldm_pdr_get_record_handle(repo, record);
2350     EXPECT_EQ(record_handle, 3);
2351 
2352     record = pldm_pdr_fru_record_set_find_by_rsi(
2353         repo, 2, &terminusHdl, &entityType, &entityInstanceNum, &containerId);
2354     EXPECT_EQ(record, nullptr);
2355 
2356     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 1, false,
2357                                                &removed_record_handle);
2358     EXPECT_EQ(rc, 0);
2359     EXPECT_EQ(removed_record_handle, 1);
2360 
2361     // remove the same record again
2362     removed_record_handle = 5;
2363     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 1, false,
2364                                                &removed_record_handle);
2365     EXPECT_EQ(rc, 0);
2366     EXPECT_NE(removed_record_handle, 1);
2367     EXPECT_EQ(removed_record_handle, 5);
2368 
2369     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 3, false,
2370                                                &removed_record_handle);
2371     EXPECT_EQ(rc, 0);
2372     EXPECT_EQ(removed_record_handle, 3);
2373 
2374     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0);
2375 
2376     pldm_pdr_destroy(repo);
2377 }
2378 #endif
2379