binarystore: Initial implementation
Dummy BinaryStore class implementation where most functions just return.
Implement getBaseBlobId/getBlobIds/canHandleBlobId and add unit tests
using real objects.
Signed-off-by: Kun Yi <kunyi@google.com>
Change-Id: Iaf8c59f3c4b1bab9de186333074a9cd0160a5764
diff --git a/test/Makefile.am b/test/Makefile.am
index 5ce51f2..59325f2 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -17,15 +17,15 @@
handler_unittest_SOURCES = handler_unittest.cpp
handler_unittest_LDADD = $(PHOSPHOR_LOGGING_LIBS) \
- $(top_builddir)/handler.o
+ $(top_builddir)/handler.o $(top_builddir)/binarystore.o
handler_unittest_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS)
handler_open_unittest_SOURCES = handler_open_unittest.cpp
handler_open_unittest_LDADD = $(PHOSPHOR_LOGGING_LIBS) \
- $(top_builddir)/handler.o
+ $(top_builddir)/handler.o $(top_builddir)/binarystore.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
+ $(top_builddir)/handler.o $(top_builddir)/binarystore.o
handler_readwrite_unittest_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS)
diff --git a/test/handler_open_unittest.cpp b/test/handler_open_unittest.cpp
index 83053ad..c3d10aa 100644
--- a/test/handler_open_unittest.cpp
+++ b/test/handler_open_unittest.cpp
@@ -10,44 +10,47 @@
namespace blobs
{
+class BinaryStoreBlobHandlerOpenTest : public BinaryStoreBlobHandlerTest
+{
+ protected:
+ static inline std::string openTestBaseId = "/test/"s;
+ static inline std::string openTestBlobId = "/test/blob0"s;
+ static inline std::string openTestInvalidBlobId = "/invalid/blob0"s;
+ static inline uint16_t openTestROFlags = OpenFlags::read;
+ static inline uint16_t openTestRWFlags = OpenFlags::read | OpenFlags::write;
+ static inline uint16_t openTestSessionId = 0;
+};
+
TEST_F(BinaryStoreBlobHandlerOpenTest, FailWhenCannotHandleId)
{
- uint16_t flags = OpenFlags::read, sessionId = 0;
- EXPECT_FALSE(handler.open(sessionId, flags, "/invalid/blob"s));
+ EXPECT_FALSE(handler.open(openTestSessionId, openTestROFlags,
+ openTestInvalidBlobId));
}
TEST_F(BinaryStoreBlobHandlerOpenTest, FailWhenStoreOpenReturnsFailure)
{
- auto testBaseId = "/test/"s;
- auto testBlobId = "/test/blob0"s;
- uint16_t flags = OpenFlags::read, sessionId = 0;
- auto bstore = std::make_unique<MockBinaryStore>();
+ auto store = defaultMockStore(openTestBaseId);
- EXPECT_CALL(*bstore, getBaseBlobId()).WillRepeatedly(Return(testBaseId));
- EXPECT_CALL(*bstore, canHandleBlob(StartsWith(testBaseId)))
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*bstore, openOrCreateBlob(_, flags)).WillOnce(Return(false));
+ EXPECT_CALL(*store, openOrCreateBlob(_, openTestROFlags))
+ .WillOnce(Return(false));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
- EXPECT_FALSE(handler.open(sessionId, flags, testBlobId));
+ EXPECT_FALSE(
+ handler.open(openTestSessionId, openTestROFlags, openTestBlobId));
}
TEST_F(BinaryStoreBlobHandlerOpenTest, SucceedWhenStoreOpenReturnsTrue)
{
- auto testBaseId = "/test/"s;
- auto testBlobId = "/test/blob0"s;
- uint16_t flags = OpenFlags::read, sessionId = 0;
- auto bstore = std::make_unique<MockBinaryStore>();
+ auto store = defaultMockStore(openTestBaseId);
- 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(*store, openOrCreateBlob(_, openTestROFlags))
+ .WillOnce(Return(true));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
- EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
+ EXPECT_TRUE(
+ handler.open(openTestSessionId, openTestROFlags, openTestBlobId));
}
TEST_F(BinaryStoreBlobHandlerOpenTest, CloseFailForInvalidSession)
@@ -58,60 +61,49 @@
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>();
+ auto store = defaultMockStore(openTestBaseId);
- 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));
+ EXPECT_CALL(*store, openOrCreateBlob(_, openTestROFlags))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*store, close()).WillOnce(Return(false));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
- EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
- EXPECT_FALSE(handler.close(sessionId));
+ EXPECT_TRUE(
+ handler.open(openTestSessionId, openTestROFlags, openTestBlobId));
+ EXPECT_FALSE(handler.close(openTestSessionId));
}
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>();
+ auto store = defaultMockStore(openTestBaseId);
- 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));
+ EXPECT_CALL(*store, openOrCreateBlob(_, openTestROFlags))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*store, close()).WillOnce(Return(true));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
- EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
- EXPECT_TRUE(handler.close(sessionId));
+ EXPECT_TRUE(
+ handler.open(openTestSessionId, openTestROFlags, openTestBlobId));
+ EXPECT_TRUE(handler.close(openTestSessionId));
}
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>();
+ auto store = defaultMockStore(openTestBaseId);
- 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));
+ EXPECT_CALL(*store, openOrCreateBlob(_, openTestROFlags))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*store, close()).WillRepeatedly(Return(true));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
- EXPECT_TRUE(handler.open(sessionId, flags, testBlobId));
- EXPECT_TRUE(handler.close(sessionId));
- EXPECT_FALSE(handler.close(sessionId));
+ EXPECT_TRUE(
+ handler.open(openTestSessionId, openTestROFlags, openTestBlobId));
+ EXPECT_TRUE(handler.close(openTestSessionId));
+ EXPECT_FALSE(handler.close(openTestSessionId));
+ EXPECT_FALSE(handler.close(openTestSessionId));
}
} // namespace blobs
diff --git a/test/handler_readwrite_unittest.cpp b/test/handler_readwrite_unittest.cpp
index b335596..17e3cef 100644
--- a/test/handler_readwrite_unittest.cpp
+++ b/test/handler_readwrite_unittest.cpp
@@ -1,5 +1,10 @@
#include "handler_unittest.hpp"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
using ::testing::_;
using ::testing::Return;
using ::testing::StartsWith;
@@ -23,28 +28,21 @@
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>();
+ auto store = defaultMockStore(rwTestBaseId);
- 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, _))
+ EXPECT_CALL(*store, openOrCreateBlob(_, flags)).WillOnce(Return(true));
+ EXPECT_CALL(*store, 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));
+ EXPECT_CALL(*store, write(rwTestOffset, emptyData)).WillOnce(Return(false));
+ EXPECT_CALL(*store, write(rwTestOffset, rwTestData)).WillOnce(Return(true));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
- EXPECT_TRUE(handler.open(rwTestSessionId, flags, testBlobId));
+ EXPECT_TRUE(handler.open(rwTestSessionId, flags, rwTestBlobId));
EXPECT_EQ(emptyData, handler.read(rwTestSessionId, rwTestOffset, 1));
EXPECT_EQ(rwTestData, handler.read(rwTestSessionId, rwTestOffset, 1));
EXPECT_FALSE(handler.write(rwTestSessionId, rwTestOffset, emptyData));
diff --git a/test/handler_unittest.cpp b/test/handler_unittest.cpp
index d51818e..ef42ea6 100644
--- a/test/handler_unittest.cpp
+++ b/test/handler_unittest.cpp
@@ -1,9 +1,19 @@
#include "handler_unittest.hpp"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::ElementsAreArray;
+using ::testing::IsEmpty;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::StrNe;
+using ::testing::UnorderedElementsAreArray;
+
using namespace std::string_literals;
using namespace binstore;
@@ -15,112 +25,116 @@
protected:
static inline std::string basicTestBaseId = "/test/"s;
static inline std::string basicTestBlobId = "/test/blob0"s;
+
+ static const std::vector<std::string> basicTestBaseIdList;
static inline std::string basicTestInvalidBlobId = "/invalid/blob0"s;
+
+ void addAllBaseIds()
+ {
+ for (size_t i = 0; i < basicTestBaseIdList.size(); ++i)
+ {
+ auto store = defaultMockStore(basicTestBaseIdList[i]);
+
+ EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
+
+ handler.addNewBinaryStore(std::move(store));
+ }
+ }
};
+const std::vector<std::string>
+ BinaryStoreBlobHandlerBasicTest::basicTestBaseIdList = {
+ BinaryStoreBlobHandlerBasicTest::basicTestBaseId, "/another/"s,
+ "/null\0/"s};
+
TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobZeroStoreFail)
{
// Cannot handle since there is no store. Shouldn't crash.
EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
}
-TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobChecksNameInvalid)
+TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobChecksName)
{
- auto bstore = std::make_unique<MockBinaryStore>();
+ auto store = defaultMockStore(basicTestBaseId);
- handler.addNewBinaryStore(std::move(bstore));
+ EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
+
+ handler.addNewBinaryStore(std::move(store));
// Verify canHandleBlob checks and returns false on an invalid name.
EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
-}
-
-TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobCanOpenValidBlob)
-{
- 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));
- 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));
}
-TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobCanOpenValidBlobMultiple)
+TEST_F(BinaryStoreBlobHandlerBasicTest, GetBlobIdEqualsConcatenationsOfBaseIds)
{
- auto bstore = std::make_unique<MockBinaryStore>();
- auto bstore1 = std::make_unique<MockBinaryStore>();
- const std::string anotherBaseId = "/another/"s;
- const std::string anotherBlobId = "/another/blob/id"s;
+ addAllBaseIds();
- 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));
- handler.addNewBinaryStore(std::move(bstore));
-
- EXPECT_CALL(*bstore1, getBaseBlobId())
- .WillRepeatedly(Return(anotherBaseId));
- EXPECT_CALL(*bstore1, canHandleBlob(StrNe(anotherBlobId)))
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*bstore1, canHandleBlob(StrEq(anotherBlobId)))
- .WillRepeatedly(Return(true));
- handler.addNewBinaryStore(std::move(bstore1));
-
- // Verify canHandleBlob return true for a blob id that it can handle
- EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
- EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
- EXPECT_TRUE(handler.canHandleBlob(anotherBlobId));
+ // When there is no other blob id, ids are just base ids (might be
+ // re-ordered).
+ EXPECT_THAT(handler.getBlobIds(),
+ UnorderedElementsAreArray(basicTestBaseIdList));
}
-TEST_F(BinaryStoreBlobHandlerBasicTest, GetBlobIdEqualsConcatenationsOfIds)
+TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobInvalidNames)
{
- std::string baseId0 = "/test/"s;
- std::string baseId1 = "/test1/"s;
- std::vector<std::string> idList0 = {"/test/"s, "/test/0"s};
- std::vector<std::string> idList1 = {"/test1/"s, "/test1/2"s};
- auto expectedIdList = idList0;
- expectedIdList.insert(expectedIdList.end(), idList1.begin(), idList1.end());
+ addAllBaseIds();
- auto bstore0 = std::make_unique<MockBinaryStore>();
- EXPECT_CALL(*bstore0, getBaseBlobId()).WillOnce(Return(baseId0));
- EXPECT_CALL(*bstore0, getBlobIds()).WillOnce(Return(idList0));
- handler.addNewBinaryStore(std::move(bstore0));
+ const std::vector<std::string> invalidNames = {
+ basicTestInvalidBlobId,
+ "/"s,
+ "//"s,
+ "/test"s, // Cannot handle the base path
+ "/test/"s,
+ "/test/this/blob"s, // Cannot handle nested path
+ };
- auto bstore1 = std::make_unique<MockBinaryStore>();
- EXPECT_CALL(*bstore1, getBaseBlobId()).WillOnce(Return(baseId1));
- EXPECT_CALL(*bstore1, getBlobIds()).WillOnce(Return(idList1));
- handler.addNewBinaryStore(std::move(bstore1));
+ // Unary helper for algorithm
+ auto canHandle = [this](const std::string& blobId) {
+ return handler.canHandleBlob(blobId);
+ };
- // Verify canHandleBlob return true for a blob id that it can handle
- EXPECT_EQ(expectedIdList, handler.getBlobIds());
+ EXPECT_TRUE(
+ std::none_of(invalidNames.cbegin(), invalidNames.cend(), canHandle));
+}
+
+TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobValidNames)
+{
+ addAllBaseIds();
+
+ const std::vector<std::string> validNames = {
+ basicTestBlobId, "/test/test"s, "/test/xyz.abc"s,
+ "/another/blob"s, "/null\0/\0\0zer\0\0"s,
+ };
+
+ // Unary helper for algorithm
+ auto canHandle = [this](const std::string& blobId) {
+ return handler.canHandleBlob(blobId);
+ };
+
+ // Verify canHandleBlob can handle a valid blob under the path.
+ EXPECT_TRUE(std::all_of(validNames.cbegin(), validNames.cend(), canHandle));
}
TEST_F(BinaryStoreBlobHandlerBasicTest, DeleteReturnsWhatStoreReturns)
{
- auto bstore = std::make_unique<MockBinaryStore>();
+ auto store = defaultMockStore(basicTestBaseId);
- 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)))
+ EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
+ EXPECT_CALL(*store, deleteBlob(StrEq(basicTestBlobId)))
.WillOnce(Return(false))
.WillOnce(Return(true));
- handler.addNewBinaryStore(std::move(bstore));
+ handler.addNewBinaryStore(std::move(store));
+
+ // Unary helper for algorithm
+ auto canHandle = [this](const std::string& blobId) {
+ return handler.canHandleBlob(blobId);
+ };
// Verify canHandleBlob return true for a blob id that it can handle
- EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
- EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
+ EXPECT_FALSE(canHandle(basicTestInvalidBlobId));
+ EXPECT_TRUE(canHandle(basicTestBlobId));
EXPECT_FALSE(handler.deleteBlob(basicTestInvalidBlobId));
EXPECT_FALSE(handler.deleteBlob(basicTestBlobId));
EXPECT_TRUE(handler.deleteBlob(basicTestBlobId));
diff --git a/test/handler_unittest.hpp b/test/handler_unittest.hpp
index 7f5df42..c35c749 100644
--- a/test/handler_unittest.hpp
+++ b/test/handler_unittest.hpp
@@ -3,8 +3,15 @@
#include "binarystore_mock.hpp"
#include "handler.hpp"
+#include <memory>
+#include <string>
+
#include <gtest/gtest.h>
+using ::testing::Contains;
+
+using namespace std::string_literals;
+
namespace blobs
{
@@ -13,10 +20,17 @@
protected:
BinaryStoreBlobHandlerTest() = default;
BinaryStoreBlobHandler handler;
-};
-class BinaryStoreBlobHandlerOpenTest : public BinaryStoreBlobHandlerTest
-{
+ std::unique_ptr<binstore::MockBinaryStore>
+ defaultMockStore(const std::string& baseId)
+ {
+ return std::make_unique<binstore::MockBinaryStore>(baseId, 0, 0, 0);
+ }
+
+ void addDefaultStore(const std::string& baseId)
+ {
+ handler.addNewBinaryStore(defaultMockStore(baseId));
+ }
};
} // namespace blobs