Moved data classes to cpp-utils
This commit is contained in:
parent
a1ab1ac4be
commit
d8a6b23962
@ -5,6 +5,8 @@ ADD_BII_TARGETS()
|
|||||||
|
|
||||||
ACTIVATE_CPP14()
|
ACTIVATE_CPP14()
|
||||||
|
|
||||||
|
ADD_BOOST(filesystem)
|
||||||
|
|
||||||
# You can safely delete lines from here...
|
# You can safely delete lines from here...
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
# Biicode configuration file
|
# Biicode configuration file
|
||||||
|
|
||||||
[requirements]
|
[requirements]
|
||||||
|
cryptopp/cryptopp: 9
|
||||||
google/gtest: 11
|
google/gtest: 11
|
||||||
messmer/cmake: 3
|
messmer/cmake: 3
|
||||||
|
messmer/tempfile: 4
|
||||||
|
|
||||||
[parent]
|
[parent]
|
||||||
messmer/cpp-utils: 2
|
messmer/cpp-utils: 2
|
||||||
|
96
data/Data.cpp
Normal file
96
data/Data.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#include "Data.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 cpputils {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<Data> Data::LoadFromFile(const bf::path &filepath) {
|
||||||
|
ifstream file(filepath.c_str(), ios::binary);
|
||||||
|
if (!file.good()) {
|
||||||
|
//TODO Test this path
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
size_t size = _getStreamSize(file);
|
||||||
|
|
||||||
|
Data result(size);
|
||||||
|
result._readFromStream(file);
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
data/Data.h
Normal file
46
data/Data.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CPPUTILS_DATA_DATA_H_
|
||||||
|
#define MESSMER_CPPUTILS_DATA_DATA_H_
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
#include "../macros.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace cpputils {
|
||||||
|
|
||||||
|
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 boost::optional<Data> LoadFromFile(const boost::filesystem::path &filepath);
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t _size;
|
||||||
|
void *_data;
|
||||||
|
|
||||||
|
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
|
91
data/DataBlockFixture.cpp
Normal file
91
data/DataBlockFixture.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "DataBlockFixture.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using std::min;
|
||||||
|
|
||||||
|
namespace cpputils {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
data/DataBlockFixture.h
Normal file
51
data/DataBlockFixture.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CPPUTILS_DATA_DATABLOCKFIXTURE_H_
|
||||||
|
#define MESSMER_CPPUTILS_DATA_DATABLOCKFIXTURE_H_
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
namespace cpputils {
|
||||||
|
|
||||||
|
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
|
112
data/FixedSizeData.h
Normal file
112
data/FixedSizeData.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
|
||||||
|
#define MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
|
||||||
|
|
||||||
|
#include <cryptopp/cryptopp/hex.h>
|
||||||
|
#include <cryptopp/cryptopp/osrng.h>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace cpputils {
|
||||||
|
|
||||||
|
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
|
166
test/data/DataTest.cpp
Normal file
166
test/data/DataTest.cpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#include "../../data/DataBlockFixture.h"
|
||||||
|
#include "../../data/Data.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 cpputils;
|
||||||
|
|
||||||
|
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()).value();
|
||||||
|
|
||||||
|
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()).value();
|
||||||
|
|
||||||
|
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_FALSE(Data::LoadFromFile(file.path()));
|
||||||
|
}
|
157
test/data/FixedSizeDataTest.cpp
Normal file
157
test/data/FixedSizeDataTest.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#include "../../data/DataBlockFixture.h"
|
||||||
|
#include "../../data/FixedSizeData.h"
|
||||||
|
#include "../../data/Data.h"
|
||||||
|
#include "google/gtest/gtest.h"
|
||||||
|
|
||||||
|
|
||||||
|
using ::testing::Test;
|
||||||
|
using ::testing::WithParamInterface;
|
||||||
|
using ::testing::Values;
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
using namespace cpputils;
|
||||||
|
|
||||||
|
class FixedSizeDataTest: public Test {
|
||||||
|
public:
|
||||||
|
static constexpr unsigned int SIZE = 16;
|
||||||
|
|
||||||
|
const string DATA1_AS_STRING = "1491BB4932A389EE14BC7090AC772972";
|
||||||
|
const string DATA2_AS_STRING = "272EE5517627CFA147A971A8E6E747E0";
|
||||||
|
|
||||||
|
const DataBlockFixture DATA3_AS_BINARY;
|
||||||
|
const DataBlockFixture DATA4_AS_BINARY;
|
||||||
|
|
||||||
|
FixedSizeDataTest() : DATA3_AS_BINARY(FixedSizeData<SIZE>::BINARY_LENGTH, 1), DATA4_AS_BINARY(FixedSizeData<SIZE>::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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<unsigned int SIZE>
|
||||||
|
void EXPECT_DATA_EQ(const DataBlockFixture &expected, const FixedSizeData<SIZE> &actual) {
|
||||||
|
EXPECT_EQ(expected.size(), SIZE);
|
||||||
|
EXPECT_EQ(0, std::memcmp(expected.data(), actual.data(), SIZE));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr unsigned int FixedSizeDataTest::SIZE;
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, CanGenerateRandomDataWithoutCrashing) {
|
||||||
|
FixedSizeData<SIZE> result = FixedSizeData<SIZE>::CreateRandom();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, CreatedRandomDatasHaveCorrectLength) {
|
||||||
|
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::CreateRandom();
|
||||||
|
EXPECT_EQ(FixedSizeData<SIZE>::STRING_LENGTH, data.ToString().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, EqualsTrue) {
|
||||||
|
FixedSizeData<SIZE> DATA1_1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
FixedSizeData<SIZE> DATA1_2 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
|
||||||
|
EXPECT_TRUE(DATA1_1 == DATA1_2);
|
||||||
|
EXPECT_TRUE(DATA1_2 == DATA1_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, EqualsFalse) {
|
||||||
|
FixedSizeData<SIZE> DATA1_1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
FixedSizeData<SIZE> DATA2_1 = FixedSizeData<SIZE>::FromString(DATA2_AS_STRING);
|
||||||
|
|
||||||
|
EXPECT_FALSE(DATA1_1 == DATA2_1);
|
||||||
|
EXPECT_FALSE(DATA2_1 == DATA1_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, NotEqualsFalse) {
|
||||||
|
FixedSizeData<SIZE> DATA1_1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
FixedSizeData<SIZE> DATA1_2 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
|
||||||
|
EXPECT_FALSE(DATA1_1 != DATA1_2);
|
||||||
|
EXPECT_FALSE(DATA1_2 != DATA1_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, NotEqualsTrue) {
|
||||||
|
FixedSizeData<SIZE> DATA1_1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
FixedSizeData<SIZE> DATA2_1 = FixedSizeData<SIZE>::FromString(DATA2_AS_STRING);
|
||||||
|
|
||||||
|
EXPECT_TRUE(DATA1_1 != DATA2_1);
|
||||||
|
EXPECT_TRUE(DATA2_1 != DATA1_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FixedSizeDataTestWithStringParam: public FixedSizeDataTest, public WithParamInterface<string> {};
|
||||||
|
INSTANTIATE_TEST_CASE_P(FixedSizeDataTestWithStringParam, FixedSizeDataTestWithStringParam, Values("2898B4B8A13CA63CBE0F0278CCE465DB", "6FFEBAD90C0DAA2B79628F0627CE9841"));
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithStringParam, FromAndToString) {
|
||||||
|
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::FromString(GetParam());
|
||||||
|
EXPECT_EQ(GetParam(), data.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithStringParam, ToAndFromString) {
|
||||||
|
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::FromString(GetParam());
|
||||||
|
FixedSizeData<SIZE> data2 = FixedSizeData<SIZE>::FromString(data.ToString());
|
||||||
|
EXPECT_EQ(data, data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FixedSizeDataTestWithBinaryParam: public FixedSizeDataTest, public WithParamInterface<const DataBlockFixture*> {
|
||||||
|
public:
|
||||||
|
static const DataBlockFixture VALUE1;
|
||||||
|
static const DataBlockFixture VALUE2;
|
||||||
|
};
|
||||||
|
const DataBlockFixture FixedSizeDataTestWithBinaryParam::VALUE1(FixedSizeData<SIZE>::BINARY_LENGTH, 3);
|
||||||
|
const DataBlockFixture FixedSizeDataTestWithBinaryParam::VALUE2(FixedSizeData<SIZE>::BINARY_LENGTH, 4);
|
||||||
|
INSTANTIATE_TEST_CASE_P(FixedSizeDataTestWithBinaryParam, FixedSizeDataTestWithBinaryParam, Values(&FixedSizeDataTestWithBinaryParam::VALUE1, &FixedSizeDataTestWithBinaryParam::VALUE2));
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithBinaryParam, FromBinary) {
|
||||||
|
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::FromBinary((uint8_t*)GetParam()->data());
|
||||||
|
EXPECT_DATA_EQ(*GetParam(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithBinaryParam, FromAndToBinary) {
|
||||||
|
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::FromBinary((uint8_t*)GetParam()->data());
|
||||||
|
Data output(FixedSizeData<SIZE>::BINARY_LENGTH);
|
||||||
|
data.ToBinary(output.data());
|
||||||
|
EXPECT_DATA_EQ(*GetParam(), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithBinaryParam, ToAndFromBinary) {
|
||||||
|
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::FromBinary((uint8_t*)GetParam()->data());
|
||||||
|
Data stored(FixedSizeData<SIZE>::BINARY_LENGTH);
|
||||||
|
data.ToBinary(stored.data());
|
||||||
|
FixedSizeData<SIZE> loaded = FixedSizeData<SIZE>::FromBinary(stored.data());
|
||||||
|
EXPECT_EQ(data, loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FixedSizeDataTestWithParam: public FixedSizeDataTest, public WithParamInterface<FixedSizeData<FixedSizeDataTest::SIZE>> {};
|
||||||
|
INSTANTIATE_TEST_CASE_P(FixedSizeDataTestWithParam, FixedSizeDataTestWithParam, Values(FixedSizeData<FixedSizeDataTest::SIZE>::FromString("2898B4B8A13CA63CBE0F0278CCE465DB"), FixedSizeData<FixedSizeDataTest::SIZE>::FromString("6FFEBAD90C0DAA2B79628F0627CE9841")));
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithParam, CopyConstructor) {
|
||||||
|
FixedSizeData<SIZE> copy(GetParam());
|
||||||
|
EXPECT_EQ(GetParam(), copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, CopyConstructorDoesntChangeSource) {
|
||||||
|
FixedSizeData<SIZE> data1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
FixedSizeData<SIZE> data2(data1);
|
||||||
|
EXPECT_EQ(DATA1_AS_STRING, data1.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(FixedSizeDataTestWithParam, IsEqualAfterAssignment1) {
|
||||||
|
FixedSizeData<SIZE> data2 = FixedSizeData<SIZE>::FromString(DATA2_AS_STRING);
|
||||||
|
EXPECT_NE(GetParam(), data2);
|
||||||
|
data2 = GetParam();
|
||||||
|
EXPECT_EQ(GetParam(), data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FixedSizeDataTest, AssignmentDoesntChangeSource) {
|
||||||
|
FixedSizeData<SIZE> data1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||||
|
FixedSizeData<SIZE> data2 = FixedSizeData<SIZE>::FromString(DATA2_AS_STRING);
|
||||||
|
data2 = data1;
|
||||||
|
EXPECT_EQ(DATA1_AS_STRING, data1.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This tests that a FixedSizeData object is very lightweight
|
||||||
|
// (it is meant to be kept on stack and passed around)
|
||||||
|
TEST_F(FixedSizeDataTest, IsLightweightObject) {
|
||||||
|
EXPECT_EQ(FixedSizeData<SIZE>::BINARY_LENGTH, sizeof(FixedSizeData<SIZE>));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user