tools/net: Handle files which don't support sendfile
This adds a fallback read / write model.
Tested: ran against non-sendfile compatible file and it sent to the BMC successfully.
Change-Id: I6fd781ad19cd37376ca90743f799988e50ed460e
Signed-off-by: William A. Kennington III <wak@google.com>
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/tools/test/tools_net_unittest.cpp b/tools/test/tools_net_unittest.cpp
index f741edb..b291e1c 100644
--- a/tools/test/tools_net_unittest.cpp
+++ b/tools/test/tools_net_unittest.cpp
@@ -21,6 +21,7 @@
using ::testing::ContainerEq;
using ::testing::DoAll;
using ::testing::Field;
+using ::testing::Ge;
using ::testing::Gt;
using ::testing::InSequence;
using ::testing::NotNull;
@@ -216,5 +217,55 @@
EXPECT_TRUE(handler.sendContents(filePath, session));
}
+TEST_F(NetHandleTest, successFallback)
+{
+ expectOpenFile();
+ expectAddrInfo();
+ expectConnection();
+
+ struct ipmi_flash::ExtChunkHdr chunk;
+ chunk.length = chunkSize;
+ std::vector<std::uint8_t> chunkBytes(sizeof(chunk));
+ std::memcpy(chunkBytes.data(), &chunk, sizeof(chunk));
+
+ {
+ InSequence seq;
+ EXPECT_CALL(sysMock, sendfile(connFd, inFd, _, _))
+ .WillOnce([](int, int, off_t*, size_t) {
+ errno = EINVAL;
+ return -1;
+ });
+
+ std::vector<uint8_t> chunk(chunkSize);
+ for (std::uint32_t offset = 0; offset < fakeFileSize;
+ offset += chunkSize)
+ {
+ for (size_t i = 0; i < chunkSize; ++i)
+ {
+ chunk[i] = i + offset;
+ }
+ EXPECT_CALL(sysMock, read(inFd, _, Ge(chunkSize)))
+ .WillOnce([chunk](int, void* buf, size_t) {
+ memcpy(buf, chunk.data(), chunkSize);
+ return chunkSize;
+ });
+ EXPECT_CALL(sysMock, send(connFd, _, chunkSize, 0))
+ .WillOnce([chunk](int, const void* data, size_t len, int) {
+ std::vector<uint8_t> dcopy(len);
+ memcpy(dcopy.data(), data, len);
+ EXPECT_THAT(dcopy, ContainerEq(chunk));
+ return chunkSize;
+ });
+ EXPECT_CALL(blobMock,
+ writeBytes(session, offset, ContainerEq(chunkBytes)));
+ EXPECT_CALL(progMock, updateProgress(chunkSize));
+ }
+ EXPECT_CALL(sysMock, read(inFd, _, Ge(chunkSize))).WillOnce(Return(0));
+ EXPECT_CALL(sysMock, send(connFd, _, 0, 0)).WillOnce(Return(0));
+ }
+
+ EXPECT_TRUE(handler.sendContents(filePath, session));
+}
+
} // namespace
} // namespace host_tool