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