Added more test cases for resizing blobs

This commit is contained in:
Sebastian Messmer 2015-03-04 02:56:17 +01:00
parent f89db143d9
commit c0e5b5db8c
3 changed files with 76 additions and 15 deletions

View File

@ -1,6 +1,7 @@
#include "testutils/DataTreeTest.h" #include "testutils/DataTreeTest.h"
#include "testutils/TwoLevelDataFixture.h" #include "testutils/TwoLevelDataFixture.h"
#include "../../../../implementations/onblocks/utils/Math.h" #include "../../../../implementations/onblocks/utils/Math.h"
#include <messmer/blockstore/utils/Data.h>
#include <tuple> #include <tuple>
@ -11,6 +12,7 @@ using std::tuple;
using std::get; using std::get;
using std::function; using std::function;
using std::mem_fn; using std::mem_fn;
using cpputils::dynamic_pointer_move;
using blobstore::onblocks::datanodestore::DataLeafNode; using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datanodestore::DataInnerNode; using blobstore::onblocks::datanodestore::DataInnerNode;
@ -19,6 +21,7 @@ using blobstore::onblocks::datanodestore::DataNodeLayout;
using blobstore::onblocks::datatreestore::DataTree; using blobstore::onblocks::datatreestore::DataTree;
using blobstore::onblocks::utils::ceilDivision; using blobstore::onblocks::utils::ceilDivision;
using blockstore::Key; using blockstore::Key;
using blockstore::Data;
using std::unique_ptr; using std::unique_ptr;
@ -93,14 +96,32 @@ public:
tree(get<0>(GetParam())(this, oldLastLeafSize)), tree(get<0>(GetParam())(this, oldLastLeafSize)),
newNumberOfLeaves(get<2>(GetParam())), newNumberOfLeaves(get<2>(GetParam())),
newLastLeafSize(get<3>(GetParam())), newLastLeafSize(get<3>(GetParam())),
newSize((newNumberOfLeaves-1) * LAYOUT.maxBytesPerLeaf() + newLastLeafSize) newSize((newNumberOfLeaves-1) * LAYOUT.maxBytesPerLeaf() + newLastLeafSize),
{} ZEROES(LAYOUT.maxBytesPerLeaf())
{
ZEROES.FillWithZeroes();
}
void ResizeTree(const Key &key, uint64_t size) {
treeStore.load(key)->resizeNumBytes(size);
}
unique_ptr<DataLeafNode> LastLeaf(const Key &key) {
auto root = nodeStore->load(key);
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
if (leaf.get() != nullptr) {
return leaf;
}
auto inner = dynamic_pointer_move<DataInnerNode>(root);
return LastLeaf(inner->LastChild()->key());
}
uint32_t oldLastLeafSize; uint32_t oldLastLeafSize;
unique_ptr<DataTree> tree; unique_ptr<DataTree> tree;
uint32_t newNumberOfLeaves; uint32_t newNumberOfLeaves;
uint32_t newLastLeafSize; uint32_t newLastLeafSize;
uint64_t newSize; uint64_t newSize;
Data ZEROES;
}; };
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeNumBytes_P, DataTreeTest_ResizeNumBytes_P, INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeNumBytes_P, DataTreeTest_ResizeNumBytes_P,
Combine( Combine(
@ -174,14 +195,44 @@ TEST_P(DataTreeTest_ResizeNumBytes_P, DataStaysIntact) {
Key key = tree->key(); Key key = tree->key();
tree.reset(); tree.reset();
data.FillInto(nodeStore->load(key).get()); data.FillInto(nodeStore->load(key).get());
tree = treeStore.load(key);
tree->resizeNumBytes(newSize); ResizeTree(key, newSize);
tree.reset();
//TODO Also check last leaf if (oldNumberOfLeaves < newNumberOfLeaves || (oldNumberOfLeaves == newNumberOfLeaves && oldLastLeafSize < newLastLeafSize)) {
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), std::min(oldNumberOfLeaves-1, newNumberOfLeaves-1)); data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), oldNumberOfLeaves, oldLastLeafSize);
} else {
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), newNumberOfLeaves, newLastLeafSize);
}
} }
//TODO Test resizing to zero size TEST_P(DataTreeTest_ResizeNumBytes_P, UnusedEndOfLastLeafIsZero) {
//TODO Test that rest data of last leaf is zeroes uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
Key key = tree->key();
tree.reset();
data.FillInto(nodeStore->load(key).get());
ResizeTree(key, newSize);
auto lastLeaf = LastLeaf(key);
EXPECT_EQ(0, std::memcmp(ZEROES.data(), (char*)lastLeaf->data()+lastLeaf->numBytes(), LAYOUT.maxBytesPerLeaf()-lastLeaf->numBytes()));
}
//Resize to zero is not caught in the parametrized test above, in the following, we test it separately.
TEST_F(DataTreeTest_ResizeNumBytes, ResizeToZero_NumBytesIsCorrect) {
auto tree = CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(10u);
tree->resizeNumBytes(0);
Key key = tree->key();
tree.reset();
auto leaf = LoadLeafNode(key);
EXPECT_EQ(0u, leaf->numBytes());
}
TEST_F(DataTreeTest_ResizeNumBytes, ResizeToZero_KeyDoesntChange) {
auto tree = CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(10u);
Key key = tree->key();
tree->resizeNumBytes(0);
EXPECT_EQ(key, tree->key());
}

View File

@ -18,9 +18,14 @@ public:
std::memcpy(leaf->data(), _data.data(), _data.size()); std::memcpy(leaf->data(), _data.data(), _data.size());
} }
void EXPECT_DATA_CORRECT(const blobstore::onblocks::datanodestore::DataLeafNode &leaf) const { void EXPECT_DATA_CORRECT(const blobstore::onblocks::datanodestore::DataLeafNode &leaf, int onlyCheckNumBytes = -1) const {
if (onlyCheckNumBytes == -1) {
EXPECT_EQ(_data.size(), leaf.numBytes()); EXPECT_EQ(_data.size(), leaf.numBytes());
EXPECT_EQ(0, std::memcmp(_data.data(), leaf.data(), _data.size())); EXPECT_EQ(0, std::memcmp(_data.data(), leaf.data(), _data.size()));
} else {
EXPECT_LE(onlyCheckNumBytes, leaf.numBytes());
EXPECT_EQ(0, std::memcmp(_data.data(), leaf.data(), onlyCheckNumBytes));
}
} }
private: private:

View File

@ -26,9 +26,14 @@ public:
}); });
} }
void EXPECT_DATA_CORRECT(blobstore::onblocks::datanodestore::DataNode *node, int maxCheckedLeaves = 0) { void EXPECT_DATA_CORRECT(blobstore::onblocks::datanodestore::DataNode *node, int maxCheckedLeaves = 0, int lastLeafMaxCheckedBytes = -1) {
ForEachLeaf(node, _iv, _iv+maxCheckedLeaves, [this] (blobstore::onblocks::datanodestore::DataLeafNode *leaf, int leafIndex) { ForEachLeaf(node, _iv, _iv+maxCheckedLeaves, [this, maxCheckedLeaves, lastLeafMaxCheckedBytes] (blobstore::onblocks::datanodestore::DataLeafNode *leaf, int leafIndex) {
if (leafIndex == _iv+maxCheckedLeaves-1) {
// It is the last leaf
LeafDataFixture(size(leafIndex, leaf), leafIndex).EXPECT_DATA_CORRECT(*leaf, lastLeafMaxCheckedBytes);
} else {
LeafDataFixture(size(leafIndex, leaf), leafIndex).EXPECT_DATA_CORRECT(*leaf); LeafDataFixture(size(leafIndex, leaf), leafIndex).EXPECT_DATA_CORRECT(*leaf);
}
}); });
} }