Generalized BlobStoreTest, added more test cases there
This commit is contained in:
parent
5355d0ca18
commit
2b112c7fdb
@ -17,6 +17,7 @@ namespace inmemory {
|
|||||||
|
|
||||||
InMemoryBlob::InMemoryBlob(size_t size)
|
InMemoryBlob::InMemoryBlob(size_t size)
|
||||||
: _data(make_shared<Data>(size)) {
|
: _data(make_shared<Data>(size)) {
|
||||||
|
_data->FillWithZeroes();
|
||||||
}
|
}
|
||||||
|
|
||||||
InMemoryBlob::InMemoryBlob(const InMemoryBlob &rhs)
|
InMemoryBlob::InMemoryBlob(const InMemoryBlob &rhs)
|
||||||
|
@ -58,15 +58,19 @@ TEST_P(OnDiskBlobCreateSizeTest, OnDiskSizeIsCorrect) {
|
|||||||
EXPECT_EQ(GetParam(), fileContent.size());
|
EXPECT_EQ(GetParam(), fileContent.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(OnDiskBlobCreateSizeTest, InMemorySizeIsCorrect) {
|
|
||||||
EXPECT_EQ(GetParam(), blob->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(OnDiskBlobCreateSizeTest, InMemoryBlobIsZeroedOut) {
|
|
||||||
EXPECT_EQ(0, std::memcmp(ZEROES.data(), blob->data(), blob->size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(OnDiskBlobCreateSizeTest, OnDiskBlobIsZeroedOut) {
|
TEST_P(OnDiskBlobCreateSizeTest, OnDiskBlobIsZeroedOut) {
|
||||||
Data fileContent = Data::LoadFromFile(file.path());
|
Data fileContent = Data::LoadFromFile(file.path());
|
||||||
EXPECT_EQ(0, std::memcmp(ZEROES.data(), fileContent.data(), fileContent.size()));
|
EXPECT_EQ(0, std::memcmp(ZEROES.data(), fileContent.data(), fileContent.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is also tested by OnDiskBlobStoreTest, but there the blob is created using the BlobStore interface.
|
||||||
|
// Here, we create it using OnDiskBlob::CreateOnDisk()
|
||||||
|
TEST_P(OnDiskBlobCreateSizeTest, InMemorySizeIsCorrect) {
|
||||||
|
EXPECT_EQ(GetParam(), blob->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test is also tested by OnDiskBlobStoreTest, but there the blob is created using the BlobStore interface.
|
||||||
|
// Here, we create it using OnDiskBlob::CreateOnDisk()
|
||||||
|
TEST_P(OnDiskBlobCreateSizeTest, InMemoryBlobIsZeroedOut) {
|
||||||
|
EXPECT_EQ(0, std::memcmp(ZEROES.data(), blob->data(), blob->size()));
|
||||||
|
}
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
};
|
};
|
||||||
INSTANTIATE_TEST_CASE_P(OnDiskBlobFlushTest, OnDiskBlobFlushTest, Values((size_t)0, (size_t)1, (size_t)1024, (size_t)4096, (size_t)10*1024*1024));
|
INSTANTIATE_TEST_CASE_P(OnDiskBlobFlushTest, OnDiskBlobFlushTest, Values((size_t)0, (size_t)1, (size_t)1024, (size_t)4096, (size_t)10*1024*1024));
|
||||||
|
|
||||||
|
// This test is also tested by OnDiskBlobStoreTest, but there the blob is created using the BlobStore interface.
|
||||||
|
// Here, we create it using OnDiskBlob::CreateOnDisk()
|
||||||
TEST_P(OnDiskBlobFlushTest, AfterCreate_FlushingDoesntChangeBlob) {
|
TEST_P(OnDiskBlobFlushTest, AfterCreate_FlushingDoesntChangeBlob) {
|
||||||
auto blob = CreateBlob();
|
auto blob = CreateBlob();
|
||||||
WriteDataToBlob(blob);
|
WriteDataToBlob(blob);
|
||||||
@ -63,6 +65,8 @@ TEST_P(OnDiskBlobFlushTest, AfterCreate_FlushingDoesntChangeBlob) {
|
|||||||
EXPECT_BLOB_DATA_CORRECT(blob);
|
EXPECT_BLOB_DATA_CORRECT(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is also tested by OnDiskBlobStoreTest, but there the blob is created using the BlobStore interface.
|
||||||
|
// Here, we create it using OnDiskBlob::CreateOnDisk() / OnDiskBlob::LoadFromDisk()
|
||||||
TEST_P(OnDiskBlobFlushTest, AfterLoad_FlushingDoesntChangeBlob) {
|
TEST_P(OnDiskBlobFlushTest, AfterLoad_FlushingDoesntChangeBlob) {
|
||||||
auto blob = CreateBlobAndLoadItFromDisk();
|
auto blob = CreateBlobAndLoadItFromDisk();
|
||||||
WriteDataToBlob(blob);
|
WriteDataToBlob(blob);
|
||||||
@ -87,6 +91,8 @@ TEST_P(OnDiskBlobFlushTest, AfterLoad_FlushingWritesCorrectData) {
|
|||||||
EXPECT_STORED_FILE_DATA_CORRECT();
|
EXPECT_STORED_FILE_DATA_CORRECT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is also tested by OnDiskBlobStoreTest, but there it can only checks blob content by loading it again.
|
||||||
|
// Here, we check the content on disk.
|
||||||
TEST_P(OnDiskBlobFlushTest, AfterCreate_FlushesWhenDestructed) {
|
TEST_P(OnDiskBlobFlushTest, AfterCreate_FlushesWhenDestructed) {
|
||||||
{
|
{
|
||||||
auto blob = CreateBlob();
|
auto blob = CreateBlob();
|
||||||
@ -95,6 +101,8 @@ TEST_P(OnDiskBlobFlushTest, AfterCreate_FlushesWhenDestructed) {
|
|||||||
EXPECT_STORED_FILE_DATA_CORRECT();
|
EXPECT_STORED_FILE_DATA_CORRECT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is also tested by OnDiskBlobStoreTest, but there it can only checks blob content by loading it again.
|
||||||
|
// Here, we check the content on disk.
|
||||||
TEST_P(OnDiskBlobFlushTest, AfterLoad_FlushesWhenDestructed) {
|
TEST_P(OnDiskBlobFlushTest, AfterLoad_FlushesWhenDestructed) {
|
||||||
{
|
{
|
||||||
auto blob = CreateBlobAndLoadItFromDisk();
|
auto blob = CreateBlobAndLoadItFromDisk();
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "test/testutils/TempDir.h"
|
#include "test/testutils/TempDir.h"
|
||||||
#include "test/testutils/VirtualTestFile.h"
|
#include "test/testutils/VirtualTestFile.h"
|
||||||
#include "blobstore/interface/BlobStore.h"
|
#include "blobstore/interface/BlobStore.h"
|
||||||
|
#include "blobstore/utils/RandomKeyGenerator.h"
|
||||||
|
|
||||||
class BlobStoreTestFixture {
|
class BlobStoreTestFixture {
|
||||||
public:
|
public:
|
||||||
@ -22,67 +23,183 @@ public:
|
|||||||
const std::vector<size_t> SIZES = {0, 1, 1024, 4096, 10*1024*1024};
|
const std::vector<size_t> SIZES = {0, 1, 1024, 4096, 10*1024*1024};
|
||||||
|
|
||||||
ConcreteBlobStoreTestFixture fixture;
|
ConcreteBlobStoreTestFixture fixture;
|
||||||
|
};
|
||||||
|
|
||||||
void TestCreateBlobAndCheckSize(size_t size) {
|
template<class ConcreateBlobStoreTestFixture>
|
||||||
auto blobStore = fixture.createBlobStore();
|
class BlobStoreSizeParameterizedTest {
|
||||||
|
public:
|
||||||
|
BlobStoreSizeParameterizedTest(ConcreateBlobStoreTestFixture &fixture, size_t size_): blobStore(fixture.createBlobStore()), size(size_) {}
|
||||||
|
|
||||||
|
void TestCreatedBlobHasCorrectSize() {
|
||||||
auto blob = blobStore->create(size);
|
auto blob = blobStore->create(size);
|
||||||
EXPECT_EQ(size, blob.blob->size());
|
EXPECT_EQ(size, blob.blob->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestLoadedBlobIsCorrect(size_t size) {
|
void TestLoadingUnchangedBlobHasCorrectSize() {
|
||||||
auto blobStore = fixture.createBlobStore();
|
auto blob = blobStore->create(size);
|
||||||
|
auto loaded_blob = blobStore->load(blob.key);
|
||||||
|
EXPECT_EQ(size, loaded_blob->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCreatedBlobIsZeroedOut() {
|
||||||
|
auto blob = blobStore->create(size);
|
||||||
|
EXPECT_EQ(0, std::memcmp(ZEROES(size).data(), blob.blob->data(), size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestLoadingUnchangedBlobIsZeroedOut() {
|
||||||
|
auto blob = blobStore->create(size);
|
||||||
|
auto loaded_blob = blobStore->load(blob.key);
|
||||||
|
EXPECT_EQ(0, std::memcmp(ZEROES(size).data(), loaded_blob->data(), size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestLoadedBlobIsCorrect() {
|
||||||
VirtualTestFile randomData(size);
|
VirtualTestFile randomData(size);
|
||||||
auto loaded_blob = StoreDataToBlobAndLoadIt(blobStore.get(), randomData);
|
auto loaded_blob = StoreDataToBlobAndLoadIt(randomData);
|
||||||
EXPECT_EQ(size, loaded_blob->size());
|
EXPECT_EQ(size, loaded_blob->size());
|
||||||
EXPECT_EQ(0, std::memcmp(randomData.data(), loaded_blob->data(), size));
|
EXPECT_EQ(0, std::memcmp(randomData.data(), loaded_blob->data(), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<blobstore::Blob> StoreDataToBlobAndLoadIt(blobstore::BlobStore *blobStore, const VirtualTestFile &data) {
|
void TestLoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing() {
|
||||||
std::string key = StoreDataToBlobAndGetKey(blobStore, data);
|
VirtualTestFile randomData(size);
|
||||||
|
auto loaded_blob = StoreDataToBlobAndLoadItDirectlyAfterFlushing(randomData);
|
||||||
|
EXPECT_EQ(size, loaded_blob->size());
|
||||||
|
EXPECT_EQ(0, std::memcmp(randomData.data(), loaded_blob->data(), size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestAfterCreate_FlushingDoesntChangeBlob() {
|
||||||
|
VirtualTestFile randomData(size);
|
||||||
|
auto blob = CreateBlob();
|
||||||
|
WriteDataToBlob(blob.get(), randomData);
|
||||||
|
blob->flush();
|
||||||
|
|
||||||
|
EXPECT_BLOB_DATA_CORRECT(*blob, randomData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestAfterLoad_FlushingDoesntChangeBlob() {
|
||||||
|
VirtualTestFile randomData(size);
|
||||||
|
auto blob = CreateBlobAndLoadIt();
|
||||||
|
WriteDataToBlob(blob.get(), randomData);
|
||||||
|
blob->flush();
|
||||||
|
|
||||||
|
EXPECT_BLOB_DATA_CORRECT(*blob, randomData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestAfterCreate_FlushesWhenDestructed() {
|
||||||
|
VirtualTestFile randomData(size);
|
||||||
|
std::string key;
|
||||||
|
{
|
||||||
|
auto blob = blobStore->create(size);
|
||||||
|
key = blob.key;
|
||||||
|
WriteDataToBlob(blob.blob.get(), randomData);
|
||||||
|
}
|
||||||
|
auto loaded_blob = blobStore->load(key);
|
||||||
|
EXPECT_BLOB_DATA_CORRECT(*loaded_blob, randomData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestAfterLoad_FlushesWhenDestructed() {
|
||||||
|
VirtualTestFile randomData(size);
|
||||||
|
std::string key;
|
||||||
|
{
|
||||||
|
key = blobStore->create(size).key;
|
||||||
|
auto blob = blobStore->load(key);
|
||||||
|
WriteDataToBlob(blob.get(), randomData);
|
||||||
|
}
|
||||||
|
auto loaded_blob = blobStore->load(key);
|
||||||
|
EXPECT_BLOB_DATA_CORRECT(*loaded_blob, randomData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestLoadNonExistingBlobWithDefinitelyValidKey() {
|
||||||
|
//TODO Specify loading error behavior more precise and test for concrete exception (or whatever behavior we choose)
|
||||||
|
EXPECT_ANY_THROW(
|
||||||
|
blobStore->load(blobstore::RandomKeyGenerator::singleton().create());
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestLoadNonExistingBlobWithMaybeInvalidKey() {
|
||||||
|
//TODO Specify loading error behavior more precise and test for concrete exception (or whatever behavior we choose)
|
||||||
|
EXPECT_ANY_THROW(
|
||||||
|
blobStore->load("not-existing-key");
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestLoadNonExistingBlobWithEmptyKey() {
|
||||||
|
//TODO Specify loading error behavior more precise and test for concrete exception (or whatever behavior we choose)
|
||||||
|
EXPECT_ANY_THROW(
|
||||||
|
blobStore->load("");
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<blobstore::BlobStore> blobStore;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
blobstore::Data ZEROES(size_t size) {
|
||||||
|
blobstore::Data ZEROES(size);
|
||||||
|
ZEROES.FillWithZeroes();
|
||||||
|
return ZEROES;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<blobstore::Blob> StoreDataToBlobAndLoadIt(const VirtualTestFile &data) {
|
||||||
|
std::string key = StoreDataToBlobAndGetKey(data);
|
||||||
return blobStore->load(key);
|
return blobStore->load(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StoreDataToBlobAndGetKey(blobstore::BlobStore *blobStore, const VirtualTestFile &data) {
|
std::string StoreDataToBlobAndGetKey(const VirtualTestFile &data) {
|
||||||
auto blob = blobStore->create(data.size());
|
auto blob = blobStore->create(data.size());
|
||||||
std::memcpy(blob.blob->data(), data.data(), data.size());
|
std::memcpy(blob.blob->data(), data.data(), data.size());
|
||||||
return blob.key;
|
return blob.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestLoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing(size_t size) {
|
std::unique_ptr<blobstore::Blob> StoreDataToBlobAndLoadItDirectlyAfterFlushing(const VirtualTestFile &data) {
|
||||||
auto blobStore = fixture.createBlobStore();
|
|
||||||
VirtualTestFile randomData(size);
|
|
||||||
auto loaded_blob = StoreDataToBlobAndLoadItDirectlyAfterFlushing(blobStore.get(), randomData);
|
|
||||||
EXPECT_EQ(size, loaded_blob->size());
|
|
||||||
EXPECT_EQ(0, std::memcmp(randomData.data(), loaded_blob->data(), size));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<blobstore::Blob> StoreDataToBlobAndLoadItDirectlyAfterFlushing(blobstore::BlobStore *blobStore, const VirtualTestFile &data) {
|
|
||||||
auto blob = blobStore->create(data.size());
|
auto blob = blobStore->create(data.size());
|
||||||
std::memcpy(blob.blob->data(), data.data(), data.size());
|
std::memcpy(blob.blob->data(), data.data(), data.size());
|
||||||
blob.blob->flush();
|
blob.blob->flush();
|
||||||
return blobStore->load(blob.key);
|
return blobStore->load(blob.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<blobstore::Blob> CreateBlobAndLoadIt() {
|
||||||
|
std::string key = blobStore->create(size).key;
|
||||||
|
return blobStore->load(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<blobstore::Blob> CreateBlob() {
|
||||||
|
return blobStore->create(size).blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteDataToBlob(blobstore::Blob *blob, const VirtualTestFile &randomData) {
|
||||||
|
std::memcpy(blob->data(), randomData.data(), randomData.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXPECT_BLOB_DATA_CORRECT(const blobstore::Blob &blob, const VirtualTestFile &randomData) {
|
||||||
|
EXPECT_EQ(randomData.size(), blob.size());
|
||||||
|
EXPECT_EQ(0, std::memcmp(randomData.data(), blob.data(), randomData.size()));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TYPED_TEST_CASE_P(BlobStoreTest);
|
TYPED_TEST_CASE_P(BlobStoreTest);
|
||||||
|
|
||||||
TYPED_TEST_P(BlobStoreTest, CreateBlobAndCheckSize) {
|
#define TYPED_TEST_P_FOR_ALL_SIZES(TestName) \
|
||||||
for (auto size: this->SIZES) {
|
TYPED_TEST_P(BlobStoreTest, TestName) { \
|
||||||
this->TestCreateBlobAndCheckSize(size);
|
for (auto size: this->SIZES) { \
|
||||||
}
|
BlobStoreSizeParameterizedTest<TypeParam>(this->fixture, size) \
|
||||||
}
|
.Test##TestName(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
|
||||||
TYPED_TEST_P(BlobStoreTest, LoadedBlobIsCorrect) {
|
|
||||||
for (auto size: this->SIZES) {
|
|
||||||
this->TestLoadedBlobIsCorrect(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TYPED_TEST_P(BlobStoreTest, LoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing) {
|
TYPED_TEST_P_FOR_ALL_SIZES(CreatedBlobHasCorrectSize);
|
||||||
for (auto size: this->SIZES) {
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadingUnchangedBlobHasCorrectSize);
|
||||||
this->TestLoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing(size);
|
TYPED_TEST_P_FOR_ALL_SIZES(CreatedBlobIsZeroedOut);
|
||||||
}
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadingUnchangedBlobIsZeroedOut);
|
||||||
}
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadedBlobIsCorrect);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(AfterCreate_FlushingDoesntChangeBlob);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(AfterLoad_FlushingDoesntChangeBlob);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(AfterCreate_FlushesWhenDestructed);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(AfterLoad_FlushesWhenDestructed);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadNonExistingBlobWithDefinitelyValidKey);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadNonExistingBlobWithMaybeInvalidKey);
|
||||||
|
TYPED_TEST_P_FOR_ALL_SIZES(LoadNonExistingBlobWithEmptyKey);
|
||||||
|
|
||||||
TYPED_TEST_P(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
|
TYPED_TEST_P(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
|
||||||
auto blobStore = this->fixture.createBlobStore();
|
auto blobStore = this->fixture.createBlobStore();
|
||||||
@ -91,7 +208,22 @@ TYPED_TEST_P(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
|
|||||||
EXPECT_NE(blob1.key, blob2.key);
|
EXPECT_NE(blob1.key, blob2.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_TYPED_TEST_CASE_P(BlobStoreTest, CreateBlobAndCheckSize, LoadedBlobIsCorrect, LoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing, TwoCreatedBlobsHaveDifferentKeys);
|
REGISTER_TYPED_TEST_CASE_P(BlobStoreTest,
|
||||||
|
CreatedBlobHasCorrectSize,
|
||||||
|
LoadingUnchangedBlobHasCorrectSize,
|
||||||
|
CreatedBlobIsZeroedOut,
|
||||||
|
LoadingUnchangedBlobIsZeroedOut,
|
||||||
|
LoadedBlobIsCorrect,
|
||||||
|
LoadedBlobIsCorrectWhenLoadedDirectlyAfterFlushing,
|
||||||
|
AfterCreate_FlushingDoesntChangeBlob,
|
||||||
|
AfterLoad_FlushingDoesntChangeBlob,
|
||||||
|
AfterCreate_FlushesWhenDestructed,
|
||||||
|
AfterLoad_FlushesWhenDestructed,
|
||||||
|
LoadNonExistingBlobWithDefinitelyValidKey,
|
||||||
|
LoadNonExistingBlobWithMaybeInvalidKey,
|
||||||
|
LoadNonExistingBlobWithEmptyKey,
|
||||||
|
TwoCreatedBlobsHaveDifferentKeys
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user