2014-12-09 18:53:11 +01:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
2014-12-11 01:31:21 +01:00
|
|
|
#include "blockstore/implementations/testfake/FakeBlockStore.h"
|
|
|
|
#include "blockstore/implementations/testfake/FakeBlock.h"
|
2014-12-09 18:53:11 +01:00
|
|
|
#include "blobstore/implementations/onblocks/BlobStoreOnBlocks.h"
|
|
|
|
#include "blobstore/implementations/onblocks/impl/DataNode.h"
|
|
|
|
#include "blobstore/implementations/onblocks/impl/DataLeafNode.h"
|
|
|
|
#include "blobstore/implementations/onblocks/impl/DataInnerNode.h"
|
|
|
|
|
|
|
|
using ::testing::Test;
|
|
|
|
using std::unique_ptr;
|
|
|
|
using std::make_unique;
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
using blockstore::BlockStore;
|
2014-12-11 01:31:21 +01:00
|
|
|
using blockstore::testfake::FakeBlockStore;
|
2014-12-09 18:53:11 +01:00
|
|
|
using namespace blobstore;
|
|
|
|
using namespace blobstore::onblocks;
|
|
|
|
|
|
|
|
class DataNodeTest: public Test {
|
|
|
|
public:
|
2014-12-11 01:31:21 +01:00
|
|
|
unique_ptr<BlockStore> blockStore = make_unique<FakeBlockStore>();
|
2014-12-09 18:53:11 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#define EXPECT_IS_PTR_TYPE(Type, ptr) EXPECT_NE(nullptr, dynamic_cast<Type*>(ptr)) << "Given pointer cannot be cast to the given type"
|
|
|
|
|
2014-12-10 22:55:02 +01:00
|
|
|
TEST_F(DataNodeTest, CreateLeafNodeCreatesLeafNode) {
|
|
|
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
|
|
|
auto node = DataNode::createNewLeafNode(std::move(block.block));
|
|
|
|
EXPECT_IS_PTR_TYPE(DataLeafNode, node.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataNodeTest, CreateInnerNodeCreatesInnerNode) {
|
2014-12-13 12:00:19 +01:00
|
|
|
auto leafblock = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
|
|
|
auto leaf = DataNode::createNewLeafNode(std::move(leafblock.block));
|
|
|
|
|
2014-12-10 22:55:02 +01:00
|
|
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
2014-12-13 12:00:19 +01:00
|
|
|
auto node = DataNode::createNewInnerNode(std::move(block.block), leafblock.key, *leaf);
|
2014-12-10 22:55:02 +01:00
|
|
|
EXPECT_IS_PTR_TYPE(DataInnerNode, node.get());
|
|
|
|
}
|
|
|
|
|
2014-12-09 18:53:11 +01:00
|
|
|
TEST_F(DataNodeTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
|
|
|
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
2014-12-09 20:36:32 +01:00
|
|
|
Key key = block.key;
|
2014-12-10 16:48:00 +01:00
|
|
|
{
|
2014-12-10 22:55:02 +01:00
|
|
|
DataNode::createNewLeafNode(std::move(block.block));
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
2014-12-09 18:53:11 +01:00
|
|
|
|
|
|
|
auto loaded_node = DataNode::load(blockStore->load(key));
|
|
|
|
|
|
|
|
EXPECT_IS_PTR_TYPE(DataLeafNode, loaded_node.get());
|
|
|
|
}
|
|
|
|
|
2014-12-13 12:00:19 +01:00
|
|
|
TEST_F(DataNodeTest, InnerNodeWithDepth1IsRecognizedAfterStoreAndLoad) {
|
|
|
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
|
|
|
Key key = block.key;
|
|
|
|
{
|
|
|
|
auto leafblock = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
|
|
|
auto leaf = DataNode::createNewLeafNode(std::move(leafblock.block));
|
|
|
|
DataNode::createNewInnerNode(std::move(block.block), leafblock.key, *leaf);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto loaded_node = DataNode::load(blockStore->load(key));
|
|
|
|
|
|
|
|
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(DataNodeTest, InnerNodeWithDepth2IsRecognizedAfterStoreAndLoad) {
|
2014-12-09 18:53:11 +01:00
|
|
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
2014-12-09 20:36:32 +01:00
|
|
|
Key key = block.key;
|
2014-12-10 16:48:00 +01:00
|
|
|
{
|
2014-12-13 12:00:19 +01:00
|
|
|
auto leafblock = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
|
|
|
auto leaf = DataNode::createNewLeafNode(std::move(leafblock.block));
|
|
|
|
auto inner1block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
|
|
|
auto inner1 = DataNode::createNewInnerNode(std::move(inner1block.block), leafblock.key, *leaf);
|
|
|
|
DataNode::createNewInnerNode(std::move(block.block), inner1block.key, *inner1);
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
2014-12-09 18:53:11 +01:00
|
|
|
|
|
|
|
auto loaded_node = DataNode::load(blockStore->load(key));
|
|
|
|
|
|
|
|
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
|
|
|
}
|
2014-12-09 18:56:45 +01:00
|
|
|
|
2014-12-13 12:00:19 +01:00
|
|
|
TEST_F(DataNodeTest, DataNodeCrashesOnLoadIfDepthIsTooHigh) {
|
2014-12-09 18:56:45 +01:00
|
|
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
2014-12-09 20:36:32 +01:00
|
|
|
Key key = block.key;
|
2014-12-10 16:48:00 +01:00
|
|
|
{
|
|
|
|
DataNodeView view(std::move(block.block));
|
2014-12-13 12:00:19 +01:00
|
|
|
*view.Depth() = 200u; // this is an invalid depth
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
2014-12-09 18:56:45 +01:00
|
|
|
|
2014-12-10 16:48:00 +01:00
|
|
|
auto loaded_block = blockStore->load(key);
|
2014-12-09 18:56:45 +01:00
|
|
|
EXPECT_ANY_THROW(
|
2014-12-10 16:48:00 +01:00
|
|
|
DataNode::load(std::move(loaded_block))
|
2014-12-09 18:56:45 +01:00
|
|
|
);
|
|
|
|
}
|