diff --git a/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp b/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp index 0cfbcfd3..c16b3991 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp +++ b/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.cpp @@ -30,13 +30,6 @@ unique_ptr DataTreeShrinkingTest::CreateTwoInnerNodeTwoOneLeaves( }); } -unique_ptr DataTreeShrinkingTest::CreateFourLevelMinData() { - return CreateInner({ - CreateFullThreeLevel(), - CreateInner({CreateInner({CreateLeaf()})}) - }); -} - unique_ptr DataTreeShrinkingTest::CreateFourLevelWithTwoSiblingLeaves1() { return CreateInner({ CreateFullThreeLevel(), diff --git a/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.h b/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.h index 166decff..37ee39fa 100644 --- a/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.h +++ b/test/implementations/onblocks/datatreestore/shrinking/testutils/DataTreeShrinkingTest.h @@ -16,7 +16,6 @@ public: std::unique_ptr CreateFourNodeThreeLeaf(); std::unique_ptr CreateTwoInnerNodeOneTwoLeaves(); std::unique_ptr CreateTwoInnerNodeTwoOneLeaves(); - std::unique_ptr CreateFourLevelMinData(); std::unique_ptr CreateFourLevelWithTwoSiblingLeaves1(); std::unique_ptr CreateFourLevelWithTwoSiblingLeaves2(); std::unique_ptr CreateWithFirstChildOfRootFullThreelevelAndSecondChildMindataThreelevel(); diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp index 3ef62831..cad3e6ee 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp @@ -75,6 +75,13 @@ unique_ptr DataTreeTest::CreateThreeLevelMinData() { }); } +unique_ptr DataTreeTest::CreateFourLevelMinData() { + return CreateInner({ + CreateFullThreeLevel(), + CreateInner({CreateInner({CreateLeaf()})}) + }); +} + unique_ptr DataTreeTest::CreateFullThreeLevel() { auto root = CreateInner({CreateFullTwoLevel().get()}); FillNodeTwoLevel(root.get()); diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h index 02fe4c82..f1b667d0 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h @@ -28,6 +28,7 @@ public: std::unique_ptr CreateFullThreeLevel(); std::unique_ptr CreateThreeLevelMinData(); + std::unique_ptr CreateFourLevelMinData(); std::unique_ptr LoadInnerNode(const blockstore::Key &key); std::unique_ptr LoadLeafNode(const blockstore::Key &key); diff --git a/test/implementations/onblocks/datatreestore/traverseLeaves/DataTreeTest_TraverseLeaves.cpp b/test/implementations/onblocks/datatreestore/traverseLeaves/DataTreeTest_TraverseLeaves.cpp index 9d937c27..36535274 100644 --- a/test/implementations/onblocks/datatreestore/traverseLeaves/DataTreeTest_TraverseLeaves.cpp +++ b/test/implementations/onblocks/datatreestore/traverseLeaves/DataTreeTest_TraverseLeaves.cpp @@ -9,6 +9,8 @@ using blobstore::onblocks::datanodestore::DataNode; using blobstore::onblocks::datatreestore::DataTree; using blockstore::Key; +using std::unique_ptr; + class TraversorMock { public: MOCK_METHOD2(called, void(DataLeafNode*, uint32_t)); @@ -20,6 +22,24 @@ MATCHER_P(KeyEq, expected, "node key equals") { class DataTreeTest_TraverseLeaves: public DataTreeTest { public: + unique_ptr CreateThreeLevel() { + return CreateInner({ + CreateFullTwoLevel(), + CreateFullTwoLevel(), + CreateFullTwoLevel(), + CreateFullTwoLevel(), + CreateFullTwoLevel(), + CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})}); + } + + unique_ptr CreateFourLevel() { + return CreateInner({ + CreateFullThreeLevel(), + CreateFullThreeLevel(), + CreateInner({CreateFullTwoLevel(), CreateInner({CreateLeaf()})}) + }); + } + void EXPECT_TRAVERSE_LEAF(const Key &key, uint32_t leafIndex) { EXPECT_CALL(traversor, called(KeyEq(key), leafIndex)).Times(1); } @@ -41,6 +61,7 @@ public: traversor.called(leaf, nodeIndex); }); } + TraversorMock traversor; }; @@ -143,6 +164,33 @@ TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstChildOfThreelevelMinDataTree) { TraverseLeaves(root.get(), 0, DataInnerNode::MAX_STORED_CHILDREN); } +TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstPartOfFullTwolevelTree) { + auto root = CreateFullTwoLevel(); + for (int i = 0; i < 5; ++i) { + EXPECT_TRAVERSE_LEAF(root->getChild(i)->key(), i); + } + + TraverseLeaves(root.get(), 0, 5); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseInnerPartOfFullTwolevelTree) { + auto root = CreateFullTwoLevel(); + for (int i = 5; i < 10; ++i) { + EXPECT_TRAVERSE_LEAF(root->getChild(i)->key(), i); + } + + TraverseLeaves(root.get(), 5, 10); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseLastPartOfFullTwolevelTree) { + auto root = CreateFullTwoLevel(); + for (int i = 5; i < DataInnerNode::MAX_STORED_CHILDREN; ++i) { + EXPECT_TRAVERSE_LEAF(root->getChild(i)->key(), i); + } + + TraverseLeaves(root.get(), 5, DataInnerNode::MAX_STORED_CHILDREN); +} + TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstPartOfThreelevelMinDataTree) { auto root = CreateThreeLevelMinData(); auto node = LoadInnerNode(root->getChild(0)->key()); @@ -174,9 +222,139 @@ TEST_F(DataTreeTest_TraverseLeaves, TraverseLastPartOfThreelevelMinDataTree) { TraverseLeaves(root.get(), 5, DataInnerNode::MAX_STORED_CHILDREN+1); } -//TODO First/Inner/LastPart of FullTwoLevelTree -//TODO Test cases with a larger threelevel tree (say 5 children being full twolevel trees) -//TODO Some few testcases with full threelevel tree -//TODO Some few testcases with fourlevel mindata tree +TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstLeafOfThreelevelTree) { + auto root = CreateThreeLevel(); + EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(0)->key())->getChild(0)->key(), 0); -//TODO ...more test cases? + TraverseLeaves(root.get(), 0, 1); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseLastLeafOfThreelevelTree) { + auto root = CreateThreeLevel(); + uint32_t numLeaves = DataInnerNode::MAX_STORED_CHILDREN * 5 + 3; + EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->LastChild()->key())->LastChild()->key(), numLeaves-1); + + TraverseLeaves(root.get(), numLeaves-1, numLeaves); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddleLeafOfThreelevelTree) { + auto root = CreateThreeLevel(); + uint32_t wantedLeafIndex = DataInnerNode::MAX_STORED_CHILDREN * 2 + 5; + EXPECT_TRAVERSE_LEAF(LoadInnerNode(root->getChild(2)->key())->getChild(5)->key(), wantedLeafIndex); + + TraverseLeaves(root.get(), wantedLeafIndex, wantedLeafIndex+1); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseFirstPartOfThreelevelTree) { + auto root = CreateThreeLevel(); + //Traverse all leaves in the first two children of the root + for(int i = 0; i < 2; ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse some of the leaves in the third child of the root + auto child = LoadInnerNode(root->getChild(2)->key()); + for(int i = 0; i < 5; ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 2 * DataInnerNode::MAX_STORED_CHILDREN + i); + } + + TraverseLeaves(root.get(), 0, 2 * DataInnerNode::MAX_STORED_CHILDREN + 5); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddlePartOfThreelevelTree_OnlyFullChildren) { + auto root = CreateThreeLevel(); + //Traverse some of the leaves in the second child of the root + auto child = LoadInnerNode(root->getChild(1)->key()); + for(int i = 5; i < DataInnerNode::MAX_STORED_CHILDREN; ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), DataInnerNode::MAX_STORED_CHILDREN + i); + } + //Traverse all leaves in the third and fourth child of the root + for(int i = 2; i < 4; ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse some of the leaves in the fifth child of the root + child = LoadInnerNode(root->getChild(4)->key()); + for(int i = 0; i < 5; ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 4 * DataInnerNode::MAX_STORED_CHILDREN + i); + } + + TraverseLeaves(root.get(), DataInnerNode::MAX_STORED_CHILDREN + 5, 4 * DataInnerNode::MAX_STORED_CHILDREN + 5); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseMiddlePartOfThreelevelTree_AlsoLastNonfullChild) { + auto root = CreateThreeLevel(); + //Traverse some of the leaves in the second child of the root + auto child = LoadInnerNode(root->getChild(1)->key()); + for(int i = 5; i < DataInnerNode::MAX_STORED_CHILDREN; ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), DataInnerNode::MAX_STORED_CHILDREN + i); + } + //Traverse all leaves in the third, fourth and fifth child of the root + for(int i = 2; i < 5; ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse some of the leaves in the sixth child of the root + child = LoadInnerNode(root->getChild(5)->key()); + for(int i = 0; i < 2; ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 5 * DataInnerNode::MAX_STORED_CHILDREN + i); + } + + TraverseLeaves(root.get(), DataInnerNode::MAX_STORED_CHILDREN + 5, 5 * DataInnerNode::MAX_STORED_CHILDREN + 2); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseLastPartOfThreelevelTree) { + auto root = CreateThreeLevel(); + //Traverse some of the leaves in the second child of the root + auto child = LoadInnerNode(root->getChild(1)->key()); + for(int i = 5; i < DataInnerNode::MAX_STORED_CHILDREN; ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), DataInnerNode::MAX_STORED_CHILDREN + i); + } + //Traverse all leaves in the third, fourth and fifth child of the root + for(int i = 2; i < 5; ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse all of the leaves in the sixth child of the root + child = LoadInnerNode(root->getChild(5)->key()); + for(int i = 0; i < child->numChildren(); ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 5 * DataInnerNode::MAX_STORED_CHILDREN + i); + } + + TraverseLeaves(root.get(), DataInnerNode::MAX_STORED_CHILDREN + 5, 5 * DataInnerNode::MAX_STORED_CHILDREN + child->numChildren()); +} + +TEST_F(DataTreeTest_TraverseLeaves, TraverseAllLeavesOfThreelevelTree) { + auto root = CreateThreeLevel(); + //Traverse all leaves in the third, fourth and fifth child of the root + for(int i = 0; i < 5; ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(root->getChild(i)->key()), i * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse all of the leaves in the sixth child of the root + auto child = LoadInnerNode(root->getChild(5)->key()); + for(int i = 0; i < child->numChildren(); ++i) { + EXPECT_TRAVERSE_LEAF(child->getChild(i)->key(), 5 * DataInnerNode::MAX_STORED_CHILDREN + i); + } + + TraverseLeaves(root.get(), 0, 5 * DataInnerNode::MAX_STORED_CHILDREN + child->numChildren()); +} + +//Disabled because it takes too long +TEST_F(DataTreeTest_TraverseLeaves, DISABLED_TraverseAllLeavesOfFourLevelTree) { + auto root = CreateFourLevel(); + //Traverse all leaves of the full threelevel tree in the first child + auto firstChild = LoadInnerNode(root->getChild(0)->key()); + for(int i = 0; i < firstChild->numChildren(); ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(firstChild->getChild(i)->key()), i * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse all leaves of the full threelevel tree in the second child + auto secondChild = LoadInnerNode(root->getChild(1)->key()); + for(int i = 0; i < secondChild->numChildren(); ++i) { + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(secondChild->getChild(i)->key()), (DataInnerNode::MAX_STORED_CHILDREN + i) * DataInnerNode::MAX_STORED_CHILDREN); + } + //Traverse all leaves of the non-full threelevel tree in the third child + auto thirdChild = LoadInnerNode(root->getChild(2)->key()); + EXPECT_TRAVERSE_ALL_CHILDREN_OF(*LoadInnerNode(thirdChild->getChild(0)->key()), 2 * DataInnerNode::MAX_STORED_CHILDREN * DataInnerNode::MAX_STORED_CHILDREN); + EXPECT_TRAVERSE_LEAF(LoadInnerNode(thirdChild->getChild(1)->key())->getChild(0)->key(), 2 * DataInnerNode::MAX_STORED_CHILDREN * DataInnerNode::MAX_STORED_CHILDREN + DataInnerNode::MAX_STORED_CHILDREN); + + TraverseLeaves(root.get(), 0, 2*DataInnerNode::MAX_STORED_CHILDREN*DataInnerNode::MAX_STORED_CHILDREN + DataInnerNode::MAX_STORED_CHILDREN + 1); +} + +//TODO Traverse inner part of four level tree +//TODO Refactor the test cases that are too long