xref: /openbmc/libpldm/tests/dsp/pdr.cpp (revision 5192e2e26f26ffbbf4256429ea5ae42237e011cc)
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 
775 #ifdef LIBPLDM_API_TESTING
TEST(PDRAccess,testRemoveByRecordHandle)776 TEST(PDRAccess, testRemoveByRecordHandle)
777 {
778     std::array<uint8_t, sizeof(pldm_pdr_hdr)> data{};
779 
780     auto repo = pldm_pdr_init();
781     uint32_t first = 0;
782     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &first),
783               0);
784 
785     uint32_t second = 0;
786     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &second),
787               0);
788 
789     uint32_t third = 0;
790     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &third),
791               0);
792 
793     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
794 
795     int rc = pldm_pdr_delete_by_record_handle(repo, 1, false);
796     EXPECT_EQ(rc, 0);
797     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
798 
799     rc = pldm_pdr_delete_by_record_handle(repo, 2, false);
800     EXPECT_EQ(rc, 0);
801     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
802 
803     pldm_pdr_destroy(repo);
804 }
805 #endif
806 
TEST(EntityAssociationPDR,testInit)807 TEST(EntityAssociationPDR, testInit)
808 {
809     auto tree = pldm_entity_association_tree_init();
810     EXPECT_NE(tree, nullptr);
811     pldm_entity_association_tree_destroy(tree);
812 }
813 
TEST(EntityAssociationPDR,testBuild)814 TEST(EntityAssociationPDR, testBuild)
815 {
816     //        1
817     //        |
818     //        2--3--4
819     //        |
820     //        5--6--7
821     //        |  |
822     //        9  8
823 
824     pldm_entity entities[9]{};
825 
826     entities[0].entity_type = 1;
827     entities[1].entity_type = 2;
828     entities[2].entity_type = 2;
829     entities[3].entity_type = 3;
830     entities[4].entity_type = 4;
831     entities[5].entity_type = 5;
832     entities[6].entity_type = 5;
833     entities[7].entity_type = 6;
834     entities[8].entity_type = 7;
835 
836     auto tree = pldm_entity_association_tree_init();
837 
838     auto l1 = pldm_entity_association_tree_add(
839         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
840     EXPECT_NE(l1, nullptr);
841     auto l2a = pldm_entity_association_tree_add(
842         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
843     EXPECT_NE(l2a, nullptr);
844     auto l2b = pldm_entity_association_tree_add(
845         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
846     EXPECT_NE(l2b, nullptr);
847     auto l2c = pldm_entity_association_tree_add(
848         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
849     EXPECT_NE(l2c, nullptr);
850     auto l3a = pldm_entity_association_tree_add(
851         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
852     EXPECT_NE(l3a, nullptr);
853     auto l3b = pldm_entity_association_tree_add(
854         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
855     EXPECT_NE(l3b, nullptr);
856     auto l3c = pldm_entity_association_tree_add(
857         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
858     EXPECT_NE(l3b, nullptr);
859     auto l4a = pldm_entity_association_tree_add(
860         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
861     EXPECT_NE(l4a, nullptr);
862     auto l4b = pldm_entity_association_tree_add(
863         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
864     EXPECT_NE(l4b, nullptr);
865 
866     EXPECT_EQ(pldm_entity_is_node_parent(l1), true);
867     EXPECT_EQ(pldm_entity_is_node_parent(l2a), true);
868     EXPECT_EQ(pldm_entity_is_node_parent(l3a), true);
869     EXPECT_EQ(pldm_entity_is_node_parent(l3b), true);
870 
871     EXPECT_EQ(pldm_entity_is_node_parent(l2b), false);
872     EXPECT_EQ(pldm_entity_is_node_parent(l2c), false);
873     EXPECT_EQ(pldm_entity_is_node_parent(l3c), false);
874     EXPECT_EQ(pldm_entity_is_node_parent(l4a), false);
875     EXPECT_EQ(pldm_entity_is_node_parent(l4b), false);
876 
877     EXPECT_EQ(pldm_entity_is_exist_parent(l1), false);
878 
879     pldm_entity nodeL1 = pldm_entity_extract(l1);
880     pldm_entity parentL2a = pldm_entity_get_parent(l2a);
881     pldm_entity parentL2b = pldm_entity_get_parent(l2b);
882     pldm_entity parentL2c = pldm_entity_get_parent(l2c);
883     EXPECT_EQ(pldm_entity_is_exist_parent(l2a), true);
884     EXPECT_EQ(pldm_entity_is_exist_parent(l2b), true);
885     EXPECT_EQ(pldm_entity_is_exist_parent(l2c), true);
886     EXPECT_EQ(parentL2a.entity_type, nodeL1.entity_type);
887     EXPECT_EQ(parentL2a.entity_instance_num, nodeL1.entity_instance_num);
888     EXPECT_EQ(parentL2a.entity_container_id, nodeL1.entity_container_id);
889     EXPECT_EQ(parentL2b.entity_type, nodeL1.entity_type);
890     EXPECT_EQ(parentL2b.entity_instance_num, nodeL1.entity_instance_num);
891     EXPECT_EQ(parentL2b.entity_container_id, nodeL1.entity_container_id);
892     EXPECT_EQ(parentL2c.entity_type, nodeL1.entity_type);
893     EXPECT_EQ(parentL2c.entity_instance_num, nodeL1.entity_instance_num);
894     EXPECT_EQ(parentL2c.entity_container_id, nodeL1.entity_container_id);
895 
896     pldm_entity nodeL2a = pldm_entity_extract(l2a);
897     pldm_entity parentL3a = pldm_entity_get_parent(l3a);
898     pldm_entity parentL3b = pldm_entity_get_parent(l3b);
899     pldm_entity parentL3c = pldm_entity_get_parent(l3c);
900     EXPECT_EQ(pldm_entity_is_exist_parent(l3a), true);
901     EXPECT_EQ(pldm_entity_is_exist_parent(l3b), true);
902     EXPECT_EQ(pldm_entity_is_exist_parent(l3c), true);
903     EXPECT_EQ(parentL3a.entity_type, nodeL2a.entity_type);
904     EXPECT_EQ(parentL3a.entity_instance_num, nodeL2a.entity_instance_num);
905     EXPECT_EQ(parentL3a.entity_container_id, nodeL2a.entity_container_id);
906     EXPECT_EQ(parentL3b.entity_type, nodeL2a.entity_type);
907     EXPECT_EQ(parentL3b.entity_instance_num, nodeL2a.entity_instance_num);
908     EXPECT_EQ(parentL3b.entity_container_id, nodeL2a.entity_container_id);
909     EXPECT_EQ(parentL3c.entity_type, nodeL2a.entity_type);
910     EXPECT_EQ(parentL3c.entity_instance_num, nodeL2a.entity_instance_num);
911     EXPECT_EQ(parentL3c.entity_container_id, nodeL2a.entity_container_id);
912 
913     pldm_entity nodeL3a = pldm_entity_extract(l3a);
914     pldm_entity parentL4a = pldm_entity_get_parent(l4a);
915     EXPECT_EQ(pldm_entity_is_exist_parent(l4a), true);
916     EXPECT_EQ(parentL4a.entity_type, nodeL3a.entity_type);
917     EXPECT_EQ(parentL4a.entity_instance_num, nodeL3a.entity_instance_num);
918     EXPECT_EQ(parentL4a.entity_container_id, nodeL3a.entity_container_id);
919 
920     pldm_entity nodeL3b = pldm_entity_extract(l3b);
921     pldm_entity parentL4b = pldm_entity_get_parent(l4b);
922     EXPECT_EQ(pldm_entity_is_exist_parent(l4b), true);
923     EXPECT_EQ(parentL4b.entity_type, nodeL3b.entity_type);
924     EXPECT_EQ(parentL4b.entity_instance_num, nodeL3b.entity_instance_num);
925     EXPECT_EQ(parentL4b.entity_container_id, nodeL3b.entity_container_id);
926 
927     size_t num{};
928     pldm_entity* out = nullptr;
929     pldm_entity_association_tree_visit(tree, &out, &num);
930     EXPECT_EQ(num, 9u);
931 
932     EXPECT_EQ(out[0].entity_type, 1u);
933     EXPECT_EQ(out[0].entity_instance_num, 1u);
934     EXPECT_EQ(out[0].entity_container_id, 0u);
935 
936     EXPECT_EQ(out[1].entity_type, 2u);
937     EXPECT_EQ(out[1].entity_instance_num, 1u);
938     EXPECT_EQ(out[1].entity_container_id, 1u);
939     EXPECT_EQ(out[2].entity_type, 2u);
940     EXPECT_EQ(out[2].entity_instance_num, 2u);
941     EXPECT_EQ(out[2].entity_container_id, 1u);
942     EXPECT_EQ(out[3].entity_type, 3u);
943     EXPECT_EQ(out[3].entity_instance_num, 1u);
944     EXPECT_EQ(out[3].entity_container_id, 1u);
945 
946     EXPECT_EQ(out[4].entity_type, 4u);
947     EXPECT_EQ(out[4].entity_instance_num, 1u);
948     EXPECT_EQ(out[4].entity_container_id, 2u);
949     EXPECT_EQ(out[5].entity_type, 5u);
950     EXPECT_EQ(out[5].entity_instance_num, 1u);
951     EXPECT_EQ(out[5].entity_container_id, 2u);
952     EXPECT_EQ(out[6].entity_type, 5u);
953     EXPECT_EQ(out[6].entity_instance_num, 2u);
954     EXPECT_EQ(out[6].entity_container_id, 2u);
955 
956     EXPECT_EQ(out[7].entity_type, 7u);
957     EXPECT_EQ(out[7].entity_instance_num, 1u);
958     EXPECT_EQ(out[7].entity_container_id, 4u);
959     EXPECT_EQ(out[8].entity_type, 6u);
960     EXPECT_EQ(out[8].entity_instance_num, 1u);
961     EXPECT_EQ(out[8].entity_container_id, 3u);
962 
963     free(out);
964 
965     pldm_entity p1 = pldm_entity_extract(l1);
966     EXPECT_EQ(p1.entity_type, 1u);
967     EXPECT_EQ(p1.entity_instance_num, 1u);
968     EXPECT_EQ(p1.entity_container_id, 0u);
969 
970     pldm_entity p2a = pldm_entity_extract(l2a);
971     EXPECT_EQ(p2a.entity_type, 2u);
972     EXPECT_EQ(p2a.entity_instance_num, 1u);
973     EXPECT_EQ(p2a.entity_container_id, 1u);
974     pldm_entity p2b = pldm_entity_extract(l2b);
975     EXPECT_EQ(p2b.entity_type, 2u);
976     EXPECT_EQ(p2b.entity_instance_num, 2u);
977     EXPECT_EQ(p2b.entity_container_id, 1u);
978     pldm_entity p2c = pldm_entity_extract(l2c);
979     EXPECT_EQ(p2c.entity_type, 3u);
980     EXPECT_EQ(p2c.entity_instance_num, 1u);
981     EXPECT_EQ(p2c.entity_container_id, 1u);
982 
983     pldm_entity p3a = pldm_entity_extract(l3a);
984     EXPECT_EQ(p3a.entity_type, 4u);
985     EXPECT_EQ(p3a.entity_instance_num, 1u);
986     EXPECT_EQ(p3a.entity_container_id, 2u);
987     pldm_entity p3b = pldm_entity_extract(l3b);
988     EXPECT_EQ(p3b.entity_type, 5u);
989     EXPECT_EQ(p3b.entity_instance_num, 1u);
990     EXPECT_EQ(p3b.entity_container_id, 2u);
991     pldm_entity p3c = pldm_entity_extract(l3c);
992     EXPECT_EQ(p3c.entity_type, 5u);
993     EXPECT_EQ(p3c.entity_instance_num, 2u);
994     EXPECT_EQ(p3c.entity_container_id, 2u);
995 
996     pldm_entity p4a = pldm_entity_extract(l4a);
997     EXPECT_EQ(p4a.entity_type, 6u);
998     EXPECT_EQ(p4a.entity_instance_num, 1u);
999     EXPECT_EQ(p4a.entity_container_id, 3u);
1000     pldm_entity p4b = pldm_entity_extract(l4b);
1001     EXPECT_EQ(p4b.entity_type, 7u);
1002     EXPECT_EQ(p4b.entity_instance_num, 1u);
1003     EXPECT_EQ(p4b.entity_container_id, 4u);
1004 
1005     pldm_entity_association_tree_destroy(tree);
1006 }
1007 
1008 #if LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,findAndAddRemotePDR)1009 TEST(EntityAssociationPDR, findAndAddRemotePDR)
1010 {
1011     //         Tree - 1
1012     //
1013     //        11521(1,0)
1014     //             |
1015     //          45 (1,1)
1016     //             |
1017     //          64 (1,2)
1018     //             |
1019     //    ------------------
1020     //    |                 |
1021     //  67(0,3)           67(1,3)
1022     //    |                 |
1023     // 135(0,4)          135(0,5)
1024     //    |                 |
1025     // 32903(0,6)         32903(0,7)
1026 
1027     pldm_entity entities[9]{};
1028     entities[0].entity_type = 11521;
1029     entities[1].entity_type = 45;
1030     entities[2].entity_type = 64;
1031     entities[3].entity_type = 67;
1032     entities[4].entity_type = 67;
1033     entities[5].entity_type = 135;
1034     entities[5].entity_container_id = 2;
1035     entities[6].entity_type = 135;
1036     entities[6].entity_container_id = 3;
1037     entities[7].entity_type = 32903;
1038     entities[8].entity_type = 32903;
1039     auto tree = pldm_entity_association_tree_init();
1040     auto l1 = pldm_entity_association_tree_add_entity(
1041         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
1042         false, true, 0xffff);
1043     EXPECT_NE(l1, nullptr);
1044     auto l2 = pldm_entity_association_tree_add_entity(
1045         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1046         false, 0xffff);
1047     EXPECT_NE(l2, nullptr);
1048     auto l3 = pldm_entity_association_tree_add_entity(
1049         tree, &entities[2], 0xffff, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1050         true, 0xffff);
1051     EXPECT_NE(l3, nullptr);
1052     auto l4a = pldm_entity_association_tree_add_entity(
1053         tree, &entities[3], 0, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1054         false, 0xffff);
1055     EXPECT_NE(l4a, nullptr);
1056     auto l4b = pldm_entity_association_tree_add_entity(
1057         tree, &entities[4], 1, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
1058         0xffff);
1059     EXPECT_NE(l4b, nullptr);
1060     auto l5a = pldm_entity_association_tree_add_entity(
1061         tree, &entities[5], 0, l4a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1062         false, 0xffff);
1063     EXPECT_NE(l5a, nullptr);
1064     auto l5b = pldm_entity_association_tree_add_entity(
1065         tree, &entities[6], 0, l4b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1066         false, 0xffff);
1067     EXPECT_NE(l5b, nullptr);
1068     pldm_entity entity{};
1069     entity.entity_type = 135;
1070     entity.entity_instance_num = 0;
1071     entity.entity_container_id = 2;
1072     auto result1 = pldm_entity_association_tree_find(tree, &entity);
1073     EXPECT_EQ(result1, l5a);
1074     EXPECT_EQ(entities[5].entity_container_id, 2);
1075     auto l6a = pldm_entity_association_tree_add_entity(
1076         tree, &entities[7], 0, result1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1077         false, 0xffff);
1078     EXPECT_NE(l6a, nullptr);
1079     entity.entity_type = 135;
1080     entity.entity_instance_num = 0;
1081     entity.entity_container_id = 3;
1082     auto result2 = pldm_entity_association_tree_find(tree, &entity);
1083     EXPECT_NE(result2, l5b);
1084     EXPECT_EQ(entities[6].entity_container_id, 3);
1085     auto l7a = pldm_entity_association_tree_add_entity(
1086         tree, &entities[8], 0, result2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1087         false, 0xffff);
1088     EXPECT_EQ(l7a, nullptr);
1089     pldm_entity_association_tree_destroy(tree);
1090 }
1091 #endif
1092 
TEST(EntityAssociationPDR,testSpecialTrees)1093 TEST(EntityAssociationPDR, testSpecialTrees)
1094 {
1095     pldm_entity entities[3]{};
1096 
1097     entities[0].entity_type = 1;
1098     entities[1].entity_type = 2;
1099     entities[2].entity_type = 1;
1100 
1101     // A
1102     auto tree = pldm_entity_association_tree_init();
1103     auto node = pldm_entity_association_tree_add(
1104         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1105     EXPECT_NE(node, nullptr);
1106     size_t num{};
1107     pldm_entity* out = nullptr;
1108     pldm_entity_association_tree_visit(tree, &out, &num);
1109     EXPECT_EQ(num, 1u);
1110     EXPECT_EQ(out[0].entity_type, 1u);
1111     EXPECT_EQ(out[0].entity_instance_num, 1u);
1112     EXPECT_EQ(out[0].entity_container_id, 0u);
1113     free(out);
1114     pldm_entity_association_tree_destroy(tree);
1115 
1116     // A-A-A
1117     tree = pldm_entity_association_tree_init();
1118     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1119                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1120     EXPECT_NE(node, nullptr);
1121     node = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, nullptr,
1122                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1123     EXPECT_NE(node, nullptr);
1124     node = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, nullptr,
1125                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1126     EXPECT_NE(node, nullptr);
1127     pldm_entity_association_tree_visit(tree, &out, &num);
1128     EXPECT_EQ(num, 3u);
1129     EXPECT_EQ(out[0].entity_type, 1u);
1130     EXPECT_EQ(out[0].entity_instance_num, 1u);
1131     EXPECT_EQ(out[0].entity_container_id, 0u);
1132     EXPECT_EQ(out[1].entity_type, 1u);
1133     EXPECT_EQ(out[1].entity_instance_num, 2u);
1134     EXPECT_EQ(out[1].entity_container_id, 0u);
1135     EXPECT_EQ(out[2].entity_type, 2u);
1136     EXPECT_EQ(out[2].entity_instance_num, 1u);
1137     EXPECT_EQ(out[2].entity_container_id, 0u);
1138     free(out);
1139     pldm_entity_association_tree_destroy(tree);
1140 
1141     // A
1142     // |
1143     // A
1144     // |
1145     // A
1146     tree = pldm_entity_association_tree_init();
1147     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1148                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1149     EXPECT_NE(node, nullptr);
1150     auto node1 = pldm_entity_association_tree_add(
1151         tree, &entities[1], 0xffff, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1152     EXPECT_NE(node1, nullptr);
1153     auto node2 = pldm_entity_association_tree_add(
1154         tree, &entities[2], 0xffff, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1155     EXPECT_NE(node2, nullptr);
1156     pldm_entity_association_tree_visit(tree, &out, &num);
1157     EXPECT_EQ(num, 3u);
1158     EXPECT_EQ(out[0].entity_type, 1u);
1159     EXPECT_EQ(out[0].entity_instance_num, 1u);
1160     EXPECT_EQ(out[0].entity_container_id, 0u);
1161     EXPECT_EQ(out[1].entity_type, 2u);
1162     EXPECT_EQ(out[1].entity_instance_num, 1u);
1163     EXPECT_EQ(out[1].entity_container_id, 1u);
1164     EXPECT_EQ(out[2].entity_type, 1u);
1165     EXPECT_EQ(out[2].entity_instance_num, 1u);
1166     EXPECT_EQ(out[2].entity_container_id, 2u);
1167     free(out);
1168     pldm_entity_association_tree_destroy(tree);
1169 
1170     // A-A
1171     //   |
1172     //   A-A
1173     tree = pldm_entity_association_tree_init();
1174     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1175                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1176     EXPECT_NE(node, nullptr);
1177     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1178                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1179     EXPECT_NE(node, nullptr);
1180     node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, node,
1181                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1182     EXPECT_NE(node1, nullptr);
1183     node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, node,
1184                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1185     EXPECT_NE(node2, nullptr);
1186     pldm_entity_association_tree_visit(tree, &out, &num);
1187     EXPECT_EQ(num, 4u);
1188     EXPECT_EQ(out[0].entity_type, 1u);
1189     EXPECT_EQ(out[0].entity_instance_num, 1u);
1190     EXPECT_EQ(out[0].entity_container_id, 0u);
1191     EXPECT_EQ(out[1].entity_type, 1u);
1192     EXPECT_EQ(out[1].entity_instance_num, 2u);
1193     EXPECT_EQ(out[1].entity_container_id, 0u);
1194     EXPECT_EQ(out[2].entity_type, 2u);
1195     EXPECT_EQ(out[2].entity_instance_num, 1u);
1196     EXPECT_EQ(out[2].entity_container_id, 1u);
1197     EXPECT_EQ(out[3].entity_type, 1u);
1198     EXPECT_EQ(out[3].entity_instance_num, 1u);
1199     EXPECT_EQ(out[3].entity_container_id, 1u);
1200     free(out);
1201     pldm_entity_association_tree_destroy(tree);
1202 }
1203 
TEST(EntityAssociationPDR,testPDR)1204 TEST(EntityAssociationPDR, testPDR)
1205 {
1206     // e = entity type, c = container id, i = instance num
1207 
1208     //        INPUT
1209     //        1(e=1)--1a(e=2)
1210     //        |
1211     //        2(e=2)--3(e=2)--4(e=2)--5(e=3)
1212     //        |
1213     //        6(e=4)--7(e=5)--8(e=5)--9(e=5)
1214     //        |       |
1215     //        11(e=6) 10(e=7)
1216 
1217     //        Expected OUTPUT
1218     //        1(e=1,c=0,i=1)
1219     //        |
1220     //        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)
1221     //        |
1222     //        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)
1223     //        |               |
1224     //        10(e=6,c=3,i=1) 11(e=7,c=4,i=1)
1225     pldm_entity entities[11]{};
1226 
1227     entities[0].entity_type = 1;
1228     entities[1].entity_type = 2;
1229     entities[2].entity_type = 3;
1230     entities[3].entity_type = 2;
1231     entities[4].entity_type = 3;
1232     entities[5].entity_type = 4;
1233     entities[6].entity_type = 5;
1234     entities[7].entity_type = 5;
1235     entities[8].entity_type = 5;
1236     entities[9].entity_type = 6;
1237     entities[10].entity_type = 7;
1238 
1239     auto tree = pldm_entity_association_tree_init();
1240 
1241     auto l1 = pldm_entity_association_tree_add(
1242         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1243     EXPECT_NE(l1, nullptr);
1244     auto l1a = pldm_entity_association_tree_add(
1245         tree, &entities[1], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1246     EXPECT_NE(l1a, nullptr);
1247 
1248     auto l2a = pldm_entity_association_tree_add(
1249         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1250     EXPECT_NE(l2a, nullptr);
1251     auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
1252                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1253     EXPECT_NE(l2b, nullptr);
1254     auto l2c = pldm_entity_association_tree_add(
1255         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1256     EXPECT_NE(l2c, nullptr);
1257     auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xffff, l1,
1258                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1259     EXPECT_NE(l2d, nullptr);
1260 
1261     auto l3a = pldm_entity_association_tree_add(
1262         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1263     EXPECT_NE(l3a, nullptr);
1264     auto l3b = pldm_entity_association_tree_add(
1265         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1266     EXPECT_NE(l3b, nullptr);
1267     auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xffff, l2a,
1268                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1269     EXPECT_NE(l3c, nullptr);
1270     auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xffff, l2a,
1271                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1272     EXPECT_NE(l3d, nullptr);
1273 
1274     auto l4a = pldm_entity_association_tree_add(
1275         tree, &entities[9], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1276     EXPECT_NE(l4a, nullptr);
1277     auto l4b = pldm_entity_association_tree_add(
1278         tree, &entities[10], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1279     EXPECT_NE(l4b, nullptr);
1280 
1281     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
1282               2);
1283     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1284               2);
1285     EXPECT_EQ(
1286         pldm_entity_get_num_children(l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 2);
1287     EXPECT_EQ(
1288         pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 0);
1289     EXPECT_EQ(pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1290               1);
1291 
1292     auto repo = pldm_pdr_init();
1293     int rc = pldm_entity_association_pdr_add(tree, repo, false, 1);
1294     ASSERT_EQ(rc, 0);
1295 
1296     EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
1297 
1298     uint32_t currRecHandle{};
1299     uint32_t nextRecHandle{};
1300     uint8_t* data = nullptr;
1301     uint32_t size{};
1302     uint32_t commonSize = sizeof(struct pldm_pdr_hdr) + sizeof(uint16_t) +
1303                           sizeof(uint8_t) + sizeof(pldm_entity) +
1304                           sizeof(uint8_t);
1305 
1306     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1307     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1308                                       l1, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1309                                   sizeof(pldm_entity)));
1310     uint8_t* start = data;
1311     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1312     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1313     EXPECT_EQ(le32toh(hdr->record_handle), 1u);
1314     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1315     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1316     start += sizeof(pldm_pdr_hdr);
1317     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1318     uint16_t* containerId = reinterpret_cast<uint16_t*>(start);
1319     EXPECT_EQ(le16toh(*containerId), 1u);
1320     start += sizeof(uint16_t);
1321     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1322     start += sizeof(uint8_t);
1323     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1324     pldm_entity* entity = reinterpret_cast<pldm_entity*>(start);
1325     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1326     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1327     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1328     start += sizeof(pldm_entity);
1329     EXPECT_EQ(*start,
1330               pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1331     start += sizeof(uint8_t);
1332     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1333     entity = reinterpret_cast<pldm_entity*>(start);
1334     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1335     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1336     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1337     start += sizeof(pldm_entity);
1338     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1339     entity = reinterpret_cast<pldm_entity*>(start);
1340     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1341     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1342     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1343 
1344     currRecHandle = nextRecHandle;
1345 
1346     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1347     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1348                                       l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1349                                   sizeof(pldm_entity)));
1350     start = data;
1351     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1352     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1353     EXPECT_EQ(le32toh(hdr->record_handle), 2u);
1354     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1355     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1356     start += sizeof(pldm_pdr_hdr);
1357     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1358     containerId = reinterpret_cast<uint16_t*>(start);
1359     EXPECT_EQ(le16toh(*containerId), 1u);
1360     start += sizeof(uint16_t);
1361     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1362     start += sizeof(uint8_t);
1363     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1364     entity = reinterpret_cast<pldm_entity*>(start);
1365     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1366     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1367     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1368     start += sizeof(pldm_entity);
1369     EXPECT_EQ(*start, pldm_entity_get_num_children(
1370                           l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1371     start += sizeof(uint8_t);
1372     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1373     entity = reinterpret_cast<pldm_entity*>(start);
1374     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1375     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1376     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1377     start += sizeof(pldm_entity);
1378     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1379     entity = reinterpret_cast<pldm_entity*>(start);
1380     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1381     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1382     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1383 
1384     currRecHandle = nextRecHandle;
1385 
1386     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1387     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1388                                       l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1389                                   sizeof(pldm_entity)));
1390     start = data;
1391     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1392     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1393     EXPECT_EQ(le32toh(hdr->record_handle), 3u);
1394     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1395     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1396     start += sizeof(pldm_pdr_hdr);
1397     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1398     containerId = reinterpret_cast<uint16_t*>(start);
1399     EXPECT_EQ(le16toh(*containerId), 2u);
1400     start += sizeof(uint16_t);
1401     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1402     start += sizeof(uint8_t);
1403     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1404     entity = reinterpret_cast<pldm_entity*>(start);
1405     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1406     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1407     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1408     start += sizeof(pldm_entity);
1409     EXPECT_EQ(*start, pldm_entity_get_num_children(
1410                           l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1411     start += sizeof(uint8_t);
1412     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1413     entity = reinterpret_cast<pldm_entity*>(start);
1414     EXPECT_EQ(le16toh(entity->entity_type), 5);
1415     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1416     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1417     start += sizeof(pldm_entity);
1418     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1419     entity = reinterpret_cast<pldm_entity*>(start);
1420     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1421     EXPECT_EQ(le16toh(entity->entity_instance_num), 3u);
1422     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1423 
1424     currRecHandle = nextRecHandle;
1425 
1426     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1427     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1428                                       l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1429                                   sizeof(pldm_entity)));
1430     start = data;
1431     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1432     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1433     EXPECT_EQ(le32toh(hdr->record_handle), 4u);
1434     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1435     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1436     start += sizeof(pldm_pdr_hdr);
1437     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1438     containerId = reinterpret_cast<uint16_t*>(start);
1439     EXPECT_EQ(le16toh(*containerId), 2u);
1440     start += sizeof(uint16_t);
1441     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1442     start += sizeof(uint8_t);
1443     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1444     entity = reinterpret_cast<pldm_entity*>(start);
1445     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1446     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1447     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1448     start += sizeof(pldm_entity);
1449     EXPECT_EQ(*start, pldm_entity_get_num_children(
1450                           l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1451     start += sizeof(uint8_t);
1452     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1453     entity = reinterpret_cast<pldm_entity*>(start);
1454     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1455     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1456     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1457     start += sizeof(pldm_entity);
1458     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1459     entity = reinterpret_cast<pldm_entity*>(start);
1460     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1461     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1462     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1463 
1464     currRecHandle = nextRecHandle;
1465 
1466     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1467     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1468                                       l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1469                                   sizeof(pldm_entity)));
1470     start = data;
1471     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1472     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1473     EXPECT_EQ(le32toh(hdr->record_handle), 5u);
1474     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1475     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1476     start += sizeof(pldm_pdr_hdr);
1477     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1478     containerId = reinterpret_cast<uint16_t*>(start);
1479     EXPECT_EQ(le16toh(*containerId), 3u);
1480     start += sizeof(uint16_t);
1481     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1482     start += sizeof(uint8_t);
1483     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1484     entity = reinterpret_cast<pldm_entity*>(start);
1485     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1486     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1487     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1488     start += sizeof(pldm_entity);
1489     EXPECT_EQ(*start, pldm_entity_get_num_children(
1490                           l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1491     start += sizeof(uint8_t);
1492     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1493     entity = reinterpret_cast<pldm_entity*>(start);
1494     EXPECT_EQ(le16toh(entity->entity_type), 6u);
1495     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1496     EXPECT_EQ(le16toh(entity->entity_container_id), 3u);
1497 
1498     currRecHandle = nextRecHandle;
1499 
1500     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1501     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1502                                       l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1503                                   sizeof(pldm_entity)));
1504     start = data;
1505     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1506     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1507     EXPECT_EQ(le32toh(hdr->record_handle), 6u);
1508     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1509     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1510     start += sizeof(pldm_pdr_hdr);
1511     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1512     containerId = reinterpret_cast<uint16_t*>(start);
1513     EXPECT_EQ(le16toh(*containerId), 4u);
1514     start += sizeof(uint16_t);
1515     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1516     start += sizeof(uint8_t);
1517     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1518     entity = reinterpret_cast<pldm_entity*>(start);
1519     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1520     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1521     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1522     start += sizeof(pldm_entity);
1523     EXPECT_EQ(*start, pldm_entity_get_num_children(
1524                           l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1525     start += sizeof(uint8_t);
1526     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1527     entity = reinterpret_cast<pldm_entity*>(start);
1528     EXPECT_EQ(le16toh(entity->entity_type), 7u);
1529     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1530     EXPECT_EQ(le16toh(entity->entity_container_id), 4u);
1531 
1532     EXPECT_EQ(nextRecHandle, 0u);
1533 
1534     pldm_pdr_destroy(repo);
1535     pldm_entity_association_tree_destroy(tree);
1536 }
1537 
TEST(EntityAssociationPDR,testPDRWithRecordHandle)1538 TEST(EntityAssociationPDR, testPDRWithRecordHandle)
1539 {
1540     // e = entity type, c = container id, i = instance num
1541 
1542     //        INPUT
1543     //        1(e=1)
1544     //        |
1545     //        2(e=2)--3(e=2)
1546 
1547     //        Expected OUTPUT
1548     //        1(e=1,c=0,i=1)
1549     //        |
1550     //        2(e=2,c=1,i=1)--3(e=2,c=1,i=2)
1551 
1552     pldm_entity entities[3] = {{1, 1, 0}, {2, 1, 1}, {3, 1, 1}};
1553     pldm_entity_test testEntities[3] = {{1, 1, 0}, {2, 1, 1}, {3, 1, 1}};
1554 
1555     auto tree = pldm_entity_association_tree_init();
1556 
1557     auto l1 = pldm_entity_association_tree_add(
1558         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1559     ASSERT_NE(l1, nullptr);
1560 
1561     auto l2a = pldm_entity_association_tree_add(
1562         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1563     ASSERT_NE(l2a, nullptr);
1564     pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
1565                                      PLDM_ENTITY_ASSOCIAION_LOGICAL);
1566     auto repo = pldm_pdr_init();
1567     pldm_entity* l_entities = entities;
1568 
1569     pldm_entity_node* node = nullptr;
1570     pldm_find_entity_ref_in_tree(tree, entities[0], &node);
1571 
1572     ASSERT_NE(node, nullptr);
1573 
1574     int numEntities = 3;
1575     pldm_entity_association_pdr_add_from_node_with_record_handle(
1576         node, repo, &l_entities, numEntities, true, 1, (10));
1577 
1578     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
1579 
1580     uint32_t currRecHandle{};
1581     uint32_t nextRecHandle{};
1582     uint8_t* data = nullptr;
1583     uint32_t size{};
1584 
1585     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1586 
1587     struct pldm_msgbuf _buf;
1588     struct pldm_msgbuf* buf = &_buf;
1589 
1590     auto rc =
1591         pldm_msgbuf_init_errno(buf,
1592                                (sizeof(struct pldm_pdr_hdr) +
1593                                 sizeof(struct pldm_pdr_entity_association)),
1594                                data, size);
1595     ASSERT_EQ(rc, 0);
1596 
1597     pldm_association_pdr_test association_pdr = pldm_association_pdr_test{
1598         10,
1599         1,
1600         PLDM_PDR_ENTITY_ASSOCIATION,
1601         1,
1602         static_cast<uint16_t>(size - sizeof(struct pldm_pdr_hdr)),
1603         1,
1604         PLDM_ENTITY_ASSOCIAION_LOGICAL,
1605         1};
1606 
1607     verifyEntityAssociationPdr(buf, association_pdr, testEntities[0],
1608                                testEntities[2]);
1609 
1610     currRecHandle = nextRecHandle;
1611     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1612     rc = pldm_msgbuf_init_errno(buf,
1613                                 (sizeof(struct pldm_pdr_hdr) +
1614                                  sizeof(struct pldm_pdr_entity_association)),
1615                                 data, size);
1616     ASSERT_EQ(rc, 0);
1617 
1618     pldm_association_pdr_test association_pdr1 = pldm_association_pdr_test{
1619         11,
1620         1,
1621         PLDM_PDR_ENTITY_ASSOCIATION,
1622         1,
1623         static_cast<uint16_t>(size - sizeof(struct pldm_pdr_hdr)),
1624         1,
1625         PLDM_ENTITY_ASSOCIAION_PHYSICAL,
1626         1};
1627 
1628     verifyEntityAssociationPdr(buf, association_pdr1, testEntities[0],
1629                                testEntities[1]);
1630 
1631     pldm_pdr_destroy(repo);
1632     pldm_entity_association_tree_destroy(tree);
1633 }
1634 
TEST(EntityAssociationPDR,testFind)1635 TEST(EntityAssociationPDR, testFind)
1636 {
1637     //        1
1638     //        |
1639     //        2--3--4
1640     //        |
1641     //        5--6--7
1642     //        |  |
1643     //        8  9
1644 
1645     pldm_entity entities[9]{};
1646 
1647     entities[0].entity_type = 1;
1648     entities[1].entity_type = 2;
1649     entities[2].entity_type = 2;
1650     entities[3].entity_type = 3;
1651     entities[4].entity_type = 4;
1652     entities[5].entity_type = 5;
1653     entities[6].entity_type = 5;
1654     entities[7].entity_type = 6;
1655     entities[8].entity_type = 7;
1656 
1657     auto tree = pldm_entity_association_tree_init();
1658 
1659     auto l1 = pldm_entity_association_tree_add(
1660         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1661     EXPECT_NE(l1, nullptr);
1662     auto l2a = pldm_entity_association_tree_add(
1663         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1664     EXPECT_NE(l2a, nullptr);
1665     auto l2b = pldm_entity_association_tree_add(
1666         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1667     EXPECT_NE(l2b, nullptr);
1668     auto l2c = pldm_entity_association_tree_add(
1669         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1670     EXPECT_NE(l2c, nullptr);
1671     auto l3a = pldm_entity_association_tree_add(
1672         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1673     EXPECT_NE(l3a, nullptr);
1674     auto l3b = pldm_entity_association_tree_add(
1675         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1676     EXPECT_NE(l3b, nullptr);
1677     auto l3c = pldm_entity_association_tree_add(
1678         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1679     EXPECT_NE(l3c, nullptr);
1680     auto l4a = pldm_entity_association_tree_add(
1681         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1682     EXPECT_NE(l4a, nullptr);
1683     auto l4b = pldm_entity_association_tree_add(
1684         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1685     EXPECT_NE(l4b, nullptr);
1686 
1687     pldm_entity entity{};
1688 
1689     entity.entity_type = 1;
1690     entity.entity_instance_num = 1;
1691     auto result = pldm_entity_association_tree_find(tree, &entity);
1692     EXPECT_EQ(result, l1);
1693     EXPECT_EQ(entity.entity_container_id, 0);
1694 
1695     entity.entity_type = 2;
1696     entity.entity_instance_num = 1;
1697     result = pldm_entity_association_tree_find(tree, &entity);
1698     EXPECT_EQ(result, l2a);
1699     EXPECT_EQ(entity.entity_container_id, 1);
1700     entity.entity_type = 2;
1701     entity.entity_instance_num = 2;
1702     result = pldm_entity_association_tree_find(tree, &entity);
1703     EXPECT_EQ(result, l2b);
1704     EXPECT_EQ(entity.entity_container_id, 1);
1705     entity.entity_type = 3;
1706     entity.entity_instance_num = 1;
1707     result = pldm_entity_association_tree_find(tree, &entity);
1708     EXPECT_EQ(result, l2c);
1709     EXPECT_EQ(entity.entity_container_id, 1);
1710 
1711     entity.entity_type = 7;
1712     entity.entity_instance_num = 1;
1713     result = pldm_entity_association_tree_find(tree, &entity);
1714     EXPECT_EQ(result, l4b);
1715     EXPECT_EQ(entity.entity_container_id, 4);
1716 
1717     pldm_entity_association_tree_destroy(tree);
1718 }
1719 
1720 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testCopyTree)1721 TEST(EntityAssociationPDR, testCopyTree)
1722 {
1723     pldm_entity entities[4]{};
1724     int rc;
1725 
1726     entities[0].entity_type = 1;
1727     entities[1].entity_type = 2;
1728     entities[2].entity_type = 2;
1729     entities[3].entity_type = 3;
1730 
1731     auto orgTree = pldm_entity_association_tree_init();
1732     auto newTree = pldm_entity_association_tree_init();
1733     auto l1 =
1734         pldm_entity_association_tree_add(orgTree, &entities[0], 0xffff, nullptr,
1735                                          PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1736     EXPECT_NE(l1, nullptr);
1737     auto l2a = pldm_entity_association_tree_add(
1738         orgTree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1739     EXPECT_NE(l2a, nullptr);
1740     auto l2b = pldm_entity_association_tree_add(
1741         orgTree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1742     EXPECT_NE(l2b, nullptr);
1743     auto l2c = pldm_entity_association_tree_add(
1744         orgTree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1745     EXPECT_NE(l2c, nullptr);
1746     size_t orgNum{};
1747     pldm_entity* orgOut = nullptr;
1748     pldm_entity_association_tree_visit(orgTree, &orgOut, &orgNum);
1749     EXPECT_EQ(orgNum, 4u);
1750 
1751     rc = pldm_entity_association_tree_copy_root_check(orgTree, newTree);
1752     ASSERT_EQ(rc, 0);
1753     size_t newNum{};
1754     pldm_entity* newOut = nullptr;
1755     pldm_entity_association_tree_visit(newTree, &newOut, &newNum);
1756     EXPECT_EQ(newNum, orgNum);
1757     EXPECT_EQ(newOut[0].entity_type, 1u);
1758     EXPECT_EQ(newOut[0].entity_instance_num, 1u);
1759     EXPECT_EQ(newOut[0].entity_container_id, 0u);
1760     free(orgOut);
1761     free(newOut);
1762     pldm_entity_association_tree_destroy(orgTree);
1763     pldm_entity_association_tree_destroy(newTree);
1764 }
1765 #endif
1766 
TEST(EntityAssociationPDR,testExtract)1767 TEST(EntityAssociationPDR, testExtract)
1768 {
1769     std::vector<uint8_t> pdr{};
1770     pdr.resize(sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_entity_association) +
1771                sizeof(pldm_entity) * 4);
1772     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1773     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
1774     hdr->type = PLDM_PDR_ENTITY_ASSOCIATION;
1775     hdr->length =
1776         htole16(sizeof(pldm_pdr_entity_association) + sizeof(pldm_entity) * 4);
1777 
1778     pldm_pdr_entity_association* e =
1779         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1780         reinterpret_cast<pldm_pdr_entity_association*>(pdr.data() +
1781                                                        sizeof(pldm_pdr_hdr));
1782     e->container_id = htole16(1);
1783     e->num_children = 5;
1784     e->container.entity_type = htole16(1);
1785     e->container.entity_instance_num = htole16(1);
1786     e->container.entity_container_id = htole16(0);
1787 
1788     pldm_entity* entity = e->children;
1789     entity->entity_type = htole16(2);
1790     entity->entity_instance_num = htole16(1);
1791     entity->entity_container_id = htole16(1);
1792     ++entity;
1793     entity->entity_type = htole16(3);
1794     entity->entity_instance_num = htole16(1);
1795     entity->entity_container_id = htole16(1);
1796     ++entity;
1797     entity->entity_type = htole16(4);
1798     entity->entity_instance_num = htole16(1);
1799     entity->entity_container_id = htole16(1);
1800     ++entity;
1801     entity->entity_type = htole16(5);
1802     entity->entity_instance_num = htole16(1);
1803     entity->entity_container_id = htole16(1);
1804     ++entity;
1805     entity->entity_type = htole16(6);
1806     entity->entity_instance_num = htole16(1);
1807     entity->entity_container_id = htole16(1);
1808 
1809     size_t num{};
1810     pldm_entity* out = nullptr;
1811     pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &num, &out);
1812     EXPECT_EQ(num, (unsigned)e->num_children + 1);
1813     EXPECT_EQ(out[0].entity_type, 1u);
1814     EXPECT_EQ(out[0].entity_instance_num, 1u);
1815     EXPECT_EQ(out[0].entity_container_id, 0u);
1816     EXPECT_EQ(out[1].entity_type, 2u);
1817     EXPECT_EQ(out[1].entity_instance_num, 1u);
1818     EXPECT_EQ(out[1].entity_container_id, 1u);
1819     EXPECT_EQ(out[2].entity_type, 3u);
1820     EXPECT_EQ(out[2].entity_instance_num, 1u);
1821     EXPECT_EQ(out[2].entity_container_id, 1u);
1822     EXPECT_EQ(out[3].entity_type, 4u);
1823     EXPECT_EQ(out[3].entity_instance_num, 1u);
1824     EXPECT_EQ(out[3].entity_container_id, 1u);
1825     EXPECT_EQ(out[4].entity_type, 5u);
1826     EXPECT_EQ(out[4].entity_instance_num, 1u);
1827     EXPECT_EQ(out[4].entity_container_id, 1u);
1828     EXPECT_EQ(out[5].entity_type, 6u);
1829     EXPECT_EQ(out[5].entity_instance_num, 1u);
1830     EXPECT_EQ(out[5].entity_container_id, 1u);
1831 
1832     free(out);
1833 }
1834 
TEST(EntityAssociationPDR,testGetChildren)1835 TEST(EntityAssociationPDR, testGetChildren)
1836 {
1837     pldm_entity entities[4]{};
1838     entities[0].entity_type = 1;
1839     entities[1].entity_type = 2;
1840     entities[2].entity_type = 2;
1841     entities[3].entity_type = 3;
1842 
1843     auto tree = pldm_entity_association_tree_init();
1844     auto l1 = pldm_entity_association_tree_add(
1845         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1846     EXPECT_NE(l1, nullptr);
1847     auto l2a = pldm_entity_association_tree_add(
1848         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1849     EXPECT_NE(l2a, nullptr);
1850     auto l2b = pldm_entity_association_tree_add(
1851         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1852     EXPECT_NE(l2b, nullptr);
1853     auto l2c = pldm_entity_association_tree_add(
1854         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1855     EXPECT_NE(l2c, nullptr);
1856 
1857     pldm_entity et1;
1858     et1.entity_type = 2;
1859     et1.entity_instance_num = 1;
1860     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et1));
1861 
1862     pldm_entity et2;
1863     et2.entity_type = 2;
1864     et2.entity_instance_num = 2;
1865     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et2));
1866 
1867     pldm_entity et3;
1868     et3.entity_type = 2;
1869     et3.entity_instance_num = 3;
1870     EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3));
1871 
1872     pldm_entity_association_tree_destroy(tree);
1873 }
1874 
TEST(EntityAssociationPDR,testEntityInstanceNumber)1875 TEST(EntityAssociationPDR, testEntityInstanceNumber)
1876 {
1877     pldm_entity entities[9]{};
1878 
1879     entities[0].entity_type = 1;
1880     entities[1].entity_type = 2;
1881     entities[2].entity_type = 2;
1882     entities[3].entity_type = 2;
1883     entities[4].entity_type = 2;
1884     entities[5].entity_type = 2;
1885     entities[6].entity_type = 2;
1886     entities[7].entity_type = 3;
1887     entities[8].entity_type = 3;
1888 
1889     auto tree = pldm_entity_association_tree_init();
1890     auto repo = pldm_pdr_init();
1891 
1892     uint16_t terminusHdl{};
1893     uint16_t entityType{};
1894     uint16_t entityInstanceNum{};
1895     uint16_t containerId{};
1896 
1897     auto node = pldm_entity_association_tree_add(
1898         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1899     EXPECT_NE(node, nullptr);
1900 
1901     auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node,
1902                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1903     uint32_t first = 1;
1904     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 1, entities[1].entity_type,
1905                                           entities[1].entity_instance_num,
1906                                           entities[1].entity_container_id,
1907                                           &first),
1908               0);
1909     EXPECT_NE(l1, nullptr);
1910     EXPECT_EQ(entities[1].entity_instance_num, 63);
1911     EXPECT_EQ(first, pldm_pdr_get_record_handle(
1912                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1913                                    repo, 1, &terminusHdl, &entityType,
1914                                    &entityInstanceNum, &containerId)));
1915     EXPECT_EQ(entityType, 2);
1916     EXPECT_EQ(entityInstanceNum, 63);
1917 
1918     auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node,
1919                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1920     uint32_t second = 2;
1921     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 2, entities[2].entity_type,
1922                                           entities[2].entity_instance_num,
1923                                           entities[2].entity_container_id,
1924                                           &second),
1925               0);
1926     EXPECT_NE(l2, nullptr);
1927     EXPECT_EQ(entities[2].entity_instance_num, 37);
1928     EXPECT_EQ(second, pldm_pdr_get_record_handle(
1929                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1930                                     repo, 2, &terminusHdl, &entityType,
1931                                     &entityInstanceNum, &containerId)));
1932     EXPECT_EQ(entityType, 2);
1933     EXPECT_EQ(entityInstanceNum, 37);
1934 
1935     auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node,
1936                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1937     uint32_t third = 3;
1938     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 3, entities[3].entity_type,
1939                                           entities[3].entity_instance_num,
1940                                           entities[3].entity_container_id,
1941                                           &third),
1942               0);
1943     EXPECT_NE(l3, nullptr);
1944     EXPECT_EQ(entities[3].entity_instance_num, 44);
1945     EXPECT_EQ(third, pldm_pdr_get_record_handle(
1946                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1947                                    repo, 3, &terminusHdl, &entityType,
1948                                    &entityInstanceNum, &containerId)));
1949     EXPECT_EQ(entityType, 2);
1950     EXPECT_EQ(entityInstanceNum, 44);
1951 
1952     auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node,
1953                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1954     uint32_t fourth = 4;
1955     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 4, entities[4].entity_type,
1956                                           entities[4].entity_instance_num,
1957                                           entities[4].entity_container_id,
1958                                           &fourth),
1959               0);
1960     EXPECT_NE(l4, nullptr);
1961     EXPECT_EQ(entities[4].entity_instance_num, 89);
1962     EXPECT_EQ(fourth, pldm_pdr_get_record_handle(
1963                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1964                                     repo, 4, &terminusHdl, &entityType,
1965                                     &entityInstanceNum, &containerId)));
1966     EXPECT_EQ(entityType, 2);
1967     EXPECT_EQ(entityInstanceNum, 89);
1968 
1969     auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xffff, node,
1970                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1971     uint32_t fifth = 5;
1972     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 5, entities[5].entity_type,
1973                                           entities[5].entity_instance_num,
1974                                           entities[5].entity_container_id,
1975                                           &fifth),
1976               0);
1977     EXPECT_NE(l5, nullptr);
1978     EXPECT_EQ(entities[5].entity_instance_num, 90);
1979     EXPECT_EQ(fifth, pldm_pdr_get_record_handle(
1980                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1981                                    repo, 5, &terminusHdl, &entityType,
1982                                    &entityInstanceNum, &containerId)));
1983     EXPECT_EQ(entityType, 2);
1984     EXPECT_EQ(entityInstanceNum, 90);
1985 
1986     auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node,
1987                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1988     EXPECT_EQ(l6, nullptr);
1989 
1990     auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1,
1991                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1992     uint32_t seventh = 7;
1993     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 7, entities[7].entity_type,
1994                                           entities[7].entity_instance_num,
1995                                           entities[7].entity_container_id,
1996                                           &seventh),
1997               0);
1998     EXPECT_NE(l7, nullptr);
1999     EXPECT_EQ(entities[7].entity_instance_num, 100);
2000     EXPECT_EQ(seventh, pldm_pdr_get_record_handle(
2001                            repo, pldm_pdr_fru_record_set_find_by_rsi(
2002                                      repo, 7, &terminusHdl, &entityType,
2003                                      &entityInstanceNum, &containerId)));
2004     EXPECT_EQ(entityType, 3);
2005     EXPECT_EQ(entityInstanceNum, 100);
2006 
2007     auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2,
2008                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2009     uint32_t eighth = 8;
2010     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 8, entities[8].entity_type,
2011                                           entities[8].entity_instance_num,
2012                                           entities[8].entity_container_id,
2013                                           &eighth),
2014               0);
2015     EXPECT_NE(l8, nullptr);
2016     EXPECT_EQ(entities[8].entity_instance_num, 100);
2017     EXPECT_EQ(eighth, pldm_pdr_get_record_handle(
2018                           repo, pldm_pdr_fru_record_set_find_by_rsi(
2019                                     repo, 8, &terminusHdl, &entityType,
2020                                     &entityInstanceNum, &containerId)));
2021     EXPECT_EQ(entityType, 3);
2022     EXPECT_EQ(entityInstanceNum, 100);
2023 
2024     pldm_pdr_destroy(repo);
2025     pldm_entity_association_tree_destroy(tree);
2026 }
2027 
2028 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testFindChildContainerID)2029 TEST(EntityAssociationPDR, testFindChildContainerID)
2030 {
2031     pldm_entity entities[3]{};
2032     entities[0].entity_type = 1;
2033     entities[1].entity_type = 2;
2034     entities[2].entity_type = 3;
2035     entities[1].entity_container_id = 2;
2036     entities[1].entity_instance_num = 1;
2037 
2038     auto tree = pldm_entity_association_tree_init();
2039     auto l1 = pldm_entity_association_tree_add_entity(
2040         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
2041         false, true, 0xffff);
2042 
2043     EXPECT_NE(l1, nullptr);
2044     auto l2 = pldm_entity_association_tree_add_entity(
2045         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2046         false, 0xffff);
2047     EXPECT_NE(l2, nullptr);
2048     auto l3 = pldm_entity_association_tree_add_entity(
2049         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2050         true, 0xffff);
2051     EXPECT_NE(l3, nullptr);
2052 
2053     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
2054               2);
2055 
2056     auto repo = pldm_pdr_init();
2057     int rc = pldm_entity_association_pdr_add(tree, repo, false, 1);
2058     ASSERT_EQ(rc, 0);
2059 
2060     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
2061 
2062     uint16_t container_id{};
2063     pldm_pdr_find_child_container_id_index_range_exclude(
2064         repo, 1, 1, 0, 0x01000000, 0x01ffffff, &container_id);
2065     EXPECT_EQ(container_id, 2);
2066 
2067     uint16_t container_id1{};
2068     pldm_pdr_find_child_container_id_index_range_exclude(
2069         repo, 1, 1, 0, 0x00000001, 0x00ffffff, &container_id1);
2070     EXPECT_EQ(container_id1, 0);
2071 
2072     pldm_pdr_destroy(repo);
2073     pldm_entity_association_tree_destroy(tree);
2074 }
2075 #endif
2076 
TEST(EntityAssociationPDR,testNodeAddCheck)2077 TEST(EntityAssociationPDR, testNodeAddCheck)
2078 {
2079     // pldm_entity entities[4]{};
2080     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 4);
2081     entities[0].entity_type = 1;
2082     entities[1].entity_type = 2;
2083     entities[2].entity_type = 2;
2084     entities[3].entity_type = 3;
2085 
2086     auto tree = pldm_entity_association_tree_init();
2087 
2088     auto l1 = pldm_entity_association_tree_add(
2089         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2090     EXPECT_NE(l1, nullptr);
2091     auto l2a = pldm_entity_association_tree_add(
2092         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2093     EXPECT_NE(l2a, nullptr);
2094     auto l2b = pldm_entity_association_tree_add(
2095         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2096     EXPECT_NE(l2b, nullptr);
2097     auto l2c = pldm_entity_association_tree_add(
2098         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2099     EXPECT_NE(l2c, nullptr);
2100 
2101     auto repo = pldm_pdr_init();
2102 
2103     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2104                   l1, repo, &entities, 4, false, 1, 0),
2105               0);
2106     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2107                   l1, repo, &entities, 4, false, 1, 2),
2108               0);
2109     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2110                   l1, repo, &entities, 4, false, 1, 23),
2111               0);
2112     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2113                   l1, repo, &entities, 4, false, 1, 34),
2114               0);
2115 
2116     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
2117 
2118     uint8_t* outData = nullptr;
2119     uint32_t size{};
2120     uint32_t nextRecHdl{};
2121     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
2122     EXPECT_NE(hdl, nullptr);
2123 
2124     outData = nullptr;
2125     auto hdl1 = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
2126     EXPECT_NE(hdl1, nullptr);
2127     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2128     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
2129     EXPECT_EQ(hdr->record_handle, 2);
2130 
2131     outData = nullptr;
2132     auto hdl2 = pldm_pdr_find_record(repo, 23, &outData, &size, &nextRecHdl);
2133     EXPECT_NE(hdl2, nullptr);
2134     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2135     pldm_pdr_hdr* hdr1 = reinterpret_cast<pldm_pdr_hdr*>(outData);
2136     EXPECT_EQ(hdr1->record_handle, 23);
2137 
2138     outData = nullptr;
2139     auto hdl3 = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
2140     EXPECT_EQ(hdl3, nullptr);
2141 
2142     free(entities);
2143     pldm_pdr_destroy(repo);
2144     pldm_entity_association_tree_destroy(tree);
2145 }
2146 
2147 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testAddContainedEntityRemotePDR)2148 TEST(EntityAssociationPDR, testAddContainedEntityRemotePDR)
2149 {
2150     // pldm_entity entities[5]{};
2151     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
2152     entities[0].entity_type = 1;
2153     entities[1].entity_type = 2;
2154     entities[2].entity_type = 3;
2155     entities[3].entity_type = 4;
2156     entities[4].entity_type = 5;
2157 
2158     auto tree = pldm_entity_association_tree_init();
2159     auto l1 = pldm_entity_association_tree_add(
2160         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2161     EXPECT_NE(l1, nullptr);
2162     auto l2a = pldm_entity_association_tree_add(
2163         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2164     EXPECT_NE(l2a, nullptr);
2165     auto l2b = pldm_entity_association_tree_add(
2166         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2167     EXPECT_NE(l2b, nullptr);
2168     auto l2c = pldm_entity_association_tree_add(
2169         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2170     EXPECT_NE(l2c, nullptr);
2171     auto l3a = pldm_entity_association_tree_add(
2172         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2173     EXPECT_NE(l3a, nullptr);
2174 
2175     auto repo = pldm_pdr_init();
2176 
2177     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2178                   l1, repo, &entities, 5, false, 1, 0),
2179               0);
2180     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2181                   l1, repo, &entities, 5, false, 1, 2),
2182               0);
2183     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2184                   l1, repo, &entities, 5, false, 1, 23),
2185               0);
2186     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2187                   l1, repo, &entities, 5, false, 1, 34),
2188               0);
2189     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2190                   l2a, repo, &entities, 5, false, 1, 3),
2191               0);
2192 
2193     pldm_entity entity1[1];
2194     entity1[0].entity_type = 2;
2195 
2196     EXPECT_EQ(pldm_entity_association_pdr_add_contained_entity_to_remote_pdr(
2197                   repo, &entity1[0], 2),
2198               0);
2199 
2200     free(entities);
2201     pldm_pdr_destroy(repo);
2202     pldm_entity_association_tree_destroy(tree);
2203 }
2204 #endif
2205 
2206 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testAddContainedEntityNew)2207 TEST(EntityAssociationPDR, testAddContainedEntityNew)
2208 {
2209     // pldm_entity entities[5]{};
2210     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
2211     entities[0].entity_type = 1;
2212     entities[1].entity_type = 2;
2213     entities[2].entity_type = 3;
2214     entities[3].entity_type = 4;
2215     entities[4].entity_type = 5;
2216 
2217     auto tree = pldm_entity_association_tree_init();
2218     auto l1 = pldm_entity_association_tree_add(
2219         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2220     EXPECT_NE(l1, nullptr);
2221     auto l2a = pldm_entity_association_tree_add(
2222         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2223     EXPECT_NE(l2a, nullptr);
2224     auto l2b = pldm_entity_association_tree_add(
2225         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2226     EXPECT_NE(l2b, nullptr);
2227     auto l2c = pldm_entity_association_tree_add(
2228         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2229     EXPECT_NE(l2c, nullptr);
2230     auto l3a = pldm_entity_association_tree_add(
2231         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
2232     EXPECT_NE(l3a, nullptr);
2233 
2234     auto repo = pldm_pdr_init();
2235 
2236     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2237                   l1, repo, &entities, 5, false, 1, 0),
2238               0);
2239     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2240                   l1, repo, &entities, 5, false, 1, 2),
2241               0);
2242     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2243                   l1, repo, &entities, 5, false, 1, 23),
2244               0);
2245     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2246                   l1, repo, &entities, 5, false, 1, 34),
2247               0);
2248     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2249                   l2a, repo, &entities, 5, false, 1, 3),
2250               0);
2251 
2252     uint32_t updated_record_handle = 0;
2253 
2254     pldm_entity entity2[1]{};
2255     entity2[0].entity_type = 4;
2256 
2257     pldm_entity entity3[1]{};
2258     entity3[0].entity_type = 4;
2259 
2260     EXPECT_EQ(pldm_entity_association_pdr_create_new(
2261                   repo, 34, &entity2[0], &entity3[0], &updated_record_handle),
2262               0);
2263 
2264     EXPECT_EQ(updated_record_handle, 35);
2265 
2266     free(entities);
2267     pldm_pdr_destroy(repo);
2268     pldm_entity_association_tree_destroy(tree);
2269 }
2270 #endif
2271 
2272 #ifdef LIBPLDM_API_TESTING
TEST(EntityAssociationPDR,testRemoveContainedEntity)2273 TEST(EntityAssociationPDR, testRemoveContainedEntity)
2274 {
2275     struct pldm_entity entities[4] = {
2276         {.entity_type = 1, .entity_instance_num = 1, .entity_container_id = 2},
2277         {.entity_type = 2, .entity_instance_num = 1, .entity_container_id = 2},
2278         {.entity_type = 3, .entity_instance_num = 3, .entity_container_id = 3},
2279         {.entity_type = 4, .entity_instance_num = 1, .entity_container_id = 2}};
2280     struct pldm_entity* base = entities;
2281 
2282     auto tree = pldm_entity_association_tree_init();
2283     auto l1 = pldm_entity_association_tree_add_entity(
2284         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
2285         false, true, 0xffff);
2286 
2287     EXPECT_NE(l1, nullptr);
2288     auto l2 = pldm_entity_association_tree_add_entity(
2289         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2290         false, 0xffff);
2291     EXPECT_NE(l2, nullptr);
2292     auto l3 = pldm_entity_association_tree_add_entity(
2293         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2294         true, 0xffff);
2295     EXPECT_NE(l3, nullptr);
2296     auto l4 = pldm_entity_association_tree_add_entity(
2297         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
2298         true, 0xffff);
2299     EXPECT_NE(l4, nullptr);
2300 
2301     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
2302               3);
2303 
2304     auto repo = pldm_pdr_init();
2305 
2306     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
2307                   l1, repo, &base, 4, false, 1, 3),
2308               0);
2309 
2310     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
2311 
2312     // Remove first contained entity from the entity association PDR
2313     uint32_t removed_record_handle{};
2314     struct pldm_entity entity[1] = {
2315         {.entity_type = 4, .entity_instance_num = 1, .entity_container_id = 2}};
2316 
2317     EXPECT_EQ(pldm_entity_association_pdr_remove_contained_entity(
2318                   repo, entity, false, &removed_record_handle),
2319               0);
2320     EXPECT_EQ(removed_record_handle, 3);
2321 
2322     // Remove second contained entity from the entity association PDR
2323     removed_record_handle = 0;
2324     EXPECT_EQ(pldm_entity_association_pdr_remove_contained_entity(
2325                   repo, &entities[1], false, &removed_record_handle),
2326               0);
2327     EXPECT_EQ(removed_record_handle, 3);
2328 
2329     // Remove third contained entity from the entity association PDR
2330     removed_record_handle = 0;
2331     EXPECT_EQ(pldm_entity_association_pdr_remove_contained_entity(
2332                   repo, &entities[2], false, &removed_record_handle),
2333               0);
2334     EXPECT_EQ(removed_record_handle, 3);
2335 
2336     // As all the contained entities are removed the entity association PDR
2337     // also gets deleted
2338     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
2339 
2340     pldm_pdr_destroy(repo);
2341     pldm_entity_association_tree_destroy(tree);
2342 }
2343 #endif
2344 
2345 #ifdef LIBPLDM_API_TESTING
TEST(PDRUpdate,testRemoveFruRecord)2346 TEST(PDRUpdate, testRemoveFruRecord)
2347 {
2348     auto repo = pldm_pdr_init();
2349 
2350     uint32_t record_handle = 1;
2351     int rc = pldm_pdr_add_fru_record_set(repo, 1, 1, 1, 0, 100, &record_handle);
2352     EXPECT_EQ(rc, 0);
2353     record_handle = 2;
2354     rc = pldm_pdr_add_fru_record_set(repo, 1, 2, 1, 1, 100, &record_handle);
2355     EXPECT_EQ(rc, 0);
2356     record_handle = 3;
2357     rc = pldm_pdr_add_fru_record_set(repo, 1, 3, 1, 2, 100, &record_handle);
2358     EXPECT_EQ(rc, 0);
2359     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3);
2360 
2361     uint32_t removed_record_handle{};
2362     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 2, false,
2363                                                &removed_record_handle);
2364     EXPECT_EQ(rc, 0);
2365     EXPECT_EQ(removed_record_handle, 2);
2366     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2);
2367 
2368     uint16_t terminusHdl{};
2369     uint16_t entityType{};
2370     uint16_t entityInstanceNum{};
2371     uint16_t containerId{};
2372     auto record = pldm_pdr_fru_record_set_find_by_rsi(
2373         repo, 1, &terminusHdl, &entityType, &entityInstanceNum, &containerId);
2374     EXPECT_NE(record, nullptr);
2375     record_handle = pldm_pdr_get_record_handle(repo, record);
2376     EXPECT_EQ(record_handle, 1);
2377 
2378     record = pldm_pdr_fru_record_set_find_by_rsi(
2379         repo, 3, &terminusHdl, &entityType, &entityInstanceNum, &containerId);
2380     EXPECT_NE(record, nullptr);
2381     record_handle = pldm_pdr_get_record_handle(repo, record);
2382     EXPECT_EQ(record_handle, 3);
2383 
2384     record = pldm_pdr_fru_record_set_find_by_rsi(
2385         repo, 2, &terminusHdl, &entityType, &entityInstanceNum, &containerId);
2386     EXPECT_EQ(record, nullptr);
2387 
2388     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 1, false,
2389                                                &removed_record_handle);
2390     EXPECT_EQ(rc, 0);
2391     EXPECT_EQ(removed_record_handle, 1);
2392 
2393     // remove the same record again
2394     removed_record_handle = 5;
2395     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 1, false,
2396                                                &removed_record_handle);
2397     EXPECT_EQ(rc, 0);
2398     EXPECT_NE(removed_record_handle, 1);
2399     EXPECT_EQ(removed_record_handle, 5);
2400 
2401     rc = pldm_pdr_remove_fru_record_set_by_rsi(repo, 3, false,
2402                                                &removed_record_handle);
2403     EXPECT_EQ(rc, 0);
2404     EXPECT_EQ(removed_record_handle, 3);
2405 
2406     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0);
2407 
2408     pldm_pdr_destroy(repo);
2409 }
2410 #endif
2411