xref: /openbmc/libpldm/tests/dsp/pdr.cpp (revision fae3641d)
1 #include <endian.h>
2 #include <libpldm/pdr.h>
3 #include <libpldm/platform.h>
4 
5 #include <array>
6 #include <cstdint>
7 #include <cstdlib>
8 #include <cstring>
9 #include <vector>
10 
11 #include <gtest/gtest.h>
12 
13 TEST(PDRAccess, testInit)
14 {
15     auto repo = pldm_pdr_init();
16     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
17     EXPECT_EQ(pldm_pdr_get_repo_size(repo), 0u);
18     pldm_pdr_destroy(repo);
19 }
20 
21 TEST(PDRUpdate, testAdd)
22 {
23     auto repo = pldm_pdr_init();
24 
25     std::array<uint8_t, 10> data{};
26     uint32_t handle = 0;
27     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
28               0);
29     EXPECT_EQ(handle, 1u);
30     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
31     EXPECT_EQ(pldm_pdr_get_repo_size(repo), data.size());
32 
33     handle = 0;
34     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
35               0);
36     EXPECT_EQ(handle, 2u);
37 
38     handle = 0;
39     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
40               0);
41     EXPECT_EQ(handle, 3u);
42 
43     handle = 0xdeeddeedu;
44     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
45               0);
46     EXPECT_EQ(handle, 0xdeeddeed);
47     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
48     EXPECT_EQ(pldm_pdr_get_repo_size(repo), data.size() * 4u);
49 
50     pldm_pdr_destroy(repo);
51 }
52 
53 TEST(PDRRemoveByTerminus, testRemoveByTerminus)
54 {
55     std::array<uint8_t, 10> data{};
56 
57     auto repo = pldm_pdr_init();
58 
59     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
60     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
61     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
62     pldm_pdr_destroy(repo);
63 
64     repo = pldm_pdr_init();
65     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 2, NULL), 0);
66     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
67     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
68     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
69     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
70     pldm_pdr_destroy(repo);
71 
72     repo = pldm_pdr_init();
73     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
74     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 2, NULL), 0);
75     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 2, NULL), 0);
76     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
77     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 2);
78     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
79     pldm_pdr_destroy(repo);
80 
81     repo = pldm_pdr_init();
82     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
83     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 2, NULL), 0);
84     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
85     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
86     pldm_pdr_remove_remote_pdrs(repo);
87     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
88     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 1);
89     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
90     pldm_pdr_remove_pdrs_by_terminus_handle(repo, 2);
91     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
92     pldm_pdr_destroy(repo);
93 }
94 
95 TEST(PDRUpdate, testRemove)
96 {
97     std::array<uint8_t, 10> data{};
98 
99     auto repo = pldm_pdr_init();
100     pldm_pdr_remove_remote_pdrs(repo);
101     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
102     pldm_pdr_destroy(repo);
103 
104     repo = pldm_pdr_init();
105     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
106     pldm_pdr_remove_remote_pdrs(repo);
107     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
108     pldm_pdr_destroy(repo);
109 
110     repo = pldm_pdr_init();
111     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
112     pldm_pdr_remove_remote_pdrs(repo);
113     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
114     pldm_pdr_destroy(repo);
115 
116     repo = pldm_pdr_init();
117     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
118     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
119     pldm_pdr_remove_remote_pdrs(repo);
120     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
121     pldm_pdr_destroy(repo);
122 
123     repo = pldm_pdr_init();
124     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
125     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
126     pldm_pdr_remove_remote_pdrs(repo);
127     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
128     pldm_pdr_destroy(repo);
129 
130     repo = pldm_pdr_init();
131     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
132     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
133     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
134     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
135     pldm_pdr_remove_remote_pdrs(repo);
136     EXPECT_EQ(pldm_pdr_get_record_count(repo), 0u);
137     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
138     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
139     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
140     pldm_pdr_destroy(repo);
141 
142     repo = pldm_pdr_init();
143     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
144     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
145     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
146     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
147     pldm_pdr_remove_remote_pdrs(repo);
148     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
149     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
150     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
151     EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
152     pldm_pdr_destroy(repo);
153 
154     repo = pldm_pdr_init();
155     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
156     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
157     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
158     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
159     pldm_pdr_remove_remote_pdrs(repo);
160     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
161     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
162     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
163     EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
164     pldm_pdr_destroy(repo);
165 
166     repo = pldm_pdr_init();
167     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
168     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
169     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
170     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
171     pldm_pdr_remove_remote_pdrs(repo);
172     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
173     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
174     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
175     EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
176     pldm_pdr_destroy(repo);
177 
178     repo = pldm_pdr_init();
179     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
180     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
181     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
182     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
183     pldm_pdr_remove_remote_pdrs(repo);
184     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
185     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
186     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
187     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
188     pldm_pdr_destroy(repo);
189 
190     repo = pldm_pdr_init();
191     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
192     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
193     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
194     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
195     pldm_pdr_remove_remote_pdrs(repo);
196     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
197     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
198     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
199     EXPECT_EQ(pldm_pdr_get_record_count(repo), 5u);
200     pldm_pdr_destroy(repo);
201 
202     repo = pldm_pdr_init();
203     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
204     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
205     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
206     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
207     pldm_pdr_remove_remote_pdrs(repo);
208     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
209     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
210     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
211     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
212     pldm_pdr_destroy(repo);
213 
214     repo = pldm_pdr_init();
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(), true, 1, NULL), 0);
217     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
218     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
219     pldm_pdr_remove_remote_pdrs(repo);
220     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
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(), true, 1, NULL), 0);
223     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
224     pldm_pdr_destroy(repo);
225 
226     repo = pldm_pdr_init();
227     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
228     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
229     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
230     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
231     pldm_pdr_remove_remote_pdrs(repo);
232     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
233     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
234     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
235     EXPECT_EQ(pldm_pdr_get_record_count(repo), 3u);
236     pldm_pdr_destroy(repo);
237 
238     repo = pldm_pdr_init();
239     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
240     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
241     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
242     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, NULL), 0);
243     pldm_pdr_remove_remote_pdrs(repo);
244     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
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(), true, 1, NULL), 0);
247     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
248     pldm_pdr_destroy(repo);
249 
250     repo = pldm_pdr_init();
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_add(repo, data.data(), data.size(), false, 1, NULL), 0);
254     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, NULL), 0);
255     pldm_pdr_remove_remote_pdrs(repo);
256     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
257     uint32_t handle = 0;
258     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle),
259               0);
260     EXPECT_EQ(handle, 3u);
261     handle = 0;
262     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle),
263               0);
264     EXPECT_EQ(handle, 4u);
265     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
266     pldm_pdr_destroy(repo);
267 }
268 
269 TEST(PDRAccess, testGet)
270 {
271     auto repo = pldm_pdr_init();
272 
273     std::array<uint32_t, 10> in{100, 345, 3, 6, 89, 0, 11, 45, 23434, 123123};
274     uint32_t handle = 1;
275     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in.data()),
276                            sizeof(in), false, 1, &handle),
277               0);
278     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
279     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in));
280     uint32_t size{};
281     uint32_t nextRecHdl{};
282     uint8_t* outData = nullptr;
283     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
284     EXPECT_NE(hdl, nullptr);
285     EXPECT_EQ(size, sizeof(in));
286     EXPECT_EQ(nextRecHdl, 0u);
287     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
288     outData = nullptr;
289 
290     auto hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
291     EXPECT_EQ(hdl, hdl2);
292     EXPECT_NE(hdl, nullptr);
293     EXPECT_EQ(size, sizeof(in));
294     EXPECT_EQ(nextRecHdl, 0u);
295     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
296     outData = nullptr;
297 
298     hdl = pldm_pdr_find_record(repo, htole32(0xdeaddead), &outData, &size,
299                                &nextRecHdl);
300     EXPECT_EQ(hdl, nullptr);
301     EXPECT_EQ(size, 0u);
302     EXPECT_EQ(nextRecHdl, 0u);
303     EXPECT_EQ(outData, nullptr);
304     outData = nullptr;
305 
306     std::array<uint32_t, 10> in2{1000, 3450, 30,  60,     890,
307                                  0,    110,  450, 234034, 123123};
308     handle = 2;
309     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
310                            sizeof(in2), false, 1, &handle),
311               0);
312     handle = 3;
313     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
314                            sizeof(in2), false, 1, &handle),
315               0);
316     handle = 4;
317     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
318                            sizeof(in2), true, 1, &handle),
319               0);
320     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
321     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4);
322     hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
323     EXPECT_NE(hdl, nullptr);
324     EXPECT_EQ(size, sizeof(in));
325     EXPECT_EQ(nextRecHdl, 2u);
326     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
327     outData = nullptr;
328     hdl2 = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
329     EXPECT_EQ(hdl, hdl2);
330     EXPECT_NE(hdl, nullptr);
331     EXPECT_EQ(size, sizeof(in));
332     EXPECT_EQ(nextRecHdl, 2u);
333     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
334     outData = nullptr;
335     hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
336     EXPECT_NE(hdl, nullptr);
337     EXPECT_EQ(size, sizeof(in2));
338     EXPECT_EQ(nextRecHdl, 3u);
339     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
340     outData = nullptr;
341     hdl = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
342     EXPECT_NE(hdl, nullptr);
343     EXPECT_EQ(pldm_pdr_record_is_remote(hdl), false);
344     EXPECT_EQ(size, sizeof(in2));
345     EXPECT_EQ(nextRecHdl, 4u);
346     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
347     outData = nullptr;
348     hdl = pldm_pdr_find_record(repo, 4, &outData, &size, &nextRecHdl);
349     EXPECT_NE(hdl, nullptr);
350     EXPECT_EQ(pldm_pdr_record_is_remote(hdl), true);
351     EXPECT_EQ(size, sizeof(in2));
352     EXPECT_EQ(nextRecHdl, 0u);
353     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
354     outData = nullptr;
355 
356     pldm_pdr_destroy(repo);
357 }
358 
359 TEST(PDRAccess, testGetNext)
360 {
361     auto repo = pldm_pdr_init();
362 
363     std::array<uint32_t, 10> in{100, 345, 3, 6, 89, 0, 11, 45, 23434, 123123};
364     uint32_t handle = 1;
365     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in.data()),
366                            sizeof(in), false, 1, &handle),
367               0);
368     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
369     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in));
370     uint32_t size{};
371     uint32_t nextRecHdl{};
372     uint8_t* outData = nullptr;
373     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
374     EXPECT_NE(hdl, nullptr);
375     EXPECT_EQ(size, sizeof(in));
376     EXPECT_EQ(nextRecHdl, 0u);
377     EXPECT_EQ(memcmp(outData, in.data(), sizeof(in)), 0);
378     outData = nullptr;
379 
380     std::array<uint32_t, 10> in2{1000, 3450, 30,  60,     890,
381                                  0,    110,  450, 234034, 123123};
382     handle = 2;
383     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
384                            sizeof(in2), false, 1, &handle),
385               0);
386     handle = 3;
387     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
388                            sizeof(in2), false, 1, &handle),
389               0);
390     handle = 4;
391     EXPECT_EQ(pldm_pdr_add(repo, reinterpret_cast<uint8_t*>(in2.data()),
392                            sizeof(in2), false, 1, &handle),
393               0);
394     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
395     EXPECT_EQ(pldm_pdr_get_repo_size(repo), sizeof(in2) * 4);
396     hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
397     EXPECT_NE(hdl, nullptr);
398     EXPECT_EQ(size, sizeof(in2));
399     EXPECT_EQ(nextRecHdl, 3u);
400     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
401     outData = nullptr;
402     hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
403     EXPECT_NE(hdl, nullptr);
404     EXPECT_EQ(size, sizeof(in2));
405     EXPECT_EQ(nextRecHdl, 4u);
406     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
407     outData = nullptr;
408     hdl = pldm_pdr_get_next_record(repo, hdl, &outData, &size, &nextRecHdl);
409     EXPECT_NE(hdl, nullptr);
410     EXPECT_EQ(size, sizeof(in2));
411     EXPECT_EQ(nextRecHdl, 0u);
412     EXPECT_EQ(memcmp(outData, in2.data(), sizeof(in2)), 0);
413     outData = nullptr;
414 
415     pldm_pdr_destroy(repo);
416 }
417 
418 TEST(PDRAccess, testFindByType)
419 {
420     auto repo = pldm_pdr_init();
421 
422     std::array<uint8_t, sizeof(pldm_pdr_hdr)> data{};
423     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(data.data());
424     hdr->type = 1;
425     uint32_t first = 0;
426     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &first),
427               0);
428     hdr->type = 2;
429     uint32_t second = 0;
430     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &second),
431               0);
432     hdr->type = 3;
433     uint32_t third = 0;
434     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &third),
435               0);
436     hdr->type = 4;
437     uint32_t fourth = 0;
438     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &fourth),
439               0);
440 
441     uint8_t* outData = nullptr;
442     uint32_t size{};
443     auto firstRec =
444         pldm_pdr_find_record_by_type(repo, 1, nullptr, &outData, &size);
445     EXPECT_EQ(pldm_pdr_get_record_handle(repo, firstRec), first);
446     outData = nullptr;
447     auto secondRec =
448         pldm_pdr_find_record_by_type(repo, 2, nullptr, &outData, &size);
449     EXPECT_EQ(pldm_pdr_get_record_handle(repo, secondRec), second);
450     outData = nullptr;
451     auto thirdRec =
452         pldm_pdr_find_record_by_type(repo, 3, nullptr, &outData, &size);
453     EXPECT_EQ(pldm_pdr_get_record_handle(repo, thirdRec), third);
454     outData = nullptr;
455     auto fourthRec =
456         pldm_pdr_find_record_by_type(repo, 4, nullptr, &outData, &size);
457     EXPECT_EQ(pldm_pdr_get_record_handle(repo, fourthRec), fourth);
458     outData = nullptr;
459     auto fifthRec =
460         pldm_pdr_find_record_by_type(repo, 5, nullptr, &outData, &size);
461     EXPECT_EQ(fifthRec, nullptr);
462     EXPECT_EQ(outData, nullptr);
463     EXPECT_EQ(size, 0u);
464 
465     auto rec =
466         pldm_pdr_find_record_by_type(repo, 3, secondRec, &outData, &size);
467     EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), third);
468     outData = nullptr;
469     rec = pldm_pdr_find_record_by_type(repo, 4, secondRec, &outData, &size);
470     EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), fourth);
471     outData = nullptr;
472     rec = pldm_pdr_find_record_by_type(repo, 2, firstRec, &outData, &size);
473     EXPECT_EQ(pldm_pdr_get_record_handle(repo, rec), second);
474     outData = nullptr;
475 
476     pldm_pdr_destroy(repo);
477 }
478 
479 TEST(PDRUpdate, testAddFruRecordSet)
480 {
481     auto repo = pldm_pdr_init();
482 
483     uint32_t handle = 0;
484     EXPECT_EQ(
485         pldm_pdr_add_fru_record_set_check(repo, 1, 10, 1, 0, 100, &handle), 0);
486     EXPECT_EQ(handle, 1u);
487     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
488     EXPECT_EQ(pldm_pdr_get_repo_size(repo),
489               sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
490     uint32_t size{};
491     uint32_t nextRecHdl{};
492     uint8_t* outData = nullptr;
493     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
494     EXPECT_NE(hdl, nullptr);
495     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
496     EXPECT_EQ(nextRecHdl, 0u);
497     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
498     EXPECT_EQ(hdr->version, 1u);
499     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
500     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
501     EXPECT_EQ(hdr->record_handle, htole32(1));
502     pldm_pdr_fru_record_set* fru = reinterpret_cast<pldm_pdr_fru_record_set*>(
503         outData + sizeof(pldm_pdr_hdr));
504     EXPECT_EQ(fru->terminus_handle, htole16(1));
505     EXPECT_EQ(fru->fru_rsi, htole16(10));
506     EXPECT_EQ(fru->entity_type, htole16(1));
507     EXPECT_EQ(fru->entity_instance_num, htole16(0));
508     EXPECT_EQ(fru->container_id, htole16(100));
509     outData = nullptr;
510 
511     handle = 0;
512     EXPECT_EQ(
513         pldm_pdr_add_fru_record_set_check(repo, 2, 11, 2, 1, 101, &handle), 0);
514     EXPECT_EQ(handle, 2u);
515     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
516     EXPECT_EQ(pldm_pdr_get_repo_size(repo),
517               2 * (sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set)));
518     hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
519     EXPECT_NE(hdl, nullptr);
520     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
521     EXPECT_EQ(nextRecHdl, 0u);
522     hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
523     EXPECT_EQ(hdr->version, 1u);
524     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
525     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
526     EXPECT_EQ(hdr->record_handle, htole32(2));
527     fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
528                                                      sizeof(pldm_pdr_hdr));
529     EXPECT_EQ(fru->terminus_handle, htole16(2));
530     EXPECT_EQ(fru->fru_rsi, htole16(11));
531     EXPECT_EQ(fru->entity_type, htole16(2));
532     EXPECT_EQ(fru->entity_instance_num, htole16(1));
533     EXPECT_EQ(fru->container_id, htole16(101));
534     outData = nullptr;
535 
536     hdl = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
537     EXPECT_NE(hdl, nullptr);
538     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
539     EXPECT_EQ(nextRecHdl, 2u);
540     hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
541     EXPECT_EQ(hdr->version, 1u);
542     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
543     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
544     EXPECT_EQ(hdr->record_handle, htole32(1));
545     fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
546                                                      sizeof(pldm_pdr_hdr));
547     EXPECT_EQ(fru->terminus_handle, htole16(1));
548     EXPECT_EQ(fru->fru_rsi, htole16(10));
549     EXPECT_EQ(fru->entity_type, htole16(1));
550     EXPECT_EQ(fru->entity_instance_num, htole16(0));
551     EXPECT_EQ(fru->container_id, htole16(100));
552     outData = nullptr;
553 
554     pldm_pdr_destroy(repo);
555 }
556 
557 TEST(PDRUpdate, tesFindtFruRecordSet)
558 {
559     auto repo = pldm_pdr_init();
560 
561     uint16_t terminusHdl{};
562     uint16_t entityType{};
563     uint16_t entityInstanceNum{};
564     uint16_t containerId{};
565     uint32_t first = 1;
566     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(repo, 1, 1, 1, 0, 100, &first),
567               0);
568     uint32_t second = 2;
569     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(repo, 1, 2, 1, 1, 100, &second),
570               0);
571     uint32_t third = 3;
572     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(repo, 1, 3, 1, 2, 100, &third),
573               0);
574     EXPECT_EQ(first, pldm_pdr_get_record_handle(
575                          repo, pldm_pdr_fru_record_set_find_by_rsi(
576                                    repo, 1, &terminusHdl, &entityType,
577                                    &entityInstanceNum, &containerId)));
578     EXPECT_EQ(second, pldm_pdr_get_record_handle(
579                           repo, pldm_pdr_fru_record_set_find_by_rsi(
580                                     repo, 2, &terminusHdl, &entityType,
581                                     &entityInstanceNum, &containerId)));
582     EXPECT_EQ(third, pldm_pdr_get_record_handle(
583                          repo, pldm_pdr_fru_record_set_find_by_rsi(
584                                    repo, 3, &terminusHdl, &entityType,
585                                    &entityInstanceNum, &containerId)));
586     EXPECT_EQ(terminusHdl, 1u);
587     EXPECT_EQ(entityType, 1u);
588     EXPECT_EQ(entityInstanceNum, 2u);
589     EXPECT_EQ(containerId, 100u);
590     EXPECT_EQ(nullptr, pldm_pdr_fru_record_set_find_by_rsi(
591                            repo, 4, &terminusHdl, &entityType,
592                            &entityInstanceNum, &containerId));
593 
594     pldm_pdr_destroy(repo);
595 }
596 
597 #ifdef LIBPLDM_API_TESTING
598 TEST(PDRUpdate, testFindLastInRange)
599 {
600     auto repo = pldm_pdr_init();
601 
602     std::array<uint8_t, 10> data{};
603     uint32_t handle1 = 0;
604     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle1),
605               0);
606     uint32_t handle2 = 23;
607     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle2),
608               0);
609     uint32_t handle3 = 77;
610     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle3),
611               0);
612     uint32_t handle4 = 16777325;
613     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle4),
614               0);
615     uint32_t handle5 = 16777344;
616     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle5),
617               0);
618 
619     auto rec1 = pldm_pdr_find_last_in_range(repo, 0, 100);
620     auto rec2 = pldm_pdr_find_last_in_range(repo, 16777300, 33554431);
621     EXPECT_NE(rec1, nullptr);
622     EXPECT_NE(rec2, nullptr);
623     EXPECT_NE(handle1, pldm_pdr_get_record_handle(repo, rec1));
624     EXPECT_NE(handle2, pldm_pdr_get_record_handle(repo, rec1));
625     EXPECT_EQ(handle3, pldm_pdr_get_record_handle(repo, rec1));
626     EXPECT_NE(handle4, pldm_pdr_get_record_handle(repo, rec2));
627     EXPECT_EQ(handle5, pldm_pdr_get_record_handle(repo, rec2));
628 
629     pldm_pdr_destroy(repo);
630 }
631 #endif
632 
633 #ifdef LIBPLDM_API_TESTING
634 TEST(PDRAccess, testGetTerminusHandle)
635 {
636 
637     auto repo = pldm_pdr_init();
638 
639     pldm_pdr_hdr hdr;
640 
641     hdr.type = 1;
642     uint16_t firstTerminusHandle = 1;
643     EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<const uint8_t*>(&hdr),
644                                  sizeof(hdr), false, firstTerminusHandle, NULL),
645               0);
646 
647     hdr.type = 2;
648     uint16_t secondTerminusHandle = 2;
649     EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<const uint8_t*>(&hdr),
650                                  sizeof(hdr), true, secondTerminusHandle, NULL),
651               0);
652 
653     hdr.type = 3;
654     uint16_t thirdTerminusHandle = 3;
655     EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<const uint8_t*>(&hdr),
656                                  sizeof(hdr), true, thirdTerminusHandle, NULL),
657               0);
658 
659     uint8_t* outData = nullptr;
660     uint32_t size{};
661 
662     auto firstRec =
663         pldm_pdr_find_record_by_type(repo, 1, nullptr, &outData, &size);
664     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, firstRec),
665               firstTerminusHandle);
666     outData = nullptr;
667 
668     auto secondRec =
669         pldm_pdr_find_record_by_type(repo, 2, nullptr, &outData, &size);
670     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, secondRec),
671               secondTerminusHandle);
672     outData = nullptr;
673 
674     auto thirdRec =
675         pldm_pdr_find_record_by_type(repo, 3, nullptr, &outData, &size);
676     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, thirdRec),
677               thirdTerminusHandle);
678     outData = nullptr;
679 
680     pldm_pdr_destroy(repo);
681 }
682 #endif
683 
684 TEST(EntityAssociationPDR, testInit)
685 {
686     auto tree = pldm_entity_association_tree_init();
687     EXPECT_NE(tree, nullptr);
688     pldm_entity_association_tree_destroy(tree);
689 }
690 
691 TEST(EntityAssociationPDR, testBuild)
692 {
693     //        1
694     //        |
695     //        2--3--4
696     //        |
697     //        5--6--7
698     //        |  |
699     //        9  8
700 
701     pldm_entity entities[9]{};
702 
703     entities[0].entity_type = 1;
704     entities[1].entity_type = 2;
705     entities[2].entity_type = 2;
706     entities[3].entity_type = 3;
707     entities[4].entity_type = 4;
708     entities[5].entity_type = 5;
709     entities[6].entity_type = 5;
710     entities[7].entity_type = 6;
711     entities[8].entity_type = 7;
712 
713     auto tree = pldm_entity_association_tree_init();
714 
715     auto l1 = pldm_entity_association_tree_add(
716         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
717     EXPECT_NE(l1, nullptr);
718     auto l2a = pldm_entity_association_tree_add(
719         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
720     EXPECT_NE(l2a, nullptr);
721     auto l2b = pldm_entity_association_tree_add(
722         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
723     EXPECT_NE(l2b, nullptr);
724     auto l2c = pldm_entity_association_tree_add(
725         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
726     EXPECT_NE(l2c, nullptr);
727     auto l3a = pldm_entity_association_tree_add(
728         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
729     EXPECT_NE(l3a, nullptr);
730     auto l3b = pldm_entity_association_tree_add(
731         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
732     EXPECT_NE(l3b, nullptr);
733     auto l3c = pldm_entity_association_tree_add(
734         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
735     EXPECT_NE(l3b, nullptr);
736     auto l4a = pldm_entity_association_tree_add(
737         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
738     EXPECT_NE(l4a, nullptr);
739     auto l4b = pldm_entity_association_tree_add(
740         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
741     EXPECT_NE(l4b, nullptr);
742 
743     EXPECT_EQ(pldm_entity_is_node_parent(l1), true);
744     EXPECT_EQ(pldm_entity_is_node_parent(l2a), true);
745     EXPECT_EQ(pldm_entity_is_node_parent(l3a), true);
746     EXPECT_EQ(pldm_entity_is_node_parent(l3b), true);
747 
748     EXPECT_EQ(pldm_entity_is_node_parent(l2b), false);
749     EXPECT_EQ(pldm_entity_is_node_parent(l2c), false);
750     EXPECT_EQ(pldm_entity_is_node_parent(l3c), false);
751     EXPECT_EQ(pldm_entity_is_node_parent(l4a), false);
752     EXPECT_EQ(pldm_entity_is_node_parent(l4b), false);
753 
754     EXPECT_EQ(pldm_entity_is_exist_parent(l1), false);
755 
756     pldm_entity nodeL1 = pldm_entity_extract(l1);
757     pldm_entity parentL2a = pldm_entity_get_parent(l2a);
758     pldm_entity parentL2b = pldm_entity_get_parent(l2b);
759     pldm_entity parentL2c = pldm_entity_get_parent(l2c);
760     EXPECT_EQ(pldm_entity_is_exist_parent(l2a), true);
761     EXPECT_EQ(pldm_entity_is_exist_parent(l2b), true);
762     EXPECT_EQ(pldm_entity_is_exist_parent(l2c), true);
763     EXPECT_EQ(parentL2a.entity_type, nodeL1.entity_type);
764     EXPECT_EQ(parentL2a.entity_instance_num, nodeL1.entity_instance_num);
765     EXPECT_EQ(parentL2a.entity_container_id, nodeL1.entity_container_id);
766     EXPECT_EQ(parentL2b.entity_type, nodeL1.entity_type);
767     EXPECT_EQ(parentL2b.entity_instance_num, nodeL1.entity_instance_num);
768     EXPECT_EQ(parentL2b.entity_container_id, nodeL1.entity_container_id);
769     EXPECT_EQ(parentL2c.entity_type, nodeL1.entity_type);
770     EXPECT_EQ(parentL2c.entity_instance_num, nodeL1.entity_instance_num);
771     EXPECT_EQ(parentL2c.entity_container_id, nodeL1.entity_container_id);
772 
773     pldm_entity nodeL2a = pldm_entity_extract(l2a);
774     pldm_entity parentL3a = pldm_entity_get_parent(l3a);
775     pldm_entity parentL3b = pldm_entity_get_parent(l3b);
776     pldm_entity parentL3c = pldm_entity_get_parent(l3c);
777     EXPECT_EQ(pldm_entity_is_exist_parent(l3a), true);
778     EXPECT_EQ(pldm_entity_is_exist_parent(l3b), true);
779     EXPECT_EQ(pldm_entity_is_exist_parent(l3c), true);
780     EXPECT_EQ(parentL3a.entity_type, nodeL2a.entity_type);
781     EXPECT_EQ(parentL3a.entity_instance_num, nodeL2a.entity_instance_num);
782     EXPECT_EQ(parentL3a.entity_container_id, nodeL2a.entity_container_id);
783     EXPECT_EQ(parentL3b.entity_type, nodeL2a.entity_type);
784     EXPECT_EQ(parentL3b.entity_instance_num, nodeL2a.entity_instance_num);
785     EXPECT_EQ(parentL3b.entity_container_id, nodeL2a.entity_container_id);
786     EXPECT_EQ(parentL3c.entity_type, nodeL2a.entity_type);
787     EXPECT_EQ(parentL3c.entity_instance_num, nodeL2a.entity_instance_num);
788     EXPECT_EQ(parentL3c.entity_container_id, nodeL2a.entity_container_id);
789 
790     pldm_entity nodeL3a = pldm_entity_extract(l3a);
791     pldm_entity parentL4a = pldm_entity_get_parent(l4a);
792     EXPECT_EQ(pldm_entity_is_exist_parent(l4a), true);
793     EXPECT_EQ(parentL4a.entity_type, nodeL3a.entity_type);
794     EXPECT_EQ(parentL4a.entity_instance_num, nodeL3a.entity_instance_num);
795     EXPECT_EQ(parentL4a.entity_container_id, nodeL3a.entity_container_id);
796 
797     pldm_entity nodeL3b = pldm_entity_extract(l3b);
798     pldm_entity parentL4b = pldm_entity_get_parent(l4b);
799     EXPECT_EQ(pldm_entity_is_exist_parent(l4b), true);
800     EXPECT_EQ(parentL4b.entity_type, nodeL3b.entity_type);
801     EXPECT_EQ(parentL4b.entity_instance_num, nodeL3b.entity_instance_num);
802     EXPECT_EQ(parentL4b.entity_container_id, nodeL3b.entity_container_id);
803 
804     size_t num{};
805     pldm_entity* out = nullptr;
806     pldm_entity_association_tree_visit(tree, &out, &num);
807     EXPECT_EQ(num, 9u);
808 
809     EXPECT_EQ(out[0].entity_type, 1u);
810     EXPECT_EQ(out[0].entity_instance_num, 1u);
811     EXPECT_EQ(out[0].entity_container_id, 0u);
812 
813     EXPECT_EQ(out[1].entity_type, 2u);
814     EXPECT_EQ(out[1].entity_instance_num, 1u);
815     EXPECT_EQ(out[1].entity_container_id, 1u);
816     EXPECT_EQ(out[2].entity_type, 2u);
817     EXPECT_EQ(out[2].entity_instance_num, 2u);
818     EXPECT_EQ(out[2].entity_container_id, 1u);
819     EXPECT_EQ(out[3].entity_type, 3u);
820     EXPECT_EQ(out[3].entity_instance_num, 1u);
821     EXPECT_EQ(out[3].entity_container_id, 1u);
822 
823     EXPECT_EQ(out[4].entity_type, 4u);
824     EXPECT_EQ(out[4].entity_instance_num, 1u);
825     EXPECT_EQ(out[4].entity_container_id, 2u);
826     EXPECT_EQ(out[5].entity_type, 5u);
827     EXPECT_EQ(out[5].entity_instance_num, 1u);
828     EXPECT_EQ(out[5].entity_container_id, 2u);
829     EXPECT_EQ(out[6].entity_type, 5u);
830     EXPECT_EQ(out[6].entity_instance_num, 2u);
831     EXPECT_EQ(out[6].entity_container_id, 2u);
832 
833     EXPECT_EQ(out[7].entity_type, 7u);
834     EXPECT_EQ(out[7].entity_instance_num, 1u);
835     EXPECT_EQ(out[7].entity_container_id, 4u);
836     EXPECT_EQ(out[8].entity_type, 6u);
837     EXPECT_EQ(out[8].entity_instance_num, 1u);
838     EXPECT_EQ(out[8].entity_container_id, 3u);
839 
840     free(out);
841 
842     pldm_entity p1 = pldm_entity_extract(l1);
843     EXPECT_EQ(p1.entity_type, 1u);
844     EXPECT_EQ(p1.entity_instance_num, 1u);
845     EXPECT_EQ(p1.entity_container_id, 0u);
846 
847     pldm_entity p2a = pldm_entity_extract(l2a);
848     EXPECT_EQ(p2a.entity_type, 2u);
849     EXPECT_EQ(p2a.entity_instance_num, 1u);
850     EXPECT_EQ(p2a.entity_container_id, 1u);
851     pldm_entity p2b = pldm_entity_extract(l2b);
852     EXPECT_EQ(p2b.entity_type, 2u);
853     EXPECT_EQ(p2b.entity_instance_num, 2u);
854     EXPECT_EQ(p2b.entity_container_id, 1u);
855     pldm_entity p2c = pldm_entity_extract(l2c);
856     EXPECT_EQ(p2c.entity_type, 3u);
857     EXPECT_EQ(p2c.entity_instance_num, 1u);
858     EXPECT_EQ(p2c.entity_container_id, 1u);
859 
860     pldm_entity p3a = pldm_entity_extract(l3a);
861     EXPECT_EQ(p3a.entity_type, 4u);
862     EXPECT_EQ(p3a.entity_instance_num, 1u);
863     EXPECT_EQ(p3a.entity_container_id, 2u);
864     pldm_entity p3b = pldm_entity_extract(l3b);
865     EXPECT_EQ(p3b.entity_type, 5u);
866     EXPECT_EQ(p3b.entity_instance_num, 1u);
867     EXPECT_EQ(p3b.entity_container_id, 2u);
868     pldm_entity p3c = pldm_entity_extract(l3c);
869     EXPECT_EQ(p3c.entity_type, 5u);
870     EXPECT_EQ(p3c.entity_instance_num, 2u);
871     EXPECT_EQ(p3c.entity_container_id, 2u);
872 
873     pldm_entity p4a = pldm_entity_extract(l4a);
874     EXPECT_EQ(p4a.entity_type, 6u);
875     EXPECT_EQ(p4a.entity_instance_num, 1u);
876     EXPECT_EQ(p4a.entity_container_id, 3u);
877     pldm_entity p4b = pldm_entity_extract(l4b);
878     EXPECT_EQ(p4b.entity_type, 7u);
879     EXPECT_EQ(p4b.entity_instance_num, 1u);
880     EXPECT_EQ(p4b.entity_container_id, 4u);
881 
882     pldm_entity_association_tree_destroy(tree);
883 }
884 
885 #if LIBPLDM_API_TESTING
886 TEST(EntityAssociationPDR, findAndAddRemotePDR)
887 {
888     //         Tree - 1
889     //
890     //        11521(1,0)
891     //             |
892     //          45 (1,1)
893     //             |
894     //          64 (1,2)
895     //             |
896     //    ------------------
897     //    |                 |
898     //  67(0,3)           67(1,3)
899     //    |                 |
900     // 135(0,4)          135(0,5)
901     //    |                 |
902     // 32903(0,6)         32903(0,7)
903 
904     pldm_entity entities[9]{};
905     entities[0].entity_type = 11521;
906     entities[1].entity_type = 45;
907     entities[2].entity_type = 64;
908     entities[3].entity_type = 67;
909     entities[4].entity_type = 67;
910     entities[5].entity_type = 135;
911     entities[5].entity_container_id = 2;
912     entities[6].entity_type = 135;
913     entities[6].entity_container_id = 3;
914     entities[7].entity_type = 32903;
915     entities[8].entity_type = 32903;
916     auto tree = pldm_entity_association_tree_init();
917     auto l1 = pldm_entity_association_tree_add_entity(
918         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
919         false, true, 0xffff);
920     EXPECT_NE(l1, nullptr);
921     auto l2 = pldm_entity_association_tree_add_entity(
922         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
923         false, 0xffff);
924     EXPECT_NE(l2, nullptr);
925     auto l3 = pldm_entity_association_tree_add_entity(
926         tree, &entities[2], 0xffff, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
927         true, 0xffff);
928     EXPECT_NE(l3, nullptr);
929     auto l4a = pldm_entity_association_tree_add_entity(
930         tree, &entities[3], 0, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
931         false, 0xffff);
932     EXPECT_NE(l4a, nullptr);
933     auto l4b = pldm_entity_association_tree_add_entity(
934         tree, &entities[4], 1, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
935         0xffff);
936     EXPECT_NE(l4b, nullptr);
937     auto l5a = pldm_entity_association_tree_add_entity(
938         tree, &entities[5], 0, l4a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
939         false, 0xffff);
940     EXPECT_NE(l5a, nullptr);
941     auto l5b = pldm_entity_association_tree_add_entity(
942         tree, &entities[6], 0, l4b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
943         false, 0xffff);
944     EXPECT_NE(l5b, nullptr);
945     pldm_entity entity{};
946     entity.entity_type = 135;
947     entity.entity_instance_num = 0;
948     entity.entity_container_id = 2;
949     auto result1 = pldm_entity_association_tree_find(tree, &entity);
950     EXPECT_EQ(result1, l5a);
951     EXPECT_EQ(entities[5].entity_container_id, 2);
952     auto l6a = pldm_entity_association_tree_add_entity(
953         tree, &entities[7], 0, result1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
954         false, 0xffff);
955     EXPECT_NE(l6a, nullptr);
956     entity.entity_type = 135;
957     entity.entity_instance_num = 0;
958     entity.entity_container_id = 3;
959     auto result2 = pldm_entity_association_tree_find(tree, &entity);
960     EXPECT_NE(result2, l5b);
961     EXPECT_EQ(entities[6].entity_container_id, 3);
962     auto l7a = pldm_entity_association_tree_add_entity(
963         tree, &entities[8], 0, result2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
964         false, 0xffff);
965     EXPECT_EQ(l7a, nullptr);
966     pldm_entity_association_tree_destroy(tree);
967 }
968 #endif
969 
970 TEST(EntityAssociationPDR, testSpecialTrees)
971 {
972     pldm_entity entities[3]{};
973 
974     entities[0].entity_type = 1;
975     entities[1].entity_type = 2;
976     entities[2].entity_type = 1;
977 
978     // A
979     auto tree = pldm_entity_association_tree_init();
980     auto node = pldm_entity_association_tree_add(
981         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
982     EXPECT_NE(node, nullptr);
983     size_t num{};
984     pldm_entity* out = nullptr;
985     pldm_entity_association_tree_visit(tree, &out, &num);
986     EXPECT_EQ(num, 1u);
987     EXPECT_EQ(out[0].entity_type, 1u);
988     EXPECT_EQ(out[0].entity_instance_num, 1u);
989     EXPECT_EQ(out[0].entity_container_id, 0u);
990     free(out);
991     pldm_entity_association_tree_destroy(tree);
992 
993     // A-A-A
994     tree = pldm_entity_association_tree_init();
995     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
996                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
997     EXPECT_NE(node, nullptr);
998     node = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, nullptr,
999                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1000     EXPECT_NE(node, nullptr);
1001     node = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, nullptr,
1002                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1003     EXPECT_NE(node, nullptr);
1004     pldm_entity_association_tree_visit(tree, &out, &num);
1005     EXPECT_EQ(num, 3u);
1006     EXPECT_EQ(out[0].entity_type, 1u);
1007     EXPECT_EQ(out[0].entity_instance_num, 1u);
1008     EXPECT_EQ(out[0].entity_container_id, 0u);
1009     EXPECT_EQ(out[1].entity_type, 1u);
1010     EXPECT_EQ(out[1].entity_instance_num, 2u);
1011     EXPECT_EQ(out[1].entity_container_id, 0u);
1012     EXPECT_EQ(out[2].entity_type, 2u);
1013     EXPECT_EQ(out[2].entity_instance_num, 1u);
1014     EXPECT_EQ(out[2].entity_container_id, 0u);
1015     free(out);
1016     pldm_entity_association_tree_destroy(tree);
1017 
1018     // A
1019     // |
1020     // A
1021     // |
1022     // A
1023     tree = pldm_entity_association_tree_init();
1024     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1025                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1026     EXPECT_NE(node, nullptr);
1027     auto node1 = pldm_entity_association_tree_add(
1028         tree, &entities[1], 0xffff, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1029     EXPECT_NE(node1, nullptr);
1030     auto node2 = pldm_entity_association_tree_add(
1031         tree, &entities[2], 0xffff, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1032     EXPECT_NE(node2, nullptr);
1033     pldm_entity_association_tree_visit(tree, &out, &num);
1034     EXPECT_EQ(num, 3u);
1035     EXPECT_EQ(out[0].entity_type, 1u);
1036     EXPECT_EQ(out[0].entity_instance_num, 1u);
1037     EXPECT_EQ(out[0].entity_container_id, 0u);
1038     EXPECT_EQ(out[1].entity_type, 2u);
1039     EXPECT_EQ(out[1].entity_instance_num, 1u);
1040     EXPECT_EQ(out[1].entity_container_id, 1u);
1041     EXPECT_EQ(out[2].entity_type, 1u);
1042     EXPECT_EQ(out[2].entity_instance_num, 1u);
1043     EXPECT_EQ(out[2].entity_container_id, 2u);
1044     free(out);
1045     pldm_entity_association_tree_destroy(tree);
1046 
1047     // A-A
1048     //   |
1049     //   A-A
1050     tree = pldm_entity_association_tree_init();
1051     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1052                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1053     EXPECT_NE(node, nullptr);
1054     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1055                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1056     EXPECT_NE(node, nullptr);
1057     node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, node,
1058                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1059     EXPECT_NE(node1, nullptr);
1060     node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, node,
1061                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1062     EXPECT_NE(node2, nullptr);
1063     pldm_entity_association_tree_visit(tree, &out, &num);
1064     EXPECT_EQ(num, 4u);
1065     EXPECT_EQ(out[0].entity_type, 1u);
1066     EXPECT_EQ(out[0].entity_instance_num, 1u);
1067     EXPECT_EQ(out[0].entity_container_id, 0u);
1068     EXPECT_EQ(out[1].entity_type, 1u);
1069     EXPECT_EQ(out[1].entity_instance_num, 2u);
1070     EXPECT_EQ(out[1].entity_container_id, 0u);
1071     EXPECT_EQ(out[2].entity_type, 2u);
1072     EXPECT_EQ(out[2].entity_instance_num, 1u);
1073     EXPECT_EQ(out[2].entity_container_id, 1u);
1074     EXPECT_EQ(out[3].entity_type, 1u);
1075     EXPECT_EQ(out[3].entity_instance_num, 1u);
1076     EXPECT_EQ(out[3].entity_container_id, 1u);
1077     free(out);
1078     pldm_entity_association_tree_destroy(tree);
1079 }
1080 
1081 TEST(EntityAssociationPDR, testPDR)
1082 {
1083     // e = entity type, c = container id, i = instance num
1084 
1085     //        INPUT
1086     //        1(e=1)--1a(e=2)
1087     //        |
1088     //        2(e=2)--3(e=2)--4(e=2)--5(e=3)
1089     //        |
1090     //        6(e=4)--7(e=5)--8(e=5)--9(e=5)
1091     //        |       |
1092     //        11(e=6) 10(e=7)
1093 
1094     //        Expected OUTPUT
1095     //        1(e=1,c=0,i=1)
1096     //        |
1097     //        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)
1098     //        |
1099     //        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)
1100     //        |               |
1101     //        10(e=6,c=3,i=1) 11(e=7,c=4,i=1)
1102     pldm_entity entities[11]{};
1103 
1104     entities[0].entity_type = 1;
1105     entities[1].entity_type = 2;
1106     entities[2].entity_type = 3;
1107     entities[3].entity_type = 2;
1108     entities[4].entity_type = 3;
1109     entities[5].entity_type = 4;
1110     entities[6].entity_type = 5;
1111     entities[7].entity_type = 5;
1112     entities[8].entity_type = 5;
1113     entities[9].entity_type = 6;
1114     entities[10].entity_type = 7;
1115 
1116     auto tree = pldm_entity_association_tree_init();
1117 
1118     auto l1 = pldm_entity_association_tree_add(
1119         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1120     EXPECT_NE(l1, nullptr);
1121     auto l1a = pldm_entity_association_tree_add(
1122         tree, &entities[1], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1123     EXPECT_NE(l1a, nullptr);
1124 
1125     auto l2a = pldm_entity_association_tree_add(
1126         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1127     EXPECT_NE(l2a, nullptr);
1128     auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
1129                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1130     EXPECT_NE(l2b, nullptr);
1131     auto l2c = pldm_entity_association_tree_add(
1132         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1133     EXPECT_NE(l2c, nullptr);
1134     auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xffff, l1,
1135                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1136     EXPECT_NE(l2d, nullptr);
1137 
1138     auto l3a = pldm_entity_association_tree_add(
1139         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1140     EXPECT_NE(l3a, nullptr);
1141     auto l3b = pldm_entity_association_tree_add(
1142         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1143     EXPECT_NE(l3b, nullptr);
1144     auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xffff, l2a,
1145                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1146     EXPECT_NE(l3c, nullptr);
1147     auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xffff, l2a,
1148                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1149     EXPECT_NE(l3d, nullptr);
1150 
1151     auto l4a = pldm_entity_association_tree_add(
1152         tree, &entities[9], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1153     EXPECT_NE(l4a, nullptr);
1154     auto l4b = pldm_entity_association_tree_add(
1155         tree, &entities[10], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1156     EXPECT_NE(l4b, nullptr);
1157 
1158     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
1159               2);
1160     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1161               2);
1162     EXPECT_EQ(
1163         pldm_entity_get_num_children(l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 2);
1164     EXPECT_EQ(
1165         pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 0);
1166     EXPECT_EQ(pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1167               1);
1168 
1169     auto repo = pldm_pdr_init();
1170     int rc = pldm_entity_association_pdr_add_check(tree, repo, false, 1);
1171     ASSERT_EQ(rc, 0);
1172 
1173     EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
1174 
1175     uint32_t currRecHandle{};
1176     uint32_t nextRecHandle{};
1177     uint8_t* data = nullptr;
1178     uint32_t size{};
1179     uint32_t commonSize = sizeof(struct pldm_pdr_hdr) + sizeof(uint16_t) +
1180                           sizeof(uint8_t) + sizeof(pldm_entity) +
1181                           sizeof(uint8_t);
1182 
1183     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1184     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1185                                       l1, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1186                                   sizeof(pldm_entity)));
1187     uint8_t* start = data;
1188     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1189     EXPECT_EQ(le32toh(hdr->record_handle), 1u);
1190     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1191     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1192     start += sizeof(pldm_pdr_hdr);
1193     uint16_t* containerId = reinterpret_cast<uint16_t*>(start);
1194     EXPECT_EQ(le16toh(*containerId), 1u);
1195     start += sizeof(uint16_t);
1196     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1197     start += sizeof(uint8_t);
1198     pldm_entity* entity = reinterpret_cast<pldm_entity*>(start);
1199     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1200     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1201     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1202     start += sizeof(pldm_entity);
1203     EXPECT_EQ(*start,
1204               pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1205     start += sizeof(uint8_t);
1206     entity = reinterpret_cast<pldm_entity*>(start);
1207     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1208     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1209     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1210     start += sizeof(pldm_entity);
1211     entity = reinterpret_cast<pldm_entity*>(start);
1212     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1213     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1214     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1215 
1216     currRecHandle = nextRecHandle;
1217 
1218     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1219     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1220                                       l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1221                                   sizeof(pldm_entity)));
1222     start = data;
1223     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1224     EXPECT_EQ(le32toh(hdr->record_handle), 2u);
1225     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1226     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1227     start += sizeof(pldm_pdr_hdr);
1228     containerId = reinterpret_cast<uint16_t*>(start);
1229     EXPECT_EQ(le16toh(*containerId), 1u);
1230     start += sizeof(uint16_t);
1231     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1232     start += sizeof(uint8_t);
1233     entity = reinterpret_cast<pldm_entity*>(start);
1234     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1235     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1236     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1237     start += sizeof(pldm_entity);
1238     EXPECT_EQ(*start, pldm_entity_get_num_children(
1239                           l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1240     start += sizeof(uint8_t);
1241     entity = reinterpret_cast<pldm_entity*>(start);
1242     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1243     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1244     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1245     start += sizeof(pldm_entity);
1246     entity = reinterpret_cast<pldm_entity*>(start);
1247     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1248     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1249     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1250 
1251     currRecHandle = nextRecHandle;
1252 
1253     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1254     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1255                                       l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1256                                   sizeof(pldm_entity)));
1257     start = data;
1258     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1259     EXPECT_EQ(le32toh(hdr->record_handle), 3u);
1260     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1261     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1262     start += sizeof(pldm_pdr_hdr);
1263     containerId = reinterpret_cast<uint16_t*>(start);
1264     EXPECT_EQ(le16toh(*containerId), 2u);
1265     start += sizeof(uint16_t);
1266     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1267     start += sizeof(uint8_t);
1268     entity = reinterpret_cast<pldm_entity*>(start);
1269     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1270     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1271     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1272     start += sizeof(pldm_entity);
1273     EXPECT_EQ(*start, pldm_entity_get_num_children(
1274                           l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1275     start += sizeof(uint8_t);
1276     entity = reinterpret_cast<pldm_entity*>(start);
1277     EXPECT_EQ(le16toh(entity->entity_type), 5);
1278     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1279     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1280     start += sizeof(pldm_entity);
1281     entity = reinterpret_cast<pldm_entity*>(start);
1282     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1283     EXPECT_EQ(le16toh(entity->entity_instance_num), 3u);
1284     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1285 
1286     currRecHandle = nextRecHandle;
1287 
1288     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1289     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1290                                       l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1291                                   sizeof(pldm_entity)));
1292     start = data;
1293     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1294     EXPECT_EQ(le32toh(hdr->record_handle), 4u);
1295     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1296     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1297     start += sizeof(pldm_pdr_hdr);
1298     containerId = reinterpret_cast<uint16_t*>(start);
1299     EXPECT_EQ(le16toh(*containerId), 2u);
1300     start += sizeof(uint16_t);
1301     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1302     start += sizeof(uint8_t);
1303     entity = reinterpret_cast<pldm_entity*>(start);
1304     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1305     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1306     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1307     start += sizeof(pldm_entity);
1308     EXPECT_EQ(*start, pldm_entity_get_num_children(
1309                           l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1310     start += sizeof(uint8_t);
1311     entity = reinterpret_cast<pldm_entity*>(start);
1312     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1313     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1314     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1315     start += sizeof(pldm_entity);
1316     entity = reinterpret_cast<pldm_entity*>(start);
1317     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1318     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1319     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1320 
1321     currRecHandle = nextRecHandle;
1322 
1323     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1324     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1325                                       l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1326                                   sizeof(pldm_entity)));
1327     start = data;
1328     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1329     EXPECT_EQ(le32toh(hdr->record_handle), 5u);
1330     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1331     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1332     start += sizeof(pldm_pdr_hdr);
1333     containerId = reinterpret_cast<uint16_t*>(start);
1334     EXPECT_EQ(le16toh(*containerId), 3u);
1335     start += sizeof(uint16_t);
1336     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1337     start += sizeof(uint8_t);
1338     entity = reinterpret_cast<pldm_entity*>(start);
1339     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1340     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1341     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1342     start += sizeof(pldm_entity);
1343     EXPECT_EQ(*start, pldm_entity_get_num_children(
1344                           l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1345     start += sizeof(uint8_t);
1346     entity = reinterpret_cast<pldm_entity*>(start);
1347     EXPECT_EQ(le16toh(entity->entity_type), 6u);
1348     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1349     EXPECT_EQ(le16toh(entity->entity_container_id), 3u);
1350 
1351     currRecHandle = nextRecHandle;
1352 
1353     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1354     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1355                                       l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1356                                   sizeof(pldm_entity)));
1357     start = data;
1358     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1359     EXPECT_EQ(le32toh(hdr->record_handle), 6u);
1360     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1361     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1362     start += sizeof(pldm_pdr_hdr);
1363     containerId = reinterpret_cast<uint16_t*>(start);
1364     EXPECT_EQ(le16toh(*containerId), 4u);
1365     start += sizeof(uint16_t);
1366     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1367     start += sizeof(uint8_t);
1368     entity = reinterpret_cast<pldm_entity*>(start);
1369     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1370     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1371     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1372     start += sizeof(pldm_entity);
1373     EXPECT_EQ(*start, pldm_entity_get_num_children(
1374                           l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1375     start += sizeof(uint8_t);
1376     entity = reinterpret_cast<pldm_entity*>(start);
1377     EXPECT_EQ(le16toh(entity->entity_type), 7u);
1378     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1379     EXPECT_EQ(le16toh(entity->entity_container_id), 4u);
1380 
1381     EXPECT_EQ(nextRecHandle, 0u);
1382 
1383     pldm_pdr_destroy(repo);
1384     pldm_entity_association_tree_destroy(tree);
1385 }
1386 
1387 TEST(EntityAssociationPDR, testFind)
1388 {
1389     //        1
1390     //        |
1391     //        2--3--4
1392     //        |
1393     //        5--6--7
1394     //        |  |
1395     //        8  9
1396 
1397     pldm_entity entities[9]{};
1398 
1399     entities[0].entity_type = 1;
1400     entities[1].entity_type = 2;
1401     entities[2].entity_type = 2;
1402     entities[3].entity_type = 3;
1403     entities[4].entity_type = 4;
1404     entities[5].entity_type = 5;
1405     entities[6].entity_type = 5;
1406     entities[7].entity_type = 6;
1407     entities[8].entity_type = 7;
1408 
1409     auto tree = pldm_entity_association_tree_init();
1410 
1411     auto l1 = pldm_entity_association_tree_add(
1412         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1413     EXPECT_NE(l1, nullptr);
1414     auto l2a = pldm_entity_association_tree_add(
1415         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1416     EXPECT_NE(l2a, nullptr);
1417     auto l2b = pldm_entity_association_tree_add(
1418         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1419     EXPECT_NE(l2b, nullptr);
1420     auto l2c = pldm_entity_association_tree_add(
1421         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1422     EXPECT_NE(l2c, nullptr);
1423     auto l3a = pldm_entity_association_tree_add(
1424         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1425     EXPECT_NE(l3a, nullptr);
1426     auto l3b = pldm_entity_association_tree_add(
1427         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1428     EXPECT_NE(l3b, nullptr);
1429     auto l3c = pldm_entity_association_tree_add(
1430         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1431     EXPECT_NE(l3c, nullptr);
1432     auto l4a = pldm_entity_association_tree_add(
1433         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1434     EXPECT_NE(l4a, nullptr);
1435     auto l4b = pldm_entity_association_tree_add(
1436         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1437     EXPECT_NE(l4b, nullptr);
1438 
1439     pldm_entity entity{};
1440 
1441     entity.entity_type = 1;
1442     entity.entity_instance_num = 1;
1443     auto result = pldm_entity_association_tree_find(tree, &entity);
1444     EXPECT_EQ(result, l1);
1445     EXPECT_EQ(entity.entity_container_id, 0);
1446 
1447     entity.entity_type = 2;
1448     entity.entity_instance_num = 1;
1449     result = pldm_entity_association_tree_find(tree, &entity);
1450     EXPECT_EQ(result, l2a);
1451     EXPECT_EQ(entity.entity_container_id, 1);
1452     entity.entity_type = 2;
1453     entity.entity_instance_num = 2;
1454     result = pldm_entity_association_tree_find(tree, &entity);
1455     EXPECT_EQ(result, l2b);
1456     EXPECT_EQ(entity.entity_container_id, 1);
1457     entity.entity_type = 3;
1458     entity.entity_instance_num = 1;
1459     result = pldm_entity_association_tree_find(tree, &entity);
1460     EXPECT_EQ(result, l2c);
1461     EXPECT_EQ(entity.entity_container_id, 1);
1462 
1463     entity.entity_type = 7;
1464     entity.entity_instance_num = 1;
1465     result = pldm_entity_association_tree_find(tree, &entity);
1466     EXPECT_EQ(result, l4b);
1467     EXPECT_EQ(entity.entity_container_id, 4);
1468 
1469     pldm_entity_association_tree_destroy(tree);
1470 }
1471 
1472 TEST(EntityAssociationPDR, testCopyTree)
1473 {
1474     pldm_entity entities[4]{};
1475     entities[0].entity_type = 1;
1476     entities[1].entity_type = 2;
1477     entities[2].entity_type = 2;
1478     entities[3].entity_type = 3;
1479 
1480     auto orgTree = pldm_entity_association_tree_init();
1481     auto newTree = pldm_entity_association_tree_init();
1482     auto l1 =
1483         pldm_entity_association_tree_add(orgTree, &entities[0], 0xffff, nullptr,
1484                                          PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1485     EXPECT_NE(l1, nullptr);
1486     auto l2a = pldm_entity_association_tree_add(
1487         orgTree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1488     EXPECT_NE(l2a, nullptr);
1489     auto l2b = pldm_entity_association_tree_add(
1490         orgTree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1491     EXPECT_NE(l2b, nullptr);
1492     auto l2c = pldm_entity_association_tree_add(
1493         orgTree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1494     EXPECT_NE(l2c, nullptr);
1495     size_t orgNum{};
1496     pldm_entity* orgOut = nullptr;
1497     pldm_entity_association_tree_visit(orgTree, &orgOut, &orgNum);
1498     EXPECT_EQ(orgNum, 4u);
1499 
1500     pldm_entity_association_tree_copy_root(orgTree, newTree);
1501     size_t newNum{};
1502     pldm_entity* newOut = nullptr;
1503     pldm_entity_association_tree_visit(newTree, &newOut, &newNum);
1504     EXPECT_EQ(newNum, orgNum);
1505     EXPECT_EQ(newOut[0].entity_type, 1u);
1506     EXPECT_EQ(newOut[0].entity_instance_num, 1u);
1507     EXPECT_EQ(newOut[0].entity_container_id, 0u);
1508     free(orgOut);
1509     free(newOut);
1510     pldm_entity_association_tree_destroy(orgTree);
1511     pldm_entity_association_tree_destroy(newTree);
1512 }
1513 
1514 TEST(EntityAssociationPDR, testExtract)
1515 {
1516     std::vector<uint8_t> pdr{};
1517     pdr.resize(sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_entity_association) +
1518                sizeof(pldm_entity) * 4);
1519     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
1520     hdr->type = PLDM_PDR_ENTITY_ASSOCIATION;
1521     hdr->length =
1522         htole16(sizeof(pldm_pdr_entity_association) + sizeof(pldm_entity) * 4);
1523 
1524     pldm_pdr_entity_association* e =
1525         reinterpret_cast<pldm_pdr_entity_association*>(pdr.data() +
1526                                                        sizeof(pldm_pdr_hdr));
1527     e->container_id = htole16(1);
1528     e->num_children = 5;
1529     e->container.entity_type = htole16(1);
1530     e->container.entity_instance_num = htole16(1);
1531     e->container.entity_container_id = htole16(0);
1532 
1533     pldm_entity* entity = e->children;
1534     entity->entity_type = htole16(2);
1535     entity->entity_instance_num = htole16(1);
1536     entity->entity_container_id = htole16(1);
1537     ++entity;
1538     entity->entity_type = htole16(3);
1539     entity->entity_instance_num = htole16(1);
1540     entity->entity_container_id = htole16(1);
1541     ++entity;
1542     entity->entity_type = htole16(4);
1543     entity->entity_instance_num = htole16(1);
1544     entity->entity_container_id = htole16(1);
1545     ++entity;
1546     entity->entity_type = htole16(5);
1547     entity->entity_instance_num = htole16(1);
1548     entity->entity_container_id = htole16(1);
1549     ++entity;
1550     entity->entity_type = htole16(6);
1551     entity->entity_instance_num = htole16(1);
1552     entity->entity_container_id = htole16(1);
1553 
1554     size_t num{};
1555     pldm_entity* out = nullptr;
1556     pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &num, &out);
1557     EXPECT_EQ(num, (unsigned)e->num_children + 1);
1558     EXPECT_EQ(out[0].entity_type, 1u);
1559     EXPECT_EQ(out[0].entity_instance_num, 1u);
1560     EXPECT_EQ(out[0].entity_container_id, 0u);
1561     EXPECT_EQ(out[1].entity_type, 2u);
1562     EXPECT_EQ(out[1].entity_instance_num, 1u);
1563     EXPECT_EQ(out[1].entity_container_id, 1u);
1564     EXPECT_EQ(out[2].entity_type, 3u);
1565     EXPECT_EQ(out[2].entity_instance_num, 1u);
1566     EXPECT_EQ(out[2].entity_container_id, 1u);
1567     EXPECT_EQ(out[3].entity_type, 4u);
1568     EXPECT_EQ(out[3].entity_instance_num, 1u);
1569     EXPECT_EQ(out[3].entity_container_id, 1u);
1570     EXPECT_EQ(out[4].entity_type, 5u);
1571     EXPECT_EQ(out[4].entity_instance_num, 1u);
1572     EXPECT_EQ(out[4].entity_container_id, 1u);
1573     EXPECT_EQ(out[5].entity_type, 6u);
1574     EXPECT_EQ(out[5].entity_instance_num, 1u);
1575     EXPECT_EQ(out[5].entity_container_id, 1u);
1576 
1577     free(out);
1578 }
1579 
1580 TEST(EntityAssociationPDR, testGetChildren)
1581 {
1582     pldm_entity entities[4]{};
1583     entities[0].entity_type = 1;
1584     entities[1].entity_type = 2;
1585     entities[2].entity_type = 2;
1586     entities[3].entity_type = 3;
1587 
1588     auto tree = pldm_entity_association_tree_init();
1589     auto l1 = pldm_entity_association_tree_add(
1590         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1591     EXPECT_NE(l1, nullptr);
1592     auto l2a = pldm_entity_association_tree_add(
1593         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1594     EXPECT_NE(l2a, nullptr);
1595     auto l2b = pldm_entity_association_tree_add(
1596         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1597     EXPECT_NE(l2b, nullptr);
1598     auto l2c = pldm_entity_association_tree_add(
1599         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1600     EXPECT_NE(l2c, nullptr);
1601 
1602     pldm_entity et1;
1603     et1.entity_type = 2;
1604     et1.entity_instance_num = 1;
1605     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et1));
1606 
1607     pldm_entity et2;
1608     et2.entity_type = 2;
1609     et2.entity_instance_num = 2;
1610     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et2));
1611 
1612     pldm_entity et3;
1613     et3.entity_type = 2;
1614     et3.entity_instance_num = 3;
1615     EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3));
1616 
1617     pldm_entity_association_tree_destroy(tree);
1618 }
1619 
1620 TEST(EntityAssociationPDR, testEntityInstanceNumber)
1621 {
1622     pldm_entity entities[9]{};
1623 
1624     entities[0].entity_type = 1;
1625     entities[1].entity_type = 2;
1626     entities[2].entity_type = 2;
1627     entities[3].entity_type = 2;
1628     entities[4].entity_type = 2;
1629     entities[5].entity_type = 2;
1630     entities[6].entity_type = 2;
1631     entities[7].entity_type = 3;
1632     entities[8].entity_type = 3;
1633 
1634     auto tree = pldm_entity_association_tree_init();
1635     auto repo = pldm_pdr_init();
1636 
1637     uint16_t terminusHdl{};
1638     uint16_t entityType{};
1639     uint16_t entityInstanceNum{};
1640     uint16_t containerId{};
1641 
1642     auto node = pldm_entity_association_tree_add(
1643         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1644     EXPECT_NE(node, nullptr);
1645 
1646     auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node,
1647                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1648     uint32_t first = 1;
1649     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1650                   repo, 1, 1, entities[1].entity_type,
1651                   entities[1].entity_instance_num,
1652                   entities[1].entity_container_id, &first),
1653               0);
1654     EXPECT_NE(l1, nullptr);
1655     EXPECT_EQ(entities[1].entity_instance_num, 63);
1656     EXPECT_EQ(first, pldm_pdr_get_record_handle(
1657                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1658                                    repo, 1, &terminusHdl, &entityType,
1659                                    &entityInstanceNum, &containerId)));
1660     EXPECT_EQ(entityType, 2);
1661     EXPECT_EQ(entityInstanceNum, 63);
1662 
1663     auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node,
1664                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1665     uint32_t second = 2;
1666     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1667                   repo, 1, 2, entities[2].entity_type,
1668                   entities[2].entity_instance_num,
1669                   entities[2].entity_container_id, &second),
1670               0);
1671     EXPECT_NE(l2, nullptr);
1672     EXPECT_EQ(entities[2].entity_instance_num, 37);
1673     EXPECT_EQ(second, pldm_pdr_get_record_handle(
1674                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1675                                     repo, 2, &terminusHdl, &entityType,
1676                                     &entityInstanceNum, &containerId)));
1677     EXPECT_EQ(entityType, 2);
1678     EXPECT_EQ(entityInstanceNum, 37);
1679 
1680     auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node,
1681                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1682     uint32_t third = 3;
1683     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1684                   repo, 1, 3, entities[3].entity_type,
1685                   entities[3].entity_instance_num,
1686                   entities[3].entity_container_id, &third),
1687               0);
1688     EXPECT_NE(l3, nullptr);
1689     EXPECT_EQ(entities[3].entity_instance_num, 44);
1690     EXPECT_EQ(third, pldm_pdr_get_record_handle(
1691                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1692                                    repo, 3, &terminusHdl, &entityType,
1693                                    &entityInstanceNum, &containerId)));
1694     EXPECT_EQ(entityType, 2);
1695     EXPECT_EQ(entityInstanceNum, 44);
1696 
1697     auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node,
1698                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1699     uint32_t fourth = 4;
1700     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1701                   repo, 1, 4, entities[4].entity_type,
1702                   entities[4].entity_instance_num,
1703                   entities[4].entity_container_id, &fourth),
1704               0);
1705     EXPECT_NE(l4, nullptr);
1706     EXPECT_EQ(entities[4].entity_instance_num, 89);
1707     EXPECT_EQ(fourth, pldm_pdr_get_record_handle(
1708                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1709                                     repo, 4, &terminusHdl, &entityType,
1710                                     &entityInstanceNum, &containerId)));
1711     EXPECT_EQ(entityType, 2);
1712     EXPECT_EQ(entityInstanceNum, 89);
1713 
1714     auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xffff, node,
1715                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1716     uint32_t fifth = 5;
1717     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1718                   repo, 1, 5, entities[5].entity_type,
1719                   entities[5].entity_instance_num,
1720                   entities[5].entity_container_id, &fifth),
1721               0);
1722     EXPECT_NE(l5, nullptr);
1723     EXPECT_EQ(entities[5].entity_instance_num, 90);
1724     EXPECT_EQ(fifth, pldm_pdr_get_record_handle(
1725                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1726                                    repo, 5, &terminusHdl, &entityType,
1727                                    &entityInstanceNum, &containerId)));
1728     EXPECT_EQ(entityType, 2);
1729     EXPECT_EQ(entityInstanceNum, 90);
1730 
1731     auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node,
1732                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1733     EXPECT_EQ(l6, nullptr);
1734 
1735     auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1,
1736                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1737     uint32_t seventh = 7;
1738     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1739                   repo, 1, 7, entities[7].entity_type,
1740                   entities[7].entity_instance_num,
1741                   entities[7].entity_container_id, &seventh),
1742               0);
1743     EXPECT_NE(l7, nullptr);
1744     EXPECT_EQ(entities[7].entity_instance_num, 100);
1745     EXPECT_EQ(seventh, pldm_pdr_get_record_handle(
1746                            repo, pldm_pdr_fru_record_set_find_by_rsi(
1747                                      repo, 7, &terminusHdl, &entityType,
1748                                      &entityInstanceNum, &containerId)));
1749     EXPECT_EQ(entityType, 3);
1750     EXPECT_EQ(entityInstanceNum, 100);
1751 
1752     auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2,
1753                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1754     uint32_t eighth = 8;
1755     EXPECT_EQ(pldm_pdr_add_fru_record_set_check(
1756                   repo, 1, 8, entities[8].entity_type,
1757                   entities[8].entity_instance_num,
1758                   entities[8].entity_container_id, &eighth),
1759               0);
1760     EXPECT_NE(l8, nullptr);
1761     EXPECT_EQ(entities[8].entity_instance_num, 100);
1762     EXPECT_EQ(eighth, pldm_pdr_get_record_handle(
1763                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1764                                     repo, 8, &terminusHdl, &entityType,
1765                                     &entityInstanceNum, &containerId)));
1766     EXPECT_EQ(entityType, 3);
1767     EXPECT_EQ(entityInstanceNum, 100);
1768 
1769     pldm_pdr_destroy(repo);
1770     pldm_entity_association_tree_destroy(tree);
1771 }
1772 
1773 #ifdef LIBPLDM_API_TESTING
1774 TEST(EntityAssociationPDR, testFindChildContainerID)
1775 {
1776     pldm_entity entities[3]{};
1777     entities[0].entity_type = 1;
1778     entities[1].entity_type = 2;
1779     entities[2].entity_type = 3;
1780     entities[1].entity_container_id = 2;
1781     entities[1].entity_instance_num = 1;
1782 
1783     auto tree = pldm_entity_association_tree_init();
1784     auto l1 = pldm_entity_association_tree_add_entity(
1785         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
1786         false, true, 0xffff);
1787 
1788     EXPECT_NE(l1, nullptr);
1789     auto l2 = pldm_entity_association_tree_add_entity(
1790         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1791         false, 0xffff);
1792     EXPECT_NE(l2, nullptr);
1793     auto l3 = pldm_entity_association_tree_add_entity(
1794         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1795         true, 0xffff);
1796     EXPECT_NE(l3, nullptr);
1797 
1798     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
1799               2);
1800 
1801     auto repo = pldm_pdr_init();
1802     int rc = pldm_entity_association_pdr_add_check(tree, repo, false, 1);
1803     ASSERT_EQ(rc, 0);
1804 
1805     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
1806 
1807     uint16_t container_id{};
1808     pldm_pdr_find_child_container_id_index_range_exclude(
1809         repo, 1, 1, 0, 0x01000000, 0x01ffffff, &container_id);
1810     EXPECT_EQ(container_id, 2);
1811 
1812     uint16_t container_id1{};
1813     pldm_pdr_find_child_container_id_index_range_exclude(
1814         repo, 1, 1, 0, 0x00000001, 0x00ffffff, &container_id1);
1815     EXPECT_EQ(container_id1, 0);
1816 
1817     pldm_pdr_destroy(repo);
1818     pldm_entity_association_tree_destroy(tree);
1819 }
1820 #endif
1821 
1822 TEST(EntityAssociationPDR, testNodeAddCheck)
1823 {
1824     // pldm_entity entities[4]{};
1825     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 4);
1826     entities[0].entity_type = 1;
1827     entities[1].entity_type = 2;
1828     entities[2].entity_type = 2;
1829     entities[3].entity_type = 3;
1830 
1831     auto tree = pldm_entity_association_tree_init();
1832 
1833     auto l1 = pldm_entity_association_tree_add(
1834         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1835     EXPECT_NE(l1, nullptr);
1836     auto l2a = pldm_entity_association_tree_add(
1837         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1838     EXPECT_NE(l2a, nullptr);
1839     auto l2b = pldm_entity_association_tree_add(
1840         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1841     EXPECT_NE(l2b, nullptr);
1842     auto l2c = pldm_entity_association_tree_add(
1843         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1844     EXPECT_NE(l2c, nullptr);
1845 
1846     auto repo = pldm_pdr_init();
1847 
1848     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1849                   l1, repo, &entities, 4, false, 1, 0),
1850               0);
1851     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1852                   l1, repo, &entities, 4, false, 1, 2),
1853               0);
1854     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1855                   l1, repo, &entities, 4, false, 1, 23),
1856               0);
1857     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1858                   l1, repo, &entities, 4, false, 1, 34),
1859               0);
1860 
1861     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
1862 
1863     uint8_t* outData = nullptr;
1864     uint32_t size{};
1865     uint32_t nextRecHdl{};
1866     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
1867     EXPECT_NE(hdl, nullptr);
1868 
1869     outData = nullptr;
1870     auto hdl1 = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
1871     EXPECT_NE(hdl1, nullptr);
1872     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
1873     EXPECT_EQ(hdr->record_handle, 2);
1874 
1875     outData = nullptr;
1876     auto hdl2 = pldm_pdr_find_record(repo, 23, &outData, &size, &nextRecHdl);
1877     EXPECT_NE(hdl2, nullptr);
1878     pldm_pdr_hdr* hdr1 = reinterpret_cast<pldm_pdr_hdr*>(outData);
1879     EXPECT_EQ(hdr1->record_handle, 23);
1880 
1881     outData = nullptr;
1882     auto hdl3 = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
1883     EXPECT_EQ(hdl3, nullptr);
1884 
1885     free(entities);
1886     pldm_pdr_destroy(repo);
1887     pldm_entity_association_tree_destroy(tree);
1888 }
1889 
1890 #ifdef LIBPLDM_API_TESTING
1891 TEST(EntityAssociationPDR, testAddContainedEntityRemotePDR)
1892 {
1893     // pldm_entity entities[5]{};
1894     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
1895     entities[0].entity_type = 1;
1896     entities[1].entity_type = 2;
1897     entities[2].entity_type = 3;
1898     entities[3].entity_type = 4;
1899     entities[4].entity_type = 5;
1900 
1901     auto tree = pldm_entity_association_tree_init();
1902     auto l1 = pldm_entity_association_tree_add(
1903         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1904     EXPECT_NE(l1, nullptr);
1905     auto l2a = pldm_entity_association_tree_add(
1906         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1907     EXPECT_NE(l2a, nullptr);
1908     auto l2b = pldm_entity_association_tree_add(
1909         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1910     EXPECT_NE(l2b, nullptr);
1911     auto l2c = pldm_entity_association_tree_add(
1912         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1913     EXPECT_NE(l2c, nullptr);
1914     auto l3a = pldm_entity_association_tree_add(
1915         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1916     EXPECT_NE(l3a, nullptr);
1917 
1918     auto repo = pldm_pdr_init();
1919 
1920     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1921                   l1, repo, &entities, 5, false, 1, 0),
1922               0);
1923     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1924                   l1, repo, &entities, 5, false, 1, 2),
1925               0);
1926     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1927                   l1, repo, &entities, 5, false, 1, 23),
1928               0);
1929     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1930                   l1, repo, &entities, 5, false, 1, 34),
1931               0);
1932     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1933                   l2a, repo, &entities, 5, false, 1, 3),
1934               0);
1935 
1936     pldm_entity entity1[1];
1937     entity1[0].entity_type = 2;
1938 
1939     EXPECT_EQ(pldm_entity_association_pdr_add_contained_entity_to_remote_pdr(
1940                   repo, &entity1[0], 2),
1941               0);
1942 
1943     free(entities);
1944     pldm_pdr_destroy(repo);
1945     pldm_entity_association_tree_destroy(tree);
1946 }
1947 #endif
1948 
1949 #ifdef LIBPLDM_API_TESTING
1950 TEST(EntityAssociationPDR, testAddContainedEntityNew)
1951 {
1952     // pldm_entity entities[5]{};
1953     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
1954     entities[0].entity_type = 1;
1955     entities[1].entity_type = 2;
1956     entities[2].entity_type = 3;
1957     entities[3].entity_type = 4;
1958     entities[4].entity_type = 5;
1959 
1960     auto tree = pldm_entity_association_tree_init();
1961     auto l1 = pldm_entity_association_tree_add(
1962         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1963     EXPECT_NE(l1, nullptr);
1964     auto l2a = pldm_entity_association_tree_add(
1965         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1966     EXPECT_NE(l2a, nullptr);
1967     auto l2b = pldm_entity_association_tree_add(
1968         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1969     EXPECT_NE(l2b, nullptr);
1970     auto l2c = pldm_entity_association_tree_add(
1971         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1972     EXPECT_NE(l2c, nullptr);
1973     auto l3a = pldm_entity_association_tree_add(
1974         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1975     EXPECT_NE(l3a, nullptr);
1976 
1977     auto repo = pldm_pdr_init();
1978 
1979     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1980                   l1, repo, &entities, 5, false, 1, 0),
1981               0);
1982     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1983                   l1, repo, &entities, 5, false, 1, 2),
1984               0);
1985     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1986                   l1, repo, &entities, 5, false, 1, 23),
1987               0);
1988     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1989                   l1, repo, &entities, 5, false, 1, 34),
1990               0);
1991     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1992                   l2a, repo, &entities, 5, false, 1, 3),
1993               0);
1994 
1995     uint32_t updated_record_handle = 0;
1996 
1997     pldm_entity entity2[1]{};
1998     entity2[0].entity_type = 4;
1999 
2000     pldm_entity entity3[1]{};
2001     entity3[0].entity_type = 4;
2002 
2003     EXPECT_EQ(pldm_entity_association_pdr_create_new(
2004                   repo, 34, &entity2[0], &entity3[0], &updated_record_handle),
2005               0);
2006 
2007     EXPECT_EQ(updated_record_handle, 35);
2008 
2009     free(entities);
2010     pldm_pdr_destroy(repo);
2011     pldm_entity_association_tree_destroy(tree);
2012 }
2013 #endif
2014