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