1 2 #include "libpldmresponder/file_io.hpp" 3 #include "libpldmresponder/file_io_by_type.hpp" 4 #include "libpldmresponder/file_io_type_cert.hpp" 5 #include "libpldmresponder/file_io_type_dump.hpp" 6 #include "libpldmresponder/file_io_type_lid.hpp" 7 #include "libpldmresponder/file_io_type_pcie.hpp" 8 #include "libpldmresponder/file_io_type_pel.hpp" 9 #include "libpldmresponder/file_table.hpp" 10 #include "xyz/openbmc_project/Common/error.hpp" 11 12 #include <libpldm/base.h> 13 #include <libpldm/oem/ibm/file_io.h> 14 15 #include <nlohmann/json.hpp> 16 17 #include <filesystem> 18 #include <fstream> 19 20 #include <gmock/gmock-matchers.h> 21 #include <gmock/gmock.h> 22 #include <gtest/gtest.h> 23 24 namespace fs = std::filesystem; 25 using Json = nlohmann::json; 26 using namespace pldm::filetable; 27 using namespace pldm::responder; 28 29 class TestFileTable : public testing::Test 30 { 31 public: 32 void SetUp() override 33 { 34 // Create a temporary directory to hold the config file and files to 35 // populate the file table. 36 char tmppldm[] = "/tmp/pldm_fileio_table.XXXXXX"; 37 dir = fs::path(mkdtemp(tmppldm)); 38 39 // Copy the sample image files to the directory 40 fs::copy("./files", dir); 41 42 imageFile = dir / "NVRAM-IMAGE"; 43 auto jsonObjects = Json::array(); 44 auto obj = Json::object(); 45 obj["path"] = imageFile.c_str(); 46 obj["file_traits"] = 1; 47 48 jsonObjects.push_back(obj); 49 obj.clear(); 50 cksumFile = dir / "NVRAM-IMAGE-CKSUM"; 51 obj["path"] = cksumFile.c_str(); 52 obj["file_traits"] = 4; 53 jsonObjects.push_back(obj); 54 55 fileTableConfig = dir / "configFile.json"; 56 std::ofstream file(fileTableConfig.c_str()); 57 file << std::setw(4) << jsonObjects << std::endl; 58 } 59 60 void TearDown() override 61 { 62 fs::remove_all(dir); 63 } 64 65 fs::path dir; 66 fs::path imageFile; 67 fs::path cksumFile; 68 fs::path fileTableConfig; 69 70 // <4 bytes - File handle - 0 (0x00 0x00 0x00 0x00)>, 71 // <2 bytes - Filename length - 11 (0x0b 0x00> 72 // <11 bytes - Filename - ASCII for NVRAM-IMAGE> 73 // <4 bytes - File size - 1024 (0x00 0x04 0x00 0x00)> 74 // <4 bytes - File traits - 1 (0x01 0x00 0x00 0x00)> 75 // <4 bytes - File handle - 1 (0x01 0x00 0x00 0x00)>, 76 // <2 bytes - Filename length - 17 (0x11 0x00> 77 // <17 bytes - Filename - ASCII for NVRAM-IMAGE-CKSUM> 78 // <4 bytes - File size - 16 (0x0f 0x00 0x00 0x00)> 79 // <4 bytes - File traits - 4 (0x04 0x00 0x00 0x00)> 80 // No pad bytes added since the length for both the file entries in the 81 // table is 56, which is a multiple of 4. 82 // <4 bytes - Checksum - 2088303182(0x4e 0xfa 0x78 0x7c)> 83 Table attrTable = { 84 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, 0x2d, 85 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 86 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, 87 0x2d, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x2d, 0x43, 0x4b, 0x53, 0x55, 0x4d, 88 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4e, 0xfa, 0x78, 0x7c}; 89 }; 90 91 namespace pldm 92 { 93 94 namespace responder 95 { 96 97 namespace dma 98 { 99 100 class MockDMA 101 { 102 public: 103 MOCK_METHOD5(transferDataHost, int(int fd, uint32_t offset, uint32_t length, 104 uint64_t address, bool upstream)); 105 }; 106 107 } // namespace dma 108 } // namespace responder 109 } // namespace pldm 110 using namespace pldm::responder; 111 using ::testing::_; 112 using ::testing::Return; 113 114 TEST(TransferDataHost, GoodPath) 115 { 116 using namespace pldm::responder::dma; 117 118 MockDMA dmaObj; 119 char tmpfile[] = "/tmp/pldm_fileio_table.XXXXXX"; 120 int fd = mkstemp(tmpfile); 121 close(fd); 122 fs::path path(tmpfile); 123 124 // Minimum length of 16 and expect transferDataHost to be called once 125 // returns the default value of 0 (the return type of transferDataHost is 126 // int, the default value for int is 0) 127 uint32_t length = minSize; 128 EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, true)).Times(1); 129 auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, 130 path, 0, length, 0, true, 0); 131 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 132 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); 133 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), 134 &length, sizeof(length))); 135 136 // maxsize of DMA 137 length = maxSize; 138 EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, true)).Times(1); 139 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, 140 0, length, 0, true, 0); 141 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 142 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); 143 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), 144 &length, sizeof(length))); 145 146 // length greater than maxsize of DMA 147 length = maxSize + minSize; 148 EXPECT_CALL(dmaObj, transferDataHost(_, 0, maxSize, 0, true)).Times(1); 149 EXPECT_CALL(dmaObj, transferDataHost(_, maxSize, minSize, maxSize, true)) 150 .Times(1); 151 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, 152 0, length, 0, true, 0); 153 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 154 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); 155 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), 156 &length, sizeof(length))); 157 158 // length greater than 2*maxsize of DMA 159 length = 3 * maxSize; 160 EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, true)).Times(3); 161 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, 162 0, length, 0, true, 0); 163 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 164 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); 165 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), 166 &length, sizeof(length))); 167 168 // check for downstream(copy data from host to BMC) parameter 169 length = minSize; 170 EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, false)).Times(1); 171 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, 172 0, length, 0, false, 0); 173 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 174 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); 175 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), 176 &length, sizeof(length))); 177 } 178 179 TEST(TransferDataHost, BadPath) 180 { 181 using namespace pldm::responder::dma; 182 183 MockDMA dmaObj; 184 char tmpfile[] = "/tmp/pldm_fileio_table.XXXXXX"; 185 int fd = mkstemp(tmpfile); 186 close(fd); 187 fs::path path(tmpfile); 188 189 // Minimum length of 16 and transferDataHost returning a negative errno 190 uint32_t length = minSize; 191 EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1)); 192 auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, 193 path, 0, length, 0, true, 0); 194 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 195 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR); 196 197 // length greater than maxsize of DMA and transferDataHost returning a 198 // negative errno 199 length = maxSize + minSize; 200 EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1)); 201 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, 202 0, length, 0, true, 0); 203 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 204 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR); 205 } 206 207 TEST(ReadFileIntoMemory, BadPath) 208 { 209 uint32_t fileHandle = 0; 210 uint32_t offset = 0; 211 uint32_t length = 10; 212 uint64_t address = 0; 213 uint8_t host_eid = 0; 214 int hostSocketFd = 0; 215 216 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 217 requestMsg{}; 218 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 219 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 220 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 221 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 222 sizeof(length)); 223 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 224 sizeof(length), 225 &address, sizeof(address)); 226 227 // Pass invalid payload length 228 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 229 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 230 nullptr, nullptr); 231 auto response = handler.readFileIntoMemory(request, 0); 232 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 233 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 234 } 235 236 TEST_F(TestFileTable, ReadFileInvalidFileHandle) 237 { 238 // Invalid file handle in the file table 239 uint32_t fileHandle = 2; 240 uint32_t offset = 0; 241 uint32_t length = 0; 242 uint64_t address = 0; 243 uint8_t host_eid = 0; 244 int hostSocketFd = 0; 245 246 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 247 requestMsg{}; 248 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 249 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 250 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 251 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 252 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 253 sizeof(length)); 254 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 255 sizeof(length), 256 &address, sizeof(address)); 257 258 using namespace pldm::filetable; 259 // Initialise the file table with 2 valid file handles 0 & 1. 260 auto& table = buildFileTable(fileTableConfig.c_str()); 261 262 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 263 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 264 nullptr, nullptr); 265 auto response = handler.readFileIntoMemory(request, requestPayloadLength); 266 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 267 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); 268 // Clear the file table contents. 269 table.clear(); 270 } 271 272 TEST_F(TestFileTable, ReadFileInvalidOffset) 273 { 274 uint32_t fileHandle = 0; 275 // The file size is 1024, so the offset is invalid 276 uint32_t offset = 1024; 277 uint32_t length = 0; 278 uint64_t address = 0; 279 uint8_t host_eid = 0; 280 int hostSocketFd = 0; 281 282 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 283 requestMsg{}; 284 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 285 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 286 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 287 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 288 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 289 sizeof(length)); 290 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 291 sizeof(length), 292 &address, sizeof(address)); 293 294 using namespace pldm::filetable; 295 auto& table = buildFileTable(fileTableConfig.c_str()); 296 297 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 298 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 299 nullptr, nullptr); 300 auto response = handler.readFileIntoMemory(request, requestPayloadLength); 301 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 302 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); 303 // Clear the file table contents. 304 table.clear(); 305 } 306 307 TEST_F(TestFileTable, ReadFileInvalidLength) 308 { 309 uint32_t fileHandle = 0; 310 uint32_t offset = 100; 311 // Length should be a multiple of dma min size(16) 312 uint32_t length = 10; 313 uint64_t address = 0; 314 uint8_t host_eid = 0; 315 int hostSocketFd = 0; 316 317 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 318 requestMsg{}; 319 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 320 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 321 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 322 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 323 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 324 sizeof(length)); 325 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 326 sizeof(length), 327 &address, sizeof(address)); 328 329 using namespace pldm::filetable; 330 auto& table = buildFileTable(fileTableConfig.c_str()); 331 332 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 333 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 334 nullptr, nullptr); 335 auto response = handler.readFileIntoMemory(request, requestPayloadLength); 336 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 337 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 338 // Clear the file table contents. 339 table.clear(); 340 } 341 342 TEST_F(TestFileTable, ReadFileInvalidEffectiveLength) 343 { 344 uint32_t fileHandle = 0; 345 // valid offset 346 uint32_t offset = 100; 347 // length + offset exceeds the size, so effective length is 348 // filesize(1024) - offset(100). The effective length is not a multiple of 349 // DMA min size(16) 350 uint32_t length = 1024; 351 uint64_t address = 0; 352 uint8_t host_eid = 0; 353 int hostSocketFd = 0; 354 355 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 356 requestMsg{}; 357 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 358 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 359 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 360 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 361 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 362 sizeof(length)); 363 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 364 sizeof(length), 365 &address, sizeof(address)); 366 367 using namespace pldm::filetable; 368 auto& table = buildFileTable(fileTableConfig.c_str()); 369 370 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 371 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 372 nullptr, nullptr); 373 auto response = handler.readFileIntoMemory(request, requestPayloadLength); 374 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 375 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 376 // Clear the file table contents. 377 table.clear(); 378 } 379 380 TEST(WriteFileFromMemory, BadPath) 381 { 382 uint32_t fileHandle = 0; 383 uint32_t offset = 0; 384 uint32_t length = 10; 385 uint64_t address = 0; 386 uint8_t host_eid = 0; 387 int hostSocketFd = 0; 388 389 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 390 requestMsg{}; 391 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 392 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 393 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 394 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 395 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 396 sizeof(length)); 397 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 398 sizeof(length), 399 &address, sizeof(address)); 400 401 // Pass invalid payload length 402 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 403 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 404 nullptr, nullptr); 405 auto response = handler.writeFileFromMemory(request, 0); 406 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 407 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 408 409 // The length field is not a multiple of DMA minsize 410 response = handler.writeFileFromMemory(request, requestPayloadLength); 411 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 412 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 413 } 414 415 TEST_F(TestFileTable, WriteFileInvalidFileHandle) 416 { 417 // Invalid file handle in the file table 418 uint32_t fileHandle = 2; 419 uint32_t offset = 0; 420 uint32_t length = 16; 421 uint64_t address = 0; 422 uint8_t host_eid = 0; 423 int hostSocketFd = 0; 424 425 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 426 requestMsg{}; 427 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 428 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 429 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 430 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 431 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 432 sizeof(length)); 433 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 434 sizeof(length), 435 &address, sizeof(address)); 436 437 using namespace pldm::filetable; 438 // Initialise the file table with 2 valid file handles 0 & 1. 439 auto& table = buildFileTable(fileTableConfig.c_str()); 440 441 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 442 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 443 nullptr, nullptr); 444 auto response = handler.writeFileFromMemory(request, requestPayloadLength); 445 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 446 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); 447 // Clear the file table contents. 448 table.clear(); 449 } 450 451 TEST_F(TestFileTable, WriteFileInvalidOffset) 452 { 453 uint32_t fileHandle = 0; 454 // The file size is 1024, so the offset is invalid 455 uint32_t offset = 1024; 456 uint32_t length = 16; 457 uint64_t address = 0; 458 uint8_t host_eid = 0; 459 int hostSocketFd = 0; 460 461 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> 462 requestMsg{}; 463 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 464 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 465 memcpy(request->payload, &fileHandle, sizeof(fileHandle)); 466 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); 467 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, 468 sizeof(length)); 469 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + 470 sizeof(length), 471 &address, sizeof(address)); 472 473 using namespace pldm::filetable; 474 // Initialise the file table with 2 valid file handles 0 & 1. 475 auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str()); 476 477 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 478 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 479 nullptr, nullptr); 480 auto response = handler.writeFileFromMemory(request, requestPayloadLength); 481 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 482 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); 483 // Clear the file table contents. 484 table.clear(); 485 } 486 487 TEST(FileTable, ConfigNotExist) 488 { 489 FileTable tableObj(""); 490 EXPECT_EQ(tableObj.isEmpty(), true); 491 } 492 493 TEST_F(TestFileTable, ValidateFileEntry) 494 { 495 FileTable tableObj(fileTableConfig.c_str()); 496 497 // Test file handle 0, the file size is 1K bytes. 498 auto value = tableObj.at(0); 499 ASSERT_EQ(value.handle, 0); 500 ASSERT_EQ(strcmp(value.fsPath.c_str(), imageFile.c_str()), 0); 501 ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value.fsPath)), 1024); 502 ASSERT_EQ(value.traits.value, 1); 503 ASSERT_EQ(true, fs::exists(value.fsPath)); 504 505 // Test file handle 1, the file size is 16 bytes 506 auto value1 = tableObj.at(1); 507 ASSERT_EQ(value1.handle, 1); 508 ASSERT_EQ(strcmp(value1.fsPath.c_str(), cksumFile.c_str()), 0); 509 ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value1.fsPath)), 16); 510 ASSERT_EQ(value1.traits.value, 4); 511 ASSERT_EQ(true, fs::exists(value1.fsPath)); 512 513 // Test invalid file handle 514 ASSERT_THROW(tableObj.at(2), std::out_of_range); 515 } 516 517 TEST_F(TestFileTable, ValidateFileTable) 518 { 519 FileTable tableObj(fileTableConfig.c_str()); 520 521 // Validate file attribute table 522 auto table = tableObj(); 523 ASSERT_EQ(true, 524 std::equal(attrTable.begin(), attrTable.end(), table.begin())); 525 } 526 527 TEST_F(TestFileTable, GetFileTableCommand) 528 { 529 // Initialise the file table with a valid handle of 0 & 1 530 auto& table = buildFileTable(fileTableConfig.c_str()); 531 532 uint32_t transferHandle = 0; 533 uint8_t opFlag = 0; 534 uint8_t type = PLDM_FILE_ATTRIBUTE_TABLE; 535 uint32_t nextTransferHandle = 0; 536 uint8_t transferFlag = PLDM_START_AND_END; 537 uint8_t host_eid = 0; 538 int hostSocketFd = 0; 539 540 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES> 541 requestMsg{}; 542 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 543 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 544 auto request = reinterpret_cast<pldm_get_file_table_req*>( 545 requestMsg.data() + sizeof(pldm_msg_hdr)); 546 request->transfer_handle = transferHandle; 547 request->operation_flag = opFlag; 548 request->table_type = type; 549 550 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 551 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 552 nullptr, nullptr); 553 auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength); 554 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 555 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); 556 size_t offsetSize = sizeof(responsePtr->payload[0]); 557 ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &nextTransferHandle, 558 sizeof(nextTransferHandle))); 559 offsetSize += sizeof(nextTransferHandle); 560 ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &transferFlag, 561 sizeof(transferFlag))); 562 offsetSize += sizeof(transferFlag); 563 ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, attrTable.data(), 564 attrTable.size())); 565 table.clear(); 566 } 567 568 TEST_F(TestFileTable, GetFileTableCommandReqLengthMismatch) 569 { 570 uint8_t host_eid = 0; 571 int hostSocketFd = 0; 572 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES> 573 requestMsg{}; 574 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 575 576 // Pass invalid command payload length 577 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 578 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 579 nullptr, nullptr); 580 auto response = handler.getFileTable(request, 0); 581 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 582 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 583 } 584 585 TEST_F(TestFileTable, GetFileTableCommandOEMAttrTable) 586 { 587 uint32_t transferHandle = 0; 588 uint8_t opFlag = 0; 589 uint8_t type = PLDM_OEM_FILE_ATTRIBUTE_TABLE; 590 uint8_t host_eid = 0; 591 int hostSocketFd = 0; 592 593 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES> 594 requestMsg{}; 595 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 596 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); 597 auto request = reinterpret_cast<pldm_get_file_table_req*>( 598 requestMsg.data() + sizeof(pldm_msg_hdr)); 599 request->transfer_handle = transferHandle; 600 request->operation_flag = opFlag; 601 request->table_type = type; 602 603 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 604 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 605 nullptr, nullptr); 606 auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength); 607 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 608 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE); 609 } 610 611 TEST_F(TestFileTable, ReadFileBadPath) 612 { 613 uint32_t fileHandle = 1; 614 uint32_t offset = 0; 615 uint32_t length = 0x4; 616 uint8_t host_eid = 0; 617 int hostSocketFd = 0; 618 619 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES> 620 requestMsg{}; 621 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 622 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); 623 auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() + 624 sizeof(pldm_msg_hdr)); 625 626 request->file_handle = fileHandle; 627 request->offset = offset; 628 request->length = length; 629 630 using namespace pldm::filetable; 631 // Initialise the file table with 2 valid file handles 0 & 1. 632 auto& table = buildFileTable(fileTableConfig.c_str()); 633 634 // Invalid payload length 635 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 636 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 637 nullptr, nullptr); 638 auto response = handler.readFile(requestMsgPtr, 0); 639 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 640 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 641 642 // Data out of range. File size is 1024, offset = 1024 is invalid. 643 request->offset = 1024; 644 645 response = handler.readFile(requestMsgPtr, payload_length); 646 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 647 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); 648 649 // Invalid file handle 650 request->file_handle = 2; 651 652 response = handler.readFile(requestMsgPtr, payload_length); 653 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 654 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); 655 656 table.clear(); 657 } 658 659 TEST_F(TestFileTable, ReadFileGoodPath) 660 { 661 uint32_t fileHandle = 0; 662 uint32_t offset = 0; 663 uint32_t length = 0x4; 664 uint8_t host_eid = 0; 665 int hostSocketFd = 0; 666 667 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES> 668 requestMsg{}; 669 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 670 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); 671 auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() + 672 sizeof(pldm_msg_hdr)); 673 674 request->file_handle = fileHandle; 675 request->offset = offset; 676 request->length = length; 677 678 using namespace pldm::filetable; 679 // Initialise the file table with 2 valid file handles 0 & 1. 680 auto& table = buildFileTable(fileTableConfig.c_str()); 681 FileEntry value{}; 682 value = table.at(fileHandle); 683 684 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary); 685 stream.seekg(offset); 686 std::vector<char> buffer(length); 687 stream.read(buffer.data(), length); 688 689 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 690 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 691 nullptr, nullptr); 692 auto responseMsg = handler.readFile(requestMsgPtr, payload_length); 693 auto response = reinterpret_cast<pldm_read_file_resp*>( 694 responseMsg.data() + sizeof(pldm_msg_hdr)); 695 ASSERT_EQ(response->completion_code, PLDM_SUCCESS); 696 ASSERT_EQ(response->length, length); 697 ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), length)); 698 699 // Test condition offset + length > fileSize; 700 size_t fileSize = 1024; 701 request->offset = 1023; 702 request->length = 10; 703 704 stream.seekg(request->offset); 705 buffer.resize(fileSize - request->offset); 706 stream.read(buffer.data(), (fileSize - request->offset)); 707 708 responseMsg = handler.readFile(requestMsgPtr, payload_length); 709 response = reinterpret_cast<pldm_read_file_resp*>(responseMsg.data() + 710 sizeof(pldm_msg_hdr)); 711 ASSERT_EQ(response->completion_code, PLDM_SUCCESS); 712 ASSERT_EQ(response->length, (fileSize - request->offset)); 713 ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), 714 (fileSize - request->offset))); 715 716 table.clear(); 717 } 718 719 TEST_F(TestFileTable, WriteFileBadPath) 720 { 721 uint32_t fileHandle = 0; 722 uint32_t offset = 0; 723 uint32_t length = 0x10; 724 uint8_t host_eid = 0; 725 int hostSocketFd = 0; 726 727 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 728 PLDM_WRITE_FILE_REQ_BYTES + length); 729 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 730 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); 731 auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() + 732 sizeof(pldm_msg_hdr)); 733 734 using namespace pldm::filetable; 735 // Initialise the file table with 2 valid file handles 0 & 1. 736 auto& table = buildFileTable(fileTableConfig.c_str()); 737 738 request->file_handle = fileHandle; 739 request->offset = offset; 740 request->length = length; 741 742 // Invalid payload length 743 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 744 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 745 nullptr, nullptr); 746 auto response = handler.writeFile(requestMsgPtr, 0); 747 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 748 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); 749 750 // Data out of range. File size is 1024, offset = 1024 is invalid. 751 request->offset = 1024; 752 753 response = handler.writeFile(requestMsgPtr, payload_length); 754 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 755 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); 756 757 // Invalid file handle 758 request->file_handle = 2; 759 760 response = handler.writeFile(requestMsgPtr, payload_length); 761 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 762 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); 763 764 table.clear(); 765 } 766 767 TEST_F(TestFileTable, WriteFileGoodPath) 768 { 769 uint32_t fileHandle = 1; 770 uint32_t offset = 0; 771 std::array<uint8_t, 4> fileData = {0x41, 0x42, 0x43, 0x44}; 772 uint32_t length = fileData.size(); 773 uint8_t host_eid = 0; 774 int hostSocketFd = 0; 775 776 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 777 PLDM_WRITE_FILE_REQ_BYTES + length); 778 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 779 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); 780 auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() + 781 sizeof(pldm_msg_hdr)); 782 783 using namespace pldm::filetable; 784 // Initialise the file table with 2 valid file handles 0 & 1. 785 auto& table = buildFileTable(fileTableConfig.c_str()); 786 FileEntry value{}; 787 value = table.at(fileHandle); 788 789 request->file_handle = fileHandle; 790 request->offset = offset; 791 request->length = length; 792 memcpy(request->file_data, fileData.data(), fileData.size()); 793 794 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 795 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 796 nullptr, nullptr); 797 auto responseMsg = handler.writeFile(requestMsgPtr, payload_length); 798 auto response = reinterpret_cast<pldm_read_file_resp*>( 799 responseMsg.data() + sizeof(pldm_msg_hdr)); 800 801 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary); 802 stream.seekg(offset); 803 std::vector<char> buffer(length); 804 stream.read(buffer.data(), length); 805 806 ASSERT_EQ(response->completion_code, PLDM_SUCCESS); 807 ASSERT_EQ(response->length, length); 808 ASSERT_EQ(0, memcmp(fileData.data(), buffer.data(), length)); 809 810 table.clear(); 811 } 812 813 TEST(writeFileByTypeFromMemory, testBadPath) 814 { 815 uint8_t host_eid = 0; 816 int hostSocketFd = 0; 817 818 const auto hdr_size = sizeof(pldm_msg_hdr); 819 std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES> 820 requestMsg{}; 821 auto req = reinterpret_cast<pldm_msg*>(requestMsg.data()); 822 size_t requestPayloadLength = requestMsg.size() - hdr_size; 823 struct pldm_read_write_file_by_type_memory_req* request = 824 reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>( 825 req->payload); 826 request->file_type = PLDM_FILE_TYPE_PEL; 827 request->file_handle = 0xFFFFFFFF; 828 request->offset = 0; 829 request->length = 17; 830 request->address = 0; 831 832 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 833 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 834 nullptr, nullptr); 835 auto response = handler.writeFileByTypeFromMemory(req, 0); 836 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 837 838 struct pldm_read_write_file_by_type_memory_resp* resp = 839 reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( 840 responsePtr->payload); 841 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code); 842 843 response = handler.writeFileByTypeFromMemory(req, requestPayloadLength); 844 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 845 846 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( 847 responsePtr->payload); 848 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code); 849 } 850 851 TEST(getHandlerByType, allPaths) 852 { 853 uint32_t fileHandle{}; 854 auto handler = getHandlerByType(PLDM_FILE_TYPE_PEL, fileHandle); 855 auto pelType = dynamic_cast<PelHandler*>(handler.get()); 856 ASSERT_TRUE(pelType != nullptr); 857 858 handler = getHandlerByType(PLDM_FILE_TYPE_LID_PERM, fileHandle); 859 auto lidType = dynamic_cast<LidHandler*>(handler.get()); 860 ASSERT_TRUE(lidType != nullptr); 861 pelType = dynamic_cast<PelHandler*>(handler.get()); 862 ASSERT_TRUE(pelType == nullptr); 863 handler = getHandlerByType(PLDM_FILE_TYPE_LID_TEMP, fileHandle); 864 lidType = dynamic_cast<LidHandler*>(handler.get()); 865 ASSERT_TRUE(lidType != nullptr); 866 867 handler = getHandlerByType(PLDM_FILE_TYPE_DUMP, fileHandle); 868 auto dumpType = dynamic_cast<DumpHandler*>(handler.get()); 869 ASSERT_TRUE(dumpType != nullptr); 870 871 handler = getHandlerByType(PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS, fileHandle); 872 dumpType = dynamic_cast<DumpHandler*>(handler.get()); 873 ASSERT_TRUE(dumpType != nullptr); 874 875 handler = getHandlerByType(PLDM_FILE_TYPE_RESOURCE_DUMP, fileHandle); 876 dumpType = dynamic_cast<DumpHandler*>(handler.get()); 877 ASSERT_TRUE(dumpType != nullptr); 878 879 handler = getHandlerByType(PLDM_FILE_TYPE_CERT_SIGNING_REQUEST, fileHandle); 880 auto certType = dynamic_cast<CertHandler*>(handler.get()); 881 ASSERT_TRUE(certType != nullptr); 882 883 handler = getHandlerByType(PLDM_FILE_TYPE_SIGNED_CERT, fileHandle); 884 certType = dynamic_cast<CertHandler*>(handler.get()); 885 ASSERT_TRUE(certType != nullptr); 886 887 handler = getHandlerByType(PLDM_FILE_TYPE_PCIE_TOPOLOGY, fileHandle); 888 auto pcieTopologyType = dynamic_cast<PCIeInfoHandler*>(handler.get()); 889 ASSERT_TRUE(pcieTopologyType != nullptr); 890 891 handler = getHandlerByType(PLDM_FILE_TYPE_CABLE_INFO, fileHandle); 892 auto cableInfoType = dynamic_cast<PCIeInfoHandler*>(handler.get()); 893 ASSERT_TRUE(cableInfoType != nullptr); 894 895 handler = getHandlerByType(PLDM_FILE_TYPE_ROOT_CERT, fileHandle); 896 certType = dynamic_cast<CertHandler*>(handler.get()); 897 ASSERT_TRUE(certType != nullptr); 898 899 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 900 ASSERT_THROW(getHandlerByType(0xFFFF, fileHandle), InternalFailure); 901 } 902 903 TEST(readFileByTypeIntoMemory, testBadPath) 904 { 905 uint8_t host_eid = 0; 906 int hostSocketFd = 0; 907 const auto hdr_size = sizeof(pldm_msg_hdr); 908 std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES> 909 requestMsg{}; 910 auto req = reinterpret_cast<pldm_msg*>(requestMsg.data()); 911 struct pldm_read_write_file_by_type_memory_req* request = 912 reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>( 913 req->payload); 914 request->file_type = 0xFFFF; 915 request->file_handle = 0; 916 request->offset = 0; 917 request->length = 17; 918 request->address = 0; 919 920 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 921 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 922 nullptr, nullptr); 923 auto response = handler.readFileByTypeIntoMemory(req, 0); 924 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 925 struct pldm_read_write_file_by_type_memory_resp* resp = 926 reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( 927 responsePtr->payload); 928 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code); 929 930 response = handler.readFileByTypeIntoMemory( 931 req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES); 932 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 933 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( 934 responsePtr->payload); 935 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code); 936 937 request->length = 16; 938 response = handler.readFileByTypeIntoMemory( 939 req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES); 940 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 941 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( 942 responsePtr->payload); 943 ASSERT_EQ(PLDM_INVALID_FILE_TYPE, resp->completion_code); 944 } 945 946 TEST(readFileByType, testBadPath) 947 { 948 uint8_t host_eid = 0; 949 int hostSocketFd = 0; 950 const auto hdr_size = sizeof(pldm_msg_hdr); 951 std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_REQ_BYTES> requestMsg{}; 952 auto payloadLength = requestMsg.size() - hdr_size; 953 auto req = reinterpret_cast<pldm_msg*>(requestMsg.data()); 954 struct pldm_read_write_file_by_type_req* request = 955 reinterpret_cast<struct pldm_read_write_file_by_type_req*>( 956 req->payload); 957 request->file_type = 0xFFFF; 958 request->file_handle = 0; 959 request->offset = 0; 960 request->length = 13; 961 962 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{}; 963 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid, 964 nullptr, nullptr); 965 auto response = handler.readFileByType(req, 0); 966 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 967 struct pldm_read_write_file_by_type_resp* resp = 968 reinterpret_cast<struct pldm_read_write_file_by_type_resp*>( 969 responsePtr->payload); 970 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code); 971 972 response = handler.readFileByType(req, payloadLength); 973 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 974 resp = reinterpret_cast<struct pldm_read_write_file_by_type_resp*>( 975 responsePtr->payload); 976 ASSERT_EQ(PLDM_INVALID_FILE_TYPE, resp->completion_code); 977 } 978 979 TEST(readFileByType, testReadFile) 980 { 981 LidHandler handler(0, true); 982 Response response; 983 uint32_t length{}; 984 985 auto rc = handler.readFile({}, 0, length, response); 986 ASSERT_EQ(PLDM_INVALID_FILE_HANDLE, rc); 987 988 char tmplt[] = "/tmp/lid.XXXXXX"; 989 auto fd = mkstemp(tmplt); 990 std::vector<uint8_t> in = {100, 10, 56, 78, 34, 56, 79, 235, 111}; 991 rc = write(fd, in.data(), in.size()); 992 ASSERT_NE(rc, PLDM_ERROR); 993 close(fd); 994 length = in.size() + 1000; 995 rc = handler.readFile(tmplt, 0, length, response); 996 ASSERT_EQ(rc, PLDM_SUCCESS); 997 ASSERT_EQ(length, in.size()); 998 ASSERT_EQ(response.size(), in.size()); 999 ASSERT_EQ(std::equal(in.begin(), in.end(), response.begin()), true); 1000 } 1001