2015-03-12 14:27:51 +01:00
|
|
|
#include "../../../interface/helpers/BlockStoreWithRandomKeys.h"
|
2015-02-17 00:23:33 +01:00
|
|
|
#include "google/gtest/gtest.h"
|
|
|
|
#include "google/gmock/gmock.h"
|
2015-04-25 16:43:52 +02:00
|
|
|
#include <messmer/cpp-utils/data/DataFixture.h>
|
2014-12-09 17:19:59 +01:00
|
|
|
|
|
|
|
using ::testing::Test;
|
|
|
|
using ::testing::_;
|
|
|
|
using ::testing::Return;
|
|
|
|
using ::testing::Invoke;
|
2015-04-18 14:47:12 +02:00
|
|
|
using ::testing::Eq;
|
|
|
|
using ::testing::ByRef;
|
2014-12-09 17:19:59 +01:00
|
|
|
|
|
|
|
using std::string;
|
2015-04-25 02:48:41 +02:00
|
|
|
using cpputils::Data;
|
2015-04-25 16:43:52 +02:00
|
|
|
using cpputils::DataFixture;
|
2015-07-20 18:57:48 +02:00
|
|
|
using cpputils::unique_ref;
|
|
|
|
using boost::optional;
|
2014-12-09 17:19:59 +01:00
|
|
|
|
|
|
|
using namespace blockstore;
|
|
|
|
|
|
|
|
class BlockStoreWithRandomKeysMock: public BlockStoreWithRandomKeys {
|
|
|
|
public:
|
2015-07-20 18:57:48 +02:00
|
|
|
optional<unique_ref<Block>> tryCreate(const Key &key, Data data) {
|
2015-07-21 18:19:34 +02:00
|
|
|
return cpputils::nullcheck(std::unique_ptr<Block>(do_create(key, data)));
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
2015-04-18 14:47:12 +02:00
|
|
|
MOCK_METHOD2(do_create, Block*(const Key &, const Data &data));
|
2015-07-21 14:50:52 +02:00
|
|
|
optional<unique_ref<Block>> load(const Key &key) {
|
2015-07-21 18:19:34 +02:00
|
|
|
return cpputils::nullcheck(std::unique_ptr<Block>(do_load(key)));
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
2014-12-09 20:36:32 +01:00
|
|
|
MOCK_METHOD1(do_load, Block*(const Key &));
|
2015-07-21 14:50:52 +02:00
|
|
|
void remove(unique_ref<Block> block) {UNUSED(block);}
|
2015-02-23 21:07:07 +01:00
|
|
|
MOCK_CONST_METHOD0(numBlocks, uint64_t());
|
2014-12-09 17:19:59 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class BlockMock: public Block {
|
|
|
|
public:
|
2015-10-22 17:41:43 +02:00
|
|
|
BlockMock(): Block(cpputils::Random::PseudoRandom().getFixedSize<Key::BINARY_LENGTH>()) {}
|
2014-12-09 17:19:59 +01:00
|
|
|
MOCK_CONST_METHOD0(data, const void*());
|
2015-03-04 20:47:02 +01:00
|
|
|
MOCK_METHOD3(write, void(const void*, uint64_t, uint64_t));
|
2014-12-09 17:19:59 +01:00
|
|
|
MOCK_METHOD0(flush, void());
|
|
|
|
MOCK_CONST_METHOD0(size, size_t());
|
2015-01-24 22:08:41 +01:00
|
|
|
MOCK_CONST_METHOD0(key, const Key&());
|
2014-12-09 17:19:59 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class BlockStoreWithRandomKeysTest: public Test {
|
|
|
|
public:
|
2015-10-17 21:10:26 +02:00
|
|
|
BlockStoreWithRandomKeysTest() :blockStoreMock(), blockStore(blockStoreMock),
|
|
|
|
key(Key::FromString("1491BB4932A389EE14BC7090AC772972")) {}
|
|
|
|
|
2014-12-09 17:19:59 +01:00
|
|
|
BlockStoreWithRandomKeysMock blockStoreMock;
|
2015-10-17 21:10:26 +02:00
|
|
|
BlockStore &blockStore;
|
|
|
|
const blockstore::Key key;
|
2015-04-18 14:47:12 +02:00
|
|
|
|
|
|
|
Data createDataWithSize(size_t size) {
|
2015-04-25 16:43:52 +02:00
|
|
|
Data fixture(DataFixture::generate(size));
|
2015-04-18 14:47:12 +02:00
|
|
|
Data data(size);
|
|
|
|
std::memcpy(data.data(), fixture.data(), size);
|
|
|
|
return data;
|
|
|
|
}
|
2014-12-09 17:19:59 +01:00
|
|
|
};
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, DataIsPassedThrough0) {
|
|
|
|
Data data = createDataWithSize(0);
|
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, Eq(ByRef(data)))).WillOnce(Return(new BlockMock));
|
|
|
|
blockStore.create(data);
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, DataIsPassedThrough1) {
|
|
|
|
Data data = createDataWithSize(1);
|
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, Eq(ByRef(data)))).WillOnce(Return(new BlockMock));
|
|
|
|
blockStore.create(data);
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, DataIsPassedThrough1024) {
|
|
|
|
Data data = createDataWithSize(1024);
|
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, Eq(ByRef(data)))).WillOnce(Return(new BlockMock));
|
|
|
|
blockStore.create(data);
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, KeyHasCorrectSize) {
|
2015-04-18 14:47:12 +02:00
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, _)).WillOnce(Invoke([](const Key &key, const Data &) {
|
2015-04-09 20:07:03 +02:00
|
|
|
EXPECT_EQ(Key::STRING_LENGTH, key.ToString().size());
|
2014-12-09 20:36:32 +01:00
|
|
|
return new BlockMock;
|
2014-12-09 17:19:59 +01:00
|
|
|
}));
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
blockStore.create(createDataWithSize(1024));
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, TwoBlocksGetDifferentKeys) {
|
2014-12-09 20:57:10 +01:00
|
|
|
Key first_key = key;
|
2014-12-09 17:19:59 +01:00
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, _))
|
2015-04-18 14:47:12 +02:00
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
first_key = key;
|
2014-12-09 20:36:32 +01:00
|
|
|
return new BlockMock;
|
2014-12-09 17:19:59 +01:00
|
|
|
}))
|
2015-04-18 14:47:12 +02:00
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
EXPECT_NE(first_key, key);
|
2014-12-09 20:36:32 +01:00
|
|
|
return new BlockMock;
|
2014-12-09 17:19:59 +01:00
|
|
|
}));
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
Data data = createDataWithSize(1024);
|
|
|
|
blockStore.create(data);
|
|
|
|
blockStore.create(data);
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, WillTryADifferentKeyIfKeyAlreadyExists) {
|
2014-12-09 20:57:10 +01:00
|
|
|
Key first_key = key;
|
2015-04-18 14:47:12 +02:00
|
|
|
Data data = createDataWithSize(1024);
|
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, Eq(ByRef(data))))
|
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
first_key = key;
|
|
|
|
return nullptr;
|
|
|
|
}))
|
2015-04-18 14:47:12 +02:00
|
|
|
//TODO Check that this test case fails when the second do_create call gets different data
|
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
EXPECT_NE(first_key, key);
|
2014-12-09 20:36:32 +01:00
|
|
|
return new BlockMock;
|
2014-12-09 17:19:59 +01:00
|
|
|
}));
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
blockStore.create(data);
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(BlockStoreWithRandomKeysTest, WillTryADifferentKeyIfKeyAlreadyExistsTwoTimes) {
|
2014-12-09 20:57:10 +01:00
|
|
|
Key first_key = key;
|
2015-04-18 14:47:12 +02:00
|
|
|
Data data = createDataWithSize(1024);
|
|
|
|
EXPECT_CALL(blockStoreMock, do_create(_, Eq(ByRef(data))))
|
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
first_key = key;
|
|
|
|
return nullptr;
|
|
|
|
}))
|
2015-04-18 14:47:12 +02:00
|
|
|
//TODO Check that this test case fails when the second/third do_create calls get different data
|
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
first_key = key;
|
|
|
|
return nullptr;
|
|
|
|
}))
|
2015-04-18 14:47:12 +02:00
|
|
|
.WillOnce(Invoke([&first_key](const Key &key, const Data &) {
|
2014-12-09 17:19:59 +01:00
|
|
|
EXPECT_NE(first_key, key);
|
2014-12-09 20:36:32 +01:00
|
|
|
return new BlockMock;
|
2014-12-09 17:19:59 +01:00
|
|
|
}));
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
blockStore.create(data);
|
2014-12-09 17:19:59 +01:00
|
|
|
}
|