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