Added more test cases for resizing blobs
This commit is contained in:
parent
f89db143d9
commit
c0e5b5db8c
@ -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());
|
||||||
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user