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:
SetUp()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
TearDown()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
TEST(TransferDataHost,GoodPath)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
TEST(TransferDataHost,BadPath)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
TEST(ReadFileIntoMemory,BadPath)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
TEST_F(TestFileTable,ReadFileInvalidFileHandle)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
TEST_F(TestFileTable,ReadFileInvalidOffset)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
TEST_F(TestFileTable,ReadFileInvalidLength)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
TEST_F(TestFileTable,ReadFileInvalidEffectiveLength)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
TEST(WriteFileFromMemory,BadPath)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
TEST_F(TestFileTable,WriteFileInvalidFileHandle)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
TEST_F(TestFileTable,WriteFileInvalidOffset)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
TEST(FileTable,ConfigNotExist)487 TEST(FileTable, ConfigNotExist)
488 {
489 FileTable tableObj("");
490 EXPECT_EQ(tableObj.isEmpty(), true);
491 }
492
TEST_F(TestFileTable,ValidateFileEntry)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
TEST_F(TestFileTable,ValidateFileTable)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
TEST_F(TestFileTable,GetFileTableCommand)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
TEST_F(TestFileTable,GetFileTableCommandReqLengthMismatch)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
TEST_F(TestFileTable,GetFileTableCommandOEMAttrTable)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
TEST_F(TestFileTable,ReadFileBadPath)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*>(
624 requestMsg.data() + 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
TEST_F(TestFileTable,ReadFileGoodPath)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*>(
672 requestMsg.data() + 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*>(
710 responseMsg.data() + 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
TEST_F(TestFileTable,WriteFileBadPath)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(
728 sizeof(pldm_msg_hdr) + 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*>(
732 requestMsg.data() + 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
TEST_F(TestFileTable,WriteFileGoodPath)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(
777 sizeof(pldm_msg_hdr) + 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*>(
781 requestMsg.data() + 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
TEST(writeFileByTypeFromMemory,testBadPath)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
TEST(getHandlerByType,allPaths)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
TEST(readFileByTypeIntoMemory,testBadPath)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
TEST(readFileByType,testBadPath)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
TEST(readFileByType,testReadFile)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