xref: /openbmc/libpldm/tests/dsp/fru.cpp (revision d0ba43af)
1 #include <endian.h>
2 #include <libpldm/base.h>
3 #include <libpldm/fru.h>
4 #include <libpldm/utils.h>
5 
6 #include <array>
7 #include <cstdint>
8 #include <cstring>
9 #include <vector>
10 
11 #include <gtest/gtest.h>
12 
TEST(GetFruRecordTableMetadata,testGoodEncodeRequest)13 TEST(GetFruRecordTableMetadata, testGoodEncodeRequest)
14 {
15     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
16     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
17     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
18     auto rc = encode_get_fru_record_table_metadata_req(
19         0, requestPtr, PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
20     ASSERT_EQ(rc, PLDM_SUCCESS);
21     ASSERT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
22     ASSERT_EQ(requestPtr->hdr.instance_id, 0u);
23     ASSERT_EQ(requestPtr->hdr.type, PLDM_FRU);
24     ASSERT_EQ(requestPtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
25 }
26 
TEST(GetFruRecordTableMetadata,testBadEncodeRequest)27 TEST(GetFruRecordTableMetadata, testBadEncodeRequest)
28 {
29     auto rc = encode_get_fru_record_table_metadata_req(0, NULL, 0);
30     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
31     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
32     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
33     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
34     rc = encode_get_fru_record_table_metadata_req(0, requestPtr, 1);
35     ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
36 }
37 
TEST(GetFruRecordTableMetadata,testGoodDecodeResponse)38 TEST(GetFruRecordTableMetadata, testGoodDecodeResponse)
39 {
40 
41     std::vector<uint8_t> responseMsg(
42         sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES);
43     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
44     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
45     size_t payload_length = responseMsg.size() - sizeof(pldm_msg_hdr);
46     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
47     auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
48         responsePtr->payload);
49 
50     responsePtr->hdr.request = PLDM_RESPONSE;
51     responsePtr->hdr.instance_id = 0;
52     responsePtr->hdr.type = PLDM_FRU;
53     responsePtr->hdr.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
54     response->completion_code = PLDM_SUCCESS;
55     response->fru_data_major_version = 0x12;
56     response->fru_data_minor_version = 0x21;
57     response->fru_table_maximum_size = htole32(0x1234abcd);
58     response->fru_table_length = htole32(0x56781234);
59     response->total_record_set_identifiers = htole16(0x34ef);
60     response->total_table_records = htole16(0xeeef);
61     response->checksum = htole32(0x6543fa71);
62 
63     uint8_t completion_code = 0xff;
64     uint8_t fru_data_major_version = 0x00;
65     uint8_t fru_data_minor_version = 0x00;
66     uint32_t fru_table_maximum_size = htole32(0x00000000);
67     uint32_t fru_table_length = htole32(0x00000000);
68     uint16_t total_record_set_identifiers = htole16(0x0000);
69     uint16_t total_table_records = htole16(0x0000);
70     uint32_t checksum = htole32(0x00000000);
71 
72     auto rc = decode_get_fru_record_table_metadata_resp(
73         responsePtr, payload_length, &completion_code, &fru_data_major_version,
74         &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
75         &total_record_set_identifiers, &total_table_records, &checksum);
76     ASSERT_EQ(rc, PLDM_SUCCESS);
77     ASSERT_EQ(completion_code, PLDM_SUCCESS);
78     ASSERT_EQ(fru_data_major_version, 0x12u);
79     ASSERT_EQ(fru_data_minor_version, 0x21u);
80     ASSERT_EQ(fru_table_maximum_size, 0x1234abcdu);
81     ASSERT_EQ(fru_table_length, 0x56781234u);
82     ASSERT_EQ(total_record_set_identifiers, 0x34efu);
83     ASSERT_EQ(total_table_records, 0xeeefu);
84     ASSERT_EQ(checksum, 0x6543fa71u);
85 
86     response->fru_data_major_version = 0x00;
87     response->fru_data_minor_version = 0x00;
88     response->fru_table_maximum_size = htole32(0x00000000);
89     response->fru_table_length = htole32(0x00000000);
90     response->total_record_set_identifiers = htole16(0x0000);
91     response->total_table_records = htole16(0x0000);
92     response->checksum = htole32(0x00000000);
93     fru_data_major_version = 0x00;
94     fru_data_minor_version = 0x00;
95     fru_table_maximum_size = htole32(0x00000000);
96     fru_table_length = htole32(0x00000000);
97     total_record_set_identifiers = htole16(0x0000);
98     total_table_records = htole16(0x0000);
99     checksum = htole32(0x00000000);
100     response->completion_code = PLDM_ERROR_INVALID_LENGTH;
101     rc = decode_get_fru_record_table_metadata_resp(
102         responsePtr, payload_length, &completion_code, &fru_data_major_version,
103         &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
104         &total_record_set_identifiers, &total_table_records, &checksum);
105     ASSERT_EQ(rc, PLDM_SUCCESS);
106     ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
107     ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
108     ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
109     ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
110     ASSERT_EQ(completion_code, PLDM_ERROR_INVALID_LENGTH);
111     ASSERT_EQ(fru_data_major_version, 0x00u);
112     ASSERT_EQ(fru_data_minor_version, 0x00u);
113     ASSERT_EQ(fru_table_maximum_size, 0x00000000u);
114     ASSERT_EQ(fru_table_length, 0x00000000u);
115     ASSERT_EQ(total_record_set_identifiers, 0x0000u);
116     ASSERT_EQ(total_table_records, 0x0000u);
117     ASSERT_EQ(checksum, 0x00000000u);
118 }
119 
TEST(GetFruRecordTableMetadata,testBadDecodeResponse)120 TEST(GetFruRecordTableMetadata, testBadDecodeResponse)
121 {
122     std::vector<uint8_t> responseMsg(
123         sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES);
124     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
125     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
126     size_t payload_length = responseMsg.size() - sizeof(pldm_msg_hdr);
127     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
128     auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
129         responsePtr->payload);
130 
131     response->completion_code = PLDM_SUCCESS;
132     response->fru_data_major_version = 0x12;
133     response->fru_data_minor_version = 0x21;
134     response->fru_table_maximum_size = htole32(0x1234abcd);
135     response->fru_table_length = htole32(0x56781234);
136     response->total_record_set_identifiers = htole16(0x34ef);
137     response->total_table_records = htole16(0xeeef);
138     response->checksum = htole32(0x6543fa71);
139 
140     uint8_t completion_code = 0xff;
141     uint8_t fru_data_major_version = 0x00;
142     uint8_t fru_data_minor_version = 0x00;
143     uint32_t fru_table_maximum_size = htole32(0x00000000);
144     uint32_t fru_table_length = htole32(0x00000000);
145     uint16_t total_record_set_identifiers = htole16(0x0000);
146     uint16_t total_table_records = htole16(0x0000);
147     uint32_t checksum = htole32(0x00000000);
148 
149     auto rc = decode_get_fru_record_table_metadata_resp(
150         responsePtr, PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES + 2,
151         &completion_code, &fru_data_major_version, &fru_data_minor_version,
152         &fru_table_maximum_size, &fru_table_length,
153         &total_record_set_identifiers, &total_table_records, &checksum);
154     ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
155 
156     rc = decode_get_fru_record_table_metadata_resp(
157         responsePtr, payload_length, &completion_code, NULL,
158         &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
159         &total_record_set_identifiers, &total_table_records, &checksum);
160     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
161 
162     rc = decode_get_fru_record_table_metadata_resp(
163         responsePtr, payload_length, &completion_code, &fru_data_major_version,
164         NULL, &fru_table_maximum_size, &fru_table_length,
165         &total_record_set_identifiers, &total_table_records, &checksum);
166     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
167 
168     rc = decode_get_fru_record_table_metadata_resp(
169         responsePtr, payload_length, &completion_code, &fru_data_major_version,
170         &fru_data_minor_version, NULL, &fru_table_length,
171         &total_record_set_identifiers, &total_table_records, &checksum);
172     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
173 
174     rc = decode_get_fru_record_table_metadata_resp(
175         responsePtr, payload_length, &completion_code, &fru_data_major_version,
176         &fru_data_minor_version, &fru_table_maximum_size, NULL,
177         &total_record_set_identifiers, &total_table_records, &checksum);
178     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
179 
180     rc = decode_get_fru_record_table_metadata_resp(
181         responsePtr, payload_length, &completion_code, &fru_data_major_version,
182         &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
183         NULL, &total_table_records, &checksum);
184     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
185 
186     rc = decode_get_fru_record_table_metadata_resp(
187         responsePtr, payload_length, &completion_code, &fru_data_major_version,
188         &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
189         &total_record_set_identifiers, NULL, &checksum);
190     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
191 
192     rc = decode_get_fru_record_table_metadata_resp(
193         responsePtr, payload_length, &completion_code, &fru_data_major_version,
194         &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
195         &total_record_set_identifiers, &total_table_records, NULL);
196     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
197 }
198 
TEST(GetFruRecordTableMetadata,testGoodEncodeResponse)199 TEST(GetFruRecordTableMetadata, testGoodEncodeResponse)
200 {
201 
202     std::array<uint8_t, sizeof(pldm_msg_hdr) +
203                             PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES>
204         responseMsg{};
205     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
206     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
207 
208     responsePtr->hdr.request = PLDM_RESPONSE;
209     responsePtr->hdr.instance_id = 0;
210     responsePtr->hdr.type = PLDM_FRU;
211     responsePtr->hdr.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
212 
213     uint8_t completion_code = PLDM_SUCCESS;
214     uint8_t fru_data_major_version = 0x12;
215     uint8_t fru_data_minor_version = 0x21;
216     uint32_t fru_table_maximum_size = htole32(0x1234abcd);
217     uint32_t fru_table_length = htole32(0x56781234);
218     uint16_t total_record_set_identifiers = htole16(0x34ef);
219     uint16_t total_table_records = htole16(0xeeef);
220     uint32_t checksum = htole32(0x6543fa71);
221 
222     auto rc = encode_get_fru_record_table_metadata_resp(
223         0, completion_code, fru_data_major_version, fru_data_minor_version,
224         fru_table_maximum_size, fru_table_length, total_record_set_identifiers,
225         total_table_records, checksum, responsePtr);
226 
227     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
228     auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
229         responsePtr->payload);
230 
231     ASSERT_EQ(rc, PLDM_SUCCESS);
232     ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
233     ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
234     ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
235     ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
236     ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
237     ASSERT_EQ(response->fru_data_major_version, 0x12u);
238     ASSERT_EQ(response->fru_data_minor_version, 0x21u);
239     ASSERT_EQ(response->fru_table_maximum_size, 0x1234abcdu);
240     ASSERT_EQ(response->fru_table_length, 0x56781234u);
241     ASSERT_EQ(response->total_record_set_identifiers, 0x34efu);
242     ASSERT_EQ(response->total_table_records, 0xeeefu);
243     ASSERT_EQ(response->checksum, 0x6543fa71u);
244 
245     response->fru_data_major_version = 0;
246     response->fru_data_major_version = 0x00;
247     response->fru_data_minor_version = 0x00;
248     response->fru_table_maximum_size = htole32(0x00000000);
249     response->fru_table_length = htole32(0x00000000);
250     response->total_record_set_identifiers = htole16(0x0000);
251     response->total_table_records = htole16(0x0000);
252     response->checksum = htole32(0x00000000);
253     completion_code = PLDM_ERROR_INVALID_DATA;
254     rc = encode_get_fru_record_table_metadata_resp(
255         0, completion_code, fru_data_major_version, fru_data_minor_version,
256         fru_table_maximum_size, fru_table_length, total_record_set_identifiers,
257         total_table_records, checksum, responsePtr);
258 
259     ASSERT_EQ(rc, PLDM_SUCCESS);
260     ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
261     ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
262     ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
263     ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE_METADATA);
264     ASSERT_EQ(completion_code, PLDM_ERROR_INVALID_DATA);
265     ASSERT_EQ(response->fru_data_major_version, 0x00u);
266     ASSERT_EQ(response->fru_data_minor_version, 0x00u);
267     ASSERT_EQ(response->fru_table_maximum_size, 0x00000000u);
268     ASSERT_EQ(response->fru_table_length, 0x00000000u);
269     ASSERT_EQ(response->total_record_set_identifiers, 0x0000u);
270     ASSERT_EQ(response->total_table_records, 0x0000u);
271     ASSERT_EQ(response->checksum, 0x00000000u);
272 }
273 
TEST(GetFruRecordTableMetadata,testBadEncodeResponse)274 TEST(GetFruRecordTableMetadata, testBadEncodeResponse)
275 {
276     std::array<uint8_t, sizeof(pldm_msg_hdr) +
277                             PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES>
278         responseMsg{};
279     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
280     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
281 
282     uint8_t completion_code = PLDM_SUCCESS;
283     uint8_t fru_data_major_version = 0x12;
284     uint8_t fru_data_minor_version = 0x21;
285     uint32_t fru_table_maximum_size = htole32(0x1234abcd);
286     uint32_t fru_table_length = htole32(0x56781234);
287     uint16_t total_record_set_identifiers = htole16(0x34ef);
288     uint16_t total_table_records = htole16(0xeeef);
289     uint32_t checksum = htole32(0x6543fa71);
290 
291     auto rc = encode_get_fru_record_table_metadata_resp(
292         0, completion_code, fru_data_major_version, fru_data_minor_version,
293         fru_table_maximum_size, fru_table_length, total_record_set_identifiers,
294         total_table_records, checksum, NULL);
295 
296     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
297     auto response = reinterpret_cast<pldm_get_fru_record_table_metadata_resp*>(
298         responsePtr->payload);
299 
300     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
301     ASSERT_EQ(completion_code, PLDM_SUCCESS);
302     ASSERT_EQ(response->fru_data_major_version, 0x00u);
303     ASSERT_EQ(response->fru_data_minor_version, 0x00u);
304     ASSERT_EQ(response->fru_table_maximum_size, 0x00000000u);
305     ASSERT_EQ(response->fru_table_length, 0x00000000u);
306     ASSERT_EQ(response->total_record_set_identifiers, 0x0000u);
307     ASSERT_EQ(response->total_table_records, 0x0000u);
308     ASSERT_EQ(response->checksum, 0x00000000u);
309 }
310 
TEST(GetFruRecordTable,testGoodDecodeRequest)311 TEST(GetFruRecordTable, testGoodDecodeRequest)
312 {
313     uint32_t data_transfer_handle = 31;
314     uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
315     std::array<uint8_t,
316                PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES + sizeof(pldm_msg_hdr)>
317         requestMsg{};
318     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
319     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
320     size_t payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
321     auto request =
322         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
323         reinterpret_cast<pldm_get_fru_record_table_req*>(requestPtr->payload);
324 
325     request->data_transfer_handle = htole32(data_transfer_handle);
326     request->transfer_operation_flag = transfer_operation_flag;
327 
328     uint32_t ret_data_transfer_handle = 0;
329     uint8_t ret_transfer_operation_flag = 0;
330 
331     // Invoke decode get FRU record table request api
332     auto rc = decode_get_fru_record_table_req(requestPtr, payload_length,
333                                               &ret_data_transfer_handle,
334                                               &ret_transfer_operation_flag);
335 
336     ASSERT_EQ(rc, PLDM_SUCCESS);
337     ASSERT_EQ(data_transfer_handle, ret_data_transfer_handle);
338     ASSERT_EQ(transfer_operation_flag, ret_transfer_operation_flag);
339 }
340 
TEST(GetFruRecordTable,testBadDecodeRequest)341 TEST(GetFruRecordTable, testBadDecodeRequest)
342 {
343     uint32_t data_transfer_handle = 0x0;
344     uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
345 
346     std::array<uint8_t,
347                sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES>
348         requestMsg{};
349     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
350     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
351 
352     // Payload message is missing
353     auto rc = decode_get_fru_record_table_req(NULL, 0, &data_transfer_handle,
354                                               &transfer_operation_flag);
355     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
356 
357     // Payload length is invalid
358     rc = decode_get_fru_record_table_req(requestPtr, 0, &data_transfer_handle,
359                                          &transfer_operation_flag);
360     ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
361 }
362 
TEST(GetFruRecordTable,testGoodEncodeResponse)363 TEST(GetFruRecordTable, testGoodEncodeResponse)
364 {
365     uint8_t completion_code = 0;
366     uint32_t next_data_transfer_handle = 32;
367     uint8_t transfer_flag = PLDM_START_AND_END;
368 
369     std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
370                                      PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
371 
372     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
373     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
374     auto response =
375         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
376         reinterpret_cast<pldm_get_fru_record_table_resp*>(responsePtr->payload);
377 
378     // Invoke encode get FRU record table response api
379     auto rc = encode_get_fru_record_table_resp(0, completion_code,
380                                                next_data_transfer_handle,
381                                                transfer_flag, responsePtr);
382 
383     ASSERT_EQ(rc, PLDM_SUCCESS);
384     ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
385     ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
386     ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
387     ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE);
388     ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
389     ASSERT_EQ(le32toh(response->next_data_transfer_handle),
390               next_data_transfer_handle);
391     ASSERT_EQ(response->transfer_flag, transfer_flag);
392 }
393 
TEST(GetFruRecordTable,testBadEncodeResponse)394 TEST(GetFruRecordTable, testBadEncodeResponse)
395 {
396     uint32_t next_data_transfer_handle = 32;
397     uint8_t transfer_flag = PLDM_START_AND_END;
398 
399     std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
400                                      PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
401 
402     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
403     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
404     auto rc = encode_get_fru_record_table_resp(
405         0, PLDM_ERROR, next_data_transfer_handle, transfer_flag, responsePtr);
406 
407     ASSERT_EQ(rc, PLDM_SUCCESS);
408     ASSERT_EQ(responsePtr->hdr.request, PLDM_RESPONSE);
409     ASSERT_EQ(responsePtr->hdr.instance_id, 0u);
410     ASSERT_EQ(responsePtr->hdr.type, PLDM_FRU);
411     ASSERT_EQ(responsePtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE);
412     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);
413 
414     rc = encode_get_fru_record_table_resp(
415         0, PLDM_SUCCESS, next_data_transfer_handle, transfer_flag, nullptr);
416 
417     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
418 }
419 
TEST(GetFruRecordTable,testGoodEncodeRequest)420 TEST(GetFruRecordTable, testGoodEncodeRequest)
421 
422 {
423     std::array<uint8_t,
424                sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES>
425         requestMsg{};
426 
427     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
428     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
429     auto request =
430         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
431         reinterpret_cast<pldm_get_fru_record_table_req*>(requestPtr->payload);
432 
433     // Random value for data transfer handle and transfer operation flag
434     uint32_t data_transfer_handle = 32;
435     uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
436 
437     // Invoke encode get FRU record table request api
438     auto rc = encode_get_fru_record_table_req(
439         0, data_transfer_handle, transfer_operation_flag, requestPtr,
440         requestMsg.size() - sizeof(pldm_msg_hdr));
441 
442     ASSERT_EQ(rc, PLDM_SUCCESS);
443     ASSERT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
444     ASSERT_EQ(requestPtr->hdr.instance_id, 0u);
445     ASSERT_EQ(requestPtr->hdr.type, PLDM_FRU);
446     ASSERT_EQ(requestPtr->hdr.command, PLDM_GET_FRU_RECORD_TABLE);
447     ASSERT_EQ(le32toh(data_transfer_handle), request->data_transfer_handle);
448     ASSERT_EQ(transfer_operation_flag, request->transfer_operation_flag);
449 }
450 
TEST(GetFruRecordTable,testBadEncodeRequest)451 TEST(GetFruRecordTable, testBadEncodeRequest)
452 
453 {
454     uint32_t data_transfer_handle = 0x0;
455     uint8_t transfer_operation_flag = PLDM_GET_FIRSTPART;
456 
457     std::array<uint8_t,
458                sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES>
459         requestMsg{};
460     auto rc = encode_get_fru_record_table_req(
461         0, data_transfer_handle, transfer_operation_flag, NULL,
462         requestMsg.size() - sizeof(pldm_msg_hdr));
463 
464     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
465 }
466 
TEST(GetFruRecordTable,testGoodDecodeResponse)467 TEST(GetFruRecordTable, testGoodDecodeResponse)
468 {
469     uint8_t completion_code = PLDM_SUCCESS;
470     uint32_t next_data_transfer_handle = 0x16;
471     uint8_t transfer_flag = PLDM_START_AND_END;
472     std::vector<uint8_t> fru_record_table_data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
473 
474     std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
475                                      PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES +
476                                      fru_record_table_data.size());
477 
478     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
479     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
480     size_t payload_length = responseMsg.size() - sizeof(pldm_msg_hdr);
481     auto response =
482         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
483         reinterpret_cast<pldm_get_fru_record_table_resp*>(responsePtr->payload);
484 
485     response->completion_code = completion_code;
486     response->next_data_transfer_handle = htole32(next_data_transfer_handle);
487     response->transfer_flag = transfer_flag;
488     memcpy(response->fru_record_table_data, fru_record_table_data.data(),
489            fru_record_table_data.size());
490 
491     uint8_t ret_completion_code = 0;
492     uint32_t ret_next_data_transfer_handle = 0;
493     uint8_t ret_transfer_flag = 0;
494     std::vector<uint8_t> ret_fru_record_table_data(9, 0);
495     size_t ret_fru_record_table_length = 0;
496 
497     // Invoke decode get FRU record table response api
498     auto rc = decode_get_fru_record_table_resp(
499         responsePtr, payload_length, &ret_completion_code,
500         &ret_next_data_transfer_handle, &ret_transfer_flag,
501         ret_fru_record_table_data.data(), &ret_fru_record_table_length);
502     ASSERT_EQ(rc, PLDM_SUCCESS);
503     ASSERT_EQ(completion_code, ret_completion_code);
504     ASSERT_EQ(next_data_transfer_handle, ret_next_data_transfer_handle);
505     ASSERT_EQ(transfer_flag, ret_transfer_flag);
506     ASSERT_EQ(0, memcmp(fru_record_table_data.data(),
507                         ret_fru_record_table_data.data(),
508                         ret_fru_record_table_length));
509     ASSERT_EQ(fru_record_table_data.size(), ret_fru_record_table_length);
510 }
511 
TEST(GetFruRecordTable,testBadDecodeResponse)512 TEST(GetFruRecordTable, testBadDecodeResponse)
513 {
514     uint8_t completion_code = 0;
515     uint32_t next_data_transfer_handle = 0;
516     uint8_t transfer_flag = PLDM_START_AND_END;
517     std::vector<uint8_t> fru_record_table_data(9, 0);
518     size_t fru_record_table_length = 0;
519 
520     std::vector<uint8_t> responseMsg(sizeof(pldm_msg_hdr) +
521                                      PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES +
522                                      fru_record_table_data.size());
523 
524     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
525     auto responsePtr = reinterpret_cast<pldm_msg*>(responseMsg.data());
526 
527     // Payload message is missing
528     auto rc = decode_get_fru_record_table_resp(
529         NULL, 0, &completion_code, &next_data_transfer_handle, &transfer_flag,
530         fru_record_table_data.data(), &fru_record_table_length);
531 
532     ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
533 
534     // Payload length is invalid
535     rc = decode_get_fru_record_table_resp(
536         responsePtr, 0, &completion_code, &next_data_transfer_handle,
537         &transfer_flag, fru_record_table_data.data(), &fru_record_table_length);
538 
539     ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
540 }
541 
TEST(GetFRURecordByOption,testGoodEncodeRequest)542 TEST(GetFRURecordByOption, testGoodEncodeRequest)
543 {
544     uint8_t instanceId = 2;
545     uint32_t dataTransferHandle = 3;
546     uint16_t fruTableHandle = 4;
547     uint16_t recordSetIdentifier = 5;
548     uint8_t recordType = 6;
549     uint8_t fieldType = 7;
550     uint8_t transferOpFlag = 0;
551 
552     constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
553 
554     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request;
555     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
556     auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
557 
558     auto rc = encode_get_fru_record_by_option_req(
559         instanceId, dataTransferHandle, fruTableHandle, recordSetIdentifier,
560         recordType, fieldType, transferOpFlag, reqMsg, payLoadLength);
561 
562     EXPECT_EQ(rc, PLDM_SUCCESS);
563     EXPECT_EQ(instanceId, reqMsg->hdr.instance_id);
564 
565     auto payLoadMsg =
566         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
567         reinterpret_cast<pldm_get_fru_record_by_option_req*>(reqMsg->payload);
568 
569     EXPECT_EQ(le32toh(payLoadMsg->data_transfer_handle), dataTransferHandle);
570     EXPECT_EQ(le16toh(payLoadMsg->fru_table_handle), fruTableHandle);
571     EXPECT_EQ(le16toh(payLoadMsg->record_set_identifier), recordSetIdentifier);
572     EXPECT_EQ(payLoadMsg->record_type, recordType);
573     EXPECT_EQ(payLoadMsg->field_type, fieldType);
574     EXPECT_EQ(payLoadMsg->transfer_op_flag, transferOpFlag);
575 }
576 
TEST(GetFRURecordByOption,testBadEncodeRequest)577 TEST(GetFRURecordByOption, testBadEncodeRequest)
578 {
579 
580     constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
581 
582     auto rc = encode_get_fru_record_by_option_req(1, 2, 3, 4, 5, 6, 0, nullptr,
583                                                   payLoadLength);
584 
585     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
586     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request;
587     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
588     auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
589 
590     rc = encode_get_fru_record_by_option_req(1, 2, 3, 4, 5, 6, 0, reqMsg,
591                                              payLoadLength - 1);
592 
593     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
594 }
595 
TEST(GetFRURecordByOption,testGoodDecodeRequest)596 TEST(GetFRURecordByOption, testGoodDecodeRequest)
597 {
598     uint8_t instanceId = 2;
599     uint32_t dataTransferHandle = 3;
600     uint16_t fruTableHandle = 4;
601     uint16_t recordSetIdentifier = 5;
602     uint8_t recordType = 6;
603     uint8_t fieldType = 7;
604     uint8_t transferOpFlag = 0;
605 
606     constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
607 
608     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request;
609     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
610     auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
611 
612     auto rc = encode_get_fru_record_by_option_req(
613         instanceId, dataTransferHandle, fruTableHandle, recordSetIdentifier,
614         recordType, fieldType, transferOpFlag, reqMsg, payLoadLength);
615 
616     EXPECT_EQ(rc, PLDM_SUCCESS);
617 
618     uint32_t retDataTransferHandle{};
619     uint16_t retFruTableHandle{};
620     uint16_t retRecordSetIdentifier{};
621     uint8_t retRecordType{};
622     uint8_t retFieldType{};
623     uint8_t retTransferOpFlag{};
624 
625     rc = decode_get_fru_record_by_option_req(
626         reqMsg, payLoadLength, &retDataTransferHandle, &retFruTableHandle,
627         &retRecordSetIdentifier, &retRecordType, &retFieldType,
628         &retTransferOpFlag);
629 
630     EXPECT_EQ(rc, PLDM_SUCCESS);
631     EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
632     EXPECT_EQ(retFruTableHandle, fruTableHandle);
633     EXPECT_EQ(retRecordSetIdentifier, recordSetIdentifier);
634     EXPECT_EQ(retRecordType, recordType);
635     EXPECT_EQ(retFieldType, fieldType);
636     EXPECT_EQ(retTransferOpFlag, transferOpFlag);
637 }
638 
TEST(GetFRURecordByOption,testBadDecodeRequest)639 TEST(GetFRURecordByOption, testBadDecodeRequest)
640 {
641     constexpr auto payLoadLength = sizeof(pldm_get_fru_record_by_option_req);
642     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> request{};
643     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
644     auto reqMsg = reinterpret_cast<pldm_msg*>(request.data());
645 
646     uint32_t retDataTransferHandle{};
647     uint16_t retFruTableHandle{};
648     uint16_t retRecordSetIdentifier{};
649     uint8_t retRecordType{};
650     uint8_t retFieldType{};
651     uint8_t retTransferOpFlag{};
652 
653     auto rc = decode_get_fru_record_by_option_req(
654         reqMsg, payLoadLength - 1, &retDataTransferHandle, &retFruTableHandle,
655         &retRecordSetIdentifier, &retRecordType, &retFieldType,
656         &retTransferOpFlag);
657 
658     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
659 
660     rc = decode_get_fru_record_by_option_req(
661         reqMsg, payLoadLength - 1, nullptr, &retFruTableHandle,
662         &retRecordSetIdentifier, &retRecordType, &retFieldType,
663         &retTransferOpFlag);
664 
665     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
666 }
667 
TEST(GetFruRecordByOption,testGoodEncodeResponse)668 TEST(GetFruRecordByOption, testGoodEncodeResponse)
669 {
670     uint8_t completionCode = PLDM_SUCCESS;
671     uint8_t instanceId = 2;
672     uint32_t dataTransferHandle = 3;
673     uint8_t transferFlag = 5;
674 
675     std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
676     constexpr auto payLoadLength =
677         sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
678 
679     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
680     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
681     auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
682 
683     auto rc = encode_get_fru_record_by_option_resp(
684         instanceId, completionCode, dataTransferHandle, transferFlag,
685         fruData.data(), fruData.size(), respMsg, payLoadLength);
686 
687     auto payLoadMsg =
688         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
689         reinterpret_cast<pldm_get_fru_record_by_option_resp*>(respMsg->payload);
690 
691     EXPECT_EQ(rc, PLDM_SUCCESS);
692     EXPECT_EQ(payLoadMsg->completion_code, completionCode);
693     EXPECT_EQ(payLoadMsg->next_data_transfer_handle,
694               htole32(dataTransferHandle));
695     EXPECT_EQ(payLoadMsg->transfer_flag, transferFlag);
696 
697     EXPECT_EQ(std::memcmp(payLoadMsg->fru_structure_data, fruData.data(),
698                           fruData.size()),
699               0);
700 }
701 
TEST(GetFruRecordByOption,testBadEncodeResponse)702 TEST(GetFruRecordByOption, testBadEncodeResponse)
703 {
704     uint8_t completionCode = PLDM_SUCCESS;
705     uint8_t instanceId = 2;
706     uint32_t dataTransferHandle = 3;
707     uint8_t transferFlag = 5;
708 
709     std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
710     constexpr auto payLoadLength =
711         sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
712 
713     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
714     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
715     auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
716 
717     auto rc = encode_get_fru_record_by_option_resp(
718         instanceId, completionCode, dataTransferHandle, transferFlag, nullptr,
719         fruData.size(), respMsg, payLoadLength);
720 
721     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
722 
723     rc = encode_get_fru_record_by_option_resp(
724         instanceId, completionCode, dataTransferHandle, transferFlag,
725         fruData.data(), fruData.size(), respMsg, payLoadLength - 1);
726 
727     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
728 }
729 
TEST(GetFruRecordByOption,testGoodDecodeResponse)730 TEST(GetFruRecordByOption, testGoodDecodeResponse)
731 {
732     uint8_t completionCode = PLDM_SUCCESS;
733     uint8_t instanceId = 2;
734     uint32_t dataTransferHandle = 3;
735     uint8_t transferFlag = 5;
736 
737     std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
738     constexpr auto payLoadLength =
739         sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
740 
741     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
742     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
743     auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
744 
745     auto rc = encode_get_fru_record_by_option_resp(
746         instanceId, completionCode, dataTransferHandle, transferFlag,
747         fruData.data(), fruData.size(), respMsg, payLoadLength);
748 
749     EXPECT_EQ(rc, PLDM_SUCCESS);
750 
751     uint8_t retCompletionCode;
752     uint32_t retDataTransferHandle;
753     uint8_t retTransferFlag;
754     variable_field retFruData;
755 
756     rc = decode_get_fru_record_by_option_resp(
757         respMsg, payLoadLength, &retCompletionCode, &retDataTransferHandle,
758         &retTransferFlag, &retFruData);
759 
760     EXPECT_EQ(rc, PLDM_SUCCESS);
761     EXPECT_EQ(retCompletionCode, completionCode);
762     EXPECT_EQ(retDataTransferHandle, dataTransferHandle);
763     EXPECT_EQ(retTransferFlag, transferFlag);
764     EXPECT_EQ(retFruData.length, fruData.size());
765     EXPECT_EQ(std::memcmp(fruData.data(), retFruData.ptr, fruData.size()), 0);
766 }
767 
TEST(GetFruRecordByOption,testBadDecodeResponse)768 TEST(GetFruRecordByOption, testBadDecodeResponse)
769 {
770 
771     uint8_t completionCode = PLDM_SUCCESS;
772     uint8_t instanceId = 2;
773     uint32_t dataTransferHandle = 3;
774     uint8_t transferFlag = 5;
775 
776     std::array<uint8_t, 5> fruData = {1, 2, 3, 4, 5};
777     constexpr auto payLoadLength =
778         sizeof(pldm_get_fru_record_by_option_resp) - 1 + fruData.size();
779 
780     std::array<uint8_t, sizeof(pldm_msg_hdr) + payLoadLength> response;
781     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
782     auto respMsg = reinterpret_cast<pldm_msg*>(response.data());
783 
784     auto rc = encode_get_fru_record_by_option_resp(
785         instanceId, completionCode, dataTransferHandle, transferFlag,
786         fruData.data(), fruData.size(), respMsg, payLoadLength);
787 
788     EXPECT_EQ(rc, PLDM_SUCCESS);
789 
790     uint8_t retCompletionCode;
791     uint32_t retDataTransferHandle;
792     uint8_t retTransferFlag;
793     variable_field retFruData;
794 
795     rc = decode_get_fru_record_by_option_resp(respMsg, payLoadLength, nullptr,
796                                               &retDataTransferHandle,
797                                               &retTransferFlag, &retFruData);
798 
799     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
800 
801     rc = decode_get_fru_record_by_option_resp(
802         respMsg, PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES - 1,
803         &retCompletionCode, &retDataTransferHandle, &retTransferFlag,
804         &retFruData);
805 
806     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
807 }
808 
TEST(SetFRURecordTable,testGoodEncodeResponse)809 TEST(SetFRURecordTable, testGoodEncodeResponse)
810 {
811     uint8_t instanceId = 2;
812     uint8_t completionCode = PLDM_SUCCESS;
813     uint32_t nextDataTransferHandle = 32;
814 
815     std::array<uint8_t,
816                sizeof(pldm_msg_hdr) + PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES>
817         responseMsg{};
818     struct pldm_msg* response =
819         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
820         reinterpret_cast<struct pldm_msg*>(responseMsg.data());
821     auto rc = encode_set_fru_record_table_resp(
822         instanceId, completionCode, nextDataTransferHandle,
823         responseMsg.size() - sizeof(pldm_msg_hdr), response);
824     EXPECT_EQ(rc, PLDM_SUCCESS);
825 
826     struct pldm_set_fru_record_table_resp* resp =
827         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
828         reinterpret_cast<struct pldm_set_fru_record_table_resp*>(
829             response->payload);
830     EXPECT_EQ(completionCode, resp->completion_code);
831     EXPECT_EQ(htole32(nextDataTransferHandle), resp->next_data_transfer_handle);
832 }
833 
TEST(SetFRURecordTable,testBadEncodeResponse)834 TEST(SetFRURecordTable, testBadEncodeResponse)
835 {
836     uint8_t instanceId = 0;
837     uint8_t completionCode = PLDM_SUCCESS;
838     uint32_t nextDataTransferHandle = 1;
839 
840     std::array<uint8_t,
841                sizeof(pldm_msg_hdr) + PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES>
842         responseMsg{};
843     struct pldm_msg* response =
844         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
845         reinterpret_cast<struct pldm_msg*>(responseMsg.data());
846 
847     auto rc = encode_set_fru_record_table_resp(
848         instanceId, completionCode, nextDataTransferHandle,
849         responseMsg.size() - sizeof(pldm_msg_hdr), NULL);
850     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
851 
852     rc = encode_set_fru_record_table_resp(
853         instanceId, completionCode, nextDataTransferHandle,
854         responseMsg.size() - sizeof(pldm_msg_hdr) - 1, response);
855     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
856 }
857 
TEST(SetFRURecordTable,testGoodDecodeRequest)858 TEST(SetFRURecordTable, testGoodDecodeRequest)
859 {
860     uint32_t transferHandle = 1;
861     uint8_t transferFlag = PLDM_GET_FIRSTPART;
862     uint32_t tableData = 44;
863 
864     std::array<uint8_t, sizeof(pldm_msg_hdr) +
865                             PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES +
866                             sizeof(tableData)>
867         requestMsg{};
868     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
869     auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
870     struct pldm_set_fru_record_table_req* req =
871         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
872         reinterpret_cast<struct pldm_set_fru_record_table_req*>(
873             request->payload);
874     req->data_transfer_handle = htole32(transferHandle);
875     req->transfer_flag = transferFlag;
876     memcpy(req->fru_record_table_data, &tableData, sizeof(tableData));
877 
878     uint32_t retTransferHandle;
879     uint8_t retTransferFlag;
880     struct variable_field table;
881 
882     auto rc = decode_set_fru_record_table_req(
883         request, requestMsg.size() - sizeof(pldm_msg_hdr), &retTransferHandle,
884         &retTransferFlag, &table);
885 
886     EXPECT_EQ(rc, PLDM_SUCCESS);
887     EXPECT_EQ(retTransferHandle, transferHandle);
888     EXPECT_EQ(retTransferFlag, transferFlag);
889     EXPECT_EQ(table.length, sizeof(tableData));
890     EXPECT_EQ(0, memcmp(table.ptr, &tableData, sizeof(tableData)));
891 }
892 
TEST(SetFRURecordTable,testBadDecodeRequest)893 TEST(SetFRURecordTable, testBadDecodeRequest)
894 {
895     uint32_t transferHandle = 1;
896     uint8_t transferFlag = PLDM_GET_FIRSTPART;
897     uint32_t tableData = 44;
898 
899     std::array<uint8_t, sizeof(pldm_msg_hdr) +
900                             PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES +
901                             sizeof(tableData)>
902         requestMsg{};
903     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
904     auto request = reinterpret_cast<struct pldm_msg*>(requestMsg.data());
905     struct pldm_set_fru_record_table_req* req =
906         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
907         reinterpret_cast<struct pldm_set_fru_record_table_req*>(
908             request->payload);
909     req->data_transfer_handle = htole32(transferHandle);
910     req->transfer_flag = transferFlag;
911     memcpy(req->fru_record_table_data, &tableData, sizeof(tableData));
912 
913     uint32_t retTransferHandle;
914     uint8_t retTransferFlag;
915 
916     auto rc = decode_set_fru_record_table_req(
917         request, requestMsg.size() - sizeof(pldm_msg_hdr), &retTransferHandle,
918         &retTransferFlag, NULL);
919     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
920 
921     struct variable_field table;
922     rc = decode_set_fru_record_table_req(
923         request,
924         requestMsg.size() - sizeof(pldm_msg_hdr) - sizeof(tableData) - 1,
925         &retTransferHandle, &retTransferFlag, &table);
926     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
927 }
928