From d62634980200ad03f05cb88b9f6ef57816dda293 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 15 Jul 2016 10:23:09 +0200 Subject: [PATCH] Finish MockBlockStore to also collect other performance metrics, and implement the standard block store tests for it. --- src/blockstore/CMakeLists.txt | 2 + .../implementations/mock/MockBlock.cpp | 18 +++ .../implementations/mock/MockBlock.h | 50 ++++++ .../implementations/mock/MockBlockStore.cpp | 1 + .../implementations/mock/MockBlockStore.h | 143 ++++++++++++++++++ .../DataTreeTest_Performance.cpp | 64 ++++---- .../datatreestore/testutils/DataTreeTest.cpp | 2 +- .../datatreestore/testutils/DataTreeTest.h | 6 +- .../datatreestore/testutils/MockBlockStore.h | 72 --------- test/blockstore/CMakeLists.txt | 1 + .../mock/MockBlockStoreTest.cpp | 22 +++ 11 files changed, 273 insertions(+), 108 deletions(-) create mode 100644 src/blockstore/implementations/mock/MockBlock.cpp create mode 100644 src/blockstore/implementations/mock/MockBlock.h create mode 100644 src/blockstore/implementations/mock/MockBlockStore.cpp create mode 100644 src/blockstore/implementations/mock/MockBlockStore.h delete mode 100644 test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h create mode 100644 test/blockstore/implementations/mock/MockBlockStoreTest.cpp diff --git a/src/blockstore/CMakeLists.txt b/src/blockstore/CMakeLists.txt index a24180b6..9387c341 100644 --- a/src/blockstore/CMakeLists.txt +++ b/src/blockstore/CMakeLists.txt @@ -32,6 +32,8 @@ set(SOURCES implementations/versioncounting/KnownBlockVersions.cpp implementations/versioncounting/ClientIdAndBlockKey.cpp implementations/versioncounting/IntegrityViolationError.cpp + implementations/mock/MockBlockStore.cpp + implementations/mock/MockBlock.cpp ) add_library(${PROJECT_NAME} STATIC ${SOURCES}) diff --git a/src/blockstore/implementations/mock/MockBlock.cpp b/src/blockstore/implementations/mock/MockBlock.cpp new file mode 100644 index 00000000..31655e05 --- /dev/null +++ b/src/blockstore/implementations/mock/MockBlock.cpp @@ -0,0 +1,18 @@ +#include "MockBlock.h" +#include "MockBlockStore.h" + +namespace blockstore { + namespace mock { + + void MockBlock::write(const void *source, uint64_t offset, uint64_t size) { + _blockStore->_increaseNumWrittenBlocks(key()); + return _baseBlock->write(source, offset, size); + } + + void MockBlock::resize(size_t newSize) { + _blockStore->_increaseNumResizedBlocks(key()); + return _baseBlock->resize(newSize); + } + + } +} diff --git a/src/blockstore/implementations/mock/MockBlock.h b/src/blockstore/implementations/mock/MockBlock.h new file mode 100644 index 00000000..adf943ab --- /dev/null +++ b/src/blockstore/implementations/mock/MockBlock.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCK_H_ +#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCK_H_ + +#include +#include + +namespace blockstore { + namespace mock { + + class MockBlockStore; + + class MockBlock final : public blockstore::Block { + public: + MockBlock(cpputils::unique_ref baseBlock, MockBlockStore *blockStore) + :Block(baseBlock->key()), _baseBlock(std::move(baseBlock)), _blockStore(blockStore) { + } + + const void *data() const override { + return _baseBlock->data(); + } + + void write(const void *source, uint64_t offset, uint64_t size) override; + + void flush() override { + return _baseBlock->flush(); + } + + size_t size() const override { + return _baseBlock->size(); + } + + void resize(size_t newSize) override; + + cpputils::unique_ref releaseBaseBlock() { + return std::move(_baseBlock); + } + + private: + cpputils::unique_ref _baseBlock; + MockBlockStore *_blockStore; + + DISALLOW_COPY_AND_ASSIGN(MockBlock); + }; + + + } +} + +#endif diff --git a/src/blockstore/implementations/mock/MockBlockStore.cpp b/src/blockstore/implementations/mock/MockBlockStore.cpp new file mode 100644 index 00000000..448b5b50 --- /dev/null +++ b/src/blockstore/implementations/mock/MockBlockStore.cpp @@ -0,0 +1 @@ +#include "MockBlockStore.h" \ No newline at end of file diff --git a/src/blockstore/implementations/mock/MockBlockStore.h b/src/blockstore/implementations/mock/MockBlockStore.h new file mode 100644 index 00000000..e30ae625 --- /dev/null +++ b/src/blockstore/implementations/mock/MockBlockStore.h @@ -0,0 +1,143 @@ +#pragma once +#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCKSTORE_H_ +#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCKSTORE_H_ + +#include +#include +#include "MockBlock.h" + +namespace blockstore { + namespace mock { + + /** + * This is a blockstore that counts the number of loaded, resized, written, ... blocks. + * It is used for testing that operations only access few blocks (performance tests). + */ + class MockBlockStore final : public BlockStore { + public: + MockBlockStore(cpputils::unique_ref baseBlockStore = cpputils::make_unique_ref()) + : _mutex(), _baseBlockStore(std::move(baseBlockStore)), _loadedBlocks(), _createdBlocks(0), _writtenBlocks(), _resizedBlocks(), _removedBlocks() { + } + + Key createKey() override { + return _baseBlockStore->createKey(); + } + + boost::optional> tryCreate(const Key &key, cpputils::Data data) override { + _increaseNumCreatedBlocks(); + auto base = _baseBlockStore->tryCreate(key, std::move(data)); + if (base == boost::none) { + return boost::none; + } + return boost::optional>(cpputils::make_unique_ref(std::move(*base), this)); + } + + boost::optional> load(const Key &key) override { + _increaseNumLoadedBlocks(key); + auto base = _baseBlockStore->load(key); + if (base == boost::none) { + return boost::none; + } + return boost::optional>(cpputils::make_unique_ref(std::move(*base), this)); + } + + void remove(const Key &key) override { + _increaseNumRemovedBlocks(key); + return _baseBlockStore->remove(key); + } + + uint64_t numBlocks() const override { + return _baseBlockStore->numBlocks(); + } + + uint64_t estimateNumFreeBytes() const override { + return _baseBlockStore->estimateNumFreeBytes(); + } + + uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override { + return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); + } + + void forEachBlock(std::function callback) const override { + return _baseBlockStore->forEachBlock(callback); + } + + void remove(cpputils::unique_ref block) override { + _increaseNumRemovedBlocks(block->key()); + auto mockBlock = cpputils::dynamic_pointer_move(block); + ASSERT(mockBlock != boost::none, "Wrong block type"); + return _baseBlockStore->remove((*mockBlock)->releaseBaseBlock()); + } + + void resetCounters() { + _loadedBlocks = {}; + _createdBlocks = 0; + _removedBlocks = {}; + _resizedBlocks = {}; + _writtenBlocks = {}; + } + + uint64_t createdBlocks() const { + return _createdBlocks; + } + + const std::vector loadedBlocks() const { + return _loadedBlocks; + } + + const std::vector removedBlocks() const { + return _removedBlocks; + } + + const std::vector resizedBlocks() const { + return _resizedBlocks; + } + + const std::vector writtenBlocks() const { + return _writtenBlocks; + } + + private: + void _increaseNumCreatedBlocks() { + std::unique_lock lock(_mutex); + _createdBlocks += 1; + } + + void _increaseNumLoadedBlocks(const Key &key) { + std::unique_lock lock(_mutex); + _loadedBlocks.push_back(key); + } + + void _increaseNumRemovedBlocks(const Key &key) { + std::unique_lock lock(_mutex); + _removedBlocks.push_back(key); + } + + void _increaseNumResizedBlocks(const Key &key) { + std::unique_lock lock(_mutex); + _resizedBlocks.push_back(key); + } + + void _increaseNumWrittenBlocks(const Key &key) { + std::unique_lock lock(_mutex); + _writtenBlocks.push_back(key); + } + + friend class MockBlock; + + std::mutex _mutex; + cpputils::unique_ref _baseBlockStore; + + std::vector _loadedBlocks; + uint64_t _createdBlocks; + std::vector _writtenBlocks; + std::vector _resizedBlocks; + std::vector _removedBlocks; + + DISALLOW_COPY_AND_ASSIGN(MockBlockStore); + }; + + } +} + +#endif diff --git a/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp b/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp index 5cab42a8..022f77ab 100644 --- a/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp +++ b/test/blobstore/implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp @@ -28,8 +28,8 @@ TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByTree) treeStore.remove(std::move(tree)); - EXPECT_EQ(1u, blockStore->loadedBlocks.size()); // First loading is from loading the tree, second one from removing it (i.e. loading the root) - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(1u, blockStore->loadedBlocks().size()); // First loading is from loading the tree, second one from removing it (i.e. loading the root) + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByKey) { @@ -38,8 +38,8 @@ TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByKey) treeStore.remove(key); - EXPECT_EQ(1u, blockStore->loadedBlocks.size()); - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(1u, blockStore->loadedBlocks().size()); + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByTree) { @@ -49,8 +49,8 @@ TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByTre treeStore.remove(std::move(tree)); - EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByKey) { @@ -59,8 +59,8 @@ TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByKey treeStore.remove(key); - EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_Twolevel_All) { @@ -70,8 +70,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_Twolevel_All) { Traverse(tree.get(), 0, maxChildrenPerInnerNode); - EXPECT_EQ(maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); // Loads all leaves (not the root, because it is already loaded in the tree) - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); // Loads all leaves (not the root, because it is already loaded in the tree) + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_Twolevel_Some) { @@ -81,8 +81,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_Twolevel_Some) { Traverse(tree.get(), 3, 5); - EXPECT_EQ(2u, blockStore->loadedBlocks.size()); // Loads both leaves (not the root, because it is already loaded in the tree) - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(2u, blockStore->loadedBlocks().size()); // Loads both leaves (not the root, because it is already loaded in the tree) + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_All) { @@ -92,8 +92,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_All) { Traverse(tree.get(), 0, maxChildrenPerInnerNode * maxChildrenPerInnerNode); - EXPECT_EQ(maxChildrenPerInnerNode + maxChildrenPerInnerNode * maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); // Loads inner nodes and all leaves once (not the root, because it is already loaded in the tree) - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(maxChildrenPerInnerNode + maxChildrenPerInnerNode * maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); // Loads inner nodes and all leaves once (not the root, because it is already loaded in the tree) + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_InOneInner) { @@ -103,8 +103,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_InOneInner) { Traverse(tree.get(), 3, 5); - EXPECT_EQ(3u, blockStore->loadedBlocks.size()); // Loads inner node and both leaves (not the root, because it is already loaded in the tree) - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(3u, blockStore->loadedBlocks().size()); // Loads inner node and both leaves (not the root, because it is already loaded in the tree) + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_InTwoInner) { @@ -114,8 +114,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_InTwoInner) { Traverse(tree.get(), 3, 3 + maxChildrenPerInnerNode); - EXPECT_EQ(2u + maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); // Loads inner node and both leaves (not the root, because it is already loaded in the tree) - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(2u + maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); // Loads inner node and both leaves (not the root, because it is already loaded in the tree) + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_WholeInner) { @@ -125,8 +125,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_Threelevel_WholeInner) { Traverse(tree.get(), maxChildrenPerInnerNode, 2*maxChildrenPerInnerNode); - EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); // Loads inner node and leaves (not the root, because it is already loaded in the tree)f - EXPECT_EQ(0u, blockStore->createdBlocks); + EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); // Loads inner node and leaves (not the root, because it is already loaded in the tree)f + EXPECT_EQ(0u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingInside) { @@ -136,8 +136,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingInside) { Traverse(tree.get(), 1, 4); - EXPECT_EQ(1u, blockStore->loadedBlocks.size()); // Loads last old child (for growing it) - EXPECT_EQ(2u, blockStore->createdBlocks); + EXPECT_EQ(1u, blockStore->loadedBlocks().size()); // Loads last old child (for growing it) + EXPECT_EQ(2u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingOutside_TwoLevel) { @@ -147,8 +147,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingOutside_TwoL Traverse(tree.get(), 4, 5); - EXPECT_EQ(1u, blockStore->loadedBlocks.size()); // Loads last old leaf for growing it - EXPECT_EQ(3u, blockStore->createdBlocks); + EXPECT_EQ(1u, blockStore->loadedBlocks().size()); // Loads last old leaf for growing it + EXPECT_EQ(3u, blockStore->createdBlocks()); } TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingOutside_ThreeLevel) { @@ -158,8 +158,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingOutside_Thre Traverse(tree.get(), 2*maxChildrenPerInnerNode+1, 2*maxChildrenPerInnerNode+2); - EXPECT_EQ(2u, blockStore->loadedBlocks.size()); // Loads last old leaf (and its inner node) for growing it - EXPECT_EQ(3u, blockStore->createdBlocks); // inner node and two leaves + EXPECT_EQ(2u, blockStore->loadedBlocks().size()); // Loads last old leaf (and its inner node) for growing it + EXPECT_EQ(3u, blockStore->createdBlocks()); // inner node and two leaves } TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingAtBeginOfChild) { @@ -169,8 +169,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTree_StartingAtBeginOfChi Traverse(tree.get(), maxChildrenPerInnerNode, 3*maxChildrenPerInnerNode); - EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks.size()); // Inner node and its leaves - EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->createdBlocks); // Creates an inner node and its leaves + EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->loadedBlocks().size()); // Inner node and its leaves + EXPECT_EQ(1u + maxChildrenPerInnerNode, blockStore->createdBlocks()); // Creates an inner node and its leaves } TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTreeDepth_StartingInOldDepth) { @@ -180,8 +180,8 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTreeDepth_StartingInOldDe Traverse(tree.get(), 4, maxChildrenPerInnerNode+2); - EXPECT_EQ(1u, blockStore->loadedBlocks.size()); // Loads last old leaf for growing it - EXPECT_EQ(2 + maxChildrenPerInnerNode, blockStore->createdBlocks); // 2x new inner node + leaves + EXPECT_EQ(1u, blockStore->loadedBlocks().size()); // Loads last old leaf for growing it + EXPECT_EQ(2 + maxChildrenPerInnerNode, blockStore->createdBlocks()); // 2x new inner node + leaves } TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTreeDepth_StartingInNewDepth) { @@ -191,6 +191,6 @@ TEST_F(DataTreeTest_Performance, TraverseLeaves_GrowingTreeDepth_StartingInNewDe Traverse(tree.get(), maxChildrenPerInnerNode, maxChildrenPerInnerNode+2); - EXPECT_EQ(1u, blockStore->loadedBlocks.size()); // Loads last old leaf for growing it - EXPECT_EQ(2 + maxChildrenPerInnerNode, blockStore->createdBlocks); // 2x new inner node + leaves + EXPECT_EQ(1u, blockStore->loadedBlocks().size()); // Loads last old leaf for growing it + EXPECT_EQ(2 + maxChildrenPerInnerNode, blockStore->createdBlocks()); // 2x new inner node + leaves } diff --git a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp index 6b0123fd..c12bb071 100644 --- a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp +++ b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp @@ -9,7 +9,7 @@ using blobstore::onblocks::datanodestore::DataNode; using blobstore::onblocks::datanodestore::DataInnerNode; using blobstore::onblocks::datanodestore::DataLeafNode; using blobstore::onblocks::datatreestore::DataTree; -using blockstore::testfake::FakeBlockStore; +using blockstore::mock::MockBlockStore; using blockstore::Key; using cpputils::unique_ref; using cpputils::make_unique_ref; diff --git a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h index 4533102c..17133cbb 100644 --- a/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h +++ b/test/blobstore/implementations/onblocks/datatreestore/testutils/DataTreeTest.h @@ -10,7 +10,7 @@ #include "blobstore/implementations/onblocks/datanodestore/DataLeafNode.h" #include "blobstore/implementations/onblocks/datatreestore/DataTree.h" #include "blobstore/implementations/onblocks/datatreestore/DataTreeStore.h" -#include "MockBlockStore.h" +#include "blockstore/implementations/mock/MockBlockStore.h" class DataTreeTest: public ::testing::Test { public: @@ -46,8 +46,8 @@ public: cpputils::unique_ref CreateFullThreeLevelWithLastLeafSize(uint32_t size); cpputils::unique_ref CreateFourLevelMinDataWithLastLeafSize(uint32_t size); - cpputils::unique_ref _blockStore; - MockBlockStore *blockStore; + cpputils::unique_ref _blockStore; + blockstore::mock::MockBlockStore *blockStore; cpputils::unique_ref _nodeStore; blobstore::onblocks::datanodestore::DataNodeStore *nodeStore; blobstore::onblocks::datatreestore::DataTreeStore treeStore; diff --git a/test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h b/test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h deleted file mode 100644 index c89bf9a4..00000000 --- a/test/blobstore/implementations/onblocks/datatreestore/testutils/MockBlockStore.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#ifndef MESSMER_BLOBSTORE_TEST_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_GROWING_TESTUTILS_MOCKBLOCKSTORE_H_ -#define MESSMER_BLOBSTORE_TEST_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_GROWING_TESTUTILS_MOCKBLOCKSTORE_H_ - -#include -#include -#include - -class MockBlockStore final : public blockstore::BlockStore { -public: - MockBlockStore(cpputils::unique_ref baseBlockStore = cpputils::make_unique_ref()) - : loadedBlocks(), createdBlocks(0), _mutex(), _baseBlockStore(std::move(baseBlockStore)) { - } - - blockstore::Key createKey() override { - return _baseBlockStore->createKey(); - } - - boost::optional> tryCreate(const blockstore::Key &key, cpputils::Data data) override { - { - std::unique_lock lock(_mutex); - createdBlocks += 1; - } - return _baseBlockStore->tryCreate(key, std::move(data)); - } - - boost::optional> load(const blockstore::Key &key) override { - { - std::unique_lock lock(_mutex); - loadedBlocks.push_back(key); - } - return _baseBlockStore->load(key); - } - - void remove(const blockstore::Key &key) override { - return _baseBlockStore->remove(key); - } - - uint64_t numBlocks() const override { - return _baseBlockStore->numBlocks(); - } - - uint64_t estimateNumFreeBytes() const override { - return _baseBlockStore->estimateNumFreeBytes(); - } - - uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override { - return _baseBlockStore->blockSizeFromPhysicalBlockSize(blockSize); - } - - void forEachBlock(std::function callback) const override { - return _baseBlockStore->forEachBlock(callback); - } - - void remove(cpputils::unique_ref block) override { - return _baseBlockStore->remove(std::move(block)); - } - - void resetCounters() { - loadedBlocks = {}; - createdBlocks = 0; - } - - std::vector loadedBlocks; - uint64_t createdBlocks; - -private: - std::mutex _mutex; - cpputils::unique_ref _baseBlockStore; -}; - -#endif diff --git a/test/blockstore/CMakeLists.txt b/test/blockstore/CMakeLists.txt index afc6e8b2..19a670da 100644 --- a/test/blockstore/CMakeLists.txt +++ b/test/blockstore/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES interface/BlockStoreTest.cpp interface/BlockTest.cpp implementations/testfake/TestFakeBlockStoreTest.cpp + implementations/mock/MockBlockStoreTest.cpp implementations/inmemory/InMemoryBlockStoreTest.cpp implementations/parallelaccess/ParallelAccessBlockStoreTest_Generic.cpp implementations/parallelaccess/ParallelAccessBlockStoreTest_Specific.cpp diff --git a/test/blockstore/implementations/mock/MockBlockStoreTest.cpp b/test/blockstore/implementations/mock/MockBlockStoreTest.cpp new file mode 100644 index 00000000..bb2372e8 --- /dev/null +++ b/test/blockstore/implementations/mock/MockBlockStoreTest.cpp @@ -0,0 +1,22 @@ +#include "blockstore/implementations/mock/MockBlock.h" +#include "blockstore/implementations/mock/MockBlockStore.h" +#include "../../testutils/BlockStoreTest.h" +#include "../../testutils/BlockStoreWithRandomKeysTest.h" +#include +#include + +using blockstore::BlockStore; +using blockstore::BlockStoreWithRandomKeys; +using blockstore::mock::MockBlockStore; +using blockstore::testfake::FakeBlockStore; +using cpputils::unique_ref; +using cpputils::make_unique_ref; + +class MockBlockStoreTestFixture: public BlockStoreTestFixture { +public: + unique_ref createBlockStore() override { + return make_unique_ref(make_unique_ref()); + } +}; + +INSTANTIATE_TYPED_TEST_CASE_P(Mock, BlockStoreTest, MockBlockStoreTestFixture);