blob: e62e8e14c973f35ddcbcad68ace9f9eccf2aab27 [file] [log] [blame]
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05301#include "libpldmresponder/file_io.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05002#include "libpldmresponder/file_io_by_type.hpp"
Deepak Kodihalli75e02f82019-11-20 02:51:05 -06003#include "libpldmresponder/file_io_type_lid.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05004#include "libpldmresponder/file_io_type_pel.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05305#include "libpldmresponder/file_table.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05006#include "xyz/openbmc_project/Common/error.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05307
8#include <filesystem>
9#include <fstream>
10#include <nlohmann/json.hpp>
Sampa Misra854e61f2019-08-22 04:36:47 -050011#include <phosphor-logging/elog-errors.hpp>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053012
13#include "libpldm/base.h"
14#include "libpldm/file_io.h"
15
16#include <gmock/gmock-matchers.h>
17#include <gmock/gmock.h>
18#include <gtest/gtest.h>
Tom Joseph0c6d22c2019-06-26 09:58:41 +053019
Tom Joseph0c6d22c2019-06-26 09:58:41 +053020namespace fs = std::filesystem;
21using Json = nlohmann::json;
22using namespace pldm::filetable;
Deepak Kodihallibc669f12019-11-28 08:52:07 -060023using namespace pldm::responder;
Tom Joseph0c6d22c2019-06-26 09:58:41 +053024
25class TestFileTable : public testing::Test
26{
27 public:
28 void SetUp() override
29 {
30 // Create a temporary directory to hold the config file and files to
31 // populate the file table.
32 char tmppldm[] = "/tmp/pldm_fileio_table.XXXXXX";
33 dir = fs::path(mkdtemp(tmppldm));
34
35 // Copy the sample image files to the directory
36 fs::copy("./files", dir);
37
38 imageFile = dir / "NVRAM-IMAGE";
39 auto jsonObjects = Json::array();
40 auto obj = Json::object();
41 obj["path"] = imageFile.c_str();
42 obj["file_traits"] = 1;
43
44 jsonObjects.push_back(obj);
45 obj.clear();
46 cksumFile = dir / "NVRAM-IMAGE-CKSUM";
47 obj["path"] = cksumFile.c_str();
48 obj["file_traits"] = 4;
49 jsonObjects.push_back(obj);
50
51 fileTableConfig = dir / "configFile.json";
52 std::ofstream file(fileTableConfig.c_str());
53 file << std::setw(4) << jsonObjects << std::endl;
54 }
55
56 void TearDown() override
57 {
58 fs::remove_all(dir);
59 }
60
61 fs::path dir;
62 fs::path imageFile;
63 fs::path cksumFile;
64 fs::path fileTableConfig;
65
66 // <4 bytes - File handle - 0 (0x00 0x00 0x00 0x00)>,
67 // <2 bytes - Filename length - 11 (0x0b 0x00>
68 // <11 bytes - Filename - ASCII for NVRAM-IMAGE>
69 // <4 bytes - File size - 1024 (0x00 0x04 0x00 0x00)>
70 // <4 bytes - File traits - 1 (0x01 0x00 0x00 0x00)>
71 // <4 bytes - File handle - 1 (0x01 0x00 0x00 0x00)>,
72 // <2 bytes - Filename length - 17 (0x11 0x00>
73 // <17 bytes - Filename - ASCII for NVRAM-IMAGE-CKSUM>
74 // <4 bytes - File size - 16 (0x0f 0x00 0x00 0x00)>
75 // <4 bytes - File traits - 4 (0x04 0x00 0x00 0x00)>
76 // No pad bytes added since the length for both the file entries in the
77 // table is 56, which is a multiple of 4.
78 // <4 bytes - Checksum - 2088303182(0x4e 0xfa 0x78 0x7c)>
79 Table attrTable = {
80 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d, 0x2d,
81 0x49, 0x4d, 0x41, 0x47, 0x45, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00,
82 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x4e, 0x56, 0x52, 0x41, 0x4d,
83 0x2d, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x2d, 0x43, 0x4b, 0x53, 0x55, 0x4d,
84 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4e, 0xfa, 0x78, 0x7c};
85};
86
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053087namespace pldm
88{
89
90namespace responder
91{
92
93namespace dma
94{
95
96class MockDMA
97{
98 public:
99 MOCK_METHOD5(transferDataHost,
100 int(const fs::path& file, uint32_t offset, uint32_t length,
101 uint64_t address, bool upstream));
102};
103
104} // namespace dma
105} // namespace responder
106} // namespace pldm
107using namespace pldm::responder;
108using ::testing::_;
109using ::testing::Return;
110
111TEST(TransferDataHost, GoodPath)
112{
113 using namespace pldm::responder::dma;
114
115 MockDMA dmaObj;
116 fs::path path("");
117
118 // Minimum length of 16 and expect transferDataHost to be called once
119 // returns the default value of 0 (the return type of transferDataHost is
120 // int, the default value for int is 0)
121 uint32_t length = minSize;
122 EXPECT_CALL(dmaObj, transferDataHost(path, 0, length, 0, true)).Times(1);
123 auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530124 path, 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530125 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
126 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
127 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
128 &length, sizeof(length)));
129
130 // maxsize of DMA
131 length = maxSize;
132 EXPECT_CALL(dmaObj, transferDataHost(path, 0, length, 0, true)).Times(1);
133 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530134 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530135 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
136 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
137 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
138 &length, sizeof(length)));
139
140 // length greater than maxsize of DMA
141 length = maxSize + minSize;
142 EXPECT_CALL(dmaObj, transferDataHost(path, 0, maxSize, 0, true)).Times(1);
143 EXPECT_CALL(dmaObj, transferDataHost(path, maxSize, minSize, maxSize, true))
144 .Times(1);
145 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530146 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530147 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
148 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
149 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
150 &length, sizeof(length)));
151
152 // length greater than 2*maxsize of DMA
153 length = 3 * maxSize;
154 EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, true)).Times(3);
155 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530156 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530157 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
158 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
159 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
160 &length, sizeof(length)));
161
162 // check for downstream(copy data from host to BMC) parameter
163 length = minSize;
164 EXPECT_CALL(dmaObj, transferDataHost(path, 0, length, 0, false)).Times(1);
165 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530166 0, length, 0, false, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530167 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
168 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
169 ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
170 &length, sizeof(length)));
171}
172
173TEST(TransferDataHost, BadPath)
174{
175 using namespace pldm::responder::dma;
176
177 MockDMA dmaObj;
178 fs::path path("");
179
180 // Minimum length of 16 and transferDataHost returning a negative errno
181 uint32_t length = minSize;
182 EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1));
183 auto response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530184 path, 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530185 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
186 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);
187
188 // length greater than maxsize of DMA and transferDataHost returning a
189 // negative errno
190 length = maxSize + minSize;
191 EXPECT_CALL(dmaObj, transferDataHost(_, _, _, _, _)).WillOnce(Return(-1));
192 response = transferAll<MockDMA>(&dmaObj, PLDM_READ_FILE_INTO_MEMORY, path,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530193 0, length, 0, true, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530194 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
195 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR);
196}
197
198TEST(ReadFileIntoMemory, BadPath)
199{
200 uint32_t fileHandle = 0;
201 uint32_t offset = 0;
202 uint32_t length = 10;
203 uint64_t address = 0;
204
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500205 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
206 requestMsg{};
207 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
208 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
209 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
210 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530211 sizeof(length));
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500212 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530213 sizeof(length),
214 &address, sizeof(address));
215
216 // Pass invalid payload length
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600217 oem_ibm::Handler handler;
218 auto response = handler.readFileIntoMemory(request, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530219 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
220 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
221}
222
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530223TEST_F(TestFileTable, ReadFileInvalidFileHandle)
224{
225 // Invalid file handle in the file table
226 uint32_t fileHandle = 2;
227 uint32_t offset = 0;
228 uint32_t length = 0;
229 uint64_t address = 0;
230
231 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
232 requestMsg{};
233 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
234 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
235 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
236 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
237 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
238 sizeof(length));
239 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
240 sizeof(length),
241 &address, sizeof(address));
242
243 using namespace pldm::filetable;
244 // Initialise the file table with 2 valid file handles 0 & 1.
245 auto& table = buildFileTable(fileTableConfig.c_str());
246
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600247 oem_ibm::Handler handler;
248 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530249 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
250 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
251 // Clear the file table contents.
252 table.clear();
253}
254
255TEST_F(TestFileTable, ReadFileInvalidOffset)
256{
257 uint32_t fileHandle = 0;
258 // The file size is 1024, so the offset is invalid
259 uint32_t offset = 1024;
260 uint32_t length = 0;
261 uint64_t address = 0;
262
263 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
264 requestMsg{};
265 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
266 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
267 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
268 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
269 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
270 sizeof(length));
271 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
272 sizeof(length),
273 &address, sizeof(address));
274
275 using namespace pldm::filetable;
276 auto& table = buildFileTable(fileTableConfig.c_str());
277
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600278 oem_ibm::Handler handler;
279 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530280 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
281 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
282 // Clear the file table contents.
283 table.clear();
284}
285
286TEST_F(TestFileTable, ReadFileInvalidLength)
287{
288 uint32_t fileHandle = 0;
289 uint32_t offset = 100;
290 // Length should be a multiple of dma min size(16)
291 uint32_t length = 10;
292 uint64_t address = 0;
293
294 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
295 requestMsg{};
296 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
297 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
298 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
299 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
300 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
301 sizeof(length));
302 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
303 sizeof(length),
304 &address, sizeof(address));
305
306 using namespace pldm::filetable;
307 auto& table = buildFileTable(fileTableConfig.c_str());
308
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600309 oem_ibm::Handler handler;
310 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530311 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
312 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH);
313 // Clear the file table contents.
314 table.clear();
315}
316
317TEST_F(TestFileTable, ReadFileInvalidEffectiveLength)
318{
319 uint32_t fileHandle = 0;
320 // valid offset
321 uint32_t offset = 100;
322 // length + offset exceeds the size, so effective length is
323 // filesize(1024) - offset(100). The effective length is not a multiple of
324 // DMA min size(16)
325 uint32_t length = 1024;
326 uint64_t address = 0;
327
328 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
329 requestMsg{};
330 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
331 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
332 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
333 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
334 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
335 sizeof(length));
336 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
337 sizeof(length),
338 &address, sizeof(address));
339
340 using namespace pldm::filetable;
341 auto& table = buildFileTable(fileTableConfig.c_str());
342
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600343 oem_ibm::Handler handler;
344 auto response = handler.readFileIntoMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530345 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
346 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_READ_LENGTH);
347 // Clear the file table contents.
348 table.clear();
349}
350
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530351TEST(WriteFileFromMemory, BadPath)
352{
353 uint32_t fileHandle = 0;
354 uint32_t offset = 0;
355 uint32_t length = 10;
356 uint64_t address = 0;
357
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500358 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
359 requestMsg{};
360 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
361 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
362 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
363 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
364 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530365 sizeof(length));
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500366 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530367 sizeof(length),
368 &address, sizeof(address));
369
370 // Pass invalid payload length
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600371 oem_ibm::Handler handler;
372 auto response = handler.writeFileFromMemory(request, 0);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530373 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
374 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
375
376 // The length field is not a multiple of DMA minsize
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600377 response = handler.writeFileFromMemory(request, requestPayloadLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530378 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
379 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_WRITE_LENGTH);
380}
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530381
382TEST_F(TestFileTable, WriteFileInvalidFileHandle)
383{
384 // Invalid file handle in the file table
385 uint32_t fileHandle = 2;
386 uint32_t offset = 0;
387 uint32_t length = 16;
388 uint64_t address = 0;
389
390 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
391 requestMsg{};
392 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
393 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
394 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
395 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
396 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
397 sizeof(length));
398 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
399 sizeof(length),
400 &address, sizeof(address));
401
402 using namespace pldm::filetable;
403 // Initialise the file table with 2 valid file handles 0 & 1.
404 auto& table = buildFileTable(fileTableConfig.c_str());
405
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600406 oem_ibm::Handler handler;
407 auto response = handler.writeFileFromMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530408 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
409 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
410 // Clear the file table contents.
411 table.clear();
412}
413
414TEST_F(TestFileTable, WriteFileInvalidOffset)
415{
416 uint32_t fileHandle = 0;
417 // The file size is 1024, so the offset is invalid
418 uint32_t offset = 1024;
419 uint32_t length = 16;
420 uint64_t address = 0;
421
422 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_REQ_BYTES>
423 requestMsg{};
424 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
425 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
426 memcpy(request->payload, &fileHandle, sizeof(fileHandle));
427 memcpy(request->payload + sizeof(fileHandle), &offset, sizeof(offset));
428 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset), &length,
429 sizeof(length));
430 memcpy(request->payload + sizeof(fileHandle) + sizeof(offset) +
431 sizeof(length),
432 &address, sizeof(address));
433
434 using namespace pldm::filetable;
435 // Initialise the file table with 2 valid file handles 0 & 1.
436 auto& table = buildFileTable(TestFileTable::fileTableConfig.c_str());
437
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600438 oem_ibm::Handler handler;
439 auto response = handler.writeFileFromMemory(request, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530440 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
441 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
442 // Clear the file table contents.
443 table.clear();
444}
445
446TEST(FileTable, ConfigNotExist)
447{
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530448 FileTable tableObj("");
John Wang881cde12019-10-24 15:08:48 +0800449 EXPECT_EQ(tableObj.isEmpty(), true);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530450}
451
452TEST_F(TestFileTable, ValidateFileEntry)
453{
454 FileTable tableObj(fileTableConfig.c_str());
455
456 // Test file handle 0, the file size is 1K bytes.
457 auto value = tableObj.at(0);
458 ASSERT_EQ(value.handle, 0);
459 ASSERT_EQ(strcmp(value.fsPath.c_str(), imageFile.c_str()), 0);
460 ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value.fsPath)), 1024);
461 ASSERT_EQ(value.traits.value, 1);
462 ASSERT_EQ(true, fs::exists(value.fsPath));
463
464 // Test file handle 1, the file size is 16 bytes
465 auto value1 = tableObj.at(1);
466 ASSERT_EQ(value1.handle, 1);
467 ASSERT_EQ(strcmp(value1.fsPath.c_str(), cksumFile.c_str()), 0);
468 ASSERT_EQ(static_cast<uint32_t>(fs::file_size(value1.fsPath)), 16);
469 ASSERT_EQ(value1.traits.value, 4);
470 ASSERT_EQ(true, fs::exists(value1.fsPath));
471
472 // Test invalid file handle
473 ASSERT_THROW(tableObj.at(2), std::out_of_range);
474}
475
476TEST_F(TestFileTable, ValidateFileTable)
477{
478 FileTable tableObj(fileTableConfig.c_str());
479
480 // Validate file attribute table
481 auto table = tableObj();
482 ASSERT_EQ(true,
483 std::equal(attrTable.begin(), attrTable.end(), table.begin()));
484}
485
486TEST_F(TestFileTable, GetFileTableCommand)
487{
488 // Initialise the file table with a valid handle of 0 & 1
489 auto& table = buildFileTable(fileTableConfig.c_str());
490
491 uint32_t transferHandle = 0;
492 uint8_t opFlag = 0;
493 uint8_t type = PLDM_FILE_ATTRIBUTE_TABLE;
494 uint32_t nextTransferHandle = 0;
495 uint8_t transferFlag = PLDM_START_AND_END;
496
497 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES>
498 requestMsg{};
499 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
500 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
501 auto request = reinterpret_cast<pldm_get_file_table_req*>(
502 requestMsg.data() + sizeof(pldm_msg_hdr));
503 request->transfer_handle = transferHandle;
504 request->operation_flag = opFlag;
505 request->table_type = type;
506
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600507 oem_ibm::Handler handler;
508 auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530509 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
510 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
511 size_t offsetSize = sizeof(responsePtr->payload[0]);
512 ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &nextTransferHandle,
513 sizeof(nextTransferHandle)));
514 offsetSize += sizeof(nextTransferHandle);
515 ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, &transferFlag,
516 sizeof(transferFlag)));
517 offsetSize += sizeof(transferFlag);
518 ASSERT_EQ(0, memcmp(responsePtr->payload + offsetSize, attrTable.data(),
519 attrTable.size()));
520 table.clear();
521}
522
523TEST_F(TestFileTable, GetFileTableCommandReqLengthMismatch)
524{
525 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES>
526 requestMsg{};
527 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
528
529 // Pass invalid command payload length
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600530 oem_ibm::Handler handler;
531 auto response = handler.getFileTable(request, 0);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530532 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
533 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
534}
535
536TEST_F(TestFileTable, GetFileTableCommandOEMAttrTable)
537{
538 uint32_t transferHandle = 0;
539 uint8_t opFlag = 0;
540 uint8_t type = PLDM_OEM_FILE_ATTRIBUTE_TABLE;
541
542 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_FILE_TABLE_REQ_BYTES>
543 requestMsg{};
544 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
545 size_t requestPayloadLength = requestMsg.size() - sizeof(pldm_msg_hdr);
546 auto request = reinterpret_cast<pldm_get_file_table_req*>(
547 requestMsg.data() + sizeof(pldm_msg_hdr));
548 request->transfer_handle = transferHandle;
549 request->operation_flag = opFlag;
550 request->table_type = type;
551
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600552 oem_ibm::Handler handler;
553 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_INVALID_FILE_TABLE_TYPE);
556}
vkaverap5b914c32019-06-30 22:23:54 -0500557
558TEST_F(TestFileTable, ReadFileBadPath)
559{
560 uint32_t fileHandle = 1;
561 uint32_t offset = 0;
562 uint32_t length = 0x4;
563
564 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES>
565 requestMsg{};
566 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
567 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
568 auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() +
569 sizeof(pldm_msg_hdr));
570
571 request->file_handle = fileHandle;
572 request->offset = offset;
573 request->length = length;
574
575 using namespace pldm::filetable;
576 // Initialise the file table with 2 valid file handles 0 & 1.
577 auto& table = buildFileTable(fileTableConfig.c_str());
578
579 // Invalid payload length
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600580 oem_ibm::Handler handler;
581 auto response = handler.readFile(requestMsgPtr, 0);
vkaverap5b914c32019-06-30 22:23:54 -0500582 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
583 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
584
585 // Data out of range. File size is 1024, offset = 1024 is invalid.
586 request->offset = 1024;
587
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600588 response = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500589 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
590 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
591
592 // Invalid file handle
593 request->file_handle = 2;
594
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600595 response = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500596 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
597 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
598
599 table.clear();
600}
601
602TEST_F(TestFileTable, ReadFileGoodPath)
603{
604 uint32_t fileHandle = 0;
605 uint32_t offset = 0;
606 uint32_t length = 0x4;
607
608 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_READ_FILE_REQ_BYTES>
609 requestMsg{};
610 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
611 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
612 auto request = reinterpret_cast<pldm_read_file_req*>(requestMsg.data() +
613 sizeof(pldm_msg_hdr));
614
615 request->file_handle = fileHandle;
616 request->offset = offset;
617 request->length = length;
618
619 using namespace pldm::filetable;
620 // Initialise the file table with 2 valid file handles 0 & 1.
621 auto& table = buildFileTable(fileTableConfig.c_str());
622 FileEntry value{};
623 value = table.at(fileHandle);
624
625 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
626 stream.seekg(offset);
627 std::vector<char> buffer(length);
628 stream.read(buffer.data(), length);
629
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600630 oem_ibm::Handler handler;
631 auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500632 auto response = reinterpret_cast<pldm_read_file_resp*>(
633 responseMsg.data() + sizeof(pldm_msg_hdr));
634 ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
635 ASSERT_EQ(response->length, length);
636 ASSERT_EQ(0, memcmp(response->file_data, buffer.data(), length));
637
638 // Test condition offset + length > fileSize;
639 size_t fileSize = 1024;
640 request->offset = 1023;
641 request->length = 10;
642
643 stream.seekg(request->offset);
644 buffer.resize(fileSize - request->offset);
645 stream.read(buffer.data(), (fileSize - request->offset));
646
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600647 responseMsg = handler.readFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500648 response = reinterpret_cast<pldm_read_file_resp*>(responseMsg.data() +
649 sizeof(pldm_msg_hdr));
650 ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
651 ASSERT_EQ(response->length, (fileSize - request->offset));
652 ASSERT_EQ(0, memcmp(response->file_data, buffer.data(),
653 (fileSize - request->offset)));
654
655 table.clear();
656}
657
658TEST_F(TestFileTable, WriteFileBadPath)
659{
660 uint32_t fileHandle = 0;
661 uint32_t offset = 0;
662 uint32_t length = 0x10;
663
664 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
665 PLDM_WRITE_FILE_REQ_BYTES + length);
666 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
667 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
668 auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() +
669 sizeof(pldm_msg_hdr));
670
671 using namespace pldm::filetable;
672 // Initialise the file table with 2 valid file handles 0 & 1.
673 auto& table = buildFileTable(fileTableConfig.c_str());
674
675 request->file_handle = fileHandle;
676 request->offset = offset;
677 request->length = length;
678
679 // Invalid payload length
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600680 oem_ibm::Handler handler;
681 auto response = handler.writeFile(requestMsgPtr, 0);
vkaverap5b914c32019-06-30 22:23:54 -0500682 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
683 ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
684
685 // Data out of range. File size is 1024, offset = 1024 is invalid.
686 request->offset = 1024;
687
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600688 response = handler.writeFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500689 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
690 ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
691
692 // Invalid file handle
693 request->file_handle = 2;
694
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600695 response = handler.writeFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500696 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
697 ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
698
699 table.clear();
700}
701
702TEST_F(TestFileTable, WriteFileGoodPath)
703{
704 uint32_t fileHandle = 1;
705 uint32_t offset = 0;
706 std::array<uint8_t, 4> fileData = {0x41, 0x42, 0x43, 0x44};
707 uint32_t length = fileData.size();
708
709 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
710 PLDM_WRITE_FILE_REQ_BYTES + length);
711 auto requestMsgPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
712 auto payload_length = requestMsg.size() - sizeof(pldm_msg_hdr);
713 auto request = reinterpret_cast<pldm_write_file_req*>(requestMsg.data() +
714 sizeof(pldm_msg_hdr));
715
716 using namespace pldm::filetable;
717 // Initialise the file table with 2 valid file handles 0 & 1.
718 auto& table = buildFileTable(fileTableConfig.c_str());
719 FileEntry value{};
720 value = table.at(fileHandle);
721
722 request->file_handle = fileHandle;
723 request->offset = offset;
724 request->length = length;
725 memcpy(request->file_data, fileData.data(), fileData.size());
726
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600727 oem_ibm::Handler handler;
728 auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
vkaverap5b914c32019-06-30 22:23:54 -0500729 auto response = reinterpret_cast<pldm_read_file_resp*>(
730 responseMsg.data() + sizeof(pldm_msg_hdr));
731
732 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
733 stream.seekg(offset);
734 std::vector<char> buffer(length);
735 stream.read(buffer.data(), length);
736
737 ASSERT_EQ(response->completion_code, PLDM_SUCCESS);
738 ASSERT_EQ(response->length, length);
739 ASSERT_EQ(0, memcmp(fileData.data(), buffer.data(), length));
740
741 table.clear();
742}
Sampa Misra854e61f2019-08-22 04:36:47 -0500743
744TEST(writeFileByTypeFromMemory, testBadPath)
745{
746 const auto hdr_size = sizeof(pldm_msg_hdr);
747 std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES>
748 requestMsg{};
749 auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
750 size_t requestPayloadLength = requestMsg.size() - hdr_size;
751 struct pldm_read_write_file_by_type_memory_req* request =
752 reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>(
753 req->payload);
754 request->file_type = PLDM_FILE_TYPE_PEL;
755 request->file_handle = 0xFFFFFFFF;
756 request->offset = 0;
757 request->length = 17;
758 request->address = 0;
759
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600760 oem_ibm::Handler handler;
761 auto response = handler.writeFileByTypeFromMemory(req, 0);
Sampa Misra854e61f2019-08-22 04:36:47 -0500762 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
763
764 struct pldm_read_write_file_by_type_memory_resp* resp =
765 reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
766 responsePtr->payload);
767 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
768
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600769 response = handler.writeFileByTypeFromMemory(req, requestPayloadLength);
Sampa Misra854e61f2019-08-22 04:36:47 -0500770 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
771
772 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
773 responsePtr->payload);
774 ASSERT_EQ(PLDM_INVALID_WRITE_LENGTH, resp->completion_code);
775}
776
777TEST(getHandlerByType, allPaths)
778{
779 uint32_t fileHandle{};
780 auto handler = getHandlerByType(PLDM_FILE_TYPE_PEL, fileHandle);
781 auto pelType = dynamic_cast<PelHandler*>(handler.get());
782 ASSERT_TRUE(pelType != nullptr);
783
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600784 handler = getHandlerByType(PLDM_FILE_TYPE_LID_PERM, fileHandle);
785 auto lidType = dynamic_cast<LidHandler*>(handler.get());
786 ASSERT_TRUE(lidType != nullptr);
787 pelType = dynamic_cast<PelHandler*>(handler.get());
788 ASSERT_TRUE(pelType == nullptr);
789 handler = getHandlerByType(PLDM_FILE_TYPE_LID_TEMP, fileHandle);
790 lidType = dynamic_cast<LidHandler*>(handler.get());
791 ASSERT_TRUE(lidType != nullptr);
792
Sampa Misra854e61f2019-08-22 04:36:47 -0500793 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
794 ASSERT_THROW(getHandlerByType(0xFFFF, fileHandle), InternalFailure);
795}
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600796
797TEST(readFileByTypeIntoMemory, testBadPath)
798{
799 const auto hdr_size = sizeof(pldm_msg_hdr);
800 std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES>
801 requestMsg{};
802 auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
803 struct pldm_read_write_file_by_type_memory_req* request =
804 reinterpret_cast<struct pldm_read_write_file_by_type_memory_req*>(
805 req->payload);
806 request->file_type = 0xFFFF;
807 request->file_handle = 0;
808 request->offset = 0;
809 request->length = 17;
810 request->address = 0;
811
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600812 oem_ibm::Handler handler;
813 auto response = handler.readFileByTypeIntoMemory(req, 0);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600814 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
815 struct pldm_read_write_file_by_type_memory_resp* resp =
816 reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
817 responsePtr->payload);
818 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
819
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600820 response = handler.readFileByTypeIntoMemory(
821 req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600822 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
823 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
824 responsePtr->payload);
825 ASSERT_EQ(PLDM_INVALID_WRITE_LENGTH, resp->completion_code);
826
827 request->length = 16;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600828 response = handler.readFileByTypeIntoMemory(
829 req, PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600830 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
831 resp = reinterpret_cast<struct pldm_read_write_file_by_type_memory_resp*>(
832 responsePtr->payload);
833 ASSERT_EQ(PLDM_INVALID_FILE_TYPE, resp->completion_code);
834}
835
836TEST(readFileByType, testBadPath)
837{
838 const auto hdr_size = sizeof(pldm_msg_hdr);
839 std::array<uint8_t, hdr_size + PLDM_RW_FILE_BY_TYPE_REQ_BYTES> requestMsg{};
840 auto payloadLength = requestMsg.size() - hdr_size;
841 auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
842 struct pldm_read_write_file_by_type_req* request =
843 reinterpret_cast<struct pldm_read_write_file_by_type_req*>(
844 req->payload);
845 request->file_type = 0xFFFF;
846 request->file_handle = 0;
847 request->offset = 0;
848 request->length = 13;
849
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600850 oem_ibm::Handler handler;
851 auto response = handler.readFileByType(req, 0);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600852 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
853 struct pldm_read_write_file_by_type_resp* resp =
854 reinterpret_cast<struct pldm_read_write_file_by_type_resp*>(
855 responsePtr->payload);
856 ASSERT_EQ(PLDM_ERROR_INVALID_LENGTH, resp->completion_code);
857
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600858 response = handler.readFileByType(req, payloadLength);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600859 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
860 resp = reinterpret_cast<struct pldm_read_write_file_by_type_resp*>(
861 responsePtr->payload);
862 ASSERT_EQ(PLDM_INVALID_FILE_TYPE, resp->completion_code);
863}
864
865TEST(readFileByType, testReadFile)
866{
867 LidHandler handler(0, true);
868 Response response;
869 uint32_t length{};
870
871 auto rc = handler.readFile({}, 0, length, response);
872 ASSERT_EQ(PLDM_INVALID_FILE_HANDLE, rc);
873
874 char tmplt[] = "/tmp/lid.XXXXXX";
875 auto fd = mkstemp(tmplt);
876 std::vector<uint8_t> in = {100, 10, 56, 78, 34, 56, 79, 235, 111};
877 write(fd, in.data(), in.size());
878 close(fd);
879 length = in.size() + 1000;
880 rc = handler.readFile(tmplt, 0, length, response);
881 ASSERT_EQ(rc, PLDM_SUCCESS);
882 ASSERT_EQ(length, in.size());
883 ASSERT_EQ(response.size(), in.size());
884 ASSERT_EQ(std::equal(in.begin(), in.end(), response.begin()), true);
885}