| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 1 | #include "libpldmresponder/file_io.hpp" | 
| Sampa Misra | 854e61f | 2019-08-22 04:36:47 -0500 | [diff] [blame] | 2 | #include "libpldmresponder/file_io_by_type.hpp" | 
|  | 3 | #include "libpldmresponder/file_io_type_pel.hpp" | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 4 | #include "libpldmresponder/file_table.hpp" | 
| Sampa Misra | 854e61f | 2019-08-22 04:36:47 -0500 | [diff] [blame] | 5 | #include "xyz/openbmc_project/Common/error.hpp" | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 6 |  | 
|  | 7 | #include <filesystem> | 
|  | 8 | #include <fstream> | 
|  | 9 | #include <nlohmann/json.hpp> | 
| Sampa Misra | 854e61f | 2019-08-22 04:36:47 -0500 | [diff] [blame] | 10 | #include <phosphor-logging/elog-errors.hpp> | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 11 |  | 
|  | 12 | #include "libpldm/base.h" | 
|  | 13 | #include "libpldm/file_io.h" | 
|  | 14 |  | 
|  | 15 | #include <gmock/gmock-matchers.h> | 
|  | 16 | #include <gmock/gmock.h> | 
|  | 17 | #include <gtest/gtest.h> | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 18 |  | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 19 | namespace fs = std::filesystem; | 
|  | 20 | using Json = nlohmann::json; | 
|  | 21 | using namespace pldm::filetable; | 
|  | 22 |  | 
|  | 23 | class TestFileTable : public testing::Test | 
|  | 24 | { | 
|  | 25 | public: | 
|  | 26 | void SetUp() override | 
|  | 27 | { | 
|  | 28 | // Create a temporary directory to hold the config file and files to | 
|  | 29 | // populate the file table. | 
|  | 30 | char tmppldm[] = "/tmp/pldm_fileio_table.XXXXXX"; | 
|  | 31 | dir = fs::path(mkdtemp(tmppldm)); | 
|  | 32 |  | 
|  | 33 | // Copy the sample image files to the directory | 
|  | 34 | fs::copy("./files", dir); | 
|  | 35 |  | 
|  | 36 | imageFile = dir / "NVRAM-IMAGE"; | 
|  | 37 | auto jsonObjects = Json::array(); | 
|  | 38 | auto obj = Json::object(); | 
|  | 39 | obj["path"] = imageFile.c_str(); | 
|  | 40 | obj["file_traits"] = 1; | 
|  | 41 |  | 
|  | 42 | jsonObjects.push_back(obj); | 
|  | 43 | obj.clear(); | 
|  | 44 | cksumFile = dir / "NVRAM-IMAGE-CKSUM"; | 
|  | 45 | obj["path"] = cksumFile.c_str(); | 
|  | 46 | obj["file_traits"] = 4; | 
|  | 47 | jsonObjects.push_back(obj); | 
|  | 48 |  | 
|  | 49 | fileTableConfig = dir / "configFile.json"; | 
|  | 50 | std::ofstream file(fileTableConfig.c_str()); | 
|  | 51 | file << std::setw(4) << jsonObjects << std::endl; | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | void TearDown() override | 
|  | 55 | { | 
|  | 56 | fs::remove_all(dir); | 
|  | 57 | } | 
|  | 58 |  | 
|  | 59 | fs::path dir; | 
|  | 60 | fs::path imageFile; | 
|  | 61 | fs::path cksumFile; | 
|  | 62 | fs::path fileTableConfig; | 
|  | 63 |  | 
|  | 64 | // <4 bytes - File handle - 0 (0x00 0x00 0x00 0x00)>, | 
|  | 65 | // <2 bytes - Filename length - 11 (0x0b 0x00> | 
|  | 66 | // <11 bytes - Filename - ASCII for NVRAM-IMAGE> | 
|  | 67 | // <4 bytes - File size - 1024 (0x00 0x04 0x00 0x00)> | 
|  | 68 | // <4 bytes - File traits - 1 (0x01 0x00 0x00 0x00)> | 
|  | 69 | // <4 bytes - File handle - 1 (0x01 0x00 0x00 0x00)>, | 
|  | 70 | // <2 bytes - Filename length - 17 (0x11 0x00> | 
|  | 71 | // <17 bytes - Filename - ASCII for NVRAM-IMAGE-CKSUM> | 
|  | 72 | // <4 bytes - File size - 16 (0x0f 0x00 0x00 0x00)> | 
|  | 73 | // <4 bytes - File traits - 4 (0x04 0x00 0x00 0x00)> | 
|  | 74 | // No pad bytes added since the length for both the file entries in the | 
|  | 75 | // table is 56, which is a multiple of 4. | 
|  | 76 | // <4 bytes - Checksum - 2088303182(0x4e 0xfa 0x78 0x7c)> | 
|  | 77 | Table attrTable = { | 
|  | 78 | 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, 0x2d, | 
|  | 79 | 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, | 
|  | 80 | 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, | 
|  | 81 | 0x2d, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x2d, 0x43, 0x4b, 0x53, 0x55, 0x4d, | 
|  | 82 | 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4e, 0xfa, 0x78, 0x7c}; | 
|  | 83 | }; | 
|  | 84 |  | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 85 | namespace pldm | 
|  | 86 | { | 
|  | 87 |  | 
|  | 88 | namespace responder | 
|  | 89 | { | 
|  | 90 |  | 
|  | 91 | namespace dma | 
|  | 92 | { | 
|  | 93 |  | 
|  | 94 | class MockDMA | 
|  | 95 | { | 
|  | 96 | public: | 
|  | 97 | MOCK_METHOD5(transferDataHost, | 
|  | 98 | int(const fs::path& file, uint32_t offset, uint32_t length, | 
|  | 99 | uint64_t address, bool upstream)); | 
|  | 100 | }; | 
|  | 101 |  | 
|  | 102 | } // namespace dma | 
|  | 103 | } // namespace responder | 
|  | 104 | } // namespace pldm | 
|  | 105 | using namespace pldm::responder; | 
|  | 106 | using ::testing::_; | 
|  | 107 | using ::testing::Return; | 
|  | 108 |  | 
|  | 109 | TEST(TransferDataHost, GoodPath) | 
|  | 110 | { | 
|  | 111 | using namespace pldm::responder::dma; | 
|  | 112 |  | 
|  | 113 | MockDMA dmaObj; | 
|  | 114 | fs::path path(""); | 
|  | 115 |  | 
|  | 116 | // Minimum length of 16 and expect transferDataHost to be called once | 
|  | 117 | // returns the default value of 0 (the return type of transferDataHost is | 
|  | 118 | // int, the default value for int is 0) | 
|  | 119 | uint32_t length = minSize; | 
|  | 120 | EXPECT_CALL(dmaObj, transferDataHost(path, 0, length, 0, true)).Times(1); | 
|  | 121 | auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 122 | path, 0, length, 0, true, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 123 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 124 | ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); | 
|  | 125 | ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), | 
|  | 126 | &length, sizeof(length))); | 
|  | 127 |  | 
|  | 128 | // maxsize of DMA | 
|  | 129 | length = maxSize; | 
|  | 130 | EXPECT_CALL(dmaObj, transferDataHost(path, 0, length, 0, true)).Times(1); | 
|  | 131 | response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 132 | 0, length, 0, true, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 133 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 134 | ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); | 
|  | 135 | ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), | 
|  | 136 | &length, sizeof(length))); | 
|  | 137 |  | 
|  | 138 | // length greater than maxsize of DMA | 
|  | 139 | length = maxSize + minSize; | 
|  | 140 | EXPECT_CALL(dmaObj, transferDataHost(path, 0, maxSize, 0, true)).Times(1); | 
|  | 141 | EXPECT_CALL(dmaObj, transferDataHost(path, maxSize, minSize, maxSize, true)) | 
|  | 142 | .Times(1); | 
|  | 143 | response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 144 | 0, length, 0, true, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 145 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 146 | ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); | 
|  | 147 | ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), | 
|  | 148 | &length, sizeof(length))); | 
|  | 149 |  | 
|  | 150 | // length greater than 2*maxsize of DMA | 
|  | 151 | length = 3 * maxSize; | 
|  | 152 | EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, true)).Times(3); | 
|  | 153 | response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 154 | 0, length, 0, true, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 155 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 156 | ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); | 
|  | 157 | ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), | 
|  | 158 | &length, sizeof(length))); | 
|  | 159 |  | 
|  | 160 | // check for downstream(copy data from host to BMC) parameter | 
|  | 161 | length = minSize; | 
|  | 162 | EXPECT_CALL(dmaObj, transferDataHost(path, 0, length, 0, false)).Times(1); | 
|  | 163 | response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 164 | 0, length, 0, false, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 165 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 166 | ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); | 
|  | 167 | ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]), | 
|  | 168 | &length, sizeof(length))); | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | TEST(TransferDataHost, BadPath) | 
|  | 172 | { | 
|  | 173 | using namespace pldm::responder::dma; | 
|  | 174 |  | 
|  | 175 | MockDMA dmaObj; | 
|  | 176 | fs::path path(""); | 
|  | 177 |  | 
|  | 178 | // Minimum length of 16 and transferDataHost returning a negative errno | 
|  | 179 | uint32_t length = minSize; | 
|  | 180 | EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1)); | 
|  | 181 | auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 182 | path, 0, length, 0, true, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 183 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 184 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR); | 
|  | 185 |  | 
|  | 186 | // length greater than maxsize of DMA and transferDataHost returning a | 
|  | 187 | // negative errno | 
|  | 188 | length = maxSize + minSize; | 
|  | 189 | EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1)); | 
|  | 190 | response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path, | 
| Jinu Joy Thomas | 33705fd | 2019-07-02 16:03:05 +0530 | [diff] [blame] | 191 | 0, length, 0, true, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 192 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 193 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR); | 
|  | 194 | } | 
|  | 195 |  | 
|  | 196 | TEST(ReadFileIntoMemory, BadPath) | 
|  | 197 | { | 
|  | 198 | uint32_t fileHandle = 0; | 
|  | 199 | uint32_t offset = 0; | 
|  | 200 | uint32_t length = 10; | 
|  | 201 | uint64_t address = 0; | 
|  | 202 |  | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 203 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 204 | requestMsg{}; | 
|  | 205 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 206 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 207 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 208 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 209 | sizeof(length)); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 210 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 211 | sizeof(length), | 
|  | 212 | &address, sizeof(address)); | 
|  | 213 |  | 
|  | 214 | // Pass invalid payload length | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 215 | auto response = readFileIntoMemory(request, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 216 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 217 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); | 
|  | 218 | } | 
|  | 219 |  | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 220 | TEST_F(TestFileTable, ReadFileInvalidFileHandle) | 
|  | 221 | { | 
|  | 222 | // Invalid file handle in the file table | 
|  | 223 | uint32_t fileHandle = 2; | 
|  | 224 | uint32_t offset = 0; | 
|  | 225 | uint32_t length = 0; | 
|  | 226 | uint64_t address = 0; | 
|  | 227 |  | 
|  | 228 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 229 | requestMsg{}; | 
|  | 230 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 231 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 232 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 233 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 234 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
|  | 235 | sizeof(length)); | 
|  | 236 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
|  | 237 | sizeof(length), | 
|  | 238 | &address, sizeof(address)); | 
|  | 239 |  | 
|  | 240 | using namespace pldm::filetable; | 
|  | 241 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 242 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 243 |  | 
|  | 244 | auto response = readFileIntoMemory(request, requestPayloadLength); | 
|  | 245 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 246 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); | 
|  | 247 | // Clear the file table contents. | 
|  | 248 | table.clear(); | 
|  | 249 | } | 
|  | 250 |  | 
|  | 251 | TEST_F(TestFileTable, ReadFileInvalidOffset) | 
|  | 252 | { | 
|  | 253 | uint32_t fileHandle = 0; | 
|  | 254 | // The file size is 1024, so the offset is invalid | 
|  | 255 | uint32_t offset = 1024; | 
|  | 256 | uint32_t length = 0; | 
|  | 257 | uint64_t address = 0; | 
|  | 258 |  | 
|  | 259 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 260 | requestMsg{}; | 
|  | 261 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 262 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 263 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 264 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 265 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
|  | 266 | sizeof(length)); | 
|  | 267 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
|  | 268 | sizeof(length), | 
|  | 269 | &address, sizeof(address)); | 
|  | 270 |  | 
|  | 271 | using namespace pldm::filetable; | 
|  | 272 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 273 |  | 
|  | 274 | auto response = readFileIntoMemory(request, requestPayloadLength); | 
|  | 275 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 276 | ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); | 
|  | 277 | // Clear the file table contents. | 
|  | 278 | table.clear(); | 
|  | 279 | } | 
|  | 280 |  | 
|  | 281 | TEST_F(TestFileTable, ReadFileInvalidLength) | 
|  | 282 | { | 
|  | 283 | uint32_t fileHandle = 0; | 
|  | 284 | uint32_t offset = 100; | 
|  | 285 | // Length should be a multiple of dma min size(16) | 
|  | 286 | uint32_t length = 10; | 
|  | 287 | uint64_t address = 0; | 
|  | 288 |  | 
|  | 289 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 290 | requestMsg{}; | 
|  | 291 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 292 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 293 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 294 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 295 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
|  | 296 | sizeof(length)); | 
|  | 297 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
|  | 298 | sizeof(length), | 
|  | 299 | &address, sizeof(address)); | 
|  | 300 |  | 
|  | 301 | using namespace pldm::filetable; | 
|  | 302 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 303 |  | 
|  | 304 | auto response = readFileIntoMemory(request, requestPayloadLength); | 
|  | 305 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 306 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH); | 
|  | 307 | // Clear the file table contents. | 
|  | 308 | table.clear(); | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | TEST_F(TestFileTable, ReadFileInvalidEffectiveLength) | 
|  | 312 | { | 
|  | 313 | uint32_t fileHandle = 0; | 
|  | 314 | // valid offset | 
|  | 315 | uint32_t offset = 100; | 
|  | 316 | // length + offset exceeds the size, so effective length is | 
|  | 317 | // filesize(1024) - offset(100). The effective length is not a multiple of | 
|  | 318 | // DMA min size(16) | 
|  | 319 | uint32_t length = 1024; | 
|  | 320 | uint64_t address = 0; | 
|  | 321 |  | 
|  | 322 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 323 | requestMsg{}; | 
|  | 324 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 325 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 326 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 327 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 328 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
|  | 329 | sizeof(length)); | 
|  | 330 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
|  | 331 | sizeof(length), | 
|  | 332 | &address, sizeof(address)); | 
|  | 333 |  | 
|  | 334 | using namespace pldm::filetable; | 
|  | 335 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 336 |  | 
|  | 337 | auto response = readFileIntoMemory(request, requestPayloadLength); | 
|  | 338 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 339 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH); | 
|  | 340 | // Clear the file table contents. | 
|  | 341 | table.clear(); | 
|  | 342 | } | 
|  | 343 |  | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 344 | TEST(WriteFileFromMemory, BadPath) | 
|  | 345 | { | 
|  | 346 | uint32_t fileHandle = 0; | 
|  | 347 | uint32_t offset = 0; | 
|  | 348 | uint32_t length = 10; | 
|  | 349 | uint64_t address = 0; | 
|  | 350 |  | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 351 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 352 | requestMsg{}; | 
|  | 353 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 354 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 355 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 356 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 357 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 358 | sizeof(length)); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 359 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 360 | sizeof(length), | 
|  | 361 | &address, sizeof(address)); | 
|  | 362 |  | 
|  | 363 | // Pass invalid payload length | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 364 | auto response = writeFileFromMemory(request, 0); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 365 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 366 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); | 
|  | 367 |  | 
|  | 368 | // The length field is not a multiple of DMA minsize | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 369 | response = writeFileFromMemory(request, requestPayloadLength); | 
| Jinu Joy Thomas | 7f57f44 | 2019-06-13 20:38:49 +0530 | [diff] [blame] | 370 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 371 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_WRITE_LENGTH); | 
|  | 372 | } | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 373 |  | 
|  | 374 | TEST_F(TestFileTable, WriteFileInvalidFileHandle) | 
|  | 375 | { | 
|  | 376 | // Invalid file handle in the file table | 
|  | 377 | uint32_t fileHandle = 2; | 
|  | 378 | uint32_t offset = 0; | 
|  | 379 | uint32_t length = 16; | 
|  | 380 | uint64_t address = 0; | 
|  | 381 |  | 
|  | 382 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 383 | requestMsg{}; | 
|  | 384 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 385 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 386 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 387 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 388 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
|  | 389 | sizeof(length)); | 
|  | 390 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
|  | 391 | sizeof(length), | 
|  | 392 | &address, sizeof(address)); | 
|  | 393 |  | 
|  | 394 | using namespace pldm::filetable; | 
|  | 395 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 396 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 397 |  | 
|  | 398 | auto response = writeFileFromMemory(request, requestPayloadLength); | 
|  | 399 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 400 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); | 
|  | 401 | // Clear the file table contents. | 
|  | 402 | table.clear(); | 
|  | 403 | } | 
|  | 404 |  | 
|  | 405 | TEST_F(TestFileTable, WriteFileInvalidOffset) | 
|  | 406 | { | 
|  | 407 | uint32_t fileHandle = 0; | 
|  | 408 | // The file size is 1024, so the offset is invalid | 
|  | 409 | uint32_t offset = 1024; | 
|  | 410 | uint32_t length = 16; | 
|  | 411 | uint64_t address = 0; | 
|  | 412 |  | 
|  | 413 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES> | 
|  | 414 | requestMsg{}; | 
|  | 415 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 416 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 417 | memcpy(request->payload, &fileHandle, sizeof(fileHandle)); | 
|  | 418 | memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset)); | 
|  | 419 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length, | 
|  | 420 | sizeof(length)); | 
|  | 421 | memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) + | 
|  | 422 | sizeof(length), | 
|  | 423 | &address, sizeof(address)); | 
|  | 424 |  | 
|  | 425 | using namespace pldm::filetable; | 
|  | 426 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 427 | auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str()); | 
|  | 428 |  | 
|  | 429 | auto response = writeFileFromMemory(request, requestPayloadLength); | 
|  | 430 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 431 | ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); | 
|  | 432 | // Clear the file table contents. | 
|  | 433 | table.clear(); | 
|  | 434 | } | 
|  | 435 |  | 
|  | 436 | TEST(FileTable, ConfigNotExist) | 
|  | 437 | { | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 438 | FileTable tableObj(""); | 
| John Wang | 881cde1 | 2019-10-24 15:08:48 +0800 | [diff] [blame] | 439 | EXPECT_EQ(tableObj.isEmpty(), true); | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 440 | } | 
|  | 441 |  | 
|  | 442 | TEST_F(TestFileTable, ValidateFileEntry) | 
|  | 443 | { | 
|  | 444 | FileTable tableObj(fileTableConfig.c_str()); | 
|  | 445 |  | 
|  | 446 | // Test file handle 0, the file size is 1K bytes. | 
|  | 447 | auto value = tableObj.at(0); | 
|  | 448 | ASSERT_EQ(value.handle, 0); | 
|  | 449 | ASSERT_EQ(strcmp(value.fsPath.c_str(), imageFile.c_str()), 0); | 
|  | 450 | ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value.fsPath)), 1024); | 
|  | 451 | ASSERT_EQ(value.traits.value, 1); | 
|  | 452 | ASSERT_EQ(true, fs::exists(value.fsPath)); | 
|  | 453 |  | 
|  | 454 | // Test file handle 1, the file size is 16 bytes | 
|  | 455 | auto value1 = tableObj.at(1); | 
|  | 456 | ASSERT_EQ(value1.handle, 1); | 
|  | 457 | ASSERT_EQ(strcmp(value1.fsPath.c_str(), cksumFile.c_str()), 0); | 
|  | 458 | ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value1.fsPath)), 16); | 
|  | 459 | ASSERT_EQ(value1.traits.value, 4); | 
|  | 460 | ASSERT_EQ(true, fs::exists(value1.fsPath)); | 
|  | 461 |  | 
|  | 462 | // Test invalid file handle | 
|  | 463 | ASSERT_THROW(tableObj.at(2), std::out_of_range); | 
|  | 464 | } | 
|  | 465 |  | 
|  | 466 | TEST_F(TestFileTable, ValidateFileTable) | 
|  | 467 | { | 
|  | 468 | FileTable tableObj(fileTableConfig.c_str()); | 
|  | 469 |  | 
|  | 470 | // Validate file attribute table | 
|  | 471 | auto table = tableObj(); | 
|  | 472 | ASSERT_EQ(true, | 
|  | 473 | std::equal(attrTable.begin(), attrTable.end(), table.begin())); | 
|  | 474 | } | 
|  | 475 |  | 
|  | 476 | TEST_F(TestFileTable, GetFileTableCommand) | 
|  | 477 | { | 
|  | 478 | // Initialise the file table with a valid handle of 0 & 1 | 
|  | 479 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 480 |  | 
|  | 481 | uint32_t transferHandle = 0; | 
|  | 482 | uint8_t opFlag = 0; | 
|  | 483 | uint8_t type = PLDM_FILE_ATTRIBUTE_TABLE; | 
|  | 484 | uint32_t nextTransferHandle = 0; | 
|  | 485 | uint8_t transferFlag = PLDM_START_AND_END; | 
|  | 486 |  | 
|  | 487 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES> | 
|  | 488 | requestMsg{}; | 
|  | 489 | auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 490 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 491 | auto request = reinterpret_cast<pldm_get_file_table_req*>( | 
|  | 492 | requestMsg.data() + sizeof(pldm_msg_hdr)); | 
|  | 493 | request->transfer_handle = transferHandle; | 
|  | 494 | request->operation_flag = opFlag; | 
|  | 495 | request->table_type = type; | 
|  | 496 |  | 
|  | 497 | auto response = getFileTable(requestMsgPtr, requestPayloadLength); | 
|  | 498 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 499 | ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS); | 
|  | 500 | size_t offsetSize = sizeof(responsePtr->payload[0]); | 
|  | 501 | ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &nextTransferHandle, | 
|  | 502 | sizeof(nextTransferHandle))); | 
|  | 503 | offsetSize += sizeof(nextTransferHandle); | 
|  | 504 | ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &transferFlag, | 
|  | 505 | sizeof(transferFlag))); | 
|  | 506 | offsetSize += sizeof(transferFlag); | 
|  | 507 | ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, attrTable.data(), | 
|  | 508 | attrTable.size())); | 
|  | 509 | table.clear(); | 
|  | 510 | } | 
|  | 511 |  | 
|  | 512 | TEST_F(TestFileTable, GetFileTableCommandReqLengthMismatch) | 
|  | 513 | { | 
|  | 514 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES> | 
|  | 515 | requestMsg{}; | 
|  | 516 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 517 |  | 
|  | 518 | // Pass invalid command payload length | 
|  | 519 | auto response = getFileTable(request, 0); | 
|  | 520 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 521 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); | 
|  | 522 | } | 
|  | 523 |  | 
|  | 524 | TEST_F(TestFileTable, GetFileTableCommandOEMAttrTable) | 
|  | 525 | { | 
|  | 526 | uint32_t transferHandle = 0; | 
|  | 527 | uint8_t opFlag = 0; | 
|  | 528 | uint8_t type = PLDM_OEM_FILE_ATTRIBUTE_TABLE; | 
|  | 529 |  | 
|  | 530 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES> | 
|  | 531 | requestMsg{}; | 
|  | 532 | auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 533 | size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 534 | auto request = reinterpret_cast<pldm_get_file_table_req*>( | 
|  | 535 | requestMsg.data() + sizeof(pldm_msg_hdr)); | 
|  | 536 | request->transfer_handle = transferHandle; | 
|  | 537 | request->operation_flag = opFlag; | 
|  | 538 | request->table_type = type; | 
|  | 539 |  | 
|  | 540 | auto response = getFileTable(requestMsgPtr, requestPayloadLength); | 
|  | 541 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 542 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE); | 
|  | 543 | } | 
| vkaverap | 5b914c3 | 2019-06-30 22:23:54 -0500 | [diff] [blame] | 544 |  | 
|  | 545 | TEST_F(TestFileTable, ReadFileBadPath) | 
|  | 546 | { | 
|  | 547 | uint32_t fileHandle = 1; | 
|  | 548 | uint32_t offset = 0; | 
|  | 549 | uint32_t length = 0x4; | 
|  | 550 |  | 
|  | 551 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES> | 
|  | 552 | requestMsg{}; | 
|  | 553 | auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 554 | auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 555 | auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() + | 
|  | 556 | sizeof(pldm_msg_hdr)); | 
|  | 557 |  | 
|  | 558 | request->file_handle = fileHandle; | 
|  | 559 | request->offset = offset; | 
|  | 560 | request->length = length; | 
|  | 561 |  | 
|  | 562 | using namespace pldm::filetable; | 
|  | 563 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 564 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 565 |  | 
|  | 566 | // Invalid payload length | 
|  | 567 | auto response = readFile(requestMsgPtr, 0); | 
|  | 568 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 569 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); | 
|  | 570 |  | 
|  | 571 | // Data out of range. File size is 1024, offset = 1024 is invalid. | 
|  | 572 | request->offset = 1024; | 
|  | 573 |  | 
|  | 574 | response = readFile(requestMsgPtr, payload_length); | 
|  | 575 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 576 | ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); | 
|  | 577 |  | 
|  | 578 | // Invalid file handle | 
|  | 579 | request->file_handle = 2; | 
|  | 580 |  | 
|  | 581 | response = readFile(requestMsgPtr, payload_length); | 
|  | 582 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 583 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); | 
|  | 584 |  | 
|  | 585 | table.clear(); | 
|  | 586 | } | 
|  | 587 |  | 
|  | 588 | TEST_F(TestFileTable, ReadFileGoodPath) | 
|  | 589 | { | 
|  | 590 | uint32_t fileHandle = 0; | 
|  | 591 | uint32_t offset = 0; | 
|  | 592 | uint32_t length = 0x4; | 
|  | 593 |  | 
|  | 594 | std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES> | 
|  | 595 | requestMsg{}; | 
|  | 596 | auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 597 | auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 598 | auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() + | 
|  | 599 | sizeof(pldm_msg_hdr)); | 
|  | 600 |  | 
|  | 601 | request->file_handle = fileHandle; | 
|  | 602 | request->offset = offset; | 
|  | 603 | request->length = length; | 
|  | 604 |  | 
|  | 605 | using namespace pldm::filetable; | 
|  | 606 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 607 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 608 | FileEntry value{}; | 
|  | 609 | value = table.at(fileHandle); | 
|  | 610 |  | 
|  | 611 | std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary); | 
|  | 612 | stream.seekg(offset); | 
|  | 613 | std::vector<char> buffer(length); | 
|  | 614 | stream.read(buffer.data(), length); | 
|  | 615 |  | 
|  | 616 | auto responseMsg = readFile(requestMsgPtr, payload_length); | 
|  | 617 | auto response = reinterpret_cast<pldm_read_file_resp*>( | 
|  | 618 | responseMsg.data() + sizeof(pldm_msg_hdr)); | 
|  | 619 | ASSERT_EQ(response->completion_code, PLDM_SUCCESS); | 
|  | 620 | ASSERT_EQ(response->length, length); | 
|  | 621 | ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), length)); | 
|  | 622 |  | 
|  | 623 | // Test condition offset + length > fileSize; | 
|  | 624 | size_t fileSize = 1024; | 
|  | 625 | request->offset = 1023; | 
|  | 626 | request->length = 10; | 
|  | 627 |  | 
|  | 628 | stream.seekg(request->offset); | 
|  | 629 | buffer.resize(fileSize - request->offset); | 
|  | 630 | stream.read(buffer.data(), (fileSize - request->offset)); | 
|  | 631 |  | 
|  | 632 | responseMsg = readFile(requestMsgPtr, payload_length); | 
|  | 633 | response = reinterpret_cast<pldm_read_file_resp*>(responseMsg.data() + | 
|  | 634 | sizeof(pldm_msg_hdr)); | 
|  | 635 | ASSERT_EQ(response->completion_code, PLDM_SUCCESS); | 
|  | 636 | ASSERT_EQ(response->length, (fileSize - request->offset)); | 
|  | 637 | ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), | 
|  | 638 | (fileSize - request->offset))); | 
|  | 639 |  | 
|  | 640 | table.clear(); | 
|  | 641 | } | 
|  | 642 |  | 
|  | 643 | TEST_F(TestFileTable, WriteFileBadPath) | 
|  | 644 | { | 
|  | 645 | uint32_t fileHandle = 0; | 
|  | 646 | uint32_t offset = 0; | 
|  | 647 | uint32_t length = 0x10; | 
|  | 648 |  | 
|  | 649 | std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + | 
|  | 650 | PLDM_WRITE_FILE_REQ_BYTES + length); | 
|  | 651 | auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 652 | auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 653 | auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() + | 
|  | 654 | sizeof(pldm_msg_hdr)); | 
|  | 655 |  | 
|  | 656 | using namespace pldm::filetable; | 
|  | 657 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 658 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 659 |  | 
|  | 660 | request->file_handle = fileHandle; | 
|  | 661 | request->offset = offset; | 
|  | 662 | request->length = length; | 
|  | 663 |  | 
|  | 664 | // Invalid payload length | 
|  | 665 | auto response = writeFile(requestMsgPtr, 0); | 
|  | 666 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 667 | ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH); | 
|  | 668 |  | 
|  | 669 | // Data out of range. File size is 1024, offset = 1024 is invalid. | 
|  | 670 | request->offset = 1024; | 
|  | 671 |  | 
|  | 672 | response = writeFile(requestMsgPtr, payload_length); | 
|  | 673 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 674 | ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE); | 
|  | 675 |  | 
|  | 676 | // Invalid file handle | 
|  | 677 | request->file_handle = 2; | 
|  | 678 |  | 
|  | 679 | response = writeFile(requestMsgPtr, payload_length); | 
|  | 680 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 681 | ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE); | 
|  | 682 |  | 
|  | 683 | table.clear(); | 
|  | 684 | } | 
|  | 685 |  | 
|  | 686 | TEST_F(TestFileTable, WriteFileGoodPath) | 
|  | 687 | { | 
|  | 688 | uint32_t fileHandle = 1; | 
|  | 689 | uint32_t offset = 0; | 
|  | 690 | std::array<uint8_t, 4> fileData = {0x41, 0x42, 0x43, 0x44}; | 
|  | 691 | uint32_t length = fileData.size(); | 
|  | 692 |  | 
|  | 693 | std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + | 
|  | 694 | PLDM_WRITE_FILE_REQ_BYTES + length); | 
|  | 695 | auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 696 | auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr); | 
|  | 697 | auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() + | 
|  | 698 | sizeof(pldm_msg_hdr)); | 
|  | 699 |  | 
|  | 700 | using namespace pldm::filetable; | 
|  | 701 | // Initialise the file table with 2 valid file handles 0 & 1. | 
|  | 702 | auto& table = buildFileTable(fileTableConfig.c_str()); | 
|  | 703 | FileEntry value{}; | 
|  | 704 | value = table.at(fileHandle); | 
|  | 705 |  | 
|  | 706 | request->file_handle = fileHandle; | 
|  | 707 | request->offset = offset; | 
|  | 708 | request->length = length; | 
|  | 709 | memcpy(request->file_data, fileData.data(), fileData.size()); | 
|  | 710 |  | 
|  | 711 | auto responseMsg = writeFile(requestMsgPtr, payload_length); | 
|  | 712 | auto response = reinterpret_cast<pldm_read_file_resp*>( | 
|  | 713 | responseMsg.data() + sizeof(pldm_msg_hdr)); | 
|  | 714 |  | 
|  | 715 | std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary); | 
|  | 716 | stream.seekg(offset); | 
|  | 717 | std::vector<char> buffer(length); | 
|  | 718 | stream.read(buffer.data(), length); | 
|  | 719 |  | 
|  | 720 | ASSERT_EQ(response->completion_code, PLDM_SUCCESS); | 
|  | 721 | ASSERT_EQ(response->length, length); | 
|  | 722 | ASSERT_EQ(0, memcmp(fileData.data(), buffer.data(), length)); | 
|  | 723 |  | 
|  | 724 | table.clear(); | 
|  | 725 | } | 
| Sampa Misra | 854e61f | 2019-08-22 04:36:47 -0500 | [diff] [blame] | 726 |  | 
|  | 727 | TEST(writeFileByTypeFromMemory, testBadPath) | 
|  | 728 | { | 
|  | 729 | const auto hdr_size = sizeof(pldm_msg_hdr); | 
|  | 730 | std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES> | 
|  | 731 | requestMsg{}; | 
|  | 732 | auto req = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 733 | size_t requestPayloadLength = requestMsg.size() - hdr_size; | 
|  | 734 | struct pldm_read_write_file_by_type_memory_req* request = | 
|  | 735 | reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>( | 
|  | 736 | req->payload); | 
|  | 737 | request->file_type = PLDM_FILE_TYPE_PEL; | 
|  | 738 | request->file_handle = 0xFFFFFFFF; | 
|  | 739 | request->offset = 0; | 
|  | 740 | request->length = 17; | 
|  | 741 | request->address = 0; | 
|  | 742 |  | 
|  | 743 | auto response = writeFileByTypeFromMemory(req, 0); | 
|  | 744 | auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 745 |  | 
|  | 746 | struct pldm_read_write_file_by_type_memory_resp* resp = | 
|  | 747 | reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( | 
|  | 748 | responsePtr->payload); | 
|  | 749 | ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code); | 
|  | 750 |  | 
|  | 751 | response = writeFileByTypeFromMemory(req, requestPayloadLength); | 
|  | 752 | responsePtr = reinterpret_cast<pldm_msg*>(response.data()); | 
|  | 753 |  | 
|  | 754 | resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>( | 
|  | 755 | responsePtr->payload); | 
|  | 756 | ASSERT_EQ(PLDM_INVALID_WRITE_LENGTH, resp->completion_code); | 
|  | 757 | } | 
|  | 758 |  | 
|  | 759 | TEST(getHandlerByType, allPaths) | 
|  | 760 | { | 
|  | 761 | uint32_t fileHandle{}; | 
|  | 762 | auto handler = getHandlerByType(PLDM_FILE_TYPE_PEL, fileHandle); | 
|  | 763 | auto pelType = dynamic_cast<PelHandler*>(handler.get()); | 
|  | 764 | ASSERT_TRUE(pelType != nullptr); | 
|  | 765 |  | 
|  | 766 | using namespace sdbusplus::xyz::openbmc_project::Common::Error; | 
|  | 767 | ASSERT_THROW(getHandlerByType(0xFFFF, fileHandle), InternalFailure); | 
|  | 768 | } |