libcryfs/test/implementations/onblocks/datanodestore/DataNodeViewTest.cpp

150 lines
5.3 KiB
C++
Raw Normal View History

2015-02-17 00:40:34 +01:00
#include "../../../../implementations/onblocks/datanodestore/DataNodeView.h"
#include <google/gtest/gtest.h>
2014-12-10 17:26:49 +01:00
2015-02-17 00:40:34 +01:00
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
#include "messmer/blockstore/implementations/testfake/FakeBlock.h"
#include "../../../../implementations/onblocks/BlobStoreOnBlocks.h"
#include "../../../testutils/DataBlockFixture.h"
2014-12-10 17:26:49 +01:00
using ::testing::Test;
using ::testing::WithParamInterface;
using ::testing::Values;
using std::unique_ptr;
using std::make_unique;
using std::string;
using blockstore::BlockStore;
using blockstore::testfake::FakeBlockStore;
2015-04-25 00:08:29 +02:00
using blockstore::Data;
2014-12-10 17:26:49 +01:00
using namespace blobstore;
using namespace blobstore::onblocks;
using namespace blobstore::onblocks::datanodestore;
2014-12-10 17:26:49 +01:00
class DataNodeViewTest: public Test {
public:
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
static constexpr uint32_t DATASIZE_BYTES = DataNodeLayout(DataNodeViewTest::BLOCKSIZE_BYTES).datasizeBytes();
unique_ptr<BlockStore> blockStore = make_unique<FakeBlockStore>();
2014-12-10 17:26:49 +01:00
};
class DataNodeViewDepthTest: public DataNodeViewTest, public WithParamInterface<uint8_t> {
};
INSTANTIATE_TEST_CASE_P(DataNodeViewDepthTest, DataNodeViewDepthTest, Values(0, 1, 3, 10, 100));
TEST_P(DataNodeViewDepthTest, DepthIsStored) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
auto key = block->key();
2014-12-10 17:26:49 +01:00
{
DataNodeView view(std::move(block));
view.setDepth(GetParam());
2014-12-10 17:26:49 +01:00
}
DataNodeView view(blockStore->load(key));
EXPECT_EQ(GetParam(), view.Depth());
2014-12-10 17:26:49 +01:00
}
class DataNodeViewSizeTest: public DataNodeViewTest, public WithParamInterface<uint32_t> {
};
INSTANTIATE_TEST_CASE_P(DataNodeViewSizeTest, DataNodeViewSizeTest, Values(0, 50, 64, 1024, 1024*1024*1024));
TEST_P(DataNodeViewSizeTest, SizeIsStored) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
auto key = block->key();
2014-12-10 17:26:49 +01:00
{
DataNodeView view(std::move(block));
view.setSize(GetParam());
2014-12-10 17:26:49 +01:00
}
DataNodeView view(blockStore->load(key));
EXPECT_EQ(GetParam(), view.Size());
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, DataIsStored) {
DataBlockFixture randomData(DATASIZE_BYTES);
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
auto key = block->key();
2014-12-10 17:26:49 +01:00
{
DataNodeView view(std::move(block));
view.write(randomData.data(), 0, randomData.size());
2014-12-10 17:26:49 +01:00
}
DataNodeView view(blockStore->load(key));
EXPECT_EQ(0, std::memcmp(view.data(), randomData.data(), randomData.size()));
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, HeaderAndBodyDontOverlap) {
DataBlockFixture randomData(DATASIZE_BYTES);
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
auto key = block->key();
2014-12-10 17:26:49 +01:00
{
DataNodeView view(std::move(block));
view.setDepth(3);
view.setSize(1000000000u);
view.write(randomData.data(), 0, DATASIZE_BYTES);
2014-12-10 17:26:49 +01:00
}
DataNodeView view(blockStore->load(key));
EXPECT_EQ(3, view.Depth());
EXPECT_EQ(1000000000u, view.Size());
EXPECT_EQ(0, std::memcmp(view.data(), randomData.data(), DATASIZE_BYTES));
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, DataBeginWorksWithOneByteEntries) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
uint8_t *blockBegin = (uint8_t*)block->data();
DataNodeView view(std::move(block));
2014-12-10 17:26:49 +01:00
EXPECT_EQ(blockBegin+DataNodeLayout::HEADERSIZE_BYTES, view.DataBegin<uint8_t>());
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, DataBeginWorksWithEightByteEntries) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
uint8_t *blockBegin = (uint8_t*)block->data();
DataNodeView view(std::move(block));
2014-12-10 17:26:49 +01:00
EXPECT_EQ(blockBegin+DataNodeLayout::HEADERSIZE_BYTES, (uint8_t*)view.DataBegin<uint64_t>());
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, DataEndWorksWithOneByteEntries) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
uint8_t *blockBegin = (uint8_t*)block->data();
DataNodeView view(std::move(block));
2014-12-10 17:26:49 +01:00
EXPECT_EQ(blockBegin+BLOCKSIZE_BYTES, view.DataEnd<uint8_t>());
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, DataEndWorksWithEightByteEntries) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
uint8_t *blockBegin = (uint8_t*)block->data();
DataNodeView view(std::move(block));
2014-12-10 17:26:49 +01:00
EXPECT_EQ(blockBegin+BLOCKSIZE_BYTES, (uint8_t*)view.DataEnd<uint64_t>());
2014-12-10 17:26:49 +01:00
}
struct SizedDataEntry {
uint8_t data[6];
};
BOOST_STATIC_ASSERT_MSG(DataNodeViewTest::DATASIZE_BYTES % sizeof(SizedDataEntry) != 0,
2014-12-10 17:26:49 +01:00
"This test case only makes sense, if the data entries don't fill up the whole space. "
"There should be some space left at the end that is not used, because it isn't enough space for a full entry. "
"If this static assertion fails, please use a different size for SizedDataEntry.");
TEST_F(DataNodeViewTest, DataBeginWorksWithStructEntries) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
uint8_t *blockBegin = (uint8_t*)block->data();
DataNodeView view(std::move(block));
2014-12-10 17:26:49 +01:00
EXPECT_EQ(blockBegin+DataNodeLayout::HEADERSIZE_BYTES, (uint8_t*)view.DataBegin<SizedDataEntry>());
2014-12-10 17:26:49 +01:00
}
TEST_F(DataNodeViewTest, DataEndWorksWithStructByteEntries) {
2015-04-25 00:08:29 +02:00
auto block = blockStore->create(Data(BLOCKSIZE_BYTES));
uint8_t *blockBegin = (uint8_t*)block->data();
DataNodeView view(std::move(block));
2014-12-10 17:26:49 +01:00
unsigned int numFittingEntries = DATASIZE_BYTES / sizeof(SizedDataEntry);
2014-12-10 17:26:49 +01:00
uint8_t *dataEnd = (uint8_t*)view.DataEnd<SizedDataEntry>();
EXPECT_EQ(blockBegin+DataNodeLayout::HEADERSIZE_BYTES + numFittingEntries * sizeof(SizedDataEntry), dataEnd);
EXPECT_LT(dataEnd, blockBegin + BLOCKSIZE_BYTES);
2014-12-10 17:26:49 +01:00
}
//TODO Test that header fields (and data) are also stored over reloads