Moved Data, FixedSizeData and DataBlockFixture to cpp-utils
This commit is contained in:
parent
60442a46f0
commit
59bfddc18f
@ -9,6 +9,7 @@
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace caching {
|
||||
|
@ -14,14 +14,14 @@ public:
|
||||
CachingBlockStore(std::unique_ptr<BlockStore> baseBlockStore);
|
||||
|
||||
Key createKey() override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, Data data) override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) override;
|
||||
std::unique_ptr<Block> load(const Key &key) override;
|
||||
void remove(std::unique_ptr<Block> block) override;
|
||||
uint64_t numBlocks() const override;
|
||||
|
||||
void release(std::unique_ptr<Block> block);
|
||||
|
||||
std::unique_ptr<Block> tryCreateInBaseStore(const Key &key, Data data);
|
||||
std::unique_ptr<Block> tryCreateInBaseStore(const Key &key, cpputils::Data data);
|
||||
void removeFromBaseStore(std::unique_ptr<Block> block);
|
||||
|
||||
private:
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace caching {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define BLOCKSTORE_IMPLEMENTATIONS_CACHING_NEWBLOCK_H_
|
||||
|
||||
#include "../../interface/BlockStore.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
#include <memory>
|
||||
@ -20,7 +20,7 @@ class CachingBlockStore;
|
||||
// It only exists in the cache and it is created in the base block store when destructed.
|
||||
class NewBlock: public Block {
|
||||
public:
|
||||
NewBlock(const Key &key, Data data, CachingBlockStore *blockStore);
|
||||
NewBlock(const Key &key, cpputils::Data data, CachingBlockStore *blockStore);
|
||||
virtual ~NewBlock();
|
||||
|
||||
const void *data() const override;
|
||||
@ -35,7 +35,7 @@ public:
|
||||
|
||||
private:
|
||||
CachingBlockStore *_blockStore;
|
||||
Data _data;
|
||||
cpputils::Data _data;
|
||||
std::unique_ptr<Block> _baseBlock;
|
||||
bool _dataChanged;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_ENCRYPTEDBLOCK_H_
|
||||
|
||||
#include "../../interface/Block.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include "../../interface/BlockStore.h"
|
||||
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
@ -21,11 +21,11 @@ template<class Cipher>
|
||||
class EncryptedBlock: public Block {
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((CipherConcept<Cipher>));
|
||||
static std::unique_ptr<EncryptedBlock> TryCreateNew(BlockStore *baseBlockStore, const Key &key, Data data, const typename Cipher::EncryptionKey &encKey);
|
||||
static std::unique_ptr<EncryptedBlock> TryCreateNew(BlockStore *baseBlockStore, const Key &key, cpputils::Data data, const typename Cipher::EncryptionKey &encKey);
|
||||
static std::unique_ptr<EncryptedBlock> TryDecrypt(std::unique_ptr<Block> baseBlock, const typename Cipher::EncryptionKey &key);
|
||||
|
||||
//TODO Storing key twice (in parent class and in object pointed to). Once would be enough.
|
||||
EncryptedBlock(std::unique_ptr<Block> baseBlock, const typename Cipher::EncryptionKey &key, Data plaintextData);
|
||||
EncryptedBlock(std::unique_ptr<Block> baseBlock, const typename Cipher::EncryptionKey &key, cpputils::Data plaintextData);
|
||||
virtual ~EncryptedBlock();
|
||||
|
||||
const void *data() const override;
|
||||
@ -38,7 +38,7 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<Block> _baseBlock;
|
||||
Data _plaintextData;
|
||||
cpputils::Data _plaintextData;
|
||||
typename Cipher::EncryptionKey _encKey;
|
||||
bool _dataChanged;
|
||||
|
||||
@ -50,8 +50,8 @@ private:
|
||||
|
||||
|
||||
template<class Cipher>
|
||||
std::unique_ptr<EncryptedBlock<Cipher>> EncryptedBlock<Cipher>::TryCreateNew(BlockStore *baseBlockStore, const Key &key, Data data, const typename Cipher::EncryptionKey &encKey) {
|
||||
Data encrypted = Cipher::encrypt((byte*)data.data(), data.size(), encKey);
|
||||
std::unique_ptr<EncryptedBlock<Cipher>> EncryptedBlock<Cipher>::TryCreateNew(BlockStore *baseBlockStore, const Key &key, cpputils::Data data, const typename Cipher::EncryptionKey &encKey) {
|
||||
cpputils::Data encrypted = Cipher::encrypt((byte*)data.data(), data.size(), encKey);
|
||||
auto baseBlock = baseBlockStore->tryCreate(key, std::move(encrypted));
|
||||
if (baseBlock.get() == nullptr) {
|
||||
//TODO Test this code branch
|
||||
@ -64,7 +64,7 @@ std::unique_ptr<EncryptedBlock<Cipher>> EncryptedBlock<Cipher>::TryCreateNew(Blo
|
||||
template<class Cipher>
|
||||
std::unique_ptr<EncryptedBlock<Cipher>> EncryptedBlock<Cipher>::TryDecrypt(std::unique_ptr<Block> baseBlock, const typename Cipher::EncryptionKey &encKey) {
|
||||
//TODO Change BlockStore so we can read their "class Data" objects instead of "void *data()", and then we can change the Cipher interface to take Data objects instead of "byte *" + size
|
||||
boost::optional<Data> plaintext = Cipher::decrypt((byte*)baseBlock->data(), baseBlock->size(), encKey);
|
||||
boost::optional<cpputils::Data> plaintext = Cipher::decrypt((byte*)baseBlock->data(), baseBlock->size(), encKey);
|
||||
if(!plaintext) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -72,7 +72,7 @@ std::unique_ptr<EncryptedBlock<Cipher>> EncryptedBlock<Cipher>::TryDecrypt(std::
|
||||
}
|
||||
|
||||
template<class Cipher>
|
||||
EncryptedBlock<Cipher>::EncryptedBlock(std::unique_ptr<Block> baseBlock, const typename Cipher::EncryptionKey &encKey, Data plaintextData)
|
||||
EncryptedBlock<Cipher>::EncryptedBlock(std::unique_ptr<Block> baseBlock, const typename Cipher::EncryptionKey &encKey, cpputils::Data plaintextData)
|
||||
:Block(baseBlock->key()),
|
||||
_baseBlock(std::move(baseBlock)),
|
||||
_plaintextData(std::move(plaintextData)),
|
||||
@ -111,7 +111,7 @@ size_t EncryptedBlock<Cipher>::size() const {
|
||||
template<class Cipher>
|
||||
void EncryptedBlock<Cipher>::_encryptToBaseBlock() {
|
||||
if (_dataChanged) {
|
||||
Data encrypted = Cipher::encrypt((byte*)_plaintextData.data(), _plaintextData.size(), _encKey);
|
||||
cpputils::Data encrypted = Cipher::encrypt((byte*)_plaintextData.data(), _plaintextData.size(), _encKey);
|
||||
_baseBlock->write(encrypted.data(), 0, encrypted.size());
|
||||
_dataChanged = false;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
EncryptedBlockStore(std::unique_ptr<BlockStore> baseBlockStore, const typename Cipher::EncryptionKey &encKey);
|
||||
|
||||
Key createKey() override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, Data data) override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) override;
|
||||
std::unique_ptr<Block> load(const Key &key) override;
|
||||
void remove(std::unique_ptr<Block> block) override;
|
||||
uint64_t numBlocks() const override;
|
||||
@ -42,7 +42,7 @@ Key EncryptedBlockStore<Cipher>::createKey() {
|
||||
}
|
||||
|
||||
template<class Cipher>
|
||||
std::unique_ptr<Block> EncryptedBlockStore<Cipher>::tryCreate(const Key &key, Data data) {
|
||||
std::unique_ptr<Block> EncryptedBlockStore<Cipher>::tryCreate(const Key &key, cpputils::Data data) {
|
||||
return EncryptedBlock<Cipher>::TryCreateNew(_baseBlockStore.get(), key, std::move(data), _encKey);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
using CryptoPP::CFB_Mode;
|
||||
using CryptoPP::AES;
|
||||
using cpputils::Data;
|
||||
using cpputils::FixedSizeData;
|
||||
|
||||
namespace blockstore {
|
||||
namespace encrypted {
|
||||
|
@ -2,8 +2,8 @@
|
||||
#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHERS_AES256_CFB_H_
|
||||
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHERS_AES256_CFB_H_
|
||||
|
||||
#include "../../../utils/FixedSizeData.h"
|
||||
#include "../../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/FixedSizeData.h>
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include <cryptopp/cryptopp/aes.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include "Cipher.h"
|
||||
@ -15,7 +15,7 @@ class AES256_CFB {
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((CipherConcept<AES256_CFB>));
|
||||
|
||||
using EncryptionKey = FixedSizeData<32>;
|
||||
using EncryptionKey = cpputils::FixedSizeData<32>;
|
||||
static_assert(32 == CryptoPP::AES::MAX_KEYLENGTH, "If AES offered larger keys, we should offer a variant with it");
|
||||
|
||||
static constexpr unsigned int ciphertextSize(unsigned int plaintextBlockSize) {
|
||||
@ -26,8 +26,8 @@ public:
|
||||
return ciphertextBlockSize - IV_SIZE;
|
||||
}
|
||||
|
||||
static Data encrypt(const byte *plaintext, unsigned int plaintextSize, const EncryptionKey &encKey);
|
||||
static boost::optional<Data> decrypt(const byte *ciphertext, unsigned int ciphertextSize, const EncryptionKey &encKey);
|
||||
static cpputils::Data encrypt(const byte *plaintext, unsigned int plaintextSize, const EncryptionKey &encKey);
|
||||
static boost::optional<cpputils::Data> decrypt(const byte *ciphertext, unsigned int ciphertextSize, const EncryptionKey &encKey);
|
||||
|
||||
private:
|
||||
static constexpr unsigned int IV_SIZE = CryptoPP::AES::BLOCKSIZE;
|
||||
|
@ -9,6 +9,8 @@ using CryptoPP::ArraySource;
|
||||
using CryptoPP::ArraySink;
|
||||
using CryptoPP::GCM_64K_Tables;
|
||||
using CryptoPP::HashVerificationFilter;
|
||||
using cpputils::Data;
|
||||
using cpputils::FixedSizeData;
|
||||
|
||||
namespace blockstore {
|
||||
namespace encrypted {
|
||||
|
@ -2,10 +2,9 @@
|
||||
#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHERS_AES256_GCM_H_
|
||||
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHERS_AES256_GCM_H_
|
||||
|
||||
#include "../../../utils/FixedSizeData.h"
|
||||
#include "../../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/FixedSizeData.h>
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include <cryptopp/cryptopp/aes.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include "Cipher.h"
|
||||
|
||||
namespace blockstore {
|
||||
@ -15,7 +14,7 @@ class AES256_GCM {
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((CipherConcept<AES256_GCM>));
|
||||
|
||||
using EncryptionKey = FixedSizeData<32>;
|
||||
using EncryptionKey = cpputils::FixedSizeData<32>;
|
||||
static_assert(32 == CryptoPP::AES::MAX_KEYLENGTH, "If AES offered larger keys, we should offer a variant with it");
|
||||
|
||||
static constexpr unsigned int ciphertextSize(unsigned int plaintextBlockSize) {
|
||||
@ -26,8 +25,8 @@ public:
|
||||
return ciphertextBlockSize - IV_SIZE - TAG_SIZE;
|
||||
}
|
||||
|
||||
static Data encrypt(const byte *plaintext, unsigned int plaintextSize, const EncryptionKey &encKey);
|
||||
static boost::optional<Data> decrypt(const byte *ciphertext, unsigned int ciphertextSize, const EncryptionKey &encKey);
|
||||
static cpputils::Data encrypt(const byte *plaintext, unsigned int plaintextSize, const EncryptionKey &encKey);
|
||||
static boost::optional<cpputils::Data> decrypt(const byte *ciphertext, unsigned int ciphertextSize, const EncryptionKey &encKey);
|
||||
|
||||
private:
|
||||
static constexpr unsigned int IV_SIZE = CryptoPP::AES::BLOCKSIZE;
|
||||
|
@ -15,8 +15,8 @@ public:
|
||||
same_type(UINT32_C(0), X::ciphertextSize(UINT32_C(5)));
|
||||
same_type(UINT32_C(0), X::plaintextSize(UINT32_C(5)));
|
||||
typename X::EncryptionKey key = X::EncryptionKey::CreateRandom();
|
||||
same_type(Data(0), X::encrypt((byte*)nullptr, UINT32_C(0), key));
|
||||
same_type(boost::optional<Data>(Data(0)), X::decrypt((byte*)nullptr, UINT32_C(0), key));
|
||||
same_type(cpputils::Data(0), X::encrypt((byte*)nullptr, UINT32_C(0), key));
|
||||
same_type(boost::optional<cpputils::Data>(cpputils::Data(0)), X::decrypt((byte*)nullptr, UINT32_C(0), key));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -9,6 +9,7 @@ using std::ostream;
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::ios;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace inmemory {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define BLOCKSTORE_IMPLEMENTATIONS_INMEMORY_INMEMORYBLOCK_H_
|
||||
|
||||
#include "../../interface/Block.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
|
||||
namespace blockstore {
|
||||
namespace inmemory {
|
||||
@ -11,7 +11,7 @@ class InMemoryBlockStore;
|
||||
|
||||
class InMemoryBlock: public Block {
|
||||
public:
|
||||
InMemoryBlock(const Key &key, Data size);
|
||||
InMemoryBlock(const Key &key, cpputils::Data size);
|
||||
InMemoryBlock(const InMemoryBlock &rhs);
|
||||
virtual ~InMemoryBlock();
|
||||
|
||||
@ -23,7 +23,7 @@ public:
|
||||
size_t size() const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Data> _data;
|
||||
std::shared_ptr<cpputils::Data> _data;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ using std::mutex;
|
||||
using std::lock_guard;
|
||||
using std::piecewise_construct;
|
||||
using std::make_tuple;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace inmemory {
|
||||
|
@ -16,7 +16,7 @@ class InMemoryBlockStore: public BlockStoreWithRandomKeys {
|
||||
public:
|
||||
InMemoryBlockStore();
|
||||
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, Data data) override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) override;
|
||||
std::unique_ptr<Block> load(const Key &key) override;
|
||||
void remove(std::unique_ptr<Block> block) override;
|
||||
uint64_t numBlocks() const override;
|
||||
|
@ -13,6 +13,7 @@ using std::ostream;
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::ios;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
@ -47,11 +48,15 @@ unique_ptr<OnDiskBlock> OnDiskBlock::LoadFromDisk(const bf::path &rootdir, const
|
||||
//If it isn't a file, Data::LoadFromFile() would usually also crash. We still need this extra check
|
||||
//upfront, because Data::LoadFromFile() doesn't crash if we give it the path of a directory
|
||||
//instead the path of a file.
|
||||
//TODO Data::LoadFromFile now returns boost::optional. Do we then still need this?
|
||||
if(!bf::is_regular_file(filepath)) {
|
||||
return nullptr;
|
||||
}
|
||||
Data data = Data::LoadFromFile(filepath);
|
||||
return unique_ptr<OnDiskBlock>(new OnDiskBlock(key, filepath, std::move(data)));
|
||||
boost::optional<Data> data = Data::LoadFromFile(filepath);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
return unique_ptr<OnDiskBlock>(new OnDiskBlock(key, filepath, std::move(*data)));
|
||||
} catch (const FileDoesntExistException &e) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include "../../interface/Block.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
@ -18,7 +18,7 @@ public:
|
||||
virtual ~OnDiskBlock();
|
||||
|
||||
static std::unique_ptr<OnDiskBlock> LoadFromDisk(const boost::filesystem::path &rootdir, const Key &key);
|
||||
static std::unique_ptr<OnDiskBlock> CreateOnDisk(const boost::filesystem::path &rootdir, const Key &key, Data data);
|
||||
static std::unique_ptr<OnDiskBlock> CreateOnDisk(const boost::filesystem::path &rootdir, const Key &key, cpputils::Data data);
|
||||
static void RemoveFromDisk(const boost::filesystem::path &rootdir, const Key &key);
|
||||
|
||||
const void *data() const override;
|
||||
@ -30,10 +30,10 @@ public:
|
||||
|
||||
private:
|
||||
const boost::filesystem::path _filepath;
|
||||
Data _data;
|
||||
cpputils::Data _data;
|
||||
bool _dataChanged;
|
||||
|
||||
OnDiskBlock(const Key &key, const boost::filesystem::path &filepath, Data data);
|
||||
OnDiskBlock(const Key &key, const boost::filesystem::path &filepath, cpputils::Data data);
|
||||
|
||||
void _fillDataWithZeroes();
|
||||
void _storeToDisk() const;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::string;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
|
@ -14,7 +14,7 @@ class OnDiskBlockStore: public BlockStoreWithRandomKeys {
|
||||
public:
|
||||
OnDiskBlockStore(const boost::filesystem::path &rootdir);
|
||||
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, Data data) override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) override;
|
||||
std::unique_ptr<Block> load(const Key &key) override;
|
||||
void remove(std::unique_ptr<Block> block) override;
|
||||
uint64_t numBlocks() const override;
|
||||
|
@ -24,7 +24,7 @@ Key ParallelAccessBlockStore::createKey() {
|
||||
return _baseBlockStore->createKey();
|
||||
}
|
||||
|
||||
unique_ptr<Block> ParallelAccessBlockStore::tryCreate(const Key &key, Data data) {
|
||||
unique_ptr<Block> ParallelAccessBlockStore::tryCreate(const Key &key, cpputils::Data data) {
|
||||
auto block = _baseBlockStore->tryCreate(key, std::move(data));
|
||||
if (block.get() == nullptr) {
|
||||
//TODO Test this code branch
|
||||
|
@ -15,7 +15,7 @@ public:
|
||||
ParallelAccessBlockStore(std::unique_ptr<BlockStore> baseBlockStore);
|
||||
|
||||
Key createKey() override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, Data data) override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) override;
|
||||
std::unique_ptr<Block> load(const Key &key) override;
|
||||
void remove(std::unique_ptr<Block> block) override;
|
||||
uint64_t numBlocks() const override;
|
||||
|
@ -10,6 +10,7 @@ using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::ios;
|
||||
using std::string;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace testfake {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define BLOCKSTORE_IMPLEMENTATIONS_INMEMORY_INMEMORYBLOCK_H_
|
||||
|
||||
#include "../../interface/Block.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
|
||||
@ -13,7 +13,7 @@ class FakeBlockStore;
|
||||
|
||||
class FakeBlock: public Block {
|
||||
public:
|
||||
FakeBlock(FakeBlockStore *store, const Key &key, std::shared_ptr<Data> data, bool dirty);
|
||||
FakeBlock(FakeBlockStore *store, const Key &key, std::shared_ptr<cpputils::Data> data, bool dirty);
|
||||
virtual ~FakeBlock();
|
||||
|
||||
const void *data() const override;
|
||||
@ -25,7 +25,7 @@ public:
|
||||
|
||||
private:
|
||||
FakeBlockStore *_store;
|
||||
std::shared_ptr<Data> _data;
|
||||
std::shared_ptr<cpputils::Data> _data;
|
||||
bool _dataChanged;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FakeBlock);
|
||||
|
@ -7,6 +7,7 @@ using std::make_shared;
|
||||
using std::string;
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace testfake {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define BLOCKSTORE_IMPLEMENTATIONS_INMEMORY_INMEMORYBLOCKSTORE_H_
|
||||
|
||||
#include "../../interface/helpers/BlockStoreWithRandomKeys.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
|
||||
#include <mutex>
|
||||
@ -31,24 +31,24 @@ class FakeBlockStore: public BlockStoreWithRandomKeys {
|
||||
public:
|
||||
FakeBlockStore();
|
||||
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, Data data) override;
|
||||
std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) override;
|
||||
std::unique_ptr<Block> load(const Key &key) override;
|
||||
void remove(std::unique_ptr<Block> block) override;
|
||||
uint64_t numBlocks() const override;
|
||||
|
||||
void updateData(const Key &key, const Data &data);
|
||||
void updateData(const Key &key, const cpputils::Data &data);
|
||||
|
||||
private:
|
||||
std::map<std::string, Data> _blocks;
|
||||
std::map<std::string, cpputils::Data> _blocks;
|
||||
|
||||
//This vector keeps a handle of the data regions for all created FakeBlock objects.
|
||||
//This way, it is ensured that no two created FakeBlock objects will work on the
|
||||
//same data region. Without this, it could happen that a test case creates a FakeBlock,
|
||||
//destructs it, creates another one, and the new one gets the same memory region.
|
||||
//We want to avoid this for the reasons mentioned above (overflow data).
|
||||
std::vector<std::shared_ptr<Data>> _used_dataregions_for_blocks;
|
||||
std::vector<std::shared_ptr<cpputils::Data>> _used_dataregions_for_blocks;
|
||||
|
||||
std::unique_ptr<Block> makeFakeBlockFromData(const Key &key, const Data &data, bool dirty);
|
||||
std::unique_ptr<Block> makeFakeBlockFromData(const Key &key, const cpputils::Data &data, bool dirty);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FakeBlockStore);
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "Block.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
@ -15,14 +15,14 @@ public:
|
||||
|
||||
virtual Key createKey() = 0;
|
||||
//Returns nullptr if key already exists
|
||||
virtual std::unique_ptr<Block> tryCreate(const Key &key, Data data) = 0;
|
||||
virtual std::unique_ptr<Block> tryCreate(const Key &key, cpputils::Data data) = 0;
|
||||
//TODO Use boost::optional (if key doesn't exist)
|
||||
// Return nullptr if block with this key doesn't exists
|
||||
virtual std::unique_ptr<Block> load(const Key &key) = 0;
|
||||
virtual void remove(std::unique_ptr<Block> block) = 0;
|
||||
virtual uint64_t numBlocks() const = 0;
|
||||
|
||||
std::unique_ptr<Block> create(const Data &data) {
|
||||
std::unique_ptr<Block> create(const cpputils::Data &data) {
|
||||
std::unique_ptr<Block> block(nullptr);
|
||||
while(block.get() == nullptr) {
|
||||
//TODO Copy necessary?
|
||||
|
@ -3,13 +3,14 @@
|
||||
#include "../../../implementations/encrypted/ciphers/AES256_GCM.h"
|
||||
#include "../../../implementations/encrypted/ciphers/Cipher.h"
|
||||
|
||||
#include "../../testutils/DataBlockFixture.h"
|
||||
#include "../../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/DataBlockFixture.h>
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
|
||||
#include <boost/optional/optional_io.hpp>
|
||||
|
||||
using namespace blockstore::encrypted;
|
||||
using blockstore::Data;
|
||||
using cpputils::Data;
|
||||
using cpputils::DataBlockFixture;
|
||||
|
||||
template<class Cipher>
|
||||
class CipherTest: public ::testing::Test {
|
||||
|
@ -2,17 +2,17 @@
|
||||
#include "../../../../implementations/ondisk/OnDiskBlock.h"
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
#include "messmer/tempfile/src/TempFile.h"
|
||||
#include "messmer/tempfile/src/TempDir.h"
|
||||
#include <messmer/cpp-utils/tempfile/TempFile.h>
|
||||
#include <messmer/cpp-utils/tempfile/TempDir.h>
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
|
||||
using tempfile::TempFile;
|
||||
using tempfile::TempDir;
|
||||
|
||||
using std::unique_ptr;
|
||||
using cpputils::Data;
|
||||
using cpputils::TempFile;
|
||||
using cpputils::TempDir;
|
||||
|
||||
using namespace blockstore;
|
||||
using namespace blockstore::ondisk;
|
||||
@ -63,12 +63,12 @@ public:
|
||||
INSTANTIATE_TEST_CASE_P(OnDiskBlockCreateSizeTest, OnDiskBlockCreateSizeTest, Values(0, 1, 5, 1024, 10*1024*1024));
|
||||
|
||||
TEST_P(OnDiskBlockCreateSizeTest, OnDiskSizeIsCorrect) {
|
||||
Data fileContent = Data::LoadFromFile(file.path());
|
||||
Data fileContent = Data::LoadFromFile(file.path()).value();
|
||||
EXPECT_EQ(GetParam(), fileContent.size());
|
||||
}
|
||||
|
||||
TEST_P(OnDiskBlockCreateSizeTest, OnDiskBlockIsZeroedOut) {
|
||||
Data fileContent = Data::LoadFromFile(file.path());
|
||||
Data fileContent = Data::LoadFromFile(file.path()).value();
|
||||
EXPECT_EQ(0, std::memcmp(ZEROES.data(), fileContent.data(), fileContent.size()));
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,20 @@
|
||||
#include "../../../../implementations/ondisk/FileAlreadyExistsException.h"
|
||||
#include "../../../../implementations/ondisk/OnDiskBlock.h"
|
||||
#include "../../../testutils/DataBlockFixture.h"
|
||||
#include <messmer/cpp-utils/data/DataBlockFixture.h>
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
#include "messmer/tempfile/src/TempFile.h"
|
||||
#include "messmer/tempfile/src/TempDir.h"
|
||||
#include <messmer/cpp-utils/tempfile/TempFile.h>
|
||||
#include <messmer/cpp-utils/tempfile/TempDir.h>
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
|
||||
using tempfile::TempFile;
|
||||
using tempfile::TempDir;
|
||||
|
||||
using std::unique_ptr;
|
||||
using cpputils::Data;
|
||||
using cpputils::DataBlockFixture;
|
||||
using cpputils::TempFile;
|
||||
using cpputils::TempDir;
|
||||
|
||||
using namespace blockstore;
|
||||
using namespace blockstore::ondisk;
|
||||
@ -60,7 +61,7 @@ public:
|
||||
}
|
||||
|
||||
void EXPECT_STORED_FILE_DATA_CORRECT() {
|
||||
Data actual = Data::LoadFromFile(file.path());
|
||||
Data actual = Data::LoadFromFile(file.path()).value();
|
||||
EXPECT_EQ(randomData.size(), actual.size());
|
||||
EXPECT_EQ(0, std::memcmp(randomData.data(), actual.data(), randomData.size()));
|
||||
}
|
||||
|
@ -1,23 +1,24 @@
|
||||
#include "../../../../implementations/ondisk/OnDiskBlock.h"
|
||||
#include "../../../testutils/DataBlockFixture.h"
|
||||
#include <messmer/cpp-utils/data/DataBlockFixture.h>
|
||||
#include "../../../../utils/FileDoesntExistException.h"
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
#include "../../../../utils/Data.h"
|
||||
#include "messmer/tempfile/src/TempFile.h"
|
||||
#include "messmer/tempfile/src/TempDir.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include <messmer/cpp-utils/tempfile/TempFile.h>
|
||||
#include <messmer/cpp-utils/tempfile/TempDir.h>
|
||||
#include <fstream>
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
|
||||
using tempfile::TempFile;
|
||||
using tempfile::TempDir;
|
||||
|
||||
using std::ofstream;
|
||||
using std::unique_ptr;
|
||||
using std::ios;
|
||||
using cpputils::Data;
|
||||
using cpputils::DataBlockFixture;
|
||||
using cpputils::TempFile;
|
||||
using cpputils::TempDir;
|
||||
|
||||
using namespace blockstore;
|
||||
using namespace blockstore::ondisk;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "../../../interface/helpers/BlockStoreWithRandomKeys.h"
|
||||
#include "google/gtest/gtest.h"
|
||||
#include "google/gmock/gmock.h"
|
||||
#include "../../testutils/DataBlockFixture.h"
|
||||
#include <messmer/cpp-utils/data/DataBlockFixture.h>
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::_;
|
||||
@ -13,6 +13,8 @@ using ::testing::ByRef;
|
||||
using std::string;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::Data;
|
||||
using cpputils::DataBlockFixture;
|
||||
|
||||
using namespace blockstore;
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
#include "DataBlockFixture.h"
|
||||
|
||||
#include "../../interface/BlockStore.h"
|
||||
|
||||
class BlockStoreTestFixture {
|
||||
@ -28,14 +26,14 @@ TYPED_TEST_CASE_P(BlockStoreTest);
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, TwoCreatedBlocksHaveDifferentKeys) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block1 = blockStore->create(blockstore::Data(1024));
|
||||
auto block2 = blockStore->create(blockstore::Data(1024));
|
||||
auto block1 = blockStore->create(cpputils::Data(1024));
|
||||
auto block2 = blockStore->create(cpputils::Data(1024));
|
||||
EXPECT_NE(block1->key(), block2->key());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, BlockIsNotLoadableAfterDeleting) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto blockkey = blockStore->create(blockstore::Data(1024))->key();
|
||||
auto blockkey = blockStore->create(cpputils::Data(1024))->key();
|
||||
auto block = blockStore->load(blockkey);
|
||||
EXPECT_NE(nullptr, block.get());
|
||||
blockStore->remove(std::move(block));
|
||||
@ -49,55 +47,55 @@ TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectOnEmptyBlockstore) {
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterAddingOneBlock) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->create(blockstore::Data(1));
|
||||
auto block = blockStore->create(cpputils::Data(1));
|
||||
EXPECT_EQ(1, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterAddingOneBlock_AfterClosingBlock) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
blockStore->create(blockstore::Data(1));
|
||||
blockStore->create(cpputils::Data(1));
|
||||
EXPECT_EQ(1, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterRemovingTheLastBlock) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->create(blockstore::Data(1));
|
||||
auto block = blockStore->create(cpputils::Data(1));
|
||||
blockStore->remove(std::move(block));
|
||||
EXPECT_EQ(0, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterAddingTwoBlocks) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block1 = blockStore->create(blockstore::Data(1));
|
||||
auto block2 = blockStore->create(blockstore::Data(0));
|
||||
auto block1 = blockStore->create(cpputils::Data(1));
|
||||
auto block2 = blockStore->create(cpputils::Data(0));
|
||||
EXPECT_EQ(2, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterAddingTwoBlocks_AfterClosingFirstBlock) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
blockStore->create(blockstore::Data(1));
|
||||
auto block2 = blockStore->create(blockstore::Data(0));
|
||||
blockStore->create(cpputils::Data(1));
|
||||
auto block2 = blockStore->create(cpputils::Data(0));
|
||||
EXPECT_EQ(2, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterAddingTwoBlocks_AfterClosingSecondBlock) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block1 = blockStore->create(blockstore::Data(1));
|
||||
blockStore->create(blockstore::Data(0));
|
||||
auto block1 = blockStore->create(cpputils::Data(1));
|
||||
blockStore->create(cpputils::Data(0));
|
||||
EXPECT_EQ(2, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterAddingTwoBlocks_AfterClosingBothBlocks) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
blockStore->create(blockstore::Data(1));
|
||||
blockStore->create(blockstore::Data(0));
|
||||
blockStore->create(cpputils::Data(1));
|
||||
blockStore->create(cpputils::Data(0));
|
||||
EXPECT_EQ(2, blockStore->numBlocks());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreTest, NumBlocksIsCorrectAfterRemovingABlock) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->create(blockstore::Data(1));
|
||||
blockStore->create(blockstore::Data(1));
|
||||
auto block = blockStore->create(cpputils::Data(1));
|
||||
blockStore->create(cpputils::Data(1));
|
||||
blockStore->remove(std::move(block));
|
||||
EXPECT_EQ(1, blockStore->numBlocks());
|
||||
}
|
||||
|
@ -13,14 +13,14 @@ public:
|
||||
: blockStore(std::move(blockStore_)),
|
||||
testData(testData_),
|
||||
foregroundData(testData.count), backgroundData(testData.blocksize) {
|
||||
DataBlockFixture _foregroundData(testData.count);
|
||||
DataBlockFixture _backgroundData(testData.blocksize);
|
||||
cpputils::DataBlockFixture _foregroundData(testData.count);
|
||||
cpputils::DataBlockFixture _backgroundData(testData.blocksize);
|
||||
std::memcpy(foregroundData.data(), _foregroundData.data(), foregroundData.size());
|
||||
std::memcpy(backgroundData.data(), _backgroundData.data(), backgroundData.size());
|
||||
}
|
||||
|
||||
void TestWriteAndReadImmediately() {
|
||||
auto block = blockStore->create(blockstore::Data(testData.blocksize).FillWithZeroes());
|
||||
auto block = blockStore->create(cpputils::Data(testData.blocksize).FillWithZeroes());
|
||||
block->write(foregroundData.data(), testData.offset, testData.count);
|
||||
|
||||
EXPECT_DATA_READS_AS(foregroundData, *block, testData.offset, testData.count);
|
||||
@ -36,7 +36,7 @@ public:
|
||||
}
|
||||
|
||||
void TestOverwriteAndRead() {
|
||||
auto block = blockStore->create(blockstore::Data(testData.blocksize));
|
||||
auto block = blockStore->create(cpputils::Data(testData.blocksize));
|
||||
block->write(backgroundData.data(), 0, testData.blocksize);
|
||||
block->write(foregroundData.data(), testData.offset, testData.count);
|
||||
EXPECT_DATA_READS_AS(foregroundData, *block, testData.offset, testData.count);
|
||||
@ -46,30 +46,30 @@ public:
|
||||
private:
|
||||
std::unique_ptr<blockstore::BlockStore> blockStore;
|
||||
DataRange testData;
|
||||
blockstore::Data foregroundData;
|
||||
blockstore::Data backgroundData;
|
||||
cpputils::Data foregroundData;
|
||||
cpputils::Data backgroundData;
|
||||
|
||||
void EXPECT_DATA_EQ(const blockstore::Data &expected, const blockstore::Data &actual) {
|
||||
void EXPECT_DATA_EQ(const cpputils::Data &expected, const cpputils::Data &actual) {
|
||||
EXPECT_EQ(expected.size(), actual.size());
|
||||
EXPECT_EQ(0, std::memcmp(expected.data(), actual.data(), expected.size()));
|
||||
}
|
||||
|
||||
blockstore::Key CreateBlockWriteToItAndReturnKey(const blockstore::Data &to_write) {
|
||||
auto newblock = blockStore->create(blockstore::Data(testData.blocksize).FillWithZeroes());
|
||||
blockstore::Key CreateBlockWriteToItAndReturnKey(const cpputils::Data &to_write) {
|
||||
auto newblock = blockStore->create(cpputils::Data(testData.blocksize).FillWithZeroes());
|
||||
|
||||
newblock->write(to_write.data(), testData.offset, testData.count);
|
||||
return newblock->key();
|
||||
}
|
||||
|
||||
void EXPECT_DATA_READS_AS(const blockstore::Data &expected, const blockstore::Block &block, off_t offset, size_t count) {
|
||||
blockstore::Data read(count);
|
||||
void EXPECT_DATA_READS_AS(const cpputils::Data &expected, const blockstore::Block &block, off_t offset, size_t count) {
|
||||
cpputils::Data read(count);
|
||||
std::memcpy(read.data(), (uint8_t*)block.data() + offset, count);
|
||||
EXPECT_DATA_EQ(expected, read);
|
||||
}
|
||||
|
||||
void EXPECT_DATA_READS_AS_OUTSIDE_OF(const blockstore::Data &expected, const blockstore::Block &block, off_t start, size_t count) {
|
||||
blockstore::Data begin(start);
|
||||
blockstore::Data end(testData.blocksize - count - start);
|
||||
void EXPECT_DATA_READS_AS_OUTSIDE_OF(const cpputils::Data &expected, const blockstore::Block &block, off_t start, size_t count) {
|
||||
cpputils::Data begin(start);
|
||||
cpputils::Data end(testData.blocksize - count - start);
|
||||
|
||||
std::memcpy(begin.data(), expected.data(), start);
|
||||
std::memcpy(end.data(), (uint8_t*)expected.data()+start+count, end.size());
|
||||
@ -79,7 +79,7 @@ private:
|
||||
}
|
||||
|
||||
void EXPECT_DATA_IS_ZEROES_OUTSIDE_OF(const blockstore::Block &block, off_t start, size_t count) {
|
||||
blockstore::Data ZEROES(testData.blocksize);
|
||||
cpputils::Data ZEROES(testData.blocksize);
|
||||
ZEROES.FillWithZeroes();
|
||||
EXPECT_DATA_READS_AS_OUTSIDE_OF(ZEROES, block, start, count);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// This file is meant to be included by BlockStoreTest.h only
|
||||
|
||||
#include "../../utils/Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include <messmer/cpp-utils/data/DataBlockFixture.h>
|
||||
|
||||
class BlockStoreSizeParameterizedTest {
|
||||
public:
|
||||
@ -18,8 +19,8 @@ public:
|
||||
}
|
||||
|
||||
void TestCreatedBlockData() {
|
||||
DataBlockFixture dataFixture(size);
|
||||
blockstore::Data data(size);
|
||||
cpputils::DataBlockFixture dataFixture(size);
|
||||
cpputils::Data data(size);
|
||||
std::memcpy(data.data(), dataFixture.data(), size);
|
||||
auto block = blockStore->create(data);
|
||||
EXPECT_EQ(0, std::memcmp(dataFixture.data(), block->data(), size));
|
||||
@ -27,8 +28,8 @@ public:
|
||||
}
|
||||
|
||||
void TestLoadingUnchangedBlockData() {
|
||||
DataBlockFixture dataFixture(size);
|
||||
blockstore::Data data(size);
|
||||
cpputils::DataBlockFixture dataFixture(size);
|
||||
cpputils::Data data(size);
|
||||
std::memcpy(data.data(), dataFixture.data(), size);
|
||||
blockstore::Key key = blockStore->create(data)->key();
|
||||
auto loaded_block = blockStore->load(key);
|
||||
@ -36,21 +37,21 @@ public:
|
||||
}
|
||||
|
||||
void TestLoadedBlockIsCorrect() {
|
||||
DataBlockFixture randomData(size);
|
||||
cpputils::DataBlockFixture randomData(size);
|
||||
auto loaded_block = StoreDataToBlockAndLoadIt(randomData);
|
||||
EXPECT_EQ(size, loaded_block->size());
|
||||
EXPECT_EQ(0, std::memcmp(randomData.data(), loaded_block->data(), size));
|
||||
}
|
||||
|
||||
void TestLoadedBlockIsCorrectWhenLoadedDirectlyAfterFlushing() {
|
||||
DataBlockFixture randomData(size);
|
||||
cpputils::DataBlockFixture randomData(size);
|
||||
auto loaded_block = StoreDataToBlockAndLoadItDirectlyAfterFlushing(randomData);
|
||||
EXPECT_EQ(size, loaded_block->size());
|
||||
EXPECT_EQ(0, std::memcmp(randomData.data(), loaded_block->data(), size));
|
||||
}
|
||||
|
||||
void TestAfterCreate_FlushingDoesntChangeBlock() {
|
||||
DataBlockFixture randomData(size);
|
||||
cpputils::DataBlockFixture randomData(size);
|
||||
auto block = CreateBlock();
|
||||
WriteDataToBlock(block.get(), randomData);
|
||||
block->flush();
|
||||
@ -59,7 +60,7 @@ public:
|
||||
}
|
||||
|
||||
void TestAfterLoad_FlushingDoesntChangeBlock() {
|
||||
DataBlockFixture randomData(size);
|
||||
cpputils::DataBlockFixture randomData(size);
|
||||
auto block = CreateBlockAndLoadIt();
|
||||
WriteDataToBlock(block.get(), randomData);
|
||||
block->flush();
|
||||
@ -68,10 +69,10 @@ public:
|
||||
}
|
||||
|
||||
void TestAfterCreate_FlushesWhenDestructed() {
|
||||
DataBlockFixture randomData(size);
|
||||
cpputils::DataBlockFixture randomData(size);
|
||||
blockstore::Key key = key;
|
||||
{
|
||||
auto block = blockStore->create(blockstore::Data(size));
|
||||
auto block = blockStore->create(cpputils::Data(size));
|
||||
key = block->key();
|
||||
WriteDataToBlock(block.get(), randomData);
|
||||
}
|
||||
@ -80,7 +81,7 @@ public:
|
||||
}
|
||||
|
||||
void TestAfterLoad_FlushesWhenDestructed() {
|
||||
DataBlockFixture randomData(size);
|
||||
cpputils::DataBlockFixture randomData(size);
|
||||
blockstore::Key key = key;
|
||||
{
|
||||
key = CreateBlock()->key();
|
||||
@ -102,25 +103,25 @@ private:
|
||||
std::unique_ptr<blockstore::BlockStore> blockStore;
|
||||
size_t size;
|
||||
|
||||
blockstore::Data ZEROES(size_t size) {
|
||||
blockstore::Data ZEROES(size);
|
||||
cpputils::Data ZEROES(size_t size) {
|
||||
cpputils::Data ZEROES(size);
|
||||
ZEROES.FillWithZeroes();
|
||||
return ZEROES;
|
||||
}
|
||||
|
||||
std::unique_ptr<blockstore::Block> StoreDataToBlockAndLoadIt(const DataBlockFixture &data) {
|
||||
std::unique_ptr<blockstore::Block> StoreDataToBlockAndLoadIt(const cpputils::DataBlockFixture &data) {
|
||||
blockstore::Key key = StoreDataToBlockAndGetKey(data);
|
||||
return blockStore->load(key);
|
||||
}
|
||||
|
||||
blockstore::Key StoreDataToBlockAndGetKey(const DataBlockFixture &dataFixture) {
|
||||
blockstore::Data data(dataFixture.size());
|
||||
blockstore::Key StoreDataToBlockAndGetKey(const cpputils::DataBlockFixture &dataFixture) {
|
||||
cpputils::Data data(dataFixture.size());
|
||||
std::memcpy(data.data(), dataFixture.data(), dataFixture.size());
|
||||
return blockStore->create(data)->key();
|
||||
}
|
||||
|
||||
std::unique_ptr<blockstore::Block> StoreDataToBlockAndLoadItDirectlyAfterFlushing(const DataBlockFixture &dataFixture) {
|
||||
blockstore::Data data(dataFixture.size());
|
||||
std::unique_ptr<blockstore::Block> StoreDataToBlockAndLoadItDirectlyAfterFlushing(const cpputils::DataBlockFixture &dataFixture) {
|
||||
cpputils::Data data(dataFixture.size());
|
||||
std::memcpy(data.data(), dataFixture.data(), dataFixture.size());
|
||||
auto block = blockStore->create(data);
|
||||
block->flush();
|
||||
@ -133,14 +134,14 @@ private:
|
||||
}
|
||||
|
||||
std::unique_ptr<blockstore::Block> CreateBlock() {
|
||||
return blockStore->create(blockstore::Data(size));
|
||||
return blockStore->create(cpputils::Data(size));
|
||||
}
|
||||
|
||||
void WriteDataToBlock(blockstore::Block *block, const DataBlockFixture &randomData) {
|
||||
void WriteDataToBlock(blockstore::Block *block, const cpputils::DataBlockFixture &randomData) {
|
||||
block->write(randomData.data(), 0, randomData.size());
|
||||
}
|
||||
|
||||
void EXPECT_BLOCK_DATA_CORRECT(const blockstore::Block &block, const DataBlockFixture &randomData) {
|
||||
void EXPECT_BLOCK_DATA_CORRECT(const blockstore::Block &block, const cpputils::DataBlockFixture &randomData) {
|
||||
EXPECT_EQ(randomData.size(), block.size());
|
||||
EXPECT_EQ(0, std::memcmp(randomData.data(), block.data(), randomData.size()));
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
#define TEST_BLOCKSTORE_IMPLEMENTATIONS_TESTUTILS_BLOCKSTOREWITHRANDOMKEYSTEST_H_
|
||||
|
||||
#include <google/gtest/gtest.h>
|
||||
#include "DataBlockFixture.h"
|
||||
|
||||
#include "../../interface/BlockStore.h"
|
||||
|
||||
@ -31,45 +30,45 @@ TYPED_TEST_CASE_P(BlockStoreWithRandomKeysTest);
|
||||
|
||||
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSameSize) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->tryCreate(this->key, blockstore::Data(1024));
|
||||
auto block = blockStore->tryCreate(this->key, cpputils::Data(1024));
|
||||
block->flush();
|
||||
auto block2 = blockStore->tryCreate(this->key, blockstore::Data(1024));
|
||||
auto block2 = blockStore->tryCreate(this->key, cpputils::Data(1024));
|
||||
EXPECT_TRUE((bool)block);
|
||||
EXPECT_FALSE((bool)block2);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndDifferentSize) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->tryCreate(this->key, blockstore::Data(1024));
|
||||
auto block = blockStore->tryCreate(this->key, cpputils::Data(1024));
|
||||
block->flush();
|
||||
auto block2 = blockStore->tryCreate(this->key, blockstore::Data(4096));
|
||||
auto block2 = blockStore->tryCreate(this->key, cpputils::Data(4096));
|
||||
EXPECT_TRUE((bool)block);
|
||||
EXPECT_FALSE((bool)block2);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndFirstNullSize) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->tryCreate(this->key, blockstore::Data(0));
|
||||
auto block = blockStore->tryCreate(this->key, cpputils::Data(0));
|
||||
block->flush();
|
||||
auto block2 = blockStore->tryCreate(this->key, blockstore::Data(1024));
|
||||
auto block2 = blockStore->tryCreate(this->key, cpputils::Data(1024));
|
||||
EXPECT_TRUE((bool)block);
|
||||
EXPECT_FALSE((bool)block2);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndSecondNullSize) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->tryCreate(this->key, blockstore::Data(1024));
|
||||
auto block = blockStore->tryCreate(this->key, cpputils::Data(1024));
|
||||
block->flush();
|
||||
auto block2 = blockStore->tryCreate(this->key, blockstore::Data(0));
|
||||
auto block2 = blockStore->tryCreate(this->key, cpputils::Data(0));
|
||||
EXPECT_TRUE((bool)block);
|
||||
EXPECT_FALSE((bool)block2);
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BlockStoreWithRandomKeysTest, CreateTwoBlocksWithSameKeyAndBothNullSize) {
|
||||
auto blockStore = this->fixture.createBlockStore();
|
||||
auto block = blockStore->tryCreate(this->key, blockstore::Data(0));
|
||||
auto block = blockStore->tryCreate(this->key, cpputils::Data(0));
|
||||
block->flush();
|
||||
auto block2 = blockStore->tryCreate(this->key, blockstore::Data(0));
|
||||
auto block2 = blockStore->tryCreate(this->key, cpputils::Data(0));
|
||||
EXPECT_TRUE((bool)block);
|
||||
EXPECT_FALSE((bool)block2);
|
||||
}
|
||||
|
@ -1,87 +0,0 @@
|
||||
#include "DataBlockFixture.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
using std::min;
|
||||
|
||||
DataBlockFixture::DataBlockFixture(size_t size, long long int IV): _fileData(new char[size]), _size(size) {
|
||||
fillFileWithRandomData(IV);
|
||||
}
|
||||
|
||||
DataBlockFixture::~DataBlockFixture() {
|
||||
delete[] _fileData;
|
||||
}
|
||||
|
||||
void DataBlockFixture::fillFileWithRandomData(long long int IV) {
|
||||
long long int val = IV;
|
||||
for(size_t i=0; i<_size/sizeof(long long int); ++i) {
|
||||
//MMIX linear congruential generator
|
||||
val *= 6364136223846793005L;
|
||||
val += 1442695040888963407;
|
||||
reinterpret_cast<long long int*>(_fileData)[i] = val;
|
||||
}
|
||||
uint64_t alreadyWritten = (_size/sizeof(long long int))*sizeof(long long int);
|
||||
val *= 6364136223846793005L;
|
||||
val += 1442695040888963407;
|
||||
char *remainingBytes = reinterpret_cast<char*>(&val);
|
||||
//Fill remaining bytes
|
||||
for(size_t i=0; i<_size-alreadyWritten; ++i) {
|
||||
reinterpret_cast<char*>(_fileData)[alreadyWritten + i] = remainingBytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
const char *DataBlockFixture::data() const {
|
||||
return _fileData;
|
||||
}
|
||||
|
||||
int DataBlockFixture::read(void *buf, size_t count, off_t offset) {
|
||||
size_t realCount = min(count, _size - offset);
|
||||
memcpy(buf, _fileData+offset, realCount);
|
||||
return realCount;
|
||||
}
|
||||
|
||||
size_t DataBlockFixture::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
bool DataBlockFixture::fileContentEqual(const char *content, size_t count, off_t offset) {
|
||||
return 0 == memcmp(content, _fileData + offset, count);
|
||||
}
|
||||
|
||||
DataBlockFixtureWriteable::DataBlockFixtureWriteable(size_t size, long long int IV)
|
||||
:DataBlockFixture(size, IV), _originalSize(size) {
|
||||
_originalFileData = new char[size];
|
||||
memcpy(_originalFileData, _fileData, size);
|
||||
}
|
||||
|
||||
DataBlockFixtureWriteable::~DataBlockFixtureWriteable() {
|
||||
delete[] _originalFileData;
|
||||
}
|
||||
|
||||
void DataBlockFixtureWriteable::write(const void *buf, size_t count, off_t offset) {
|
||||
extendFileSizeIfNecessary(count + offset);
|
||||
|
||||
memcpy(_fileData+offset, buf, count);
|
||||
}
|
||||
|
||||
void DataBlockFixtureWriteable::extendFileSizeIfNecessary(size_t size) {
|
||||
if (size > _size) {
|
||||
extendFileSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
void DataBlockFixtureWriteable::extendFileSize(size_t size) {
|
||||
char *newfile = new char[size];
|
||||
memcpy(newfile, _fileData, _size);
|
||||
delete[] _fileData;
|
||||
_fileData = newfile;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
bool DataBlockFixtureWriteable::sizeUnchanged() {
|
||||
return _size == _originalSize;
|
||||
}
|
||||
|
||||
bool DataBlockFixtureWriteable::regionUnchanged(off_t offset, size_t count) {
|
||||
return 0 == memcmp(_fileData+offset, _originalFileData+offset, count);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef TEST_TESTUTILS_DATABLOCKFIXTURE_H_
|
||||
#define TEST_TESTUTILS_DATABLOCKFIXTURE_H_
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
class DataBlockFixture {
|
||||
public:
|
||||
DataBlockFixture(size_t size, long long int IV = 1);
|
||||
virtual ~DataBlockFixture();
|
||||
|
||||
int read(void *buf, size_t count, off_t offset);
|
||||
|
||||
// Return true, iff the given data is equal to the data of the file at the given offset.
|
||||
bool fileContentEqual(const char *content, size_t count, off_t offset);
|
||||
|
||||
const char *data() const;
|
||||
|
||||
size_t size() const;
|
||||
|
||||
protected:
|
||||
char *_fileData;
|
||||
size_t _size;
|
||||
|
||||
private:
|
||||
void fillFileWithRandomData(long long int IV);
|
||||
};
|
||||
|
||||
class DataBlockFixtureWriteable: public DataBlockFixture {
|
||||
public:
|
||||
DataBlockFixtureWriteable(size_t size, long long int IV = 1);
|
||||
virtual ~DataBlockFixtureWriteable();
|
||||
|
||||
void write(const void *buf, size_t count, off_t offset);
|
||||
|
||||
bool sizeUnchanged();
|
||||
bool regionUnchanged(off_t offset, size_t count);
|
||||
|
||||
private:
|
||||
void extendFileSizeIfNecessary(size_t size);
|
||||
void extendFileSize(size_t size);
|
||||
|
||||
char *_originalFileData;
|
||||
size_t _originalSize;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#include "../../implementations/testfake/FakeBlockStore.h"
|
||||
#include "../testutils/DataBlockFixture.h"
|
||||
#include <messmer/cpp-utils/data/DataBlockFixture.h>
|
||||
#include "../../utils/BlockStoreUtils.h"
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
@ -11,6 +11,8 @@ using ::testing::Values;
|
||||
|
||||
using std::make_unique;
|
||||
using std::unique_ptr;
|
||||
using cpputils::Data;
|
||||
using cpputils::DataBlockFixture;
|
||||
|
||||
using namespace blockstore;
|
||||
using namespace blockstore::utils;
|
||||
|
@ -1,170 +0,0 @@
|
||||
#include "../testutils/DataBlockFixture.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include "../../utils/FileDoesntExistException.h"
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
#include "messmer/tempfile/src/TempFile.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
|
||||
using tempfile::TempFile;
|
||||
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
using namespace blockstore;
|
||||
|
||||
class DataTest: public Test {
|
||||
public:
|
||||
bool DataIsZeroes(const Data &data) {
|
||||
for (size_t i = 0; i != data.size(); ++ i) {
|
||||
if (((char*)data.data())[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FillData(const DataBlockFixture &fillData, Data *data) {
|
||||
ASSERT_EQ(fillData.size(), data->size());
|
||||
std::memcpy(data->data(), fillData.data(), fillData.size());
|
||||
}
|
||||
|
||||
void EXPECT_DATA_CORRECT(const DataBlockFixture &expectedData, const Data &data) {
|
||||
ASSERT_EQ(expectedData.size(), data.size());
|
||||
EXPECT_EQ(0, std::memcmp(expectedData.data(), data.data(), expectedData.size()));
|
||||
}
|
||||
};
|
||||
|
||||
class DataTestWithSizeParam: public DataTest, public WithParamInterface<size_t> {
|
||||
public:
|
||||
DataBlockFixture randomData;
|
||||
|
||||
DataTestWithSizeParam(): randomData(GetParam()) {}
|
||||
|
||||
void FillData(Data *data) {
|
||||
DataTest::FillData(randomData, data);
|
||||
}
|
||||
|
||||
void StoreData(const bf::path &filepath) {
|
||||
ofstream file(filepath.c_str(), std::ios::binary | std::ios::trunc);
|
||||
file.write(randomData.data(), randomData.size());
|
||||
}
|
||||
|
||||
void EXPECT_STORED_FILE_DATA_CORRECT(const bf::path &filepath) {
|
||||
EXPECT_EQ(randomData.size(), bf::file_size(filepath));
|
||||
|
||||
ifstream file(filepath.c_str(), std::ios::binary);
|
||||
char *read_data = new char[randomData.size()];
|
||||
file.read(read_data, randomData.size());
|
||||
|
||||
EXPECT_EQ(0, std::memcmp(randomData.data(), read_data, randomData.size()));
|
||||
delete[] read_data;
|
||||
}
|
||||
|
||||
void EXPECT_DATA_CORRECT(const Data &data) {
|
||||
DataTest::EXPECT_DATA_CORRECT(randomData, data);
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(DataTestWithSizeParam, DataTestWithSizeParam, Values(0, 1, 2, 1024, 4096, 10*1024*1024));
|
||||
|
||||
// Working on a large data area without a crash is a good indicator that we
|
||||
// are actually working on memory that was validly allocated for us.
|
||||
TEST_P(DataTestWithSizeParam, WriteAndCheck) {
|
||||
Data data(GetParam());
|
||||
|
||||
FillData(&data);
|
||||
EXPECT_DATA_CORRECT(data);
|
||||
}
|
||||
|
||||
TEST_P(DataTestWithSizeParam, Size) {
|
||||
Data data(GetParam());
|
||||
EXPECT_EQ(GetParam(), data.size());
|
||||
}
|
||||
|
||||
TEST_P(DataTestWithSizeParam, CheckStoredFile) {
|
||||
Data data(GetParam());
|
||||
FillData(&data);
|
||||
|
||||
TempFile file;
|
||||
data.StoreToFile(file.path());
|
||||
|
||||
EXPECT_STORED_FILE_DATA_CORRECT(file.path());
|
||||
}
|
||||
|
||||
TEST_P(DataTestWithSizeParam, CheckLoadedData) {
|
||||
TempFile file;
|
||||
StoreData(file.path());
|
||||
|
||||
Data data = Data::LoadFromFile(file.path());
|
||||
|
||||
EXPECT_DATA_CORRECT(data);
|
||||
}
|
||||
|
||||
TEST_P(DataTestWithSizeParam, StoreDoesntChangeData) {
|
||||
Data data(GetParam());
|
||||
FillData(&data);
|
||||
|
||||
TempFile file;
|
||||
data.StoreToFile(file.path());
|
||||
|
||||
EXPECT_DATA_CORRECT(data);
|
||||
}
|
||||
|
||||
TEST_P(DataTestWithSizeParam, StoreAndLoad) {
|
||||
Data data(GetParam());
|
||||
FillData(&data);
|
||||
|
||||
TempFile file;
|
||||
data.StoreToFile(file.path());
|
||||
Data loaded_data = Data::LoadFromFile(file.path());
|
||||
|
||||
EXPECT_DATA_CORRECT(loaded_data);
|
||||
}
|
||||
|
||||
TEST_P(DataTestWithSizeParam, Copy) {
|
||||
Data data(GetParam());
|
||||
FillData(&data);
|
||||
|
||||
Data copy = data.copy();
|
||||
|
||||
EXPECT_DATA_CORRECT(copy);
|
||||
}
|
||||
|
||||
TEST_F(DataTest, InitializeWithZeroes) {
|
||||
Data data(10*1024);
|
||||
data.FillWithZeroes();
|
||||
EXPECT_TRUE(DataIsZeroes(data));
|
||||
}
|
||||
|
||||
TEST_F(DataTest, FillModifiedDataWithZeroes) {
|
||||
Data data(10*1024);
|
||||
DataBlockFixture randomData(10*1024);
|
||||
FillData(randomData, &data);
|
||||
EXPECT_FALSE(DataIsZeroes(data));
|
||||
|
||||
data.FillWithZeroes();
|
||||
EXPECT_TRUE(DataIsZeroes(data));
|
||||
}
|
||||
|
||||
//Needs 64bit for representation. This value isn't in the size param list, because the list is also used for read/write checks.
|
||||
TEST_F(DataTest, LargesizeSize) {
|
||||
size_t size = 10L*1024*1024*1024;
|
||||
Data data(size);
|
||||
EXPECT_EQ(size, data.size());
|
||||
}
|
||||
|
||||
TEST_F(DataTest, LoadingNonexistingFile) {
|
||||
TempFile file(false); // Pass false to constructor, so the tempfile is not created
|
||||
EXPECT_THROW(
|
||||
Data::LoadFromFile(file.path()),
|
||||
FileDoesntExistException
|
||||
);
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
#include "../testutils/DataBlockFixture.h"
|
||||
#include "../../utils/Data.h"
|
||||
#include "../../utils/Key.h"
|
||||
#include "google/gtest/gtest.h"
|
||||
|
||||
|
||||
using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
|
||||
using std::string;
|
||||
|
||||
using namespace blockstore;
|
||||
|
||||
//TODO Test blockstore::FixedSizeData instead of blockstore::Key
|
||||
|
||||
class KeyTest: public Test {
|
||||
public:
|
||||
const string KEY1_AS_STRING = "1491BB4932A389EE14BC7090AC772972";
|
||||
const string KEY2_AS_STRING = "272EE5517627CFA147A971A8E6E747E0";
|
||||
|
||||
const DataBlockFixture KEY3_AS_BINARY;
|
||||
const DataBlockFixture KEY4_AS_BINARY;
|
||||
|
||||
KeyTest() : KEY3_AS_BINARY(Key::BINARY_LENGTH, 1), KEY4_AS_BINARY(Key::BINARY_LENGTH, 2) {}
|
||||
|
||||
void EXPECT_DATA_EQ(const DataBlockFixture &expected, const Data &actual) {
|
||||
EXPECT_EQ(expected.size(), actual.size());
|
||||
EXPECT_EQ(0, std::memcmp(expected.data(), actual.data(), expected.size()));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(KeyTest, CanGenerateRandomKeysWithoutCrashing) {
|
||||
Key result = Key::CreateRandom();
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, CreatedRandomKeysHaveCorrectLength) {
|
||||
Key key = Key::CreateRandom();
|
||||
EXPECT_EQ(Key::STRING_LENGTH, key.ToString().size());
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, EqualsTrue) {
|
||||
Key key1_1 = Key::FromString(KEY1_AS_STRING);
|
||||
Key key1_2 = Key::FromString(KEY1_AS_STRING);
|
||||
|
||||
EXPECT_TRUE(key1_1 == key1_2);
|
||||
EXPECT_TRUE(key1_2 == key1_1);
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, EqualsFalse) {
|
||||
Key key1_1 = Key::FromString(KEY1_AS_STRING);
|
||||
Key key2_1 = Key::FromString(KEY2_AS_STRING);
|
||||
|
||||
EXPECT_FALSE(key1_1 == key2_1);
|
||||
EXPECT_FALSE(key2_1 == key1_1);
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, NotEqualsFalse) {
|
||||
Key key1_1 = Key::FromString(KEY1_AS_STRING);
|
||||
Key key1_2 = Key::FromString(KEY1_AS_STRING);
|
||||
|
||||
EXPECT_FALSE(key1_1 != key1_2);
|
||||
EXPECT_FALSE(key1_2 != key1_1);
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, NotEqualsTrue) {
|
||||
Key key1_1 = Key::FromString(KEY1_AS_STRING);
|
||||
Key key2_1 = Key::FromString(KEY2_AS_STRING);
|
||||
|
||||
EXPECT_TRUE(key1_1 != key2_1);
|
||||
EXPECT_TRUE(key2_1 != key1_1);
|
||||
}
|
||||
|
||||
class KeyTestWithStringKeyParam: public KeyTest, public WithParamInterface<string> {};
|
||||
INSTANTIATE_TEST_CASE_P(KeyTestWithStringKeyParam, KeyTestWithStringKeyParam, Values("2898B4B8A13CA63CBE0F0278CCE465DB", "6FFEBAD90C0DAA2B79628F0627CE9841"));
|
||||
|
||||
TEST_P(KeyTestWithStringKeyParam, FromAndToString) {
|
||||
Key key = Key::FromString(GetParam());
|
||||
EXPECT_EQ(GetParam(), key.ToString());
|
||||
}
|
||||
|
||||
TEST_P(KeyTestWithStringKeyParam, ToAndFromString) {
|
||||
Key key = Key::FromString(GetParam());
|
||||
Key key2 = Key::FromString(key.ToString());
|
||||
EXPECT_EQ(key, key2);
|
||||
}
|
||||
|
||||
class KeyTestWithBinaryKeyParam: public KeyTest, public WithParamInterface<const DataBlockFixture*> {
|
||||
public:
|
||||
static const DataBlockFixture VALUE1;
|
||||
static const DataBlockFixture VALUE2;
|
||||
};
|
||||
const DataBlockFixture KeyTestWithBinaryKeyParam::VALUE1(Key::BINARY_LENGTH, 3);
|
||||
const DataBlockFixture KeyTestWithBinaryKeyParam::VALUE2(Key::BINARY_LENGTH, 4);
|
||||
INSTANTIATE_TEST_CASE_P(KeyTestWithBinaryKeyParam, KeyTestWithBinaryKeyParam, Values(&KeyTestWithBinaryKeyParam::VALUE1, &KeyTestWithBinaryKeyParam::VALUE2));
|
||||
|
||||
TEST_P(KeyTestWithBinaryKeyParam, FromAndToBinary) {
|
||||
Key key = Key::FromBinary((uint8_t*)GetParam()->data());
|
||||
Data keydata(Key::BINARY_LENGTH);
|
||||
key.ToBinary(keydata.data());
|
||||
EXPECT_DATA_EQ(*GetParam(), keydata);
|
||||
}
|
||||
|
||||
TEST_P(KeyTestWithBinaryKeyParam, ToAndFromBinary) {
|
||||
Key key = Key::FromBinary((uint8_t*)GetParam()->data());
|
||||
Data stored(Key::BINARY_LENGTH);
|
||||
key.ToBinary(stored.data());
|
||||
Key loaded = Key::FromBinary(stored.data());
|
||||
EXPECT_EQ(key, loaded);
|
||||
}
|
||||
|
||||
class KeyTestWithKeyParam: public KeyTest, public WithParamInterface<Key> {};
|
||||
INSTANTIATE_TEST_CASE_P(KeyTestWithKeyParam, KeyTestWithKeyParam, Values(Key::FromString("2898B4B8A13CA63CBE0F0278CCE465DB"), Key::FromString("6FFEBAD90C0DAA2B79628F0627CE9841")));
|
||||
|
||||
TEST_P(KeyTestWithKeyParam, CopyConstructor) {
|
||||
Key copy(GetParam());
|
||||
EXPECT_EQ(GetParam(), copy);
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, CopyConstructorDoesntChangeSource) {
|
||||
Key key1 = Key::FromString(KEY1_AS_STRING);
|
||||
Key key2(key1);
|
||||
EXPECT_EQ(KEY1_AS_STRING, key1.ToString());
|
||||
}
|
||||
|
||||
TEST_P(KeyTestWithKeyParam, IsEqualAfterAssignment1) {
|
||||
Key key2 = Key::FromString(KEY2_AS_STRING);
|
||||
EXPECT_NE(GetParam(), key2);
|
||||
key2 = GetParam();
|
||||
EXPECT_EQ(GetParam(), key2);
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, AssignmentDoesntChangeSource) {
|
||||
Key key1 = Key::FromString(KEY1_AS_STRING);
|
||||
Key key2 = Key::FromString(KEY2_AS_STRING);
|
||||
key2 = key1;
|
||||
EXPECT_EQ(KEY1_AS_STRING, key1.ToString());
|
||||
}
|
||||
|
||||
// This tests that a Key object is very lightweight
|
||||
// (we will often pass keys around)
|
||||
TEST_F(KeyTest, KeyIsLightweightObject) {
|
||||
EXPECT_EQ(Key::BINARY_LENGTH, sizeof(Key));
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
#include "../interface/BlockStore.h"
|
||||
#include "BlockStoreUtils.h"
|
||||
#include "Data.h"
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
using std::unique_ptr;
|
||||
using cpputils::Data;
|
||||
|
||||
namespace blockstore {
|
||||
namespace utils {
|
||||
|
100
utils/Data.cpp
100
utils/Data.cpp
@ -1,100 +0,0 @@
|
||||
#include "Data.h"
|
||||
#include "FileDoesntExistException.h"
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
|
||||
using std::istream;
|
||||
using std::ofstream;
|
||||
using std::ifstream;
|
||||
using std::ios;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
Data::Data(size_t size)
|
||||
: _size(size), _data(std::malloc(size)) {
|
||||
if (nullptr == _data) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
Data::Data(Data &&rhs)
|
||||
: _size(rhs._size), _data(rhs._data) {
|
||||
// Make rhs invalid, so the memory doesn't get freed in its destructor.
|
||||
rhs._data = nullptr;
|
||||
}
|
||||
|
||||
Data::~Data() {
|
||||
std::free(_data);
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
Data Data::copy() const {
|
||||
Data copy(_size);
|
||||
std::memcpy(copy._data, _data, _size);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void *Data::data() {
|
||||
return const_cast<void*>(const_cast<const Data*>(this)->data());
|
||||
}
|
||||
|
||||
const void *Data::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
size_t Data::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
Data &Data::FillWithZeroes() {
|
||||
std::memset(_data, 0, _size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Data::StoreToFile(const bf::path &filepath) const {
|
||||
ofstream file(filepath.c_str(), ios::binary | ios::trunc);
|
||||
file.write((const char*)_data, _size);
|
||||
}
|
||||
|
||||
Data Data::LoadFromFile(const bf::path &filepath) {
|
||||
ifstream file(filepath.c_str(), ios::binary);
|
||||
_assertFileExists(file, filepath);
|
||||
size_t size = _getStreamSize(file);
|
||||
|
||||
Data result(size);
|
||||
result._readFromStream(file);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Data::_assertFileExists(const ifstream &file, const bf::path &filepath) {
|
||||
if (!file.good()) {
|
||||
throw FileDoesntExistException(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Data::_getStreamSize(istream &stream) {
|
||||
auto current_pos = stream.tellg();
|
||||
|
||||
//Retrieve length
|
||||
stream.seekg(0, stream.end);
|
||||
auto endpos = stream.tellg();
|
||||
|
||||
//Restore old position
|
||||
stream.seekg(current_pos, stream.beg);
|
||||
|
||||
return endpos - current_pos;
|
||||
}
|
||||
|
||||
void Data::_readFromStream(istream &stream) {
|
||||
stream.read((char*)_data, _size);
|
||||
}
|
||||
|
||||
bool operator==(const Data &lhs, const Data &rhs) {
|
||||
return lhs.size() == rhs.size() && 0 == memcmp(lhs.data(), rhs.data(), lhs.size());
|
||||
}
|
||||
|
||||
}
|
46
utils/Data.h
46
utils/Data.h
@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef BLOCKSTORE_IMPLEMENTATIONS_ONDISK_DATA_H_
|
||||
#define BLOCKSTORE_IMPLEMENTATIONS_ONDISK_DATA_H_
|
||||
|
||||
#include <cstdlib>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <messmer/cpp-utils/macros.h>
|
||||
#include <memory>
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
class Data {
|
||||
public:
|
||||
explicit Data(size_t size);
|
||||
Data(Data &&rhs); // move constructor
|
||||
virtual ~Data();
|
||||
|
||||
Data copy() const;
|
||||
|
||||
void *data();
|
||||
const void *data() const;
|
||||
|
||||
size_t size() const;
|
||||
|
||||
Data &FillWithZeroes();
|
||||
|
||||
void StoreToFile(const boost::filesystem::path &filepath) const;
|
||||
static Data LoadFromFile(const boost::filesystem::path &filepath);
|
||||
|
||||
private:
|
||||
size_t _size;
|
||||
void *_data;
|
||||
|
||||
static void _assertFileExists(const std::ifstream &file, const boost::filesystem::path &filepath);
|
||||
static size_t _getStreamSize(std::istream &stream);
|
||||
void _readFromStream(std::istream &stream);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Data);
|
||||
};
|
||||
|
||||
//TODO Test operator==
|
||||
bool operator==(const Data &lhs, const Data &rhs);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,112 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef BLOCKSTORE_UTILS_data_H_
|
||||
#define BLOCKSTORE_UTILS_data_H_
|
||||
|
||||
#include <cryptopp/cryptopp/hex.h>
|
||||
#include <cryptopp/cryptopp/osrng.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
template<unsigned int SIZE>
|
||||
class FixedSizeData {
|
||||
public:
|
||||
//Non-virtual destructor because we want objects to be small
|
||||
~FixedSizeData() {}
|
||||
|
||||
static constexpr unsigned int BINARY_LENGTH = SIZE;
|
||||
static constexpr unsigned int STRING_LENGTH = 2 * BINARY_LENGTH; // Hex encoding
|
||||
|
||||
static FixedSizeData<SIZE> CreateRandom();
|
||||
|
||||
static FixedSizeData<SIZE> FromString(const std::string &data);
|
||||
std::string ToString() const;
|
||||
|
||||
static FixedSizeData<SIZE> FromBinary(const void *source);
|
||||
void ToBinary(void *target) const;
|
||||
|
||||
const unsigned char *data() const;
|
||||
|
||||
private:
|
||||
FixedSizeData() {}
|
||||
static CryptoPP::AutoSeededRandomPool &RandomPool();
|
||||
|
||||
unsigned char _data[BINARY_LENGTH];
|
||||
};
|
||||
|
||||
template<unsigned int SIZE> bool operator==(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
|
||||
template<unsigned int SIZE> bool operator!=(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
|
||||
|
||||
// ----- Implementation -----
|
||||
|
||||
template<unsigned int SIZE> constexpr unsigned int FixedSizeData<SIZE>::BINARY_LENGTH;
|
||||
template<unsigned int SIZE> constexpr unsigned int FixedSizeData<SIZE>::STRING_LENGTH;
|
||||
|
||||
template<unsigned int SIZE>
|
||||
CryptoPP::AutoSeededRandomPool &FixedSizeData<SIZE>::RandomPool() {
|
||||
static CryptoPP::AutoSeededRandomPool singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::CreateRandom() {
|
||||
FixedSizeData<SIZE> result;
|
||||
RandomPool().GenerateBlock(result._data, BINARY_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromString(const std::string &data) {
|
||||
assert(data.size() == STRING_LENGTH);
|
||||
FixedSizeData<SIZE> result;
|
||||
CryptoPP::StringSource(data, true,
|
||||
new CryptoPP::HexDecoder(
|
||||
new CryptoPP::ArraySink(result._data, BINARY_LENGTH)
|
||||
)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
std::string FixedSizeData<SIZE>::ToString() const {
|
||||
std::string result;
|
||||
CryptoPP::ArraySource(_data, BINARY_LENGTH, true,
|
||||
new CryptoPP::HexEncoder(
|
||||
new CryptoPP::StringSink(result)
|
||||
)
|
||||
);
|
||||
assert(result.size() == STRING_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
const unsigned char *FixedSizeData<SIZE>::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
void FixedSizeData<SIZE>::ToBinary(void *target) const {
|
||||
std::memcpy(target, _data, BINARY_LENGTH);
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromBinary(const void *source) {
|
||||
FixedSizeData<SIZE> result;
|
||||
std::memcpy(result._data, source, BINARY_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
bool operator==(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
|
||||
return 0 == std::memcmp(lhs.data(), rhs.data(), FixedSizeData<SIZE>::BINARY_LENGTH);
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
bool operator!=(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -3,12 +3,12 @@
|
||||
#define BLOCKSTORE_UTILS_KEY_H_
|
||||
|
||||
#include <string>
|
||||
#include "FixedSizeData.h"
|
||||
#include <messmer/cpp-utils/data/FixedSizeData.h>
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
// A key here is NOT a key for encryption, but a key as used in key->value mappings ("access handle for a block").
|
||||
using Key = FixedSizeData<16>;
|
||||
using Key = cpputils::FixedSizeData<16>;
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user