Finish MockBlockStore to also collect other performance metrics, and implement the standard block store tests for it.
This commit is contained in:
parent
fdcd3b1314
commit
d626349802
@ -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})
|
||||
|
18
src/blockstore/implementations/mock/MockBlock.cpp
Normal file
18
src/blockstore/implementations/mock/MockBlock.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
50
src/blockstore/implementations/mock/MockBlock.h
Normal file
50
src/blockstore/implementations/mock/MockBlock.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCK_H_
|
||||
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCK_H_
|
||||
|
||||
#include <blockstore/interface/Block.h>
|
||||
#include <cpp-utils/pointer/unique_ref.h>
|
||||
|
||||
namespace blockstore {
|
||||
namespace mock {
|
||||
|
||||
class MockBlockStore;
|
||||
|
||||
class MockBlock final : public blockstore::Block {
|
||||
public:
|
||||
MockBlock(cpputils::unique_ref<blockstore::Block> 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<blockstore::Block> releaseBaseBlock() {
|
||||
return std::move(_baseBlock);
|
||||
}
|
||||
|
||||
private:
|
||||
cpputils::unique_ref<blockstore::Block> _baseBlock;
|
||||
MockBlockStore *_blockStore;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MockBlock);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
1
src/blockstore/implementations/mock/MockBlockStore.cpp
Normal file
1
src/blockstore/implementations/mock/MockBlockStore.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "MockBlockStore.h"
|
143
src/blockstore/implementations/mock/MockBlockStore.h
Normal file
143
src/blockstore/implementations/mock/MockBlockStore.h
Normal file
@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCKSTORE_H_
|
||||
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_MOCK_MOCKBLOCKSTORE_H_
|
||||
|
||||
#include <blockstore/implementations/testfake/FakeBlockStore.h>
|
||||
#include <mutex>
|
||||
#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<BlockStore> baseBlockStore = cpputils::make_unique_ref<testfake::FakeBlockStore>())
|
||||
: _mutex(), _baseBlockStore(std::move(baseBlockStore)), _loadedBlocks(), _createdBlocks(0), _writtenBlocks(), _resizedBlocks(), _removedBlocks() {
|
||||
}
|
||||
|
||||
Key createKey() override {
|
||||
return _baseBlockStore->createKey();
|
||||
}
|
||||
|
||||
boost::optional<cpputils::unique_ref<Block>> 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::unique_ref<Block>>(cpputils::make_unique_ref<MockBlock>(std::move(*base), this));
|
||||
}
|
||||
|
||||
boost::optional<cpputils::unique_ref<Block>> load(const Key &key) override {
|
||||
_increaseNumLoadedBlocks(key);
|
||||
auto base = _baseBlockStore->load(key);
|
||||
if (base == boost::none) {
|
||||
return boost::none;
|
||||
}
|
||||
return boost::optional<cpputils::unique_ref<Block>>(cpputils::make_unique_ref<MockBlock>(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<void(const Key &)> callback) const override {
|
||||
return _baseBlockStore->forEachBlock(callback);
|
||||
}
|
||||
|
||||
void remove(cpputils::unique_ref<Block> block) override {
|
||||
_increaseNumRemovedBlocks(block->key());
|
||||
auto mockBlock = cpputils::dynamic_pointer_move<MockBlock>(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<Key> loadedBlocks() const {
|
||||
return _loadedBlocks;
|
||||
}
|
||||
|
||||
const std::vector<Key> removedBlocks() const {
|
||||
return _removedBlocks;
|
||||
}
|
||||
|
||||
const std::vector<Key> resizedBlocks() const {
|
||||
return _resizedBlocks;
|
||||
}
|
||||
|
||||
const std::vector<Key> writtenBlocks() const {
|
||||
return _writtenBlocks;
|
||||
}
|
||||
|
||||
private:
|
||||
void _increaseNumCreatedBlocks() {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_createdBlocks += 1;
|
||||
}
|
||||
|
||||
void _increaseNumLoadedBlocks(const Key &key) {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_loadedBlocks.push_back(key);
|
||||
}
|
||||
|
||||
void _increaseNumRemovedBlocks(const Key &key) {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_removedBlocks.push_back(key);
|
||||
}
|
||||
|
||||
void _increaseNumResizedBlocks(const Key &key) {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_resizedBlocks.push_back(key);
|
||||
}
|
||||
|
||||
void _increaseNumWrittenBlocks(const Key &key) {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_writtenBlocks.push_back(key);
|
||||
}
|
||||
|
||||
friend class MockBlock;
|
||||
|
||||
std::mutex _mutex;
|
||||
cpputils::unique_ref<BlockStore> _baseBlockStore;
|
||||
|
||||
std::vector<Key> _loadedBlocks;
|
||||
uint64_t _createdBlocks;
|
||||
std::vector<Key> _writtenBlocks;
|
||||
std::vector<Key> _resizedBlocks;
|
||||
std::vector<Key> _removedBlocks;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MockBlockStore);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevelWithLastLeafSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinDataWithLastLeafSize(uint32_t size);
|
||||
|
||||
cpputils::unique_ref<MockBlockStore> _blockStore;
|
||||
MockBlockStore *blockStore;
|
||||
cpputils::unique_ref<blockstore::mock::MockBlockStore> _blockStore;
|
||||
blockstore::mock::MockBlockStore *blockStore;
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataNodeStore> _nodeStore;
|
||||
blobstore::onblocks::datanodestore::DataNodeStore *nodeStore;
|
||||
blobstore::onblocks::datatreestore::DataTreeStore treeStore;
|
||||
|
@ -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 <gmock/gmock.h>
|
||||
#include <blockstore/implementations/testfake/FakeBlockStore.h>
|
||||
#include <mutex>
|
||||
|
||||
class MockBlockStore final : public blockstore::BlockStore {
|
||||
public:
|
||||
MockBlockStore(cpputils::unique_ref<BlockStore> baseBlockStore = cpputils::make_unique_ref<blockstore::testfake::FakeBlockStore>())
|
||||
: loadedBlocks(), createdBlocks(0), _mutex(), _baseBlockStore(std::move(baseBlockStore)) {
|
||||
}
|
||||
|
||||
blockstore::Key createKey() override {
|
||||
return _baseBlockStore->createKey();
|
||||
}
|
||||
|
||||
boost::optional<cpputils::unique_ref<blockstore::Block>> tryCreate(const blockstore::Key &key, cpputils::Data data) override {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
createdBlocks += 1;
|
||||
}
|
||||
return _baseBlockStore->tryCreate(key, std::move(data));
|
||||
}
|
||||
|
||||
boost::optional<cpputils::unique_ref<blockstore::Block>> load(const blockstore::Key &key) override {
|
||||
{
|
||||
std::unique_lock<std::mutex> 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<void(const blockstore::Key &)> callback) const override {
|
||||
return _baseBlockStore->forEachBlock(callback);
|
||||
}
|
||||
|
||||
void remove(cpputils::unique_ref<blockstore::Block> block) override {
|
||||
return _baseBlockStore->remove(std::move(block));
|
||||
}
|
||||
|
||||
void resetCounters() {
|
||||
loadedBlocks = {};
|
||||
createdBlocks = 0;
|
||||
}
|
||||
|
||||
std::vector<blockstore::Key> loadedBlocks;
|
||||
uint64_t createdBlocks;
|
||||
|
||||
private:
|
||||
std::mutex _mutex;
|
||||
cpputils::unique_ref<blockstore::BlockStore> _baseBlockStore;
|
||||
};
|
||||
|
||||
#endif
|
@ -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
|
||||
|
22
test/blockstore/implementations/mock/MockBlockStoreTest.cpp
Normal file
22
test/blockstore/implementations/mock/MockBlockStoreTest.cpp
Normal file
@ -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 <gtest/gtest.h>
|
||||
#include <cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
||||
|
||||
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<BlockStore> createBlockStore() override {
|
||||
return make_unique_ref<MockBlockStore>(make_unique_ref<FakeBlockStore>());
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(Mock, BlockStoreTest, MockBlockStoreTestFixture);
|
Loading…
Reference in New Issue
Block a user