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