blob: 36c6e7459f14625282e46e27f1493376d0067062 [file] [log] [blame]
George Liu6492f522020-06-16 10:34:05 +08001
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05302#include "libpldmresponder/file_io.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05003#include "libpldmresponder/file_io_by_type.hpp"
Sampa Misrad823cc02020-03-24 04:53:20 -05004#include "libpldmresponder/file_io_type_cert.hpp"
Sampa Misra18967162020-01-14 02:31:41 -06005#include "libpldmresponder/file_io_type_dump.hpp"
Deepak Kodihalli75e02f82019-11-20 02:51:05 -06006#include "libpldmresponder/file_io_type_lid.hpp"
Archana Kakanid6b00562024-03-31 17:53:58 -05007#include "libpldmresponder/file_io_type_pcie.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05008#include "libpldmresponder/file_io_type_pel.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05309#include "libpldmresponder/file_table.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050010#include "xyz/openbmc_project/Common/error.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +053011
George Liuc453e162022-12-21 17:16:23 +080012#include <libpldm/base.h>
Andrew Jeffery21f128d2024-01-15 15:34:26 +103013#include <libpldm/oem/ibm/file_io.h>
George Liuc453e162022-12-21 17:16:23 +080014
Tom Joseph0c6d22c2019-06-26 09:58:41 +053015#include <nlohmann/json.hpp>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053016
George Liu6492f522020-06-16 10:34:05 +080017#include <filesystem>
18#include <fstream>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053019
20#include <gmock/gmock-matchers.h>
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
Tom Joseph0c6d22c2019-06-26 09:58:41 +053023
Tom Joseph0c6d22c2019-06-26 09:58:41 +053024namespace fs = std::filesystem;
25using Json = nlohmann::json;
26using namespace pldm::filetable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -060027using namespace pldm::responder;
Tom Joseph0c6d22c2019-06-26 09:58:41 +053028
29class 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
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053091namespace pldm
92{
93
94namespace responder
95{
96
97namespace dma
98{
99
100class MockDMA
101{
102 public:
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600103 MOCK_METHOD5(transferDataHost, int(int fd, uint32_t offset, uint32_t length,
104 uint64_t address, bool upstream));
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530105};
106
107} // namespace dma
108} // namespace responder
109} // namespace pldm
110using namespace pldm::responder;
111using ::testing::_;
112using ::testing::Return;
113
114TEST(TransferDataHost, GoodPath)
115{
116 using namespace pldm::responder::dma;
117
118 MockDMA dmaObj;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600119 char tmpfile[] = "/tmp/pldm_fileio_table.XXXXXX";
120 int fd = mkstemp(tmpfile);
121 close(fd);
122 fs::path path(tmpfile);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530123
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;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600128 EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, true)).Times(1);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530129 auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530130 path, 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530131 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;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600138 EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, true)).Times(1);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530139 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530140 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530141 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;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600148 EXPECT_CALL(dmaObj, transferDataHost(_, 0, maxSize, 0, true)).Times(1);
149 EXPECT_CALL(dmaObj, transferDataHost(_, maxSize, minSize, maxSize, true))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530150 .Times(1);
151 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530152 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530153 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,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530162 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530163 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;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600170 EXPECT_CALL(dmaObj, transferDataHost(_, 0, length, 0, false)).Times(1);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530171 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530172 0, length, 0, false, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530173 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
179TEST(TransferDataHost, BadPath)
180{
181 using namespace pldm::responder::dma;
182
183 MockDMA dmaObj;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600184 char tmpfile[] = "/tmp/pldm_fileio_table.XXXXXX";
185 int fd = mkstemp(tmpfile);
186 close(fd);
187 fs::path path(tmpfile);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530188
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,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530193 path, 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530194 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,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530202 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530203 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
204 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);
205}
206
207TEST(ReadFileIntoMemory, BadPath)
208{
209 uint32_t fileHandle = 0;
210 uint32_t offset = 0;
211 uint32_t length = 10;
212 uint64_t address = 0;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530213 uint8_t host_eid = 0;
214 int hostSocketFd = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530215
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500216 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,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530222 sizeof(length));
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500223 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530224 sizeof(length),
225 &address, sizeof(address));
226
227 // Pass invalid payload length
Sampa Misraaea5dde2020-08-31 08:33:47 -0500228 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530229 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500230 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600231 auto response = handler.readFileIntoMemory(request, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530232 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
233 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
234}
235
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530236TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530243 uint8_t host_eid = 0;
244 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530245
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500262 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530263 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500264 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600265 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530266 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
272TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530279 uint8_t host_eid = 0;
280 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530281
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500297 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530298 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500299 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600300 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530301 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
307TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530314 uint8_t host_eid = 0;
315 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530316
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500332 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530333 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500334 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600335 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530336 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500337 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530338 // Clear the file table contents.
339 table.clear();
340}
341
342TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530352 uint8_t host_eid = 0;
353 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530354
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500370 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530371 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500372 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600373 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530374 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500375 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530376 // Clear the file table contents.
377 table.clear();
378}
379
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530380TEST(WriteFileFromMemory, BadPath)
381{
382 uint32_t fileHandle = 0;
383 uint32_t offset = 0;
384 uint32_t length = 10;
385 uint64_t address = 0;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530386 uint8_t host_eid = 0;
387 int hostSocketFd = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530388
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500389 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,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530396 sizeof(length));
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500397 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530398 sizeof(length),
399 &address, sizeof(address));
400
401 // Pass invalid payload length
Sampa Misraaea5dde2020-08-31 08:33:47 -0500402 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530403 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500404 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600405 auto response = handler.writeFileFromMemory(request, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530406 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600410 response = handler.writeFileFromMemory(request, requestPayloadLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530411 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500412 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530413}
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530414
415TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530422 uint8_t host_eid = 0;
423 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530424
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500441 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530442 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500443 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600444 auto response = handler.writeFileFromMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530445 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
451TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530458 uint8_t host_eid = 0;
459 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530460
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500477 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530478 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500479 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600480 auto response = handler.writeFileFromMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530481 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
487TEST(FileTable, ConfigNotExist)
488{
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530489 FileTable tableObj("");
John Wang881cde12019-10-24 15:08:48 +0800490 EXPECT_EQ(tableObj.isEmpty(), true);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530491}
492
493TEST_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
517TEST_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
527TEST_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;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530537 uint8_t host_eid = 0;
538 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530539
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500550 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530551 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500552 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600553 auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530554 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
568TEST_F(TestFileTable, GetFileTableCommandReqLengthMismatch)
569{
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530570 uint8_t host_eid = 0;
571 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530572 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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500577 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530578 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500579 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600580 auto response = handler.getFileTable(request, 0);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530581 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
582 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
583}
584
585TEST_F(TestFileTable, GetFileTableCommandOEMAttrTable)
586{
587 uint32_t transferHandle = 0;
588 uint8_t opFlag = 0;
589 uint8_t type = PLDM_OEM_FILE_ATTRIBUTE_TABLE;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530590 uint8_t host_eid = 0;
591 int hostSocketFd = 0;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530592
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500603 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530604 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500605 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600606 auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530607 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
608 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
609}
vkaverap5b914c32019-06-30 22:23:54 -0500610
611TEST_F(TestFileTable, ReadFileBadPath)
612{
613 uint32_t fileHandle = 1;
614 uint32_t offset = 0;
615 uint32_t length = 0x4;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530616 uint8_t host_eid = 0;
617 int hostSocketFd = 0;
vkaverap5b914c32019-06-30 22:23:54 -0500618
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);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400623 auto request = reinterpret_cast<pldm_read_file_req*>(
624 requestMsg.data() + sizeof(pldm_msg_hdr));
vkaverap5b914c32019-06-30 22:23:54 -0500625
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500635 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530636 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500637 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600638 auto response = handler.readFile(requestMsgPtr, 0);
vkaverap5b914c32019-06-30 22:23:54 -0500639 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600645 response = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500646 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600652 response = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500653 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
654 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
655
656 table.clear();
657}
658
659TEST_F(TestFileTable, ReadFileGoodPath)
660{
661 uint32_t fileHandle = 0;
662 uint32_t offset = 0;
663 uint32_t length = 0x4;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530664 uint8_t host_eid = 0;
665 int hostSocketFd = 0;
vkaverap5b914c32019-06-30 22:23:54 -0500666
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);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400671 auto request = reinterpret_cast<pldm_read_file_req*>(
672 requestMsg.data() + sizeof(pldm_msg_hdr));
vkaverap5b914c32019-06-30 22:23:54 -0500673
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500689 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530690 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500691 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600692 auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500693 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600708 responseMsg = handler.readFile(requestMsgPtr, payload_length);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400709 response = reinterpret_cast<pldm_read_file_resp*>(
710 responseMsg.data() + sizeof(pldm_msg_hdr));
vkaverap5b914c32019-06-30 22:23:54 -0500711 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
719TEST_F(TestFileTable, WriteFileBadPath)
720{
721 uint32_t fileHandle = 0;
722 uint32_t offset = 0;
723 uint32_t length = 0x10;
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530724 uint8_t host_eid = 0;
725 int hostSocketFd = 0;
vkaverap5b914c32019-06-30 22:23:54 -0500726
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400727 std::vector<uint8_t> requestMsg(
728 sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_REQ_BYTES + length);
vkaverap5b914c32019-06-30 22:23:54 -0500729 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
730 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400731 auto request = reinterpret_cast<pldm_write_file_req*>(
732 requestMsg.data() + sizeof(pldm_msg_hdr));
vkaverap5b914c32019-06-30 22:23:54 -0500733
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500743 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530744 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500745 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600746 auto response = handler.writeFile(requestMsgPtr, 0);
vkaverap5b914c32019-06-30 22:23:54 -0500747 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600753 response = handler.writeFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500754 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600760 response = handler.writeFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500761 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
762 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
763
764 table.clear();
765}
766
767TEST_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();
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530773 uint8_t host_eid = 0;
774 int hostSocketFd = 0;
vkaverap5b914c32019-06-30 22:23:54 -0500775
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400776 std::vector<uint8_t> requestMsg(
777 sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_REQ_BYTES + length);
vkaverap5b914c32019-06-30 22:23:54 -0500778 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
779 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400780 auto request = reinterpret_cast<pldm_write_file_req*>(
781 requestMsg.data() + sizeof(pldm_msg_hdr));
vkaverap5b914c32019-06-30 22:23:54 -0500782
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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500794 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530795 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500796 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600797 auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500798 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}
Sampa Misra854e61f2019-08-22 04:36:47 -0500812
813TEST(writeFileByTypeFromMemory, testBadPath)
814{
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530815 uint8_t host_eid = 0;
816 int hostSocketFd = 0;
817
Sampa Misra854e61f2019-08-22 04:36:47 -0500818 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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500832 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530833 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500834 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600835 auto response = handler.writeFileByTypeFromMemory(req, 0);
Sampa Misra854e61f2019-08-22 04:36:47 -0500836 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600843 response = handler.writeFileByTypeFromMemory(req, requestPayloadLength);
Sampa Misra854e61f2019-08-22 04:36:47 -0500844 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
845
846 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
847 responsePtr->payload);
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500848 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
Sampa Misra854e61f2019-08-22 04:36:47 -0500849}
850
851TEST(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
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600858 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
Sampa Misra18967162020-01-14 02:31:41 -0600867 handler = getHandlerByType(PLDM_FILE_TYPE_DUMP, fileHandle);
868 auto dumpType = dynamic_cast<DumpHandler*>(handler.get());
869 ASSERT_TRUE(dumpType != nullptr);
870
Jayashankar Padathdb124362021-01-28 21:12:34 -0600871 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
Sampa Misrad823cc02020-03-24 04:53:20 -0500879 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
Archana Kakanid6b00562024-03-31 17:53:58 -0500887 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
Sampa Misrad823cc02020-03-24 04:53:20 -0500895 handler = getHandlerByType(PLDM_FILE_TYPE_ROOT_CERT, fileHandle);
896 certType = dynamic_cast<CertHandler*>(handler.get());
897 ASSERT_TRUE(certType != nullptr);
898
Sampa Misra854e61f2019-08-22 04:36:47 -0500899 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
900 ASSERT_THROW(getHandlerByType(0xFFFF, fileHandle), InternalFailure);
901}
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600902
903TEST(readFileByTypeIntoMemory, testBadPath)
904{
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530905 uint8_t host_eid = 0;
906 int hostSocketFd = 0;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600907 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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500920 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530921 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500922 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600923 auto response = handler.readFileByTypeIntoMemory(req, 0);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600924 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600930 response = handler.readFileByTypeIntoMemory(
931 req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600932 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
933 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
934 responsePtr->payload);
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500935 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600936
937 request->length = 16;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600938 response = handler.readFileByTypeIntoMemory(
939 req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600940 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
946TEST(readFileByType, testBadPath)
947{
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530948 uint8_t host_eid = 0;
949 int hostSocketFd = 0;
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600950 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
Sampa Misraaea5dde2020-08-31 08:33:47 -0500962 std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530963 oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
Sampa Misrac0c79482021-06-02 08:01:54 -0500964 nullptr, nullptr);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600965 auto response = handler.readFileByType(req, 0);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600966 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
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600972 response = handler.readFileByType(req, payloadLength);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600973 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
979TEST(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};
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530991 rc = write(fd, in.data(), in.size());
Pavithra Barithaya5e3a2472023-07-10 08:43:59 -0500992 ASSERT_NE(rc, PLDM_ERROR);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600993 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}