Add test case ensuring that leaves aren't loaded on delete

This commit is contained in:
Sebastian Messmer 2016-07-14 23:38:17 +02:00
parent f42e08a5f6
commit 4e689f2411
5 changed files with 114 additions and 1 deletions

View File

@ -14,6 +14,7 @@ set(SOURCES
implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp
implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp
implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp
implementations/onblocks/datatreestore/DataTreeTest_Performance.cpp
implementations/onblocks/datatreestore/DataTreeTest_ResizeByTraversing.cpp
implementations/onblocks/datatreestore/DataTreeTest_NumStoredBytes.cpp
implementations/onblocks/datatreestore/DataTreeTest_ResizeNumBytes.cpp

View File

@ -0,0 +1,44 @@
#include "testutils/DataTreeTest.h"
#include <gmock/gmock.h>
using blobstore::onblocks::datanodestore::DataNodeStore;
using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datanodestore::DataInnerNode;
using blobstore::onblocks::datanodestore::DataNode;
using blobstore::onblocks::datatreestore::DataTree;
using blockstore::Key;
using blockstore::testfake::FakeBlockStore;
using cpputils::Data;
using cpputils::make_unique_ref;
class DataTreeTest_Performance: public DataTreeTest {
public:
};
TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByTree) {
auto key = this->CreateFullTwoLevel()->key();
auto tree = this->treeStore.load(key).value();
this->treeStore.remove(std::move(tree));
EXPECT_EQ(2u, blockStore->loadedBlocks.size());
}
TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Twolevel_DeleteByKey) {
auto key = this->CreateFullTwoLevel()->key();
this->treeStore.remove(key);
EXPECT_EQ(1u, blockStore->loadedBlocks.size());
}
TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByTree) {
auto key = this->CreateFullThreeLevel()->key();
auto tree = this->treeStore.load(key).value();
this->treeStore.remove(std::move(tree));
EXPECT_EQ(2u + nodeStore->layout().maxChildrenPerInnerNode(), blockStore->loadedBlocks.size());
}
TEST_F(DataTreeTest_Performance, DeletingDoesntLoadLeaves_Threelevel_DeleteByKey) {
auto key = this->CreateFullThreeLevel()->key();
this->treeStore.remove(key);
EXPECT_EQ(1u + nodeStore->layout().maxChildrenPerInnerNode(), blockStore->loadedBlocks.size());
}

View File

@ -21,7 +21,9 @@ using cpputils::dynamic_pointer_move;
constexpr uint32_t DataTreeTest::BLOCKSIZE_BYTES;
DataTreeTest::DataTreeTest()
:_nodeStore(make_unique_ref<DataNodeStore>(make_unique_ref<FakeBlockStore>(), BLOCKSIZE_BYTES)),
:_blockStore(make_unique_ref<MockBlockStore>()),
blockStore(_blockStore.get()),
_nodeStore(make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
nodeStore(_nodeStore.get()),
treeStore(std::move(_nodeStore)) {
}

View File

@ -3,12 +3,14 @@
#define MESSMER_BLOBSTORE_TEST_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_DATATREETEST_H_
#include <gtest/gtest.h>
#include <blockstore/implementations/testfake/FakeBlockStore.h>
#include "blobstore/implementations/onblocks/datanodestore/DataNodeStore.h"
#include "blobstore/implementations/onblocks/datanodestore/DataInnerNode.h"
#include "blobstore/implementations/onblocks/datanodestore/DataLeafNode.h"
#include "blobstore/implementations/onblocks/datatreestore/DataTree.h"
#include "blobstore/implementations/onblocks/datatreestore/DataTreeStore.h"
#include "MockBlockStore.h"
class DataTreeTest: public ::testing::Test {
public:
@ -44,6 +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<blobstore::onblocks::datanodestore::DataNodeStore> _nodeStore;
blobstore::onblocks::datanodestore::DataNodeStore *nodeStore;
blobstore::onblocks::datatreestore::DataTreeStore treeStore;

View File

@ -0,0 +1,62 @@
#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>())
: _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 {
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));
}
std::vector<blockstore::Key> loadedBlocks;
private:
std::mutex _mutex;
cpputils::unique_ref<blockstore::BlockStore> _baseBlockStore;
};
#endif