xref: /openbmc/libpldm/tests/dsp/pdr.cpp (revision d72ea4b8)
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(pldm_pdr_add_fru_record_set(repo, 1, 10, 1, 0, 100, &handle), 0);
485     EXPECT_EQ(handle, 1u);
486     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
487     EXPECT_EQ(pldm_pdr_get_repo_size(repo),
488               sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
489     uint32_t size{};
490     uint32_t nextRecHdl{};
491     uint8_t* outData = nullptr;
492     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
493     EXPECT_NE(hdl, nullptr);
494     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
495     EXPECT_EQ(nextRecHdl, 0u);
496     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
497     EXPECT_EQ(hdr->version, 1u);
498     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
499     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
500     EXPECT_EQ(hdr->record_handle, htole32(1));
501     pldm_pdr_fru_record_set* fru = reinterpret_cast<pldm_pdr_fru_record_set*>(
502         outData + sizeof(pldm_pdr_hdr));
503     EXPECT_EQ(fru->terminus_handle, htole16(1));
504     EXPECT_EQ(fru->fru_rsi, htole16(10));
505     EXPECT_EQ(fru->entity_type, htole16(1));
506     EXPECT_EQ(fru->entity_instance_num, htole16(0));
507     EXPECT_EQ(fru->container_id, htole16(100));
508     outData = nullptr;
509 
510     handle = 0;
511     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 2, 11, 2, 1, 101, &handle), 0);
512     EXPECT_EQ(handle, 2u);
513     EXPECT_EQ(pldm_pdr_get_record_count(repo), 2u);
514     EXPECT_EQ(pldm_pdr_get_repo_size(repo),
515               2 * (sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set)));
516     hdl = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
517     EXPECT_NE(hdl, nullptr);
518     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
519     EXPECT_EQ(nextRecHdl, 0u);
520     hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
521     EXPECT_EQ(hdr->version, 1u);
522     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
523     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
524     EXPECT_EQ(hdr->record_handle, htole32(2));
525     fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
526                                                      sizeof(pldm_pdr_hdr));
527     EXPECT_EQ(fru->terminus_handle, htole16(2));
528     EXPECT_EQ(fru->fru_rsi, htole16(11));
529     EXPECT_EQ(fru->entity_type, htole16(2));
530     EXPECT_EQ(fru->entity_instance_num, htole16(1));
531     EXPECT_EQ(fru->container_id, htole16(101));
532     outData = nullptr;
533 
534     hdl = pldm_pdr_find_record(repo, 1, &outData, &size, &nextRecHdl);
535     EXPECT_NE(hdl, nullptr);
536     EXPECT_EQ(size, sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_fru_record_set));
537     EXPECT_EQ(nextRecHdl, 2u);
538     hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
539     EXPECT_EQ(hdr->version, 1u);
540     EXPECT_EQ(hdr->type, PLDM_PDR_FRU_RECORD_SET);
541     EXPECT_EQ(hdr->length, htole16(sizeof(pldm_pdr_fru_record_set)));
542     EXPECT_EQ(hdr->record_handle, htole32(1));
543     fru = reinterpret_cast<pldm_pdr_fru_record_set*>(outData +
544                                                      sizeof(pldm_pdr_hdr));
545     EXPECT_EQ(fru->terminus_handle, htole16(1));
546     EXPECT_EQ(fru->fru_rsi, htole16(10));
547     EXPECT_EQ(fru->entity_type, htole16(1));
548     EXPECT_EQ(fru->entity_instance_num, htole16(0));
549     EXPECT_EQ(fru->container_id, htole16(100));
550     outData = nullptr;
551 
552     pldm_pdr_destroy(repo);
553 }
554 
555 TEST(PDRUpdate, tesFindtFruRecordSet)
556 {
557     auto repo = pldm_pdr_init();
558 
559     uint16_t terminusHdl{};
560     uint16_t entityType{};
561     uint16_t entityInstanceNum{};
562     uint16_t containerId{};
563     uint32_t first = 1;
564     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 1, 1, 0, 100, &first), 0);
565     uint32_t second = 2;
566     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 2, 1, 1, 100, &second), 0);
567     uint32_t third = 3;
568     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 3, 1, 2, 100, &third), 0);
569     EXPECT_EQ(first, pldm_pdr_get_record_handle(
570                          repo, pldm_pdr_fru_record_set_find_by_rsi(
571                                    repo, 1, &terminusHdl, &entityType,
572                                    &entityInstanceNum, &containerId)));
573     EXPECT_EQ(second, pldm_pdr_get_record_handle(
574                           repo, pldm_pdr_fru_record_set_find_by_rsi(
575                                     repo, 2, &terminusHdl, &entityType,
576                                     &entityInstanceNum, &containerId)));
577     EXPECT_EQ(third, pldm_pdr_get_record_handle(
578                          repo, pldm_pdr_fru_record_set_find_by_rsi(
579                                    repo, 3, &terminusHdl, &entityType,
580                                    &entityInstanceNum, &containerId)));
581     EXPECT_EQ(terminusHdl, 1u);
582     EXPECT_EQ(entityType, 1u);
583     EXPECT_EQ(entityInstanceNum, 2u);
584     EXPECT_EQ(containerId, 100u);
585     EXPECT_EQ(nullptr, pldm_pdr_fru_record_set_find_by_rsi(
586                            repo, 4, &terminusHdl, &entityType,
587                            &entityInstanceNum, &containerId));
588 
589     pldm_pdr_destroy(repo);
590 }
591 
592 #ifdef LIBPLDM_API_TESTING
593 TEST(PDRUpdate, testFindLastInRange)
594 {
595     auto repo = pldm_pdr_init();
596 
597     std::array<uint8_t, 10> data{};
598     uint32_t handle1 = 0;
599     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle1),
600               0);
601     uint32_t handle2 = 23;
602     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle2),
603               0);
604     uint32_t handle3 = 77;
605     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), false, 1, &handle3),
606               0);
607     uint32_t handle4 = 16777325;
608     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle4),
609               0);
610     uint32_t handle5 = 16777344;
611     EXPECT_EQ(pldm_pdr_add(repo, data.data(), data.size(), true, 1, &handle5),
612               0);
613 
614     auto rec1 = pldm_pdr_find_last_in_range(repo, 0, 100);
615     auto rec2 = pldm_pdr_find_last_in_range(repo, 16777300, 33554431);
616     EXPECT_NE(rec1, nullptr);
617     EXPECT_NE(rec2, nullptr);
618     EXPECT_NE(handle1, pldm_pdr_get_record_handle(repo, rec1));
619     EXPECT_NE(handle2, pldm_pdr_get_record_handle(repo, rec1));
620     EXPECT_EQ(handle3, pldm_pdr_get_record_handle(repo, rec1));
621     EXPECT_NE(handle4, pldm_pdr_get_record_handle(repo, rec2));
622     EXPECT_EQ(handle5, pldm_pdr_get_record_handle(repo, rec2));
623 
624     pldm_pdr_destroy(repo);
625 }
626 #endif
627 
628 #ifdef LIBPLDM_API_TESTING
629 TEST(PDRAccess, testGetTerminusHandle)
630 {
631 
632     auto repo = pldm_pdr_init();
633 
634     pldm_pdr_hdr hdr;
635 
636     hdr.type = 1;
637     uint16_t firstTerminusHandle = 1;
638     EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<const uint8_t*>(&hdr),
639                                  sizeof(hdr), false, firstTerminusHandle, NULL),
640               0);
641 
642     hdr.type = 2;
643     uint16_t secondTerminusHandle = 2;
644     EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<const uint8_t*>(&hdr),
645                                  sizeof(hdr), true, secondTerminusHandle, NULL),
646               0);
647 
648     hdr.type = 3;
649     uint16_t thirdTerminusHandle = 3;
650     EXPECT_EQ(pldm_pdr_add_check(repo, reinterpret_cast<const uint8_t*>(&hdr),
651                                  sizeof(hdr), true, thirdTerminusHandle, NULL),
652               0);
653 
654     uint8_t* outData = nullptr;
655     uint32_t size{};
656 
657     auto firstRec =
658         pldm_pdr_find_record_by_type(repo, 1, nullptr, &outData, &size);
659     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, firstRec),
660               firstTerminusHandle);
661     outData = nullptr;
662 
663     auto secondRec =
664         pldm_pdr_find_record_by_type(repo, 2, nullptr, &outData, &size);
665     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, secondRec),
666               secondTerminusHandle);
667     outData = nullptr;
668 
669     auto thirdRec =
670         pldm_pdr_find_record_by_type(repo, 3, nullptr, &outData, &size);
671     EXPECT_EQ(pldm_pdr_get_terminus_handle(repo, thirdRec),
672               thirdTerminusHandle);
673     outData = nullptr;
674 
675     pldm_pdr_destroy(repo);
676 }
677 #endif
678 
679 TEST(EntityAssociationPDR, testInit)
680 {
681     auto tree = pldm_entity_association_tree_init();
682     EXPECT_NE(tree, nullptr);
683     pldm_entity_association_tree_destroy(tree);
684 }
685 
686 TEST(EntityAssociationPDR, testBuild)
687 {
688     //        1
689     //        |
690     //        2--3--4
691     //        |
692     //        5--6--7
693     //        |  |
694     //        9  8
695 
696     pldm_entity entities[9]{};
697 
698     entities[0].entity_type = 1;
699     entities[1].entity_type = 2;
700     entities[2].entity_type = 2;
701     entities[3].entity_type = 3;
702     entities[4].entity_type = 4;
703     entities[5].entity_type = 5;
704     entities[6].entity_type = 5;
705     entities[7].entity_type = 6;
706     entities[8].entity_type = 7;
707 
708     auto tree = pldm_entity_association_tree_init();
709 
710     auto l1 = pldm_entity_association_tree_add(
711         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
712     EXPECT_NE(l1, nullptr);
713     auto l2a = pldm_entity_association_tree_add(
714         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
715     EXPECT_NE(l2a, nullptr);
716     auto l2b = pldm_entity_association_tree_add(
717         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
718     EXPECT_NE(l2b, nullptr);
719     auto l2c = pldm_entity_association_tree_add(
720         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
721     EXPECT_NE(l2c, nullptr);
722     auto l3a = pldm_entity_association_tree_add(
723         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
724     EXPECT_NE(l3a, nullptr);
725     auto l3b = pldm_entity_association_tree_add(
726         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
727     EXPECT_NE(l3b, nullptr);
728     auto l3c = pldm_entity_association_tree_add(
729         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
730     EXPECT_NE(l3b, nullptr);
731     auto l4a = pldm_entity_association_tree_add(
732         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
733     EXPECT_NE(l4a, nullptr);
734     auto l4b = pldm_entity_association_tree_add(
735         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
736     EXPECT_NE(l4b, nullptr);
737 
738     EXPECT_EQ(pldm_entity_is_node_parent(l1), true);
739     EXPECT_EQ(pldm_entity_is_node_parent(l2a), true);
740     EXPECT_EQ(pldm_entity_is_node_parent(l3a), true);
741     EXPECT_EQ(pldm_entity_is_node_parent(l3b), true);
742 
743     EXPECT_EQ(pldm_entity_is_node_parent(l2b), false);
744     EXPECT_EQ(pldm_entity_is_node_parent(l2c), false);
745     EXPECT_EQ(pldm_entity_is_node_parent(l3c), false);
746     EXPECT_EQ(pldm_entity_is_node_parent(l4a), false);
747     EXPECT_EQ(pldm_entity_is_node_parent(l4b), false);
748 
749     EXPECT_EQ(pldm_entity_is_exist_parent(l1), false);
750 
751     pldm_entity nodeL1 = pldm_entity_extract(l1);
752     pldm_entity parentL2a = pldm_entity_get_parent(l2a);
753     pldm_entity parentL2b = pldm_entity_get_parent(l2b);
754     pldm_entity parentL2c = pldm_entity_get_parent(l2c);
755     EXPECT_EQ(pldm_entity_is_exist_parent(l2a), true);
756     EXPECT_EQ(pldm_entity_is_exist_parent(l2b), true);
757     EXPECT_EQ(pldm_entity_is_exist_parent(l2c), true);
758     EXPECT_EQ(parentL2a.entity_type, nodeL1.entity_type);
759     EXPECT_EQ(parentL2a.entity_instance_num, nodeL1.entity_instance_num);
760     EXPECT_EQ(parentL2a.entity_container_id, nodeL1.entity_container_id);
761     EXPECT_EQ(parentL2b.entity_type, nodeL1.entity_type);
762     EXPECT_EQ(parentL2b.entity_instance_num, nodeL1.entity_instance_num);
763     EXPECT_EQ(parentL2b.entity_container_id, nodeL1.entity_container_id);
764     EXPECT_EQ(parentL2c.entity_type, nodeL1.entity_type);
765     EXPECT_EQ(parentL2c.entity_instance_num, nodeL1.entity_instance_num);
766     EXPECT_EQ(parentL2c.entity_container_id, nodeL1.entity_container_id);
767 
768     pldm_entity nodeL2a = pldm_entity_extract(l2a);
769     pldm_entity parentL3a = pldm_entity_get_parent(l3a);
770     pldm_entity parentL3b = pldm_entity_get_parent(l3b);
771     pldm_entity parentL3c = pldm_entity_get_parent(l3c);
772     EXPECT_EQ(pldm_entity_is_exist_parent(l3a), true);
773     EXPECT_EQ(pldm_entity_is_exist_parent(l3b), true);
774     EXPECT_EQ(pldm_entity_is_exist_parent(l3c), true);
775     EXPECT_EQ(parentL3a.entity_type, nodeL2a.entity_type);
776     EXPECT_EQ(parentL3a.entity_instance_num, nodeL2a.entity_instance_num);
777     EXPECT_EQ(parentL3a.entity_container_id, nodeL2a.entity_container_id);
778     EXPECT_EQ(parentL3b.entity_type, nodeL2a.entity_type);
779     EXPECT_EQ(parentL3b.entity_instance_num, nodeL2a.entity_instance_num);
780     EXPECT_EQ(parentL3b.entity_container_id, nodeL2a.entity_container_id);
781     EXPECT_EQ(parentL3c.entity_type, nodeL2a.entity_type);
782     EXPECT_EQ(parentL3c.entity_instance_num, nodeL2a.entity_instance_num);
783     EXPECT_EQ(parentL3c.entity_container_id, nodeL2a.entity_container_id);
784 
785     pldm_entity nodeL3a = pldm_entity_extract(l3a);
786     pldm_entity parentL4a = pldm_entity_get_parent(l4a);
787     EXPECT_EQ(pldm_entity_is_exist_parent(l4a), true);
788     EXPECT_EQ(parentL4a.entity_type, nodeL3a.entity_type);
789     EXPECT_EQ(parentL4a.entity_instance_num, nodeL3a.entity_instance_num);
790     EXPECT_EQ(parentL4a.entity_container_id, nodeL3a.entity_container_id);
791 
792     pldm_entity nodeL3b = pldm_entity_extract(l3b);
793     pldm_entity parentL4b = pldm_entity_get_parent(l4b);
794     EXPECT_EQ(pldm_entity_is_exist_parent(l4b), true);
795     EXPECT_EQ(parentL4b.entity_type, nodeL3b.entity_type);
796     EXPECT_EQ(parentL4b.entity_instance_num, nodeL3b.entity_instance_num);
797     EXPECT_EQ(parentL4b.entity_container_id, nodeL3b.entity_container_id);
798 
799     size_t num{};
800     pldm_entity* out = nullptr;
801     pldm_entity_association_tree_visit(tree, &out, &num);
802     EXPECT_EQ(num, 9u);
803 
804     EXPECT_EQ(out[0].entity_type, 1u);
805     EXPECT_EQ(out[0].entity_instance_num, 1u);
806     EXPECT_EQ(out[0].entity_container_id, 0u);
807 
808     EXPECT_EQ(out[1].entity_type, 2u);
809     EXPECT_EQ(out[1].entity_instance_num, 1u);
810     EXPECT_EQ(out[1].entity_container_id, 1u);
811     EXPECT_EQ(out[2].entity_type, 2u);
812     EXPECT_EQ(out[2].entity_instance_num, 2u);
813     EXPECT_EQ(out[2].entity_container_id, 1u);
814     EXPECT_EQ(out[3].entity_type, 3u);
815     EXPECT_EQ(out[3].entity_instance_num, 1u);
816     EXPECT_EQ(out[3].entity_container_id, 1u);
817 
818     EXPECT_EQ(out[4].entity_type, 4u);
819     EXPECT_EQ(out[4].entity_instance_num, 1u);
820     EXPECT_EQ(out[4].entity_container_id, 2u);
821     EXPECT_EQ(out[5].entity_type, 5u);
822     EXPECT_EQ(out[5].entity_instance_num, 1u);
823     EXPECT_EQ(out[5].entity_container_id, 2u);
824     EXPECT_EQ(out[6].entity_type, 5u);
825     EXPECT_EQ(out[6].entity_instance_num, 2u);
826     EXPECT_EQ(out[6].entity_container_id, 2u);
827 
828     EXPECT_EQ(out[7].entity_type, 7u);
829     EXPECT_EQ(out[7].entity_instance_num, 1u);
830     EXPECT_EQ(out[7].entity_container_id, 4u);
831     EXPECT_EQ(out[8].entity_type, 6u);
832     EXPECT_EQ(out[8].entity_instance_num, 1u);
833     EXPECT_EQ(out[8].entity_container_id, 3u);
834 
835     free(out);
836 
837     pldm_entity p1 = pldm_entity_extract(l1);
838     EXPECT_EQ(p1.entity_type, 1u);
839     EXPECT_EQ(p1.entity_instance_num, 1u);
840     EXPECT_EQ(p1.entity_container_id, 0u);
841 
842     pldm_entity p2a = pldm_entity_extract(l2a);
843     EXPECT_EQ(p2a.entity_type, 2u);
844     EXPECT_EQ(p2a.entity_instance_num, 1u);
845     EXPECT_EQ(p2a.entity_container_id, 1u);
846     pldm_entity p2b = pldm_entity_extract(l2b);
847     EXPECT_EQ(p2b.entity_type, 2u);
848     EXPECT_EQ(p2b.entity_instance_num, 2u);
849     EXPECT_EQ(p2b.entity_container_id, 1u);
850     pldm_entity p2c = pldm_entity_extract(l2c);
851     EXPECT_EQ(p2c.entity_type, 3u);
852     EXPECT_EQ(p2c.entity_instance_num, 1u);
853     EXPECT_EQ(p2c.entity_container_id, 1u);
854 
855     pldm_entity p3a = pldm_entity_extract(l3a);
856     EXPECT_EQ(p3a.entity_type, 4u);
857     EXPECT_EQ(p3a.entity_instance_num, 1u);
858     EXPECT_EQ(p3a.entity_container_id, 2u);
859     pldm_entity p3b = pldm_entity_extract(l3b);
860     EXPECT_EQ(p3b.entity_type, 5u);
861     EXPECT_EQ(p3b.entity_instance_num, 1u);
862     EXPECT_EQ(p3b.entity_container_id, 2u);
863     pldm_entity p3c = pldm_entity_extract(l3c);
864     EXPECT_EQ(p3c.entity_type, 5u);
865     EXPECT_EQ(p3c.entity_instance_num, 2u);
866     EXPECT_EQ(p3c.entity_container_id, 2u);
867 
868     pldm_entity p4a = pldm_entity_extract(l4a);
869     EXPECT_EQ(p4a.entity_type, 6u);
870     EXPECT_EQ(p4a.entity_instance_num, 1u);
871     EXPECT_EQ(p4a.entity_container_id, 3u);
872     pldm_entity p4b = pldm_entity_extract(l4b);
873     EXPECT_EQ(p4b.entity_type, 7u);
874     EXPECT_EQ(p4b.entity_instance_num, 1u);
875     EXPECT_EQ(p4b.entity_container_id, 4u);
876 
877     pldm_entity_association_tree_destroy(tree);
878 }
879 
880 #if LIBPLDM_API_TESTING
881 TEST(EntityAssociationPDR, findAndAddRemotePDR)
882 {
883     //         Tree - 1
884     //
885     //        11521(1,0)
886     //             |
887     //          45 (1,1)
888     //             |
889     //          64 (1,2)
890     //             |
891     //    ------------------
892     //    |                 |
893     //  67(0,3)           67(1,3)
894     //    |                 |
895     // 135(0,4)          135(0,5)
896     //    |                 |
897     // 32903(0,6)         32903(0,7)
898 
899     pldm_entity entities[9]{};
900     entities[0].entity_type = 11521;
901     entities[1].entity_type = 45;
902     entities[2].entity_type = 64;
903     entities[3].entity_type = 67;
904     entities[4].entity_type = 67;
905     entities[5].entity_type = 135;
906     entities[5].entity_container_id = 2;
907     entities[6].entity_type = 135;
908     entities[6].entity_container_id = 3;
909     entities[7].entity_type = 32903;
910     entities[8].entity_type = 32903;
911     auto tree = pldm_entity_association_tree_init();
912     auto l1 = pldm_entity_association_tree_add_entity(
913         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
914         false, true, 0xffff);
915     EXPECT_NE(l1, nullptr);
916     auto l2 = pldm_entity_association_tree_add_entity(
917         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
918         false, 0xffff);
919     EXPECT_NE(l2, nullptr);
920     auto l3 = pldm_entity_association_tree_add_entity(
921         tree, &entities[2], 0xffff, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
922         true, 0xffff);
923     EXPECT_NE(l3, nullptr);
924     auto l4a = pldm_entity_association_tree_add_entity(
925         tree, &entities[3], 0, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
926         false, 0xffff);
927     EXPECT_NE(l4a, nullptr);
928     auto l4b = pldm_entity_association_tree_add_entity(
929         tree, &entities[4], 1, l3, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
930         0xffff);
931     EXPECT_NE(l4b, nullptr);
932     auto l5a = pldm_entity_association_tree_add_entity(
933         tree, &entities[5], 0, l4a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
934         false, 0xffff);
935     EXPECT_NE(l5a, nullptr);
936     auto l5b = pldm_entity_association_tree_add_entity(
937         tree, &entities[6], 0, l4b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
938         false, 0xffff);
939     EXPECT_NE(l5b, nullptr);
940     pldm_entity entity{};
941     entity.entity_type = 135;
942     entity.entity_instance_num = 0;
943     entity.entity_container_id = 2;
944     auto result1 = pldm_entity_association_tree_find(tree, &entity);
945     EXPECT_EQ(result1, l5a);
946     EXPECT_EQ(entities[5].entity_container_id, 2);
947     auto l6a = pldm_entity_association_tree_add_entity(
948         tree, &entities[7], 0, result1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
949         false, 0xffff);
950     EXPECT_NE(l6a, nullptr);
951     entity.entity_type = 135;
952     entity.entity_instance_num = 0;
953     entity.entity_container_id = 3;
954     auto result2 = pldm_entity_association_tree_find(tree, &entity);
955     EXPECT_NE(result2, l5b);
956     EXPECT_EQ(entities[6].entity_container_id, 3);
957     auto l7a = pldm_entity_association_tree_add_entity(
958         tree, &entities[8], 0, result2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
959         false, 0xffff);
960     EXPECT_EQ(l7a, nullptr);
961     pldm_entity_association_tree_destroy(tree);
962 }
963 #endif
964 
965 TEST(EntityAssociationPDR, testSpecialTrees)
966 {
967     pldm_entity entities[3]{};
968 
969     entities[0].entity_type = 1;
970     entities[1].entity_type = 2;
971     entities[2].entity_type = 1;
972 
973     // A
974     auto tree = pldm_entity_association_tree_init();
975     auto node = pldm_entity_association_tree_add(
976         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
977     EXPECT_NE(node, nullptr);
978     size_t num{};
979     pldm_entity* out = nullptr;
980     pldm_entity_association_tree_visit(tree, &out, &num);
981     EXPECT_EQ(num, 1u);
982     EXPECT_EQ(out[0].entity_type, 1u);
983     EXPECT_EQ(out[0].entity_instance_num, 1u);
984     EXPECT_EQ(out[0].entity_container_id, 0u);
985     free(out);
986     pldm_entity_association_tree_destroy(tree);
987 
988     // A-A-A
989     tree = pldm_entity_association_tree_init();
990     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
991                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
992     EXPECT_NE(node, nullptr);
993     node = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, nullptr,
994                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
995     EXPECT_NE(node, nullptr);
996     node = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, nullptr,
997                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
998     EXPECT_NE(node, nullptr);
999     pldm_entity_association_tree_visit(tree, &out, &num);
1000     EXPECT_EQ(num, 3u);
1001     EXPECT_EQ(out[0].entity_type, 1u);
1002     EXPECT_EQ(out[0].entity_instance_num, 1u);
1003     EXPECT_EQ(out[0].entity_container_id, 0u);
1004     EXPECT_EQ(out[1].entity_type, 1u);
1005     EXPECT_EQ(out[1].entity_instance_num, 2u);
1006     EXPECT_EQ(out[1].entity_container_id, 0u);
1007     EXPECT_EQ(out[2].entity_type, 2u);
1008     EXPECT_EQ(out[2].entity_instance_num, 1u);
1009     EXPECT_EQ(out[2].entity_container_id, 0u);
1010     free(out);
1011     pldm_entity_association_tree_destroy(tree);
1012 
1013     // A
1014     // |
1015     // A
1016     // |
1017     // A
1018     tree = pldm_entity_association_tree_init();
1019     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1020                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1021     EXPECT_NE(node, nullptr);
1022     auto node1 = pldm_entity_association_tree_add(
1023         tree, &entities[1], 0xffff, node, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1024     EXPECT_NE(node1, nullptr);
1025     auto node2 = pldm_entity_association_tree_add(
1026         tree, &entities[2], 0xffff, node1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1027     EXPECT_NE(node2, nullptr);
1028     pldm_entity_association_tree_visit(tree, &out, &num);
1029     EXPECT_EQ(num, 3u);
1030     EXPECT_EQ(out[0].entity_type, 1u);
1031     EXPECT_EQ(out[0].entity_instance_num, 1u);
1032     EXPECT_EQ(out[0].entity_container_id, 0u);
1033     EXPECT_EQ(out[1].entity_type, 2u);
1034     EXPECT_EQ(out[1].entity_instance_num, 1u);
1035     EXPECT_EQ(out[1].entity_container_id, 1u);
1036     EXPECT_EQ(out[2].entity_type, 1u);
1037     EXPECT_EQ(out[2].entity_instance_num, 1u);
1038     EXPECT_EQ(out[2].entity_container_id, 2u);
1039     free(out);
1040     pldm_entity_association_tree_destroy(tree);
1041 
1042     // A-A
1043     //   |
1044     //   A-A
1045     tree = pldm_entity_association_tree_init();
1046     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1047                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1048     EXPECT_NE(node, nullptr);
1049     node = pldm_entity_association_tree_add(tree, &entities[0], 0xffff, nullptr,
1050                                             PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1051     EXPECT_NE(node, nullptr);
1052     node1 = pldm_entity_association_tree_add(tree, &entities[1], 0xffff, node,
1053                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1054     EXPECT_NE(node1, nullptr);
1055     node2 = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, node,
1056                                              PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1057     EXPECT_NE(node2, nullptr);
1058     pldm_entity_association_tree_visit(tree, &out, &num);
1059     EXPECT_EQ(num, 4u);
1060     EXPECT_EQ(out[0].entity_type, 1u);
1061     EXPECT_EQ(out[0].entity_instance_num, 1u);
1062     EXPECT_EQ(out[0].entity_container_id, 0u);
1063     EXPECT_EQ(out[1].entity_type, 1u);
1064     EXPECT_EQ(out[1].entity_instance_num, 2u);
1065     EXPECT_EQ(out[1].entity_container_id, 0u);
1066     EXPECT_EQ(out[2].entity_type, 2u);
1067     EXPECT_EQ(out[2].entity_instance_num, 1u);
1068     EXPECT_EQ(out[2].entity_container_id, 1u);
1069     EXPECT_EQ(out[3].entity_type, 1u);
1070     EXPECT_EQ(out[3].entity_instance_num, 1u);
1071     EXPECT_EQ(out[3].entity_container_id, 1u);
1072     free(out);
1073     pldm_entity_association_tree_destroy(tree);
1074 }
1075 
1076 TEST(EntityAssociationPDR, testPDR)
1077 {
1078     // e = entity type, c = container id, i = instance num
1079 
1080     //        INPUT
1081     //        1(e=1)--1a(e=2)
1082     //        |
1083     //        2(e=2)--3(e=2)--4(e=2)--5(e=3)
1084     //        |
1085     //        6(e=4)--7(e=5)--8(e=5)--9(e=5)
1086     //        |       |
1087     //        11(e=6) 10(e=7)
1088 
1089     //        Expected OUTPUT
1090     //        1(e=1,c=0,i=1)
1091     //        |
1092     //        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)
1093     //        |
1094     //        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)
1095     //        |               |
1096     //        10(e=6,c=3,i=1) 11(e=7,c=4,i=1)
1097     pldm_entity entities[11]{};
1098 
1099     entities[0].entity_type = 1;
1100     entities[1].entity_type = 2;
1101     entities[2].entity_type = 3;
1102     entities[3].entity_type = 2;
1103     entities[4].entity_type = 3;
1104     entities[5].entity_type = 4;
1105     entities[6].entity_type = 5;
1106     entities[7].entity_type = 5;
1107     entities[8].entity_type = 5;
1108     entities[9].entity_type = 6;
1109     entities[10].entity_type = 7;
1110 
1111     auto tree = pldm_entity_association_tree_init();
1112 
1113     auto l1 = pldm_entity_association_tree_add(
1114         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1115     EXPECT_NE(l1, nullptr);
1116     auto l1a = pldm_entity_association_tree_add(
1117         tree, &entities[1], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1118     EXPECT_NE(l1a, nullptr);
1119 
1120     auto l2a = pldm_entity_association_tree_add(
1121         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1122     EXPECT_NE(l2a, nullptr);
1123     auto l2b = pldm_entity_association_tree_add(tree, &entities[2], 0xffff, l1,
1124                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1125     EXPECT_NE(l2b, nullptr);
1126     auto l2c = pldm_entity_association_tree_add(
1127         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1128     EXPECT_NE(l2c, nullptr);
1129     auto l2d = pldm_entity_association_tree_add(tree, &entities[4], 0xffff, l1,
1130                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1131     EXPECT_NE(l2d, nullptr);
1132 
1133     auto l3a = pldm_entity_association_tree_add(
1134         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1135     EXPECT_NE(l3a, nullptr);
1136     auto l3b = pldm_entity_association_tree_add(
1137         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1138     EXPECT_NE(l3b, nullptr);
1139     auto l3c = pldm_entity_association_tree_add(tree, &entities[7], 0xffff, l2a,
1140                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1141     EXPECT_NE(l3c, nullptr);
1142     auto l3d = pldm_entity_association_tree_add(tree, &entities[8], 0xffff, l2a,
1143                                                 PLDM_ENTITY_ASSOCIAION_LOGICAL);
1144     EXPECT_NE(l3d, nullptr);
1145 
1146     auto l4a = pldm_entity_association_tree_add(
1147         tree, &entities[9], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1148     EXPECT_NE(l4a, nullptr);
1149     auto l4b = pldm_entity_association_tree_add(
1150         tree, &entities[10], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1151     EXPECT_NE(l4b, nullptr);
1152 
1153     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
1154               2);
1155     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1156               2);
1157     EXPECT_EQ(
1158         pldm_entity_get_num_children(l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 2);
1159     EXPECT_EQ(
1160         pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL), 0);
1161     EXPECT_EQ(pldm_entity_get_num_children(l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL),
1162               1);
1163 
1164     auto repo = pldm_pdr_init();
1165     int rc = pldm_entity_association_pdr_add(tree, repo, false, 1);
1166     ASSERT_EQ(rc, 0);
1167 
1168     EXPECT_EQ(pldm_pdr_get_record_count(repo), 6u);
1169 
1170     uint32_t currRecHandle{};
1171     uint32_t nextRecHandle{};
1172     uint8_t* data = nullptr;
1173     uint32_t size{};
1174     uint32_t commonSize = sizeof(struct pldm_pdr_hdr) + sizeof(uint16_t) +
1175                           sizeof(uint8_t) + sizeof(pldm_entity) +
1176                           sizeof(uint8_t);
1177 
1178     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1179     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1180                                       l1, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1181                                   sizeof(pldm_entity)));
1182     uint8_t* start = data;
1183     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1184     EXPECT_EQ(le32toh(hdr->record_handle), 1u);
1185     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1186     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1187     start += sizeof(pldm_pdr_hdr);
1188     uint16_t* containerId = reinterpret_cast<uint16_t*>(start);
1189     EXPECT_EQ(le16toh(*containerId), 1u);
1190     start += sizeof(uint16_t);
1191     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1192     start += sizeof(uint8_t);
1193     pldm_entity* entity = reinterpret_cast<pldm_entity*>(start);
1194     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1195     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1196     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1197     start += sizeof(pldm_entity);
1198     EXPECT_EQ(*start,
1199               pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1200     start += sizeof(uint8_t);
1201     entity = reinterpret_cast<pldm_entity*>(start);
1202     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1203     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1204     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1205     start += sizeof(pldm_entity);
1206     entity = reinterpret_cast<pldm_entity*>(start);
1207     EXPECT_EQ(le16toh(entity->entity_type), 3u);
1208     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1209     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1210 
1211     currRecHandle = nextRecHandle;
1212 
1213     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1214     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1215                                       l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1216                                   sizeof(pldm_entity)));
1217     start = data;
1218     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1219     EXPECT_EQ(le32toh(hdr->record_handle), 2u);
1220     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1221     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1222     start += sizeof(pldm_pdr_hdr);
1223     containerId = reinterpret_cast<uint16_t*>(start);
1224     EXPECT_EQ(le16toh(*containerId), 1u);
1225     start += sizeof(uint16_t);
1226     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1227     start += sizeof(uint8_t);
1228     entity = reinterpret_cast<pldm_entity*>(start);
1229     EXPECT_EQ(le16toh(entity->entity_type), 1u);
1230     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1231     EXPECT_EQ(le16toh(entity->entity_container_id), 0u);
1232     start += sizeof(pldm_entity);
1233     EXPECT_EQ(*start, pldm_entity_get_num_children(
1234                           l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1235     start += sizeof(uint8_t);
1236     entity = reinterpret_cast<pldm_entity*>(start);
1237     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1238     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1239     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1240     start += sizeof(pldm_entity);
1241     entity = reinterpret_cast<pldm_entity*>(start);
1242     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1243     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1244     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1245 
1246     currRecHandle = nextRecHandle;
1247 
1248     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1249     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1250                                       l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1251                                   sizeof(pldm_entity)));
1252     start = data;
1253     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1254     EXPECT_EQ(le32toh(hdr->record_handle), 3u);
1255     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1256     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1257     start += sizeof(pldm_pdr_hdr);
1258     containerId = reinterpret_cast<uint16_t*>(start);
1259     EXPECT_EQ(le16toh(*containerId), 2u);
1260     start += sizeof(uint16_t);
1261     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1262     start += sizeof(uint8_t);
1263     entity = reinterpret_cast<pldm_entity*>(start);
1264     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1265     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1266     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1267     start += sizeof(pldm_entity);
1268     EXPECT_EQ(*start, pldm_entity_get_num_children(
1269                           l2a, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1270     start += sizeof(uint8_t);
1271     entity = reinterpret_cast<pldm_entity*>(start);
1272     EXPECT_EQ(le16toh(entity->entity_type), 5);
1273     EXPECT_EQ(le16toh(entity->entity_instance_num), 2u);
1274     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1275     start += sizeof(pldm_entity);
1276     entity = reinterpret_cast<pldm_entity*>(start);
1277     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1278     EXPECT_EQ(le16toh(entity->entity_instance_num), 3u);
1279     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1280 
1281     currRecHandle = nextRecHandle;
1282 
1283     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1284     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1285                                       l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1286                                   sizeof(pldm_entity)));
1287     start = data;
1288     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1289     EXPECT_EQ(le32toh(hdr->record_handle), 4u);
1290     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1291     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1292     start += sizeof(pldm_pdr_hdr);
1293     containerId = reinterpret_cast<uint16_t*>(start);
1294     EXPECT_EQ(le16toh(*containerId), 2u);
1295     start += sizeof(uint16_t);
1296     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1297     start += sizeof(uint8_t);
1298     entity = reinterpret_cast<pldm_entity*>(start);
1299     EXPECT_EQ(le16toh(entity->entity_type), 2u);
1300     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1301     EXPECT_EQ(le16toh(entity->entity_container_id), 1u);
1302     start += sizeof(pldm_entity);
1303     EXPECT_EQ(*start, pldm_entity_get_num_children(
1304                           l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1305     start += sizeof(uint8_t);
1306     entity = reinterpret_cast<pldm_entity*>(start);
1307     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1308     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1309     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1310     start += sizeof(pldm_entity);
1311     entity = reinterpret_cast<pldm_entity*>(start);
1312     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1313     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1314     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1315 
1316     currRecHandle = nextRecHandle;
1317 
1318     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1319     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1320                                       l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL) *
1321                                   sizeof(pldm_entity)));
1322     start = data;
1323     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1324     EXPECT_EQ(le32toh(hdr->record_handle), 5u);
1325     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1326     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1327     start += sizeof(pldm_pdr_hdr);
1328     containerId = reinterpret_cast<uint16_t*>(start);
1329     EXPECT_EQ(le16toh(*containerId), 3u);
1330     start += sizeof(uint16_t);
1331     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1332     start += sizeof(uint8_t);
1333     entity = reinterpret_cast<pldm_entity*>(start);
1334     EXPECT_EQ(le16toh(entity->entity_type), 4u);
1335     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1336     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1337     start += sizeof(pldm_entity);
1338     EXPECT_EQ(*start, pldm_entity_get_num_children(
1339                           l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL));
1340     start += sizeof(uint8_t);
1341     entity = reinterpret_cast<pldm_entity*>(start);
1342     EXPECT_EQ(le16toh(entity->entity_type), 6u);
1343     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1344     EXPECT_EQ(le16toh(entity->entity_container_id), 3u);
1345 
1346     currRecHandle = nextRecHandle;
1347 
1348     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
1349     EXPECT_EQ(size, commonSize + (pldm_entity_get_num_children(
1350                                       l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL) *
1351                                   sizeof(pldm_entity)));
1352     start = data;
1353     hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
1354     EXPECT_EQ(le32toh(hdr->record_handle), 6u);
1355     EXPECT_EQ(hdr->type, PLDM_PDR_ENTITY_ASSOCIATION);
1356     EXPECT_EQ(le16toh(hdr->length), size - sizeof(struct pldm_pdr_hdr));
1357     start += sizeof(pldm_pdr_hdr);
1358     containerId = reinterpret_cast<uint16_t*>(start);
1359     EXPECT_EQ(le16toh(*containerId), 4u);
1360     start += sizeof(uint16_t);
1361     EXPECT_EQ(*start, PLDM_ENTITY_ASSOCIAION_LOGICAL);
1362     start += sizeof(uint8_t);
1363     entity = reinterpret_cast<pldm_entity*>(start);
1364     EXPECT_EQ(le16toh(entity->entity_type), 5u);
1365     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1366     EXPECT_EQ(le16toh(entity->entity_container_id), 2u);
1367     start += sizeof(pldm_entity);
1368     EXPECT_EQ(*start, pldm_entity_get_num_children(
1369                           l3b, PLDM_ENTITY_ASSOCIAION_LOGICAL));
1370     start += sizeof(uint8_t);
1371     entity = reinterpret_cast<pldm_entity*>(start);
1372     EXPECT_EQ(le16toh(entity->entity_type), 7u);
1373     EXPECT_EQ(le16toh(entity->entity_instance_num), 1u);
1374     EXPECT_EQ(le16toh(entity->entity_container_id), 4u);
1375 
1376     EXPECT_EQ(nextRecHandle, 0u);
1377 
1378     pldm_pdr_destroy(repo);
1379     pldm_entity_association_tree_destroy(tree);
1380 }
1381 
1382 TEST(EntityAssociationPDR, testFind)
1383 {
1384     //        1
1385     //        |
1386     //        2--3--4
1387     //        |
1388     //        5--6--7
1389     //        |  |
1390     //        8  9
1391 
1392     pldm_entity entities[9]{};
1393 
1394     entities[0].entity_type = 1;
1395     entities[1].entity_type = 2;
1396     entities[2].entity_type = 2;
1397     entities[3].entity_type = 3;
1398     entities[4].entity_type = 4;
1399     entities[5].entity_type = 5;
1400     entities[6].entity_type = 5;
1401     entities[7].entity_type = 6;
1402     entities[8].entity_type = 7;
1403 
1404     auto tree = pldm_entity_association_tree_init();
1405 
1406     auto l1 = pldm_entity_association_tree_add(
1407         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1408     EXPECT_NE(l1, nullptr);
1409     auto l2a = pldm_entity_association_tree_add(
1410         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1411     EXPECT_NE(l2a, nullptr);
1412     auto l2b = pldm_entity_association_tree_add(
1413         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1414     EXPECT_NE(l2b, nullptr);
1415     auto l2c = pldm_entity_association_tree_add(
1416         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1417     EXPECT_NE(l2c, nullptr);
1418     auto l3a = pldm_entity_association_tree_add(
1419         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1420     EXPECT_NE(l3a, nullptr);
1421     auto l3b = pldm_entity_association_tree_add(
1422         tree, &entities[5], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1423     EXPECT_NE(l3b, nullptr);
1424     auto l3c = pldm_entity_association_tree_add(
1425         tree, &entities[6], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1426     EXPECT_NE(l3c, nullptr);
1427     auto l4a = pldm_entity_association_tree_add(
1428         tree, &entities[7], 0xffff, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1429     EXPECT_NE(l4a, nullptr);
1430     auto l4b = pldm_entity_association_tree_add(
1431         tree, &entities[8], 0xffff, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1432     EXPECT_NE(l4b, nullptr);
1433 
1434     pldm_entity entity{};
1435 
1436     entity.entity_type = 1;
1437     entity.entity_instance_num = 1;
1438     auto result = pldm_entity_association_tree_find(tree, &entity);
1439     EXPECT_EQ(result, l1);
1440     EXPECT_EQ(entity.entity_container_id, 0);
1441 
1442     entity.entity_type = 2;
1443     entity.entity_instance_num = 1;
1444     result = pldm_entity_association_tree_find(tree, &entity);
1445     EXPECT_EQ(result, l2a);
1446     EXPECT_EQ(entity.entity_container_id, 1);
1447     entity.entity_type = 2;
1448     entity.entity_instance_num = 2;
1449     result = pldm_entity_association_tree_find(tree, &entity);
1450     EXPECT_EQ(result, l2b);
1451     EXPECT_EQ(entity.entity_container_id, 1);
1452     entity.entity_type = 3;
1453     entity.entity_instance_num = 1;
1454     result = pldm_entity_association_tree_find(tree, &entity);
1455     EXPECT_EQ(result, l2c);
1456     EXPECT_EQ(entity.entity_container_id, 1);
1457 
1458     entity.entity_type = 7;
1459     entity.entity_instance_num = 1;
1460     result = pldm_entity_association_tree_find(tree, &entity);
1461     EXPECT_EQ(result, l4b);
1462     EXPECT_EQ(entity.entity_container_id, 4);
1463 
1464     pldm_entity_association_tree_destroy(tree);
1465 }
1466 
1467 TEST(EntityAssociationPDR, testCopyTree)
1468 {
1469     pldm_entity entities[4]{};
1470     entities[0].entity_type = 1;
1471     entities[1].entity_type = 2;
1472     entities[2].entity_type = 2;
1473     entities[3].entity_type = 3;
1474 
1475     auto orgTree = pldm_entity_association_tree_init();
1476     auto newTree = pldm_entity_association_tree_init();
1477     auto l1 =
1478         pldm_entity_association_tree_add(orgTree, &entities[0], 0xffff, nullptr,
1479                                          PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1480     EXPECT_NE(l1, nullptr);
1481     auto l2a = pldm_entity_association_tree_add(
1482         orgTree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1483     EXPECT_NE(l2a, nullptr);
1484     auto l2b = pldm_entity_association_tree_add(
1485         orgTree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1486     EXPECT_NE(l2b, nullptr);
1487     auto l2c = pldm_entity_association_tree_add(
1488         orgTree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1489     EXPECT_NE(l2c, nullptr);
1490     size_t orgNum{};
1491     pldm_entity* orgOut = nullptr;
1492     pldm_entity_association_tree_visit(orgTree, &orgOut, &orgNum);
1493     EXPECT_EQ(orgNum, 4u);
1494 
1495     pldm_entity_association_tree_copy_root(orgTree, newTree);
1496     size_t newNum{};
1497     pldm_entity* newOut = nullptr;
1498     pldm_entity_association_tree_visit(newTree, &newOut, &newNum);
1499     EXPECT_EQ(newNum, orgNum);
1500     EXPECT_EQ(newOut[0].entity_type, 1u);
1501     EXPECT_EQ(newOut[0].entity_instance_num, 1u);
1502     EXPECT_EQ(newOut[0].entity_container_id, 0u);
1503     free(orgOut);
1504     free(newOut);
1505     pldm_entity_association_tree_destroy(orgTree);
1506     pldm_entity_association_tree_destroy(newTree);
1507 }
1508 
1509 TEST(EntityAssociationPDR, testExtract)
1510 {
1511     std::vector<uint8_t> pdr{};
1512     pdr.resize(sizeof(pldm_pdr_hdr) + sizeof(pldm_pdr_entity_association) +
1513                sizeof(pldm_entity) * 4);
1514     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
1515     hdr->type = PLDM_PDR_ENTITY_ASSOCIATION;
1516     hdr->length =
1517         htole16(sizeof(pldm_pdr_entity_association) + sizeof(pldm_entity) * 4);
1518 
1519     pldm_pdr_entity_association* e =
1520         reinterpret_cast<pldm_pdr_entity_association*>(pdr.data() +
1521                                                        sizeof(pldm_pdr_hdr));
1522     e->container_id = htole16(1);
1523     e->num_children = 5;
1524     e->container.entity_type = htole16(1);
1525     e->container.entity_instance_num = htole16(1);
1526     e->container.entity_container_id = htole16(0);
1527 
1528     pldm_entity* entity = e->children;
1529     entity->entity_type = htole16(2);
1530     entity->entity_instance_num = htole16(1);
1531     entity->entity_container_id = htole16(1);
1532     ++entity;
1533     entity->entity_type = htole16(3);
1534     entity->entity_instance_num = htole16(1);
1535     entity->entity_container_id = htole16(1);
1536     ++entity;
1537     entity->entity_type = htole16(4);
1538     entity->entity_instance_num = htole16(1);
1539     entity->entity_container_id = htole16(1);
1540     ++entity;
1541     entity->entity_type = htole16(5);
1542     entity->entity_instance_num = htole16(1);
1543     entity->entity_container_id = htole16(1);
1544     ++entity;
1545     entity->entity_type = htole16(6);
1546     entity->entity_instance_num = htole16(1);
1547     entity->entity_container_id = htole16(1);
1548 
1549     size_t num{};
1550     pldm_entity* out = nullptr;
1551     pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &num, &out);
1552     EXPECT_EQ(num, (unsigned)e->num_children + 1);
1553     EXPECT_EQ(out[0].entity_type, 1u);
1554     EXPECT_EQ(out[0].entity_instance_num, 1u);
1555     EXPECT_EQ(out[0].entity_container_id, 0u);
1556     EXPECT_EQ(out[1].entity_type, 2u);
1557     EXPECT_EQ(out[1].entity_instance_num, 1u);
1558     EXPECT_EQ(out[1].entity_container_id, 1u);
1559     EXPECT_EQ(out[2].entity_type, 3u);
1560     EXPECT_EQ(out[2].entity_instance_num, 1u);
1561     EXPECT_EQ(out[2].entity_container_id, 1u);
1562     EXPECT_EQ(out[3].entity_type, 4u);
1563     EXPECT_EQ(out[3].entity_instance_num, 1u);
1564     EXPECT_EQ(out[3].entity_container_id, 1u);
1565     EXPECT_EQ(out[4].entity_type, 5u);
1566     EXPECT_EQ(out[4].entity_instance_num, 1u);
1567     EXPECT_EQ(out[4].entity_container_id, 1u);
1568     EXPECT_EQ(out[5].entity_type, 6u);
1569     EXPECT_EQ(out[5].entity_instance_num, 1u);
1570     EXPECT_EQ(out[5].entity_container_id, 1u);
1571 
1572     free(out);
1573 }
1574 
1575 TEST(EntityAssociationPDR, testGetChildren)
1576 {
1577     pldm_entity entities[4]{};
1578     entities[0].entity_type = 1;
1579     entities[1].entity_type = 2;
1580     entities[2].entity_type = 2;
1581     entities[3].entity_type = 3;
1582 
1583     auto tree = pldm_entity_association_tree_init();
1584     auto l1 = pldm_entity_association_tree_add(
1585         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1586     EXPECT_NE(l1, nullptr);
1587     auto l2a = pldm_entity_association_tree_add(
1588         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1589     EXPECT_NE(l2a, nullptr);
1590     auto l2b = pldm_entity_association_tree_add(
1591         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1592     EXPECT_NE(l2b, nullptr);
1593     auto l2c = pldm_entity_association_tree_add(
1594         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1595     EXPECT_NE(l2c, nullptr);
1596 
1597     pldm_entity et1;
1598     et1.entity_type = 2;
1599     et1.entity_instance_num = 1;
1600     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et1));
1601 
1602     pldm_entity et2;
1603     et2.entity_type = 2;
1604     et2.entity_instance_num = 2;
1605     EXPECT_EQ(true, pldm_is_current_parent_child(l1, &et2));
1606 
1607     pldm_entity et3;
1608     et3.entity_type = 2;
1609     et3.entity_instance_num = 3;
1610     EXPECT_EQ(false, pldm_is_current_parent_child(l1, &et3));
1611 
1612     pldm_entity_association_tree_destroy(tree);
1613 }
1614 
1615 TEST(EntityAssociationPDR, testEntityInstanceNumber)
1616 {
1617     pldm_entity entities[9]{};
1618 
1619     entities[0].entity_type = 1;
1620     entities[1].entity_type = 2;
1621     entities[2].entity_type = 2;
1622     entities[3].entity_type = 2;
1623     entities[4].entity_type = 2;
1624     entities[5].entity_type = 2;
1625     entities[6].entity_type = 2;
1626     entities[7].entity_type = 3;
1627     entities[8].entity_type = 3;
1628 
1629     auto tree = pldm_entity_association_tree_init();
1630     auto repo = pldm_pdr_init();
1631 
1632     uint16_t terminusHdl{};
1633     uint16_t entityType{};
1634     uint16_t entityInstanceNum{};
1635     uint16_t containerId{};
1636 
1637     auto node = pldm_entity_association_tree_add(
1638         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1639     EXPECT_NE(node, nullptr);
1640 
1641     auto l1 = pldm_entity_association_tree_add(tree, &entities[1], 63, node,
1642                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1643     uint32_t first = 1;
1644     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 1, entities[1].entity_type,
1645                                           entities[1].entity_instance_num,
1646                                           entities[1].entity_container_id,
1647                                           &first),
1648               0);
1649     EXPECT_NE(l1, nullptr);
1650     EXPECT_EQ(entities[1].entity_instance_num, 63);
1651     EXPECT_EQ(first, pldm_pdr_get_record_handle(
1652                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1653                                    repo, 1, &terminusHdl, &entityType,
1654                                    &entityInstanceNum, &containerId)));
1655     EXPECT_EQ(entityType, 2);
1656     EXPECT_EQ(entityInstanceNum, 63);
1657 
1658     auto l2 = pldm_entity_association_tree_add(tree, &entities[2], 37, node,
1659                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1660     uint32_t second = 2;
1661     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 2, entities[2].entity_type,
1662                                           entities[2].entity_instance_num,
1663                                           entities[2].entity_container_id,
1664                                           &second),
1665               0);
1666     EXPECT_NE(l2, nullptr);
1667     EXPECT_EQ(entities[2].entity_instance_num, 37);
1668     EXPECT_EQ(second, pldm_pdr_get_record_handle(
1669                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1670                                     repo, 2, &terminusHdl, &entityType,
1671                                     &entityInstanceNum, &containerId)));
1672     EXPECT_EQ(entityType, 2);
1673     EXPECT_EQ(entityInstanceNum, 37);
1674 
1675     auto l3 = pldm_entity_association_tree_add(tree, &entities[3], 44, node,
1676                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1677     uint32_t third = 3;
1678     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 3, entities[3].entity_type,
1679                                           entities[3].entity_instance_num,
1680                                           entities[3].entity_container_id,
1681                                           &third),
1682               0);
1683     EXPECT_NE(l3, nullptr);
1684     EXPECT_EQ(entities[3].entity_instance_num, 44);
1685     EXPECT_EQ(third, pldm_pdr_get_record_handle(
1686                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1687                                    repo, 3, &terminusHdl, &entityType,
1688                                    &entityInstanceNum, &containerId)));
1689     EXPECT_EQ(entityType, 2);
1690     EXPECT_EQ(entityInstanceNum, 44);
1691 
1692     auto l4 = pldm_entity_association_tree_add(tree, &entities[4], 89, node,
1693                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1694     uint32_t fourth = 4;
1695     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 4, entities[4].entity_type,
1696                                           entities[4].entity_instance_num,
1697                                           entities[4].entity_container_id,
1698                                           &fourth),
1699               0);
1700     EXPECT_NE(l4, nullptr);
1701     EXPECT_EQ(entities[4].entity_instance_num, 89);
1702     EXPECT_EQ(fourth, pldm_pdr_get_record_handle(
1703                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1704                                     repo, 4, &terminusHdl, &entityType,
1705                                     &entityInstanceNum, &containerId)));
1706     EXPECT_EQ(entityType, 2);
1707     EXPECT_EQ(entityInstanceNum, 89);
1708 
1709     auto l5 = pldm_entity_association_tree_add(tree, &entities[5], 0xffff, node,
1710                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1711     uint32_t fifth = 5;
1712     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 5, entities[5].entity_type,
1713                                           entities[5].entity_instance_num,
1714                                           entities[5].entity_container_id,
1715                                           &fifth),
1716               0);
1717     EXPECT_NE(l5, nullptr);
1718     EXPECT_EQ(entities[5].entity_instance_num, 90);
1719     EXPECT_EQ(fifth, pldm_pdr_get_record_handle(
1720                          repo, pldm_pdr_fru_record_set_find_by_rsi(
1721                                    repo, 5, &terminusHdl, &entityType,
1722                                    &entityInstanceNum, &containerId)));
1723     EXPECT_EQ(entityType, 2);
1724     EXPECT_EQ(entityInstanceNum, 90);
1725 
1726     auto l6 = pldm_entity_association_tree_add(tree, &entities[6], 90, node,
1727                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1728     EXPECT_EQ(l6, nullptr);
1729 
1730     auto l7 = pldm_entity_association_tree_add(tree, &entities[7], 100, l1,
1731                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1732     uint32_t seventh = 7;
1733     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 7, entities[7].entity_type,
1734                                           entities[7].entity_instance_num,
1735                                           entities[7].entity_container_id,
1736                                           &seventh),
1737               0);
1738     EXPECT_NE(l7, nullptr);
1739     EXPECT_EQ(entities[7].entity_instance_num, 100);
1740     EXPECT_EQ(seventh, pldm_pdr_get_record_handle(
1741                            repo, pldm_pdr_fru_record_set_find_by_rsi(
1742                                      repo, 7, &terminusHdl, &entityType,
1743                                      &entityInstanceNum, &containerId)));
1744     EXPECT_EQ(entityType, 3);
1745     EXPECT_EQ(entityInstanceNum, 100);
1746 
1747     auto l8 = pldm_entity_association_tree_add(tree, &entities[8], 100, l2,
1748                                                PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1749     uint32_t eighth = 8;
1750     EXPECT_EQ(pldm_pdr_add_fru_record_set(repo, 1, 8, entities[8].entity_type,
1751                                           entities[8].entity_instance_num,
1752                                           entities[8].entity_container_id,
1753                                           &eighth),
1754               0);
1755     EXPECT_NE(l8, nullptr);
1756     EXPECT_EQ(entities[8].entity_instance_num, 100);
1757     EXPECT_EQ(eighth, pldm_pdr_get_record_handle(
1758                           repo, pldm_pdr_fru_record_set_find_by_rsi(
1759                                     repo, 8, &terminusHdl, &entityType,
1760                                     &entityInstanceNum, &containerId)));
1761     EXPECT_EQ(entityType, 3);
1762     EXPECT_EQ(entityInstanceNum, 100);
1763 
1764     pldm_pdr_destroy(repo);
1765     pldm_entity_association_tree_destroy(tree);
1766 }
1767 
1768 #ifdef LIBPLDM_API_TESTING
1769 TEST(EntityAssociationPDR, testFindChildContainerID)
1770 {
1771     pldm_entity entities[3]{};
1772     entities[0].entity_type = 1;
1773     entities[1].entity_type = 2;
1774     entities[2].entity_type = 3;
1775     entities[1].entity_container_id = 2;
1776     entities[1].entity_instance_num = 1;
1777 
1778     auto tree = pldm_entity_association_tree_init();
1779     auto l1 = pldm_entity_association_tree_add_entity(
1780         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_LOGICAL,
1781         false, true, 0xffff);
1782 
1783     EXPECT_NE(l1, nullptr);
1784     auto l2 = pldm_entity_association_tree_add_entity(
1785         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1786         false, 0xffff);
1787     EXPECT_NE(l2, nullptr);
1788     auto l3 = pldm_entity_association_tree_add_entity(
1789         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, false,
1790         true, 0xffff);
1791     EXPECT_NE(l3, nullptr);
1792 
1793     EXPECT_EQ(pldm_entity_get_num_children(l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL),
1794               2);
1795 
1796     auto repo = pldm_pdr_init();
1797     int rc = pldm_entity_association_pdr_add(tree, repo, false, 1);
1798     ASSERT_EQ(rc, 0);
1799 
1800     EXPECT_EQ(pldm_pdr_get_record_count(repo), 1u);
1801 
1802     uint16_t container_id{};
1803     pldm_pdr_find_child_container_id_index_range_exclude(
1804         repo, 1, 1, 0, 0x01000000, 0x01ffffff, &container_id);
1805     EXPECT_EQ(container_id, 2);
1806 
1807     uint16_t container_id1{};
1808     pldm_pdr_find_child_container_id_index_range_exclude(
1809         repo, 1, 1, 0, 0x00000001, 0x00ffffff, &container_id1);
1810     EXPECT_EQ(container_id1, 0);
1811 
1812     pldm_pdr_destroy(repo);
1813     pldm_entity_association_tree_destroy(tree);
1814 }
1815 #endif
1816 
1817 TEST(EntityAssociationPDR, testNodeAddCheck)
1818 {
1819     // pldm_entity entities[4]{};
1820     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 4);
1821     entities[0].entity_type = 1;
1822     entities[1].entity_type = 2;
1823     entities[2].entity_type = 2;
1824     entities[3].entity_type = 3;
1825 
1826     auto tree = pldm_entity_association_tree_init();
1827 
1828     auto l1 = pldm_entity_association_tree_add(
1829         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1830     EXPECT_NE(l1, nullptr);
1831     auto l2a = pldm_entity_association_tree_add(
1832         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1833     EXPECT_NE(l2a, nullptr);
1834     auto l2b = pldm_entity_association_tree_add(
1835         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1836     EXPECT_NE(l2b, nullptr);
1837     auto l2c = pldm_entity_association_tree_add(
1838         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1839     EXPECT_NE(l2c, nullptr);
1840 
1841     auto repo = pldm_pdr_init();
1842 
1843     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1844                   l1, repo, &entities, 4, false, 1, 0),
1845               0);
1846     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1847                   l1, repo, &entities, 4, false, 1, 2),
1848               0);
1849     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1850                   l1, repo, &entities, 4, false, 1, 23),
1851               0);
1852     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1853                   l1, repo, &entities, 4, false, 1, 34),
1854               0);
1855 
1856     EXPECT_EQ(pldm_pdr_get_record_count(repo), 4u);
1857 
1858     uint8_t* outData = nullptr;
1859     uint32_t size{};
1860     uint32_t nextRecHdl{};
1861     auto hdl = pldm_pdr_find_record(repo, 0, &outData, &size, &nextRecHdl);
1862     EXPECT_NE(hdl, nullptr);
1863 
1864     outData = nullptr;
1865     auto hdl1 = pldm_pdr_find_record(repo, 2, &outData, &size, &nextRecHdl);
1866     EXPECT_NE(hdl1, nullptr);
1867     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(outData);
1868     EXPECT_EQ(hdr->record_handle, 2);
1869 
1870     outData = nullptr;
1871     auto hdl2 = pldm_pdr_find_record(repo, 23, &outData, &size, &nextRecHdl);
1872     EXPECT_NE(hdl2, nullptr);
1873     pldm_pdr_hdr* hdr1 = reinterpret_cast<pldm_pdr_hdr*>(outData);
1874     EXPECT_EQ(hdr1->record_handle, 23);
1875 
1876     outData = nullptr;
1877     auto hdl3 = pldm_pdr_find_record(repo, 3, &outData, &size, &nextRecHdl);
1878     EXPECT_EQ(hdl3, nullptr);
1879 
1880     free(entities);
1881     pldm_pdr_destroy(repo);
1882     pldm_entity_association_tree_destroy(tree);
1883 }
1884 
1885 #ifdef LIBPLDM_API_TESTING
1886 TEST(EntityAssociationPDR, testAddContainedEntityRemotePDR)
1887 {
1888     // pldm_entity entities[5]{};
1889     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
1890     entities[0].entity_type = 1;
1891     entities[1].entity_type = 2;
1892     entities[2].entity_type = 3;
1893     entities[3].entity_type = 4;
1894     entities[4].entity_type = 5;
1895 
1896     auto tree = pldm_entity_association_tree_init();
1897     auto l1 = pldm_entity_association_tree_add(
1898         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1899     EXPECT_NE(l1, nullptr);
1900     auto l2a = pldm_entity_association_tree_add(
1901         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1902     EXPECT_NE(l2a, nullptr);
1903     auto l2b = pldm_entity_association_tree_add(
1904         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1905     EXPECT_NE(l2b, nullptr);
1906     auto l2c = pldm_entity_association_tree_add(
1907         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1908     EXPECT_NE(l2c, nullptr);
1909     auto l3a = pldm_entity_association_tree_add(
1910         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1911     EXPECT_NE(l3a, nullptr);
1912 
1913     auto repo = pldm_pdr_init();
1914 
1915     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1916                   l1, repo, &entities, 5, false, 1, 0),
1917               0);
1918     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1919                   l1, repo, &entities, 5, false, 1, 2),
1920               0);
1921     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1922                   l1, repo, &entities, 5, false, 1, 23),
1923               0);
1924     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1925                   l1, repo, &entities, 5, false, 1, 34),
1926               0);
1927     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1928                   l2a, repo, &entities, 5, false, 1, 3),
1929               0);
1930 
1931     pldm_entity entity1[1];
1932     entity1[0].entity_type = 2;
1933 
1934     EXPECT_EQ(pldm_entity_association_pdr_add_contained_entity_to_remote_pdr(
1935                   repo, &entity1[0], 2),
1936               0);
1937 
1938     free(entities);
1939     pldm_pdr_destroy(repo);
1940     pldm_entity_association_tree_destroy(tree);
1941 }
1942 #endif
1943 
1944 #ifdef LIBPLDM_API_TESTING
1945 TEST(EntityAssociationPDR, testAddContainedEntityNew)
1946 {
1947     // pldm_entity entities[5]{};
1948     pldm_entity* entities = (pldm_entity*)malloc(sizeof(pldm_entity) * 5);
1949     entities[0].entity_type = 1;
1950     entities[1].entity_type = 2;
1951     entities[2].entity_type = 3;
1952     entities[3].entity_type = 4;
1953     entities[4].entity_type = 5;
1954 
1955     auto tree = pldm_entity_association_tree_init();
1956     auto l1 = pldm_entity_association_tree_add(
1957         tree, &entities[0], 0xffff, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1958     EXPECT_NE(l1, nullptr);
1959     auto l2a = pldm_entity_association_tree_add(
1960         tree, &entities[1], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1961     EXPECT_NE(l2a, nullptr);
1962     auto l2b = pldm_entity_association_tree_add(
1963         tree, &entities[2], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1964     EXPECT_NE(l2b, nullptr);
1965     auto l2c = pldm_entity_association_tree_add(
1966         tree, &entities[3], 0xffff, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1967     EXPECT_NE(l2c, nullptr);
1968     auto l3a = pldm_entity_association_tree_add(
1969         tree, &entities[4], 0xffff, l2a, PLDM_ENTITY_ASSOCIAION_PHYSICAL);
1970     EXPECT_NE(l3a, nullptr);
1971 
1972     auto repo = pldm_pdr_init();
1973 
1974     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1975                   l1, repo, &entities, 5, false, 1, 0),
1976               0);
1977     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1978                   l1, repo, &entities, 5, false, 1, 2),
1979               0);
1980     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1981                   l1, repo, &entities, 5, false, 1, 23),
1982               0);
1983     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1984                   l1, repo, &entities, 5, false, 1, 34),
1985               0);
1986     EXPECT_EQ(pldm_entity_association_pdr_add_from_node_with_record_handle(
1987                   l2a, repo, &entities, 5, false, 1, 3),
1988               0);
1989 
1990     uint32_t updated_record_handle = 0;
1991 
1992     pldm_entity entity2[1]{};
1993     entity2[0].entity_type = 4;
1994 
1995     pldm_entity entity3[1]{};
1996     entity3[0].entity_type = 4;
1997 
1998     EXPECT_EQ(pldm_entity_association_pdr_create_new(
1999                   repo, 34, &entity2[0], &entity3[0], &updated_record_handle),
2000               0);
2001 
2002     EXPECT_EQ(updated_record_handle, 35);
2003 
2004     free(entities);
2005     pldm_pdr_destroy(repo);
2006     pldm_entity_association_tree_destroy(tree);
2007 }
2008 #endif
2009