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(); 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 read(void *target, uint64_t offset, uint64_t size) const override;
void write(const void *source, uint64_t offset, uint64_t size) override; void write(const void *source, uint64_t offset, uint64_t size) override;
std::unique_ptr<datatreestore::DataTree> releaseTree();
private: private:
void traverseLeaves(uint64_t offsetBytes, uint64_t sizeBytes, std::function<void (uint64_t, datanodestore::DataLeafNode *, uint32_t, uint32_t)>) const; 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 "BlobStoreOnBlocks.h"
#include "BlobOnBlocks.h" #include "BlobOnBlocks.h"
#include <messmer/cpp-utils/pointer.h>
using std::unique_ptr; using std::unique_ptr;
using std::make_unique; using std::make_unique;
using blockstore::BlockStore; using blockstore::BlockStore;
using blockstore::Key; using blockstore::Key;
using cpputils::dynamic_pointer_move;
namespace blobstore { namespace blobstore {
namespace onblocks { namespace onblocks {
@ -30,7 +32,16 @@ unique_ptr<Blob> BlobStoreOnBlocks::create() {
} }
unique_ptr<Blob> BlobStoreOnBlocks::load(const Key &key) { 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> create() override;
std::unique_ptr<Blob> load(const blockstore::Key &key) override; std::unique_ptr<Blob> load(const blockstore::Key &key) override;
void remove(std::unique_ptr<Blob> blob) override;
private: private:
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore; std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
}; };

View File

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