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