rbtree_unittest.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  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
  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"};
  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(13, 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(13, 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(14, rbtree.getNodeCount());
  83. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("example.com"), &rbtnode));
  84. EXPECT_EQ(15, 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(15, 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(17, 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(18, 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(19, 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(20, rbtree.getNodeCount());
  104. EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("l.a"), &rbtnode));
  105. EXPECT_EQ(Name("l"), rbtnode->getName());
  106. EXPECT_EQ(21, 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(23, 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<void*>(Name("a"), &crbtnode,
  152. chain, NULL, NULL));
  153. // trying to reuse the same chain. it should result in an exception.
  154. EXPECT_THROW(rbtree.find<void*>(Name("a"), &crbtnode, chain, NULL, NULL),
  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<void*>(node_name, &crbtnode, chain, NULL, NULL));
  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<void*>(node_name, &crbtnode, found_chain,
  259. NULL, NULL));
  260. EXPECT_EQ(i, found_chain.getLevelCount());
  261. }
  262. // Confirm the last inserted name has the possible maximum length with
  263. // maximum label count. This confirms the rbtree and chain level cannot
  264. // be larger.
  265. EXPECT_EQ(Name::MAX_LABELS, node_name.getLabelCount());
  266. EXPECT_THROW(node_name.concatenate(Name("a.")), TooLongName);
  267. }
  268. TEST_F(RBTreeTest, getAbsoluteNameError) {
  269. // an empty chain isn't allowed.
  270. RBTreeNodeChain<int> chain;
  271. EXPECT_THROW(chain.getAbsoluteName(), BadValue);
  272. }
  273. /*
  274. *the domain order should be:
  275. * 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,
  276. * z.d.e.f, j.z.d.e.f, g.h, i.g.h
  277. * b
  278. * / \
  279. * a d.e.f
  280. * / | \
  281. * c | g.h
  282. * | |
  283. * w.y i
  284. * / | \
  285. * x | z
  286. * | |
  287. * p j
  288. * / \
  289. * o q
  290. */
  291. const char* const names[] = {
  292. "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f",
  293. "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f", "g.h", "i.g.h"};
  294. const size_t name_count(sizeof(names) / sizeof(*names));
  295. TEST_F(RBTreeTest, nextNode) {
  296. const char* const names[] = {
  297. "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f",
  298. "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f", "g.h", "i.g.h"};
  299. const int name_count = sizeof(names) / sizeof(names[0]);
  300. RBTreeNodeChain<int> node_path;
  301. const RBNode<int>* node = NULL;
  302. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  303. rbtree.find<void*>(Name(names[0]), &node, node_path, NULL,
  304. NULL));
  305. for (int i = 0; i < name_count; ++i) {
  306. EXPECT_NE(static_cast<void*>(NULL), node);
  307. EXPECT_EQ(Name(names[i]), node_path.getAbsoluteName());
  308. node = rbtree.nextNode(node_path);
  309. }
  310. // We should have reached the end of the tree.
  311. EXPECT_EQ(static_cast<void*>(NULL), node);
  312. }
  313. // Just walk using previousNode until the beginning of the tree and check it is
  314. // OK
  315. //
  316. // rbtree - the tree to walk
  317. // node - result of previous call to find(), starting position of the walk
  318. // node_path - the path from the previous call to find(), will be modified
  319. // chain_length - the number of names that should be in the chain to be walked
  320. // (0 means it should be empty, 3 means 'a', 'b' and 'c' should be there -
  321. // this is always from the beginning of the names[] list).
  322. // skip_first - if this is false, the node should already contain the node with
  323. // the first name of the chain. If it is true, the node should be NULL
  324. // (true is for finds that return no match, false for the ones that return
  325. // match)
  326. void
  327. previousWalk(RBTree<int>& rbtree, const RBNode<int>* node,
  328. RBTreeNodeChain<int>& node_path, size_t chain_length,
  329. bool skip_first)
  330. {
  331. if (skip_first) {
  332. // If the first is not found, this is supposed to be NULL and we skip
  333. // it in our checks.
  334. EXPECT_EQ(static_cast<void*>(NULL), node);
  335. node = rbtree.previousNode(node_path);
  336. }
  337. for (size_t i(chain_length); i > 0; --i) {
  338. EXPECT_NE(static_cast<void*>(NULL), node);
  339. EXPECT_EQ(Name(names[i - 1]), node_path.getAbsoluteName());
  340. // Find the node at the path and check the value is the same
  341. // (that it really returns the correct corresponding node)
  342. //
  343. // The "empty" nodes can not be found
  344. if (node->getData()) {
  345. const RBNode<int>* node2(NULL);
  346. RBTreeNodeChain<int> node_path2;
  347. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  348. rbtree.find<void*>(Name(names[i - 1]), &node2,
  349. node_path2, NULL, NULL));
  350. EXPECT_EQ(node, node2);
  351. }
  352. node = rbtree.previousNode(node_path);
  353. }
  354. // We should have reached the end of the tree.
  355. EXPECT_EQ(static_cast<void*>(NULL), node);
  356. // This is all the same then
  357. EXPECT_EQ(static_cast<void*>(NULL), node);
  358. }
  359. // Check the previousNode
  360. TEST_F(RBTreeTest, previousNode) {
  361. // First, iterate the whole tree from the end to the beginning.
  362. RBTreeNodeChain<int> node_path;
  363. EXPECT_THROW(rbtree.previousNode(node_path), isc::BadValue) <<
  364. "Throw before a search was done on the path";
  365. const RBNode<int>* node(NULL);
  366. {
  367. SCOPED_TRACE("Iterate through");
  368. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  369. rbtree.find<void*>(Name(names[name_count - 1]), &node,
  370. node_path, NULL, NULL));
  371. previousWalk(rbtree, node, node_path, name_count, false);
  372. node = NULL;
  373. node_path.clear();
  374. }
  375. {
  376. SCOPED_TRACE("Iterate from the middle");
  377. // Now, start somewhere in the middle, but within the real node.
  378. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  379. rbtree.find<void*>(Name(names[4]), &node, node_path,
  380. NULL, NULL));
  381. previousWalk(rbtree, node, node_path, 5, false);
  382. node = NULL;
  383. node_path.clear();
  384. }
  385. {
  386. SCOPED_TRACE("Start at the first");
  387. // If we start at the lowest (which is "a"), we get to the beginning
  388. // right away.
  389. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  390. rbtree.find<void*>(Name(names[0]), &node, node_path, NULL,
  391. NULL));
  392. EXPECT_NE(static_cast<void*>(NULL), node);
  393. EXPECT_EQ(static_cast<void*>(NULL), rbtree.previousNode(node_path));
  394. node = NULL;
  395. node_path.clear();
  396. }
  397. {
  398. SCOPED_TRACE("Start before the first");
  399. // If we start before the lowest (0 < a), we should not get a node nor
  400. EXPECT_EQ(RBTree<int>::NOTFOUND,
  401. rbtree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
  402. EXPECT_EQ(static_cast<void*>(NULL), node);
  403. EXPECT_EQ(static_cast<void*>(NULL), rbtree.previousNode(node_path));
  404. node = NULL;
  405. node_path.clear();
  406. }
  407. {
  408. SCOPED_TRACE("Start after the last");
  409. EXPECT_EQ(RBTree<int>::NOTFOUND,
  410. rbtree.find<void*>(Name("z"), &node, node_path, NULL, NULL));
  411. previousWalk(rbtree, node, node_path, name_count, true);
  412. node = NULL;
  413. node_path.clear();
  414. }
  415. {
  416. SCOPED_TRACE("Start below a leaf");
  417. // We exit a leaf by going down. We should start by the one
  418. // we exited - 'c' (actually, we should get it by the find, as partial
  419. // match).
  420. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  421. rbtree.find<void*>(Name("b.c"), &node, node_path, NULL,
  422. NULL));
  423. previousWalk(rbtree, node, node_path, 3, false);
  424. node = NULL;
  425. node_path.clear();
  426. }
  427. {
  428. SCOPED_TRACE("Start to the right of a leaf");
  429. // When searching for this, we exit the 'x' node to the right side,
  430. // so we should go x afterwards.
  431. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  432. // and not PARTIALMATCH.
  433. EXPECT_EQ(RBTree<int>::NOTFOUND,
  434. rbtree.find<void*>(Name("xy.d.e.f"), &node, node_path,
  435. NULL, NULL));
  436. previousWalk(rbtree, node, node_path, 5, true);
  437. node = NULL;
  438. node_path.clear();
  439. }
  440. {
  441. SCOPED_TRACE("Start to the left of a leaf");
  442. // This is similar to the previous, but we exit the 'z' leaf to the
  443. // left side, so should not visit z at all then.
  444. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  445. // and not PARTIALMATCH.
  446. EXPECT_EQ(RBTree<int>::NOTFOUND,
  447. rbtree.find<void*>(Name("yz.d.e.f"), &node, node_path,
  448. NULL, NULL));
  449. previousWalk(rbtree, node, node_path, 9, true);
  450. node = NULL;
  451. node_path.clear();
  452. }
  453. {
  454. SCOPED_TRACE("Start inside a wrong node");
  455. // The d.e.f is a single node, but we want only part of it. We
  456. // should start iterating before it.
  457. EXPECT_EQ(RBTree<int>::NOTFOUND,
  458. rbtree.find<void*>(Name("e.f"), &node, node_path,
  459. NULL, NULL));
  460. previousWalk(rbtree, node, node_path, 3, true);
  461. node = NULL;
  462. node_path.clear();
  463. }
  464. {
  465. SCOPED_TRACE("Lookup in empty tree");
  466. // Just check it doesn't crash, etc.
  467. RBTree<int> empty_tree;
  468. EXPECT_EQ(RBTree<int>::NOTFOUND,
  469. empty_tree.find<void*>(Name("x"), &node, node_path,
  470. NULL, NULL));
  471. EXPECT_EQ(static_cast<void*>(NULL), node);
  472. EXPECT_EQ(static_cast<void*>(NULL),
  473. empty_tree.previousNode(node_path));
  474. node = NULL;
  475. node_path.clear();
  476. }
  477. }
  478. TEST_F(RBTreeTest, nextNodeError) {
  479. // Empty chain for nextNode() is invalid.
  480. RBTreeNodeChain<int> chain;
  481. EXPECT_THROW(rbtree.nextNode(chain), BadValue);
  482. }
  483. // A helper function for getLastComparedNode() below.
  484. void
  485. comparisonChecks(const RBTreeNodeChain<int>& chain,
  486. int expected_order, int expected_common_labels,
  487. NameComparisonResult::NameRelation expected_reln)
  488. {
  489. if (expected_order > 0) {
  490. EXPECT_LT(0, chain.getLastComparisonResult().getOrder());
  491. } else if (expected_order < 0) {
  492. EXPECT_GT(0, chain.getLastComparisonResult().getOrder());
  493. } else {
  494. EXPECT_EQ(0, chain.getLastComparisonResult().getOrder());
  495. }
  496. EXPECT_EQ(expected_common_labels,
  497. chain.getLastComparisonResult().getCommonLabels());
  498. EXPECT_EQ(expected_reln,
  499. chain.getLastComparisonResult().getRelation());
  500. }
  501. TEST_F(RBTreeTest, getLastComparedNode) {
  502. RBTree<int>& tree = rbtree_expose_empty_node; // use the "empty OK" mode
  503. RBTreeNodeChain<int> chain;
  504. // initially there should be no 'last compared'.
  505. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  506. // A search for an empty tree should result in no 'last compared', too.
  507. RBTree<int> empty_tree;
  508. EXPECT_EQ(RBTree<int>::NOTFOUND,
  509. empty_tree.find<void*>(Name("a"), &crbtnode, chain, NULL, NULL));
  510. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  511. chain.clear();
  512. const RBNode<int>* expected_node = NULL;
  513. // Exact match case. The returned node should be last compared.
  514. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  515. tree.find<void*>(Name("x.d.e.f"), &expected_node, chain,
  516. NULL, NULL));
  517. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  518. // 2 = # labels of "x."
  519. comparisonChecks(chain, 0, 2, NameComparisonResult::EQUAL);
  520. chain.clear();
  521. // Partial match, search stopped at the matching node, which should be
  522. // the last compared node.
  523. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  524. tree.find(Name("i.g.h"), &expected_node));
  525. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  526. tree.find<void*>(Name("x.i.g.h"), &crbtnode, chain,
  527. NULL, NULL));
  528. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  529. // i.g.h < x.i.g.h, 2 = # labels of "i."
  530. comparisonChecks(chain, 1, 2, NameComparisonResult::SUBDOMAIN);
  531. chain.clear();
  532. // Partial match, search stopped in the subtree below the matching node
  533. // after following a left branch.
  534. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  535. tree.find(Name("x.d.e.f"), &expected_node));
  536. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  537. tree.find<void*>(Name("a.d.e.f"), &crbtnode, chain,
  538. NULL, NULL));
  539. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  540. // a < x, 1 = # labels of "." (trailing dot)
  541. comparisonChecks(chain, -1, 1, NameComparisonResult::COMMONANCESTOR);
  542. chain.clear();
  543. // Partial match, search stopped in the subtree below the matching node
  544. // after following a right branch.
  545. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  546. tree.find(Name("z.d.e.f"), &expected_node));
  547. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  548. tree.find<void*>(Name("zz.d.e.f"), &crbtnode, chain,
  549. NULL, NULL));
  550. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  551. // zz > z, 1 = # labels of "." (trailing dot)
  552. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  553. chain.clear();
  554. // Partial match, search stopped at a node for a super domain of the
  555. // search name in the subtree below the matching node.
  556. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  557. tree.find(Name("w.y.d.e.f"), &expected_node));
  558. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  559. tree.find<void*>(Name("y.d.e.f"), &crbtnode, chain,
  560. NULL, NULL));
  561. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  562. // y < w.y, 2 = # labels of "y."
  563. comparisonChecks(chain, -1, 2, NameComparisonResult::SUPERDOMAIN);
  564. chain.clear();
  565. // Partial match, search stopped at a node that share a common ancestor
  566. // with the search name in the subtree below the matching node.
  567. // (the expected node is the same as the previous case)
  568. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  569. tree.find<void*>(Name("z.y.d.e.f"), &crbtnode, chain,
  570. NULL, NULL));
  571. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  572. // z.y > w.y, 2 = # labels of "y."
  573. comparisonChecks(chain, 1, 2, NameComparisonResult::COMMONANCESTOR);
  574. chain.clear();
  575. // Search stops in the highest level after following a left branch.
  576. EXPECT_EQ(RBTree<int>::EXACTMATCH, tree.find(Name("c"), &expected_node));
  577. EXPECT_EQ(RBTree<int>::NOTFOUND,
  578. tree.find<void*>(Name("bb"), &crbtnode, chain, NULL, NULL));
  579. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  580. // bb < c, 1 = # labels of "." (trailing dot)
  581. comparisonChecks(chain, -1, 1, NameComparisonResult::COMMONANCESTOR);
  582. chain.clear();
  583. // Search stops in the highest level after following a right branch.
  584. // (the expected node is the same as the previous case)
  585. EXPECT_EQ(RBTree<int>::NOTFOUND,
  586. tree.find<void*>(Name("d"), &crbtnode, chain, NULL, NULL));
  587. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  588. // d > c, 1 = # labels of "." (trailing dot)
  589. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  590. chain.clear();
  591. }
  592. TEST_F(RBTreeTest, dumpTree) {
  593. std::ostringstream str;
  594. std::ostringstream str2;
  595. rbtree.dumpTree(str);
  596. str2 << "tree has 13 node(s)\nb. (black)\n a. (black)\n NULL\n NULL\n d.e.f. (black)[invisible] \n begin down from d.e.f.\n w.y. (black)[invisible] \n begin down from w.y.\n p. (black)\n o. (red)\n NULL\n NULL\n q. (red)\n NULL\n NULL\n end down from w.y.\n x. (red)\n NULL\n NULL\n z. (red)\n begin down from z.\n j. (black)\n NULL\n NULL\n end down from z.\n NULL\n NULL\n end down from d.e.f.\n c. (red)\n NULL\n NULL\n g.h. (red)\n begin down from g.h.\n i. (black)\n NULL\n NULL\n end down from g.h.\n NULL\n NULL\n";
  597. EXPECT_EQ(str.str(), str2.str());
  598. }
  599. TEST_F(RBTreeTest, swap) {
  600. // Store info about the first tree
  601. std::ostringstream str1;
  602. rbtree.dumpTree(str1);
  603. size_t count1(rbtree.getNodeCount());
  604. // Create second one and store state
  605. RBTree<int> tree2;
  606. RBNode<int>* node;
  607. tree2.insert(Name("second"), &node);
  608. std::ostringstream str2;
  609. tree2.dumpTree(str2);
  610. // Swap them
  611. ASSERT_NO_THROW(tree2.swap(rbtree));
  612. // Check their sizes
  613. ASSERT_EQ(1, rbtree.getNodeCount());
  614. ASSERT_EQ(count1, tree2.getNodeCount());
  615. // And content
  616. std::ostringstream out;
  617. rbtree.dumpTree(out);
  618. ASSERT_EQ(str2.str(), out.str());
  619. out.str("");
  620. tree2.dumpTree(out);
  621. ASSERT_EQ(str1.str(), out.str());
  622. }
  623. // Matching in the "root zone" may be special (e.g. there's no parent,
  624. // any domain names should be considered a subdomain of it), so it makes
  625. // sense to test cases with the root zone explicitly.
  626. TEST_F(RBTreeTest, root) {
  627. RBTree<int> root;
  628. root.insert(Name::ROOT_NAME(), &rbtnode);
  629. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
  630. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  631. root.find(Name::ROOT_NAME(), &crbtnode));
  632. EXPECT_EQ(rbtnode, crbtnode);
  633. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  634. root.find(Name("example.com"), &crbtnode));
  635. EXPECT_EQ(rbtnode, crbtnode);
  636. // Insert a new name that better matches the query name. find() should
  637. // find the better one.
  638. root.insert(Name("com"), &rbtnode);
  639. rbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
  640. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  641. root.find(Name("example.com"), &crbtnode));
  642. EXPECT_EQ(rbtnode, crbtnode);
  643. // Perform the same tests for the tree that allows matching against empty
  644. // nodes.
  645. RBTree<int> root_emptyok(true);
  646. root_emptyok.insert(Name::ROOT_NAME(), &rbtnode);
  647. EXPECT_EQ(RBTree<int>::EXACTMATCH,
  648. root_emptyok.find(Name::ROOT_NAME(), &crbtnode));
  649. EXPECT_EQ(rbtnode, crbtnode);
  650. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  651. root_emptyok.find(Name("example.com"), &crbtnode));
  652. EXPECT_EQ(rbtnode, crbtnode);
  653. root.insert(Name("com"), &rbtnode);
  654. EXPECT_EQ(RBTree<int>::PARTIALMATCH,
  655. root.find(Name("example.com"), &crbtnode));
  656. EXPECT_EQ(rbtnode, crbtnode);
  657. }
  658. }