handler: Implement read/write/close/delete
Implement read/write/close/delete as pass-through functions.
Signed-off-by: Kun Yi <kunyi@google.com>
Change-Id: I56b935b03b8048a70a168d00061c043795b90f5e
diff --git a/binarystore.hpp b/binarystore.hpp
index 0fc316b..11ca241 100644
--- a/binarystore.hpp
+++ b/binarystore.hpp
@@ -27,6 +27,7 @@
virtual bool canHandleBlob(const std::string& blobId) const = 0;
virtual bool openOrCreateBlob(const std::string& blobId,
uint16_t flags) = 0;
+ virtual bool deleteBlob(const std::string& blobId) = 0;
virtual std::vector<uint8_t> read(uint32_t offset,
uint32_t requestedSize) = 0;
virtual bool write(uint32_t offset, const std::vector<uint8_t>& data) = 0;
diff --git a/binarystore_mock.hpp b/binarystore_mock.hpp
index ada526d..7792e74 100644
--- a/binarystore_mock.hpp
+++ b/binarystore_mock.hpp
@@ -14,6 +14,7 @@
MOCK_CONST_METHOD1(canHandleBlob, bool(const std::string&));
MOCK_CONST_METHOD0(getBlobIds, std::vector<std::string>());
MOCK_METHOD2(openOrCreateBlob, bool(const std::string&, uint16_t));
+ MOCK_METHOD1(deleteBlob, bool(const std::string&));
MOCK_METHOD2(read, std::vector<uint8_t>(uint32_t, uint32_t));
MOCK_METHOD2(write, bool(uint32_t, const std::vector<uint8_t>&));
MOCK_METHOD0(commit, bool());
diff --git a/handler.cpp b/handler.cpp
index 7bbac6b..ae21ab1 100644
--- a/handler.cpp
+++ b/handler.cpp
@@ -46,8 +46,13 @@
bool BinaryStoreBlobHandler::deleteBlob(const std::string& path)
{
- // TODO: implement
- return false;
+ auto it = stores_.find(internal::getBaseFromId(path));
+ if (it == stores_.end())
+ {
+ return false;
+ }
+
+ return it->second->deleteBlob(path);
}
bool BinaryStoreBlobHandler::stat(const std::string& path,
@@ -92,16 +97,25 @@
uint32_t offset,
uint32_t requestedSize)
{
- // TODO: implement
- std::vector<uint8_t> result;
- return result;
+ auto it = sessions_.find(session);
+ if (it == sessions_.end())
+ {
+ return std::vector<uint8_t>();
+ }
+
+ return it->second->read(offset, requestedSize);
}
bool BinaryStoreBlobHandler::write(uint16_t session, uint32_t offset,
const std::vector<uint8_t>& data)
{
- // TODO: implement
- return false;
+ auto it = sessions_.find(session);
+ if (it == sessions_.end())
+ {
+ return false;
+ }
+
+ return it->second->write(offset, data);
}
bool BinaryStoreBlobHandler::writeMeta(uint16_t session, uint32_t offset,
@@ -120,8 +134,19 @@
bool BinaryStoreBlobHandler::close(uint16_t session)
{
- // TODO: implement
- return false;
+ auto it = sessions_.find(session);
+ if (it == sessions_.end())
+ {
+ return false;
+ }
+
+ if (!it->second->close())
+ {
+ return false;
+ }
+
+ sessions_.erase(session);
+ return true;
}
bool BinaryStoreBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
diff --git a/test/Makefile.am b/test/Makefile.am
index 5b3fe6c..5ce51f2 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -11,6 +11,7 @@
# Run all 'check' test programs
check_PROGRAMS = \
handler_open_unittest \
+ handler_readwrite_unittest \
handler_unittest
TESTS = $(check_PROGRAMS)
@@ -23,3 +24,8 @@
handler_open_unittest_LDADD = $(PHOSPHOR_LOGGING_LIBS) \
$(top_builddir)/handler.o
handler_open_unittest_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS)
+
+handler_readwrite_unittest_SOURCES = handler_readwrite_unittest.cpp
+handler_readwrite_unittest_LDADD = $(PHOSPHOR_LOGGING_LIBS) \
+ $(top_builddir)/handler.o
+handler_readwrite_unittest_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS)
diff --git a/test/handler_open_unittest.cpp b/test/handler_open_unittest.cpp
index 1d69f24..83053ad 100644
--- a/test/handler_open_unittest.cpp
+++ b/test/handler_open_unittest.cpp
@@ -50,4 +50,68 @@
EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
}
+TEST_F(BinaryStoreBlobHandlerOpenTest, CloseFailForInvalidSession)
+{
+ uint16_t invalidSessionId = 1;
+ EXPECT_FALSE(handler.close(invalidSessionId));
+}
+
+TEST_F(BinaryStoreBlobHandlerOpenTest, CloseFailWhenStoreCloseFails)
+{
+ auto testBaseId = "/test/"s;
+ auto testBlobId = "/test/blob0"s;
+ uint16_t flags = OpenFlags::read, sessionId = 0;
+ auto bstore = std::make_unique<MockBinaryStore>();
+
+ EXPECT_CALL(*bstore, getBaseBlobId()).WillRepeatedly(Return(testBaseId));
+ EXPECT_CALL(*bstore, canHandleBlob(StartsWith(testBaseId)))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*bstore, openOrCreateBlob(_, flags)).WillOnce(Return(true));
+ EXPECT_CALL(*bstore, close()).WillOnce(Return(false));
+
+ handler.addNewBinaryStore(std::move(bstore));
+
+ EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
+ EXPECT_FALSE(handler.close(sessionId));
+}
+
+TEST_F(BinaryStoreBlobHandlerOpenTest, CloseSucceedWhenStoreCloseSucceeds)
+{
+ auto testBaseId = "/test/"s;
+ auto testBlobId = "/test/blob0"s;
+ uint16_t flags = OpenFlags::read, sessionId = 0;
+ auto bstore = std::make_unique<MockBinaryStore>();
+
+ EXPECT_CALL(*bstore, getBaseBlobId()).WillRepeatedly(Return(testBaseId));
+ EXPECT_CALL(*bstore, canHandleBlob(StartsWith(testBaseId)))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*bstore, openOrCreateBlob(_, flags)).WillOnce(Return(true));
+ EXPECT_CALL(*bstore, close()).WillOnce(Return(true));
+
+ handler.addNewBinaryStore(std::move(bstore));
+
+ EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
+ EXPECT_TRUE(handler.close(sessionId));
+}
+
+TEST_F(BinaryStoreBlobHandlerOpenTest, ClosedSessionCannotBeReclosed)
+{
+ auto testBaseId = "/test/"s;
+ auto testBlobId = "/test/blob0"s;
+ uint16_t flags = OpenFlags::read, sessionId = 0;
+ auto bstore = std::make_unique<MockBinaryStore>();
+
+ EXPECT_CALL(*bstore, getBaseBlobId()).WillRepeatedly(Return(testBaseId));
+ EXPECT_CALL(*bstore, canHandleBlob(StartsWith(testBaseId)))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*bstore, openOrCreateBlob(_, flags)).WillOnce(Return(true));
+ EXPECT_CALL(*bstore, close()).WillRepeatedly(Return(true));
+
+ handler.addNewBinaryStore(std::move(bstore));
+
+ EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
+ EXPECT_TRUE(handler.close(sessionId));
+ EXPECT_FALSE(handler.close(sessionId));
+}
+
} // namespace blobs
diff --git a/test/handler_readwrite_unittest.cpp b/test/handler_readwrite_unittest.cpp
new file mode 100644
index 0000000..b335596
--- /dev/null
+++ b/test/handler_readwrite_unittest.cpp
@@ -0,0 +1,54 @@
+#include "handler_unittest.hpp"
+
+using ::testing::_;
+using ::testing::Return;
+using ::testing::StartsWith;
+
+using namespace std::string_literals;
+using namespace binstore;
+
+namespace blobs
+{
+
+class BinaryStoreBlobHandlerReadWriteTest : public BinaryStoreBlobHandlerTest
+{
+ protected:
+ static inline std::string rwTestBaseId = "/test/"s;
+ static inline std::string rwTestBlobId = "/test/blob0"s;
+ static inline std::vector<uint8_t> rwTestData = {0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9};
+ static inline uint16_t rwTestSessionId = 0;
+ static inline uint32_t rwTestOffset = 0;
+};
+
+TEST_F(BinaryStoreBlobHandlerReadWriteTest, ReadWriteReturnsWhatStoreReturns)
+{
+ auto testBaseId = "/test/"s;
+ auto testBlobId = "/test/blob0"s;
+ uint16_t flags = OpenFlags::read;
+ const std::vector<uint8_t> emptyData;
+ auto bstore = std::make_unique<MockBinaryStore>();
+
+ EXPECT_CALL(*bstore, getBaseBlobId()).WillRepeatedly(Return(testBaseId));
+ EXPECT_CALL(*bstore, canHandleBlob(StartsWith(testBaseId)))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*bstore, openOrCreateBlob(_, flags)).WillOnce(Return(true));
+ EXPECT_CALL(*bstore, read(rwTestOffset, _))
+ .WillOnce(Return(emptyData))
+ .WillOnce(Return(rwTestData));
+
+ EXPECT_CALL(*bstore, write(rwTestOffset, emptyData))
+ .WillOnce(Return(false));
+ EXPECT_CALL(*bstore, write(rwTestOffset, rwTestData))
+ .WillOnce(Return(true));
+
+ handler.addNewBinaryStore(std::move(bstore));
+
+ EXPECT_TRUE(handler.open(rwTestSessionId, flags, testBlobId));
+ EXPECT_EQ(emptyData, handler.read(rwTestSessionId, rwTestOffset, 1));
+ EXPECT_EQ(rwTestData, handler.read(rwTestSessionId, rwTestOffset, 1));
+ EXPECT_FALSE(handler.write(rwTestSessionId, rwTestOffset, emptyData));
+ EXPECT_TRUE(handler.write(rwTestSessionId, rwTestOffset, rwTestData));
+}
+
+} // namespace blobs
diff --git a/test/handler_unittest.cpp b/test/handler_unittest.cpp
index d96fc41..d51818e 100644
--- a/test/handler_unittest.cpp
+++ b/test/handler_unittest.cpp
@@ -103,4 +103,27 @@
EXPECT_EQ(expectedIdList, handler.getBlobIds());
}
+TEST_F(BinaryStoreBlobHandlerBasicTest, DeleteReturnsWhatStoreReturns)
+{
+ auto bstore = std::make_unique<MockBinaryStore>();
+
+ EXPECT_CALL(*bstore, getBaseBlobId())
+ .WillRepeatedly(Return(basicTestBaseId));
+ EXPECT_CALL(*bstore, canHandleBlob(StrNe(basicTestBlobId)))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*bstore, canHandleBlob(StrEq(basicTestBlobId)))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*bstore, deleteBlob(StrEq(basicTestBlobId)))
+ .WillOnce(Return(false))
+ .WillOnce(Return(true));
+ handler.addNewBinaryStore(std::move(bstore));
+
+ // Verify canHandleBlob return true for a blob id that it can handle
+ EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
+ EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
+ EXPECT_FALSE(handler.deleteBlob(basicTestInvalidBlobId));
+ EXPECT_FALSE(handler.deleteBlob(basicTestBlobId));
+ EXPECT_TRUE(handler.deleteBlob(basicTestBlobId));
+}
+
} // namespace blobs