rbtree_unittest.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <gtest/gtest.h>
  15. #include <exceptions/exceptions.h>
  16. #include <dns/name.h>
  17. #include <dns/rrclass.h>
  18. #include <dns/rrset.h>
  19. #include <dns/rrtype.h>
  20. #include <dns/rrttl.h>
  21. #include <datasrc/rbtree.h>
  22. #include <dns/tests/unittest_util.h>
  23. using namespace std;
  24. using namespace isc;
  25. using namespace isc::dns;
  26. using isc::UnitTestUtil;
  27. using namespace isc::datasrc;
  28. // XXX: some compilers cannot find class static constants used in
  29. // EXPECT_xxx macros, for which we need an explicit empty definition.
  30. const size_t Name::MAX_LABELS;
  31. /* The initial structure of rbtree
  32. *
  33. * b
  34. * / \
  35. * a d.e.f
  36. * / | \
  37. * c | g.h
  38. * | |
  39. * w.y i
  40. * / | \ \
  41. * x | z k
  42. * | |
  43. * p j
  44. * / \
  45. * o q
  46. */
  47. namespace {
  48. class RBTreeTest : public::testing::Test {
  49. protected:
  50. RBTreeTest() : rbtree_expose_empty_node(true), crbtnode(NULL) {
  51. const char* const domain_names[] = {
  52. "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f",
  53. "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
  54. int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
  55. for (int i = 0; i < name_count; ++i) {
  56. rbtree.insert(Name(domain_names[i]), &rbtnode);
  57. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(i + 1)));
  58. rbtree_expose_empty_node.insert(Name(domain_names[i]), &rbtnode);
  59. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(i + 1)));
  60. }
  61. }
  62. RBTree<int> rbtree;
  63. RBTree<int> rbtree_expose_empty_node;
  64. RBNode<int>* rbtnode;
  65. const RBNode<int>* crbtnode;
  66. };
  67. TEST_F(RBTreeTest, getNodeCount) {
  68. EXPECT_EQ(14, rbtree.getNodeCount());
  69. }
  70. TEST_F(RBTreeTest, setGetData) {
  71. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(11)));
  72. EXPECT_EQ(11, *(rbtnode->getData()));
  73. }
  74. TEST_F(RBTreeTest, insertNames) {
  75. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("d.e.f"),
  76. &rbtnode));
  77. EXPECT_EQ(Name("d.e.f"), rbtnode->getName());
  78. EXPECT_EQ(14, rbtree.getNodeCount());
  79. //insert not exist node
  80. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("."), &rbtnode));
  81. EXPECT_EQ(Name("."), rbtnode->getName());
  82. EXPECT_EQ(15, rbtree.getNodeCount());
  83. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("example.com"), &rbtnode));
  84. EXPECT_EQ(16, rbtree.getNodeCount());
  85. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(12)));
  86. // return ALREADYEXISTS, since node "example.com" already has been explicitly inserted
  87. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("example.com"), &rbtnode));
  88. EXPECT_EQ(16, rbtree.getNodeCount());
  89. // split the node "d.e.f"
  90. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("k.e.f"), &rbtnode));
  91. EXPECT_EQ(Name("k"), rbtnode->getName());
  92. EXPECT_EQ(18, rbtree.getNodeCount());
  93. // split the node "g.h"
  94. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("h"), &rbtnode));
  95. EXPECT_EQ(Name("h"), rbtnode->getName());
  96. EXPECT_EQ(19, rbtree.getNodeCount());
  97. // add child domain
  98. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("m.p.w.y.d.e.f"), &rbtnode));
  99. EXPECT_EQ(Name("m"), rbtnode->getName());
  100. EXPECT_EQ(20, rbtree.getNodeCount());
  101. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("n.p.w.y.d.e.f"), &rbtnode));
  102. EXPECT_EQ(Name("n"), rbtnode->getName());
  103. EXPECT_EQ(21, rbtree.getNodeCount());
  104. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("l.a"), &rbtnode));
  105. EXPECT_EQ(Name("l"), rbtnode->getName());
  106. EXPECT_EQ(22, rbtree.getNodeCount());
  107. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("r.d.e.f"), &rbtnode));
  108. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("s.d.e.f"), &rbtnode));
  109. EXPECT_EQ(24, rbtree.getNodeCount());
  110. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("h.w.y.d.e.f"), &rbtnode));
  111. // add more nodes one by one to cover leftRotate and rightRotate
  112. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("f"), &rbtnode));
  113. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("m"), &rbtnode));
  114. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("nm"), &rbtnode));
  115. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("om"), &rbtnode));
  116. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("k"), &rbtnode));
  117. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("l"), &rbtnode));
  118. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("fe"), &rbtnode));
  119. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("ge"), &rbtnode));
  120. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("i"), &rbtnode));
  121. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("ae"), &rbtnode));
  122. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("n"), &rbtnode));
  123. }
  124. TEST_F(RBTreeTest, findName) {
  125. // find const rbtnode
  126. // exact match
  127. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("a"), &crbtnode));
  128. EXPECT_EQ(Name("a"), crbtnode->getName());
  129. // not found
  130. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("d.e.f"), &crbtnode));
  131. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("y.d.e.f"), &crbtnode));
  132. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("x"), &crbtnode));
  133. EXPECT_EQ(RBTree<int>::NOTFOUND, rbtree.find(Name("m.n"), &crbtnode));
  134. // if we expose empty node, we can get the empty node created during insert
  135. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  136. rbtree_expose_empty_node.find(Name("d.e.f"), &crbtnode));
  137. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  138. rbtree_expose_empty_node.find(Name("w.y.d.e.f"), &crbtnode));
  139. // partial match
  140. EXPECT_EQ(RBTree<int>::PARTIALMATCH, rbtree.find(Name("m.b"), &crbtnode));
  141. EXPECT_EQ(Name("b"), crbtnode->getName());
  142. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  143. rbtree_expose_empty_node.find(Name("m.d.e.f"), &crbtnode));
  144. // find rbtnode
  145. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("q.w.y.d.e.f"), &rbtnode));
  146. EXPECT_EQ(Name("q"), rbtnode->getName());
  147. }
  148. TEST_F(RBTreeTest, findError) {
  149. // For the version that takes a node chain, the chain must be empty.
  150. RBTreeNodeChain<int> chain;
  151. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("a"), &crbtnode,
  152. chain));
  153. // trying to reuse the same chain. it should result in an exception.
  154. EXPECT_THROW(rbtree.find(Name("a"), &crbtnode, chain),
  155. BadValue);
  156. }
  157. TEST_F(RBTreeTest, flags) {
  158. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("flags.example"),
  159. &rbtnode));
  160. // by default, flags are all off
  161. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  162. // set operation, by default it enables the flag
  163. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  164. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  165. // try disable the flag explicitly
  166. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK, false);
  167. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  168. // try enable the flag explicitly
  169. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK, true);
  170. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  171. // setting an unknown flag will trigger an exception
  172. EXPECT_THROW(rbtnode->setFlag(static_cast<RBNode<int>::Flags>(2), true),
  173. isc::InvalidParameter);
  174. }
  175. bool
  176. testCallback(const RBNode<int>&, bool* callack_checker) {
  177. *callack_checker = true;
  178. return (false);
  179. }
  180. TEST_F(RBTreeTest, callback) {
  181. // by default callback isn't enabled
  182. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("callback.example"),
  183. &rbtnode));
  184. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
  185. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  186. // enable/re-disable callback
  187. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  188. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  189. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK, false);
  190. EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  191. // enable again for subsequent tests
  192. rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  193. // add more levels below and above the callback node for partial match.
  194. RBNode<int>* subrbtnode;
  195. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("sub.callback.example"),
  196. &subrbtnode));
  197. subrbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
  198. RBNode<int>* parentrbtnode;
  199. EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("example"),
  200. &parentrbtnode));
  201. // the chilld/parent nodes shouldn't "inherit" the callback flag.
  202. // "rbtnode" may be invalid due to the insertion, so we need to re-find
  203. // it.
  204. EXPECT_EQ(RBTree<int>::EXACTMATCH, rbtree.find(Name("callback.example"),
  205. &rbtnode));
  206. EXPECT_TRUE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  207. EXPECT_FALSE(subrbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  208. EXPECT_FALSE(parentrbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
  209. // check if the callback is called from find()
  210. RBTreeNodeChain<int> node_path1;
  211. bool callback_called = false;
  212. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  213. rbtree.find(Name("sub.callback.example"), &crbtnode, node_path1,
  214. testCallback, &callback_called));
  215. EXPECT_TRUE(callback_called);
  216. // enable callback at the parent node, but it doesn't have data so
  217. // the callback shouldn't be called.
  218. RBTreeNodeChain<int> node_path2;
  219. parentrbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
  220. callback_called = false;
  221. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  222. rbtree.find(Name("callback.example"), &crbtnode, node_path2,
  223. testCallback, &callback_called));
  224. EXPECT_FALSE(callback_called);
  225. }
  226. TEST_F(RBTreeTest, chainLevel) {
  227. RBTreeNodeChain<int> chain;
  228. // by default there should be no level in the chain.
  229. EXPECT_EQ(0, chain.getLevelCount());
  230. // insert one node to the tree and find it. there should be exactly
  231. // one level in the chain.
  232. RBTree<int> tree(true);
  233. Name node_name(Name::ROOT_NAME());
  234. EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(node_name, &rbtnode));
  235. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  236. tree.find(node_name, &crbtnode, chain));
  237. EXPECT_EQ(1, chain.getLevelCount());
  238. /*
  239. * Now creating a possibly deepest tree with MAX_LABELS levels.
  240. * it should look like:
  241. * (.)
  242. * |
  243. * a
  244. * |
  245. * a
  246. * : (MAX_LABELS - 1) "a"'s
  247. *
  248. * then confirm that find() for the deepest name succeeds without any
  249. * disruption, and the resulting chain has the expected level.
  250. * Note that the root name (".") solely belongs to a single level,
  251. * so the levels begin with 2.
  252. */
  253. for (unsigned int i = 2; i <= Name::MAX_LABELS; ++i) {
  254. node_name = Name("a.").concatenate(node_name);
  255. EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(node_name, &rbtnode));
  256. RBTreeNodeChain<int> found_chain;
  257. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  258. tree.find(node_name, &crbtnode, found_chain));
  259. EXPECT_EQ(i, found_chain.getLevelCount());
  260. }
  261. // Confirm the last inserted name has the possible maximum length with
  262. // maximum label count. This confirms the rbtree and chain level cannot
  263. // be larger.
  264. EXPECT_EQ(Name::MAX_LABELS, node_name.getLabelCount());
  265. EXPECT_THROW(node_name.concatenate(Name("a.")), TooLongName);
  266. }
  267. TEST_F(RBTreeTest, getAbsoluteNameError) {
  268. // an empty chain isn't allowed.
  269. RBTreeNodeChain<int> chain;
  270. EXPECT_THROW(chain.getAbsoluteName(), BadValue);
  271. }
  272. /*
  273. *the domain order should be:
  274. * a, b, c, d.e.f, x.d.e.f, w.y.d.e.f, o.w.y.d.e.f, p.w.y.d.e.f, q.w.y.d.e.f,
  275. * z.d.e.f, j.z.d.e.f, g.h, i.g.h, k.g.h
  276. * b
  277. * / \
  278. * a d.e.f
  279. * / | \
  280. * c | g.h
  281. * | |
  282. * w.y i
  283. * / | \ \
  284. * x | z k
  285. * | |
  286. * p j
  287. * / \
  288. * o q
  289. */
  290. const char* const names[] = {
  291. "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f",
  292. "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f",
  293. "g.h", "i.g.h", "k.g.h"};
  294. const size_t name_count(sizeof(names) / sizeof(*names));
  295. TEST_F(RBTreeTest, nextNode) {
  296. RBTreeNodeChain<int> node_path;
  297. const RBNode<int>* node = NULL;
  298. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  299. rbtree.find(Name(names[0]), &node, node_path));
  300. for (int i = 0; i < name_count; ++i) {
  301. EXPECT_NE(static_cast<void*>(NULL), node);
  302. EXPECT_EQ(Name(names[i]), node_path.getAbsoluteName());
  303. node = rbtree.nextNode(node_path);
  304. }
  305. // We should have reached the end of the tree.
  306. EXPECT_EQ(static_cast<void*>(NULL), node);
  307. }
  308. // Just walk using previousNode until the beginning of the tree and check it is
  309. // OK
  310. //
  311. // rbtree - the tree to walk
  312. // node - result of previous call to find(), starting position of the walk
  313. // node_path - the path from the previous call to find(), will be modified
  314. // chain_length - the number of names that should be in the chain to be walked
  315. // (0 means it should be empty, 3 means 'a', 'b' and 'c' should be there -
  316. // this is always from the beginning of the names[] list).
  317. // skip_first - if this is false, the node should already contain the node with
  318. // the first name of the chain. If it is true, the node should be NULL
  319. // (true is for finds that return no match, false for the ones that return
  320. // match)
  321. void
  322. previousWalk(RBTree<int>& rbtree, const RBNode<int>* node,
  323. RBTreeNodeChain<int>& node_path, size_t chain_length,
  324. bool skip_first)
  325. {
  326. if (skip_first) {
  327. // If the first is not found, this is supposed to be NULL and we skip
  328. // it in our checks.
  329. EXPECT_EQ(static_cast<void*>(NULL), node);
  330. node = rbtree.previousNode(node_path);
  331. }
  332. for (size_t i(chain_length); i > 0; --i) {
  333. EXPECT_NE(static_cast<void*>(NULL), node);
  334. EXPECT_EQ(Name(names[i - 1]), node_path.getAbsoluteName());
  335. // Find the node at the path and check the value is the same
  336. // (that it really returns the correct corresponding node)
  337. //
  338. // The "empty" nodes can not be found
  339. if (node->getData()) {
  340. const RBNode<int>* node2(NULL);
  341. RBTreeNodeChain<int> node_path2;
  342. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  343. rbtree.find(Name(names[i - 1]), &node2, node_path2));
  344. EXPECT_EQ(node, node2);
  345. }
  346. node = rbtree.previousNode(node_path);
  347. }
  348. // We should have reached the start of the tree.
  349. EXPECT_EQ(static_cast<void*>(NULL), node);
  350. // Calling previousNode() yet again should still return NULL without
  351. // fail.
  352. node = rbtree.previousNode(node_path);
  353. EXPECT_EQ(static_cast<void*>(NULL), node);
  354. }
  355. // Check the previousNode
  356. TEST_F(RBTreeTest, previousNode) {
  357. // First, iterate the whole tree from the end to the beginning.
  358. RBTreeNodeChain<int> node_path;
  359. EXPECT_THROW(rbtree.previousNode(node_path), isc::BadValue) <<
  360. "Throw before a search was done on the path";
  361. const RBNode<int>* node(NULL);
  362. {
  363. SCOPED_TRACE("Iterate through");
  364. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  365. rbtree.find(Name(names[name_count - 1]), &node, node_path));
  366. previousWalk(rbtree, node, node_path, name_count, false);
  367. node = NULL;
  368. node_path.clear();
  369. }
  370. {
  371. SCOPED_TRACE("Iterate from the middle");
  372. // Now, start somewhere in the middle, but within the real node.
  373. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  374. rbtree.find(Name(names[4]), &node, node_path));
  375. previousWalk(rbtree, node, node_path, 5, false);
  376. node = NULL;
  377. node_path.clear();
  378. }
  379. {
  380. SCOPED_TRACE("Start at the first");
  381. // If we start at the lowest (which is "a"), we get to the beginning
  382. // right away.
  383. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  384. rbtree.find(Name(names[0]), &node, node_path));
  385. EXPECT_NE(static_cast<void*>(NULL), node);
  386. EXPECT_EQ(static_cast<void*>(NULL), rbtree.previousNode(node_path));
  387. node = NULL;
  388. node_path.clear();
  389. }
  390. {
  391. SCOPED_TRACE("Start before the first");
  392. // If we start before the lowest (0 < a), we should not get a node nor
  393. EXPECT_EQ(RBTree<int>::NOTFOUND,
  394. rbtree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
  395. EXPECT_EQ(static_cast<void*>(NULL), node);
  396. EXPECT_EQ(static_cast<void*>(NULL), rbtree.previousNode(node_path));
  397. node = NULL;
  398. node_path.clear();
  399. }
  400. {
  401. SCOPED_TRACE("Start after the last");
  402. EXPECT_EQ(RBTree<int>::NOTFOUND,
  403. rbtree.find(Name("z"), &node, node_path));
  404. previousWalk(rbtree, node, node_path, name_count, true);
  405. node = NULL;
  406. node_path.clear();
  407. }
  408. {
  409. SCOPED_TRACE("Start below a leaf");
  410. // We exit a leaf by going down. We should start by the one
  411. // we exited - 'c' (actually, we should get it by the find, as partial
  412. // match).
  413. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  414. rbtree.find(Name("b.c"), &node, node_path));
  415. previousWalk(rbtree, node, node_path, 3, false);
  416. node = NULL;
  417. node_path.clear();
  418. }
  419. {
  420. SCOPED_TRACE("Start to the right of a leaf");
  421. // When searching for this, we exit the 'x' node to the right side,
  422. // so we should go x afterwards.
  423. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  424. // and not PARTIALMATCH.
  425. EXPECT_EQ(RBTree<int>::NOTFOUND,
  426. rbtree.find(Name("xy.d.e.f"), &node, node_path));
  427. previousWalk(rbtree, node, node_path, 5, true);
  428. node = NULL;
  429. node_path.clear();
  430. }
  431. {
  432. SCOPED_TRACE("Start to the left of a leaf");
  433. // This is similar to the previous, but we exit the 'z' leaf to the
  434. // left side, so should not visit z at all then.
  435. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  436. // and not PARTIALMATCH.
  437. EXPECT_EQ(RBTree<int>::NOTFOUND,
  438. rbtree.find(Name("yz.d.e.f"), &node, node_path));
  439. previousWalk(rbtree, node, node_path, 9, true);
  440. node = NULL;
  441. node_path.clear();
  442. }
  443. {
  444. SCOPED_TRACE("Start to the right of a parent");
  445. // When searching for this, we exit the 'g.h' node to the right
  446. // side, so we should go to g.h's children afterwards.
  447. // 'g.h' is an empty node, so we get a NOTFOUND and not
  448. // PARTIALMATCH.
  449. EXPECT_EQ(RBTree<int>::NOTFOUND,
  450. rbtree.find(Name("x.h"), &node, node_path));
  451. // 'g.h' is the COMMONANCESTOR.
  452. EXPECT_EQ(node_path.getLastComparedNode()->getName(), Name("g.h"));
  453. EXPECT_EQ(NameComparisonResult::COMMONANCESTOR,
  454. node_path.getLastComparisonResult().getRelation());
  455. // find() exits to the right of 'g.h'
  456. EXPECT_GT(node_path.getLastComparisonResult().getOrder(), 0);
  457. // We then descend into 'i.g.h' and walk all the nodes in the
  458. // tree.
  459. previousWalk(rbtree, node, node_path, name_count, true);
  460. node = NULL;
  461. node_path.clear();
  462. }
  463. {
  464. SCOPED_TRACE("Start inside a wrong node");
  465. // The d.e.f is a single node, but we want only part of it. We
  466. // should start iterating before it.
  467. EXPECT_EQ(RBTree<int>::NOTFOUND,
  468. rbtree.find(Name("e.f"), &node, node_path));
  469. previousWalk(rbtree, node, node_path, 3, true);
  470. node = NULL;
  471. node_path.clear();
  472. }
  473. {
  474. SCOPED_TRACE("Lookup in empty tree");
  475. // Just check it doesn't crash, etc.
  476. RBTree<int> empty_tree;
  477. EXPECT_EQ(RBTree<int>::NOTFOUND,
  478. empty_tree.find(Name("x"), &node, node_path));
  479. EXPECT_EQ(static_cast<void*>(NULL), node);
  480. EXPECT_EQ(static_cast<void*>(NULL),
  481. empty_tree.previousNode(node_path));
  482. node = NULL;
  483. node_path.clear();
  484. }
  485. }
  486. TEST_F(RBTreeTest, nextNodeError) {
  487. // Empty chain for nextNode() is invalid.
  488. RBTreeNodeChain<int> chain;
  489. EXPECT_THROW(rbtree.nextNode(chain), BadValue);
  490. }
  491. // A helper function for getLastComparedNode() below.
  492. void
  493. comparisonChecks(const RBTreeNodeChain<int>& chain,
  494. int expected_order, int expected_common_labels,
  495. NameComparisonResult::NameRelation expected_reln)
  496. {
  497. if (expected_order > 0) {
  498. EXPECT_LT(0, chain.getLastComparisonResult().getOrder());
  499. } else if (expected_order < 0) {
  500. EXPECT_GT(0, chain.getLastComparisonResult().getOrder());
  501. } else {
  502. EXPECT_EQ(0, chain.getLastComparisonResult().getOrder());
  503. }
  504. EXPECT_EQ(expected_common_labels,
  505. chain.getLastComparisonResult().getCommonLabels());
  506. EXPECT_EQ(expected_reln,
  507. chain.getLastComparisonResult().getRelation());
  508. }
  509. TEST_F(RBTreeTest, getLastComparedNode) {
  510. RBTree<int>& tree = rbtree_expose_empty_node; // use the "empty OK" mode
  511. RBTreeNodeChain<int> chain;
  512. // initially there should be no 'last compared'.
  513. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  514. // A search for an empty tree should result in no 'last compared', too.
  515. RBTree<int> empty_tree;
  516. EXPECT_EQ(RBTree<int>::NOTFOUND,
  517. empty_tree.find(Name("a"), &crbtnode, chain));
  518. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  519. chain.clear();
  520. const RBNode<int>* expected_node = NULL;
  521. // Exact match case. The returned node should be last compared.
  522. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  523. tree.find(Name("x.d.e.f"), &expected_node, chain));
  524. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  525. // 2 = # labels of "x."
  526. comparisonChecks(chain, 0, 2, NameComparisonResult::EQUAL);
  527. chain.clear();
  528. // Partial match, search stopped at the matching node, which should be
  529. // the last compared node.
  530. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  531. tree.find(Name("k.g.h"), &expected_node));
  532. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  533. tree.find(Name("x.k.g.h"), &crbtnode, chain));
  534. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  535. // k.g.h < x.k.g.h, 2 = # labels of "k."
  536. comparisonChecks(chain, 1, 2, NameComparisonResult::SUBDOMAIN);
  537. chain.clear();
  538. // Partial match, search stopped in the subtree below the matching node
  539. // after following a left branch.
  540. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  541. tree.find(Name("x.d.e.f"), &expected_node));
  542. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  543. tree.find(Name("a.d.e.f"), &crbtnode, chain));
  544. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  545. // a < x, 1 = # labels of "." (trailing dot)
  546. comparisonChecks(chain, -1, 1, NameComparisonResult::COMMONANCESTOR);
  547. chain.clear();
  548. // Partial match, search stopped in the subtree below the matching node
  549. // after following a right branch.
  550. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  551. tree.find(Name("z.d.e.f"), &expected_node));
  552. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  553. tree.find(Name("zz.d.e.f"), &crbtnode, chain));
  554. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  555. // zz > z, 1 = # labels of "." (trailing dot)
  556. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  557. chain.clear();
  558. // Partial match, search stopped at a node for a super domain of the
  559. // search name in the subtree below the matching node.
  560. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  561. tree.find(Name("w.y.d.e.f"), &expected_node));
  562. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  563. tree.find(Name("y.d.e.f"), &crbtnode, chain));
  564. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  565. // y < w.y, 2 = # labels of "y."
  566. comparisonChecks(chain, -1, 2, NameComparisonResult::SUPERDOMAIN);
  567. chain.clear();
  568. // Partial match, search stopped at a node that share a common ancestor
  569. // with the search name in the subtree below the matching node.
  570. // (the expected node is the same as the previous case)
  571. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  572. tree.find(Name("z.y.d.e.f"), &crbtnode, chain));
  573. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  574. // z.y > w.y, 2 = # labels of "y."
  575. comparisonChecks(chain, 1, 2, NameComparisonResult::COMMONANCESTOR);
  576. chain.clear();
  577. // Search stops in the highest level after following a left branch.
  578. EXPECT_EQ(RBTree<int>::EXACTMATCH, tree.find(Name("c"), &expected_node));
  579. EXPECT_EQ(RBTree<int>::NOTFOUND,
  580. tree.find(Name("bb"), &crbtnode, chain));
  581. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  582. // bb < c, 1 = # labels of "." (trailing dot)
  583. comparisonChecks(chain, -1, 1, NameComparisonResult::COMMONANCESTOR);
  584. chain.clear();
  585. // Search stops in the highest level after following a right branch.
  586. // (the expected node is the same as the previous case)
  587. EXPECT_EQ(RBTree<int>::NOTFOUND,
  588. tree.find(Name("d"), &crbtnode, chain));
  589. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  590. // d > c, 1 = # labels of "." (trailing dot)
  591. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  592. chain.clear();
  593. }
  594. TEST_F(RBTreeTest, dumpTree) {
  595. std::ostringstream str;
  596. std::ostringstream str2;
  597. rbtree.dumpTree(str);
  598. str2 << "tree has 14 node(s)\n"
  599. "b. (black) [subtreeroot]\n"
  600. " a. (black)\n"
  601. " NULL\n"
  602. " NULL\n"
  603. " d.e.f. (black) [invisible]\n"
  604. " begin down from d.e.f.\n"
  605. " w.y. (black) [invisible] [subtreeroot]\n"
  606. " begin down from w.y.\n"
  607. " p. (black) [subtreeroot]\n"
  608. " o. (red)\n"
  609. " NULL\n"
  610. " NULL\n"
  611. " q. (red)\n"
  612. " NULL\n"
  613. " NULL\n"
  614. " end down from w.y.\n"
  615. " x. (red)\n"
  616. " NULL\n"
  617. " NULL\n"
  618. " z. (red)\n"
  619. " begin down from z.\n"
  620. " j. (black) [subtreeroot]\n"
  621. " NULL\n"
  622. " NULL\n"
  623. " end down from z.\n"
  624. " NULL\n"
  625. " NULL\n"
  626. " end down from d.e.f.\n"
  627. " c. (red)\n"
  628. " NULL\n"
  629. " NULL\n"
  630. " g.h. (red)\n"
  631. " begin down from g.h.\n"
  632. " i. (black) [subtreeroot]\n"
  633. " NULL\n"
  634. " k. (red)\n"
  635. " NULL\n"
  636. " NULL\n"
  637. " end down from g.h.\n"
  638. " NULL\n"
  639. " NULL\n";
  640. EXPECT_EQ(str2.str(), str.str());
  641. }
  642. TEST_F(RBTreeTest, swap) {
  643. // Store info about the first tree
  644. std::ostringstream str1;
  645. rbtree.dumpTree(str1);
  646. size_t count1(rbtree.getNodeCount());
  647. // Create second one and store state
  648. RBTree<int> tree2;
  649. RBNode<int>* node;
  650. tree2.insert(Name("second"), &node);
  651. std::ostringstream str2;
  652. tree2.dumpTree(str2);
  653. // Swap them
  654. ASSERT_NO_THROW(tree2.swap(rbtree));
  655. // Check their sizes
  656. ASSERT_EQ(1, rbtree.getNodeCount());
  657. ASSERT_EQ(count1, tree2.getNodeCount());
  658. // And content
  659. std::ostringstream out;
  660. rbtree.dumpTree(out);
  661. ASSERT_EQ(str2.str(), out.str());
  662. out.str("");
  663. tree2.dumpTree(out);
  664. ASSERT_EQ(str1.str(), out.str());
  665. }
  666. // Matching in the "root zone" may be special (e.g. there's no parent,
  667. // any domain names should be considered a subdomain of it), so it makes
  668. // sense to test cases with the root zone explicitly.
  669. TEST_F(RBTreeTest, root) {
  670. RBTree<int> root;
  671. root.insert(Name::ROOT_NAME(), &rbtnode);
  672. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
  673. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  674. root.find(Name::ROOT_NAME(), &crbtnode));
  675. EXPECT_EQ(rbtnode, crbtnode);
  676. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  677. root.find(Name("example.com"), &crbtnode));
  678. EXPECT_EQ(rbtnode, crbtnode);
  679. // Insert a new name that better matches the query name. find() should
  680. // find the better one.
  681. root.insert(Name("com"), &rbtnode);
  682. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
  683. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  684. root.find(Name("example.com"), &crbtnode));
  685. EXPECT_EQ(rbtnode, crbtnode);
  686. // Perform the same tests for the tree that allows matching against empty
  687. // nodes.
  688. RBTree<int> root_emptyok(true);
  689. root_emptyok.insert(Name::ROOT_NAME(), &rbtnode);
  690. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  691. root_emptyok.find(Name::ROOT_NAME(), &crbtnode));
  692. EXPECT_EQ(rbtnode, crbtnode);
  693. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  694. root_emptyok.find(Name("example.com"), &crbtnode));
  695. EXPECT_EQ(rbtnode, crbtnode);
  696. root.insert(Name("com"), &rbtnode);
  697. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  698. root.find(Name("example.com"), &crbtnode));
  699. EXPECT_EQ(rbtnode, crbtnode);
  700. }
  701. }