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