Fixed loading nonexisting blobs and wrote more test cases

This commit is contained in:
Sebastian Messmer 2015-03-06 02:21:20 +01:00
parent f834f8892d
commit 75d1ef11fe
8 changed files with 127 additions and 61 deletions

View File

@ -68,5 +68,9 @@ Key BlobOnBlocks::key() const {
return _datatree->key();
}
unique_ptr<DataTree> BlobOnBlocks::releaseTree() {
return std::move(_datatree);
}
}
}

View File

@ -28,6 +28,8 @@ public:
void read(void *target, uint64_t offset, uint64_t size) const override;
void write(const void *source, uint64_t offset, uint64_t size) override;
std::unique_ptr<datatreestore::DataTree> releaseTree();
private:
void traverseLeaves(uint64_t offsetBytes, uint64_t sizeBytes, std::function<void (uint64_t, datanodestore::DataLeafNode *, uint32_t, uint32_t)>) const;

View File

@ -5,12 +5,14 @@
#include "BlobStoreOnBlocks.h"
#include "BlobOnBlocks.h"
#include <messmer/cpp-utils/pointer.h>
using std::unique_ptr;
using std::make_unique;
using blockstore::BlockStore;
using blockstore::Key;
using cpputils::dynamic_pointer_move;
namespace blobstore {
namespace onblocks {
@ -30,7 +32,16 @@ unique_ptr<Blob> BlobStoreOnBlocks::create() {
}
unique_ptr<Blob> BlobStoreOnBlocks::load(const Key &key) {
return make_unique<BlobOnBlocks>(_dataTreeStore->load(key));
auto tree = _dataTreeStore->load(key);
if (tree == nullptr) {
return nullptr;
}
return make_unique<BlobOnBlocks>(std::move(tree));
}
void BlobStoreOnBlocks::remove(unique_ptr<Blob> blob) {
auto _blob = dynamic_pointer_move<BlobOnBlocks>(blob);
_dataTreeStore->remove(_blob->releaseTree());
}
}

View File

@ -19,6 +19,8 @@ public:
std::unique_ptr<Blob> create() override;
std::unique_ptr<Blob> load(const blockstore::Key &key) override;
void remove(std::unique_ptr<Blob> blob) override;
private:
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
};

View File

@ -18,8 +18,7 @@ public:
//TODO Use boost::optional (if key doesn't exist)
// Return nullptr if block with this key doesn't exists
virtual std::unique_ptr<Blob> load(const blockstore::Key &key) = 0;
//TODO Needed for performance? Or is deleting loaded blocks enough?
//virtual void remove(const std::string &key) = 0;
virtual void remove(std::unique_ptr<Blob> blob) = 0;
};
}

View File

@ -1,58 +0,0 @@
#include "testutils/BlobStoreTest.h"
using std::unique_ptr;
using namespace blobstore;
class BlobResizeTest: public BlobStoreTest {
public:
BlobResizeTest(): blob(blobStore->create()) {}
static constexpr uint32_t LARGE_SIZE = 10 * 1024 * 1024;
unique_ptr<Blob> blob;
};
constexpr uint32_t BlobResizeTest::LARGE_SIZE;
TEST_F(BlobResizeTest, CreatedBlobIsEmpty) {
EXPECT_EQ(0, blob->size());
}
TEST_F(BlobResizeTest, Growing_1Byte) {
blob->resize(1);
EXPECT_EQ(1, blob->size());
}
TEST_F(BlobResizeTest, Growing_Large) {
blob->resize(LARGE_SIZE);
EXPECT_EQ(LARGE_SIZE, blob->size());
}
TEST_F(BlobResizeTest, Shrinking_Empty) {
blob->resize(LARGE_SIZE);
blob->resize(0);
EXPECT_EQ(0, blob->size());
}
TEST_F(BlobResizeTest, Shrinking_1Byte) {
blob->resize(LARGE_SIZE);
blob->resize(1);
EXPECT_EQ(1, blob->size());
}
TEST_F(BlobResizeTest, ResizingToItself_Empty) {
blob->resize(0);
EXPECT_EQ(0, blob->size());
}
TEST_F(BlobResizeTest, ResizingToItself_1Byte) {
blob->resize(1);
blob->resize(1);
EXPECT_EQ(1, blob->size());
}
TEST_F(BlobResizeTest, ResizingToItself_Large) {
blob->resize(LARGE_SIZE);
blob->resize(LARGE_SIZE);
EXPECT_EQ(LARGE_SIZE, blob->size());
}

View File

@ -0,0 +1,74 @@
#include "testutils/BlobStoreTest.h"
using std::unique_ptr;
using namespace blobstore;
using blockstore::Key;
class BlobSizeTest: public BlobStoreTest {
public:
BlobSizeTest(): blob(blobStore->create()) {}
static constexpr uint32_t LARGE_SIZE = 10 * 1024 * 1024;
unique_ptr<Blob> blob;
};
constexpr uint32_t BlobSizeTest::LARGE_SIZE;
TEST_F(BlobSizeTest, CreatedBlobIsEmpty) {
EXPECT_EQ(0, blob->size());
}
TEST_F(BlobSizeTest, Growing_1Byte) {
blob->resize(1);
EXPECT_EQ(1, blob->size());
}
TEST_F(BlobSizeTest, Growing_Large) {
blob->resize(LARGE_SIZE);
EXPECT_EQ(LARGE_SIZE, blob->size());
}
TEST_F(BlobSizeTest, Shrinking_Empty) {
blob->resize(LARGE_SIZE);
blob->resize(0);
EXPECT_EQ(0, blob->size());
}
TEST_F(BlobSizeTest, Shrinking_1Byte) {
blob->resize(LARGE_SIZE);
blob->resize(1);
EXPECT_EQ(1, blob->size());
}
TEST_F(BlobSizeTest, ResizingToItself_Empty) {
blob->resize(0);
EXPECT_EQ(0, blob->size());
}
TEST_F(BlobSizeTest, ResizingToItself_1Byte) {
blob->resize(1);
blob->resize(1);
EXPECT_EQ(1, blob->size());
}
TEST_F(BlobSizeTest, ResizingToItself_Large) {
blob->resize(LARGE_SIZE);
blob->resize(LARGE_SIZE);
EXPECT_EQ(LARGE_SIZE, blob->size());
}
TEST_F(BlobSizeTest, EmptyBlobStaysEmptyWhenLoading) {
Key key = blob->key();
blob.reset();
auto loaded = blobStore->load(key);
EXPECT_EQ(0, loaded->size());
}
TEST_F(BlobSizeTest, BlobSizeStaysIntactWhenLoading) {
blob->resize(LARGE_SIZE);
Key key = blob->key();
blob.reset();
auto loaded = blobStore->load(key);
EXPECT_EQ(LARGE_SIZE, loaded->size());
}

View File

@ -0,0 +1,32 @@
#include "testutils/BlobStoreTest.h"
using blockstore::Key;
TEST_F(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
auto blob1 = blobStore->create();
auto blob2 = blobStore->create();
EXPECT_NE(blob1->key(), blob2->key());
}
TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteDirectly) {
auto blob = blobStore->create();
Key key = blob->key();
blobStore->remove(std::move(blob));
EXPECT_EQ(nullptr, blobStore->load(key).get());
}
TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteAfterLoading) {
auto blob = blobStore->create();
Key key = blob->key();
blob.reset();
blobStore->remove(blobStore->load(key));
EXPECT_EQ(nullptr, blobStore->load(key).get());
}
//TODO Test read/write
//TODO Test read/write with loading inbetween
//Taken from BlockStoreTest.h:
//TODO Created blob is zeroed out
//TODO Created blob is zeroed out after loading
//TODO Try loading nonexisting blob