domaintree_unittest.cc 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  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 <util/memory_segment_local.h>
  17. #include <dns/name.h>
  18. #include <dns/rrclass.h>
  19. #include <dns/rrset.h>
  20. #include <dns/rrtype.h>
  21. #include <dns/rrttl.h>
  22. #include <datasrc/memory/domaintree.h>
  23. #include <dns/tests/unittest_util.h>
  24. using namespace std;
  25. using namespace isc;
  26. using namespace isc::dns;
  27. using isc::UnitTestUtil;
  28. using namespace isc::datasrc::memory;
  29. // XXX: some compilers cannot find class static constants used in
  30. // EXPECT_xxx macros, for which we need an explicit empty definition.
  31. const size_t Name::MAX_LABELS;
  32. /* The initial structure of dtree
  33. *
  34. * .
  35. * |
  36. * b
  37. * / \
  38. * a d.e.f
  39. * / | \
  40. * c | g.h
  41. * | |
  42. * w.y i
  43. * / | \ \
  44. * x | z k
  45. * | |
  46. * p j
  47. * / \
  48. * o q
  49. */
  50. namespace {
  51. void deleteData(int* i) {
  52. delete i;
  53. }
  54. typedef DomainTree<int> TestDomainTree;
  55. typedef DomainTreeNode<int> TestDomainTreeNode;
  56. typedef DomainTreeNodeChain<int> TestDomainTreeNodeChain;
  57. class TreeHolder {
  58. public:
  59. TreeHolder(util::MemorySegment& mem_sgmt, TestDomainTree* tree) :
  60. mem_sgmt_(mem_sgmt), tree_(tree)
  61. {}
  62. ~TreeHolder() {
  63. TestDomainTree::destroy(mem_sgmt_, tree_, deleteData);
  64. }
  65. TestDomainTree* get() { return (tree_); }
  66. private:
  67. util::MemorySegment& mem_sgmt_;
  68. TestDomainTree* tree_;
  69. };
  70. class DomainTreeTest : public::testing::Test {
  71. protected:
  72. DomainTreeTest() :
  73. dtree_holder_(mem_sgmt_, TestDomainTree::create(mem_sgmt_)),
  74. dtree_expose_empty_node_holder_(mem_sgmt_,
  75. TestDomainTree::create(mem_sgmt_, true)),
  76. dtree(*dtree_holder_.get()),
  77. dtree_expose_empty_node(*dtree_expose_empty_node_holder_.get()),
  78. cdtnode(NULL)
  79. {
  80. const char* const domain_names[] = {
  81. "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f",
  82. "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
  83. int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
  84. for (int i = 0; i < name_count; ++i) {
  85. dtree.insert(mem_sgmt_, Name(domain_names[i]), &dtnode);
  86. // Check the node doesn't have any data initially.
  87. EXPECT_EQ(static_cast<int*>(NULL),
  88. dtnode->setData(new int(i + 1)));
  89. dtree_expose_empty_node.insert(mem_sgmt_, Name(domain_names[i]),
  90. &dtnode);
  91. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(i + 1)));
  92. }
  93. }
  94. util::MemorySegmentLocal mem_sgmt_;
  95. TreeHolder dtree_holder_;
  96. TreeHolder dtree_expose_empty_node_holder_;
  97. TestDomainTree& dtree;
  98. TestDomainTree& dtree_expose_empty_node;
  99. TestDomainTreeNode* dtnode;
  100. const TestDomainTreeNode* cdtnode;
  101. uint8_t buf[LabelSequence::MAX_SERIALIZED_LENGTH];
  102. };
  103. TEST_F(DomainTreeTest, nodeCount) {
  104. EXPECT_EQ(15, dtree.getNodeCount());
  105. // Delete all nodes, then the count should be set to 0. This also tests
  106. // the behavior of deleteAllNodes().
  107. dtree.deleteAllNodes(mem_sgmt_, deleteData);
  108. EXPECT_EQ(0, dtree.getNodeCount());
  109. }
  110. TEST_F(DomainTreeTest, setGetData) {
  111. // set new data to an existing node. It should have some data.
  112. int* newdata = new int(11);
  113. int* olddata = dtnode->setData(newdata);
  114. EXPECT_NE(static_cast<int*>(NULL), olddata);
  115. deleteData(olddata);
  116. EXPECT_EQ(11, *(dtnode->getData()));
  117. // clear the node. we should get the new data back we just passed.
  118. olddata = dtnode->setData(NULL);
  119. EXPECT_EQ(newdata, olddata);
  120. deleteData(olddata);
  121. }
  122. TEST_F(DomainTreeTest, insertNames) {
  123. EXPECT_EQ(TestDomainTree::ALREADYEXISTS, dtree.insert(mem_sgmt_,
  124. Name("d.e.f"),
  125. &dtnode));
  126. EXPECT_EQ(Name("d.e.f"), dtnode->getName());
  127. EXPECT_EQ(15, dtree.getNodeCount());
  128. // insert not exist node
  129. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("0"),
  130. &dtnode));
  131. EXPECT_EQ(Name("0"), dtnode->getName());
  132. EXPECT_EQ(16, dtree.getNodeCount());
  133. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_,
  134. Name("example.com"),
  135. &dtnode));
  136. EXPECT_EQ(17, dtree.getNodeCount());
  137. // add data to it; also make sure it doesn't have data right now
  138. // (otherwise it would leak)
  139. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(12)));
  140. // return ALREADYEXISTS, since node "example.com" already has
  141. // been explicitly inserted
  142. EXPECT_EQ(TestDomainTree::ALREADYEXISTS, dtree.insert(mem_sgmt_,
  143. Name("example.com"),
  144. &dtnode));
  145. EXPECT_EQ(17, dtree.getNodeCount());
  146. // split the node "d.e.f"
  147. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("k.e.f"),
  148. &dtnode));
  149. EXPECT_EQ(Name("k"), dtnode->getName());
  150. EXPECT_EQ(19, dtree.getNodeCount());
  151. // split the node "g.h"
  152. EXPECT_EQ(TestDomainTree::ALREADYEXISTS, dtree.insert(mem_sgmt_, Name("h"),
  153. &dtnode));
  154. EXPECT_EQ(Name("h"), dtnode->getName());
  155. EXPECT_EQ(20, dtree.getNodeCount());
  156. // add child domain
  157. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_,
  158. Name("m.p.w.y.d.e.f"),
  159. &dtnode));
  160. EXPECT_EQ(Name("m"), dtnode->getName());
  161. EXPECT_EQ(21, dtree.getNodeCount());
  162. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_,
  163. Name("n.p.w.y.d.e.f"),
  164. &dtnode));
  165. EXPECT_EQ(Name("n"), dtnode->getName());
  166. EXPECT_EQ(22, dtree.getNodeCount());
  167. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("l.a"),
  168. &dtnode));
  169. EXPECT_EQ(Name("l"), dtnode->getName());
  170. EXPECT_EQ(23, dtree.getNodeCount());
  171. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("r.d.e.f"),
  172. &dtnode));
  173. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("s.d.e.f"),
  174. &dtnode));
  175. EXPECT_EQ(25, dtree.getNodeCount());
  176. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_,
  177. Name("h.w.y.d.e.f"),
  178. &dtnode));
  179. // add more nodes one by one to cover leftRotate and rightRotate
  180. EXPECT_EQ(TestDomainTree::ALREADYEXISTS, dtree.insert(mem_sgmt_, Name("f"),
  181. &dtnode));
  182. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("m"),
  183. &dtnode));
  184. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("nm"),
  185. &dtnode));
  186. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("om"),
  187. &dtnode));
  188. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("k"),
  189. &dtnode));
  190. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("l"),
  191. &dtnode));
  192. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("fe"),
  193. &dtnode));
  194. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("ge"),
  195. &dtnode));
  196. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("i"),
  197. &dtnode));
  198. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("ae"),
  199. &dtnode));
  200. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_, Name("n"),
  201. &dtnode));
  202. }
  203. TEST_F(DomainTreeTest, subTreeRoot) {
  204. // This is a testcase for a particular issue that went unchecked in
  205. // #2089's implementation, but was fixed in #2092. The issue was
  206. // that when a node was fissioned, FLAG_SUBTREE_ROOT was not being
  207. // copied correctly.
  208. EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
  209. dtree_expose_empty_node.insert(mem_sgmt_, Name("d.e.f"),
  210. &dtnode));
  211. EXPECT_EQ(TestDomainTree::SUCCESS,
  212. dtree_expose_empty_node.insert(mem_sgmt_, Name("0"),
  213. &dtnode));
  214. EXPECT_EQ(TestDomainTree::SUCCESS,
  215. dtree_expose_empty_node.insert(mem_sgmt_, Name("example.com"),
  216. &dtnode));
  217. EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
  218. dtree_expose_empty_node.insert(mem_sgmt_, Name("example.com"),
  219. &dtnode));
  220. EXPECT_EQ(TestDomainTree::SUCCESS,
  221. dtree_expose_empty_node.insert(mem_sgmt_, Name("k.e.f"),
  222. &dtnode));
  223. // "g.h" is not a subtree root
  224. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  225. dtree_expose_empty_node.find(Name("g.h"), &dtnode));
  226. EXPECT_FALSE(dtnode->isSubTreeRoot());
  227. // fission the node "g.h"
  228. EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
  229. dtree_expose_empty_node.insert(mem_sgmt_, Name("h"),
  230. &dtnode));
  231. // the node "h" (h.down_ -> "g") should not be a subtree root. "g"
  232. // should be a subtree root.
  233. EXPECT_FALSE(dtnode->isSubTreeRoot());
  234. // "g.h" should be a subtree root now.
  235. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  236. dtree_expose_empty_node.find(Name("g.h"), &dtnode));
  237. EXPECT_TRUE(dtnode->isSubTreeRoot());
  238. }
  239. TEST_F(DomainTreeTest, additionalNodeFission) {
  240. // These are additional nodeFission tests added by #2054's rewrite
  241. // of DomainTree::nodeFission(). These test specific corner cases that
  242. // are not covered by other tests.
  243. // Insert "t.0" (which becomes the left child of its parent)
  244. EXPECT_EQ(TestDomainTree::SUCCESS,
  245. dtree_expose_empty_node.insert(mem_sgmt_, Name("t.0"),
  246. &dtnode));
  247. // "t.0" is not a subtree root
  248. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  249. dtree_expose_empty_node.find(Name("t.0"), &dtnode));
  250. EXPECT_FALSE(dtnode->isSubTreeRoot());
  251. // fission the node "t.0"
  252. EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
  253. dtree_expose_empty_node.insert(mem_sgmt_, Name("0"),
  254. &dtnode));
  255. // the node "0" ("0".down_ -> "t") should not be a subtree root. "t"
  256. // should be a subtree root.
  257. EXPECT_FALSE(dtnode->isSubTreeRoot());
  258. // "t.0" should be a subtree root now.
  259. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  260. dtree_expose_empty_node.find(Name("t.0"), &dtnode));
  261. EXPECT_TRUE(dtnode->isSubTreeRoot());
  262. }
  263. TEST_F(DomainTreeTest, findName) {
  264. // find const dtnode
  265. // exact match
  266. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("a"), &cdtnode));
  267. EXPECT_EQ(Name("a"), cdtnode->getName());
  268. // not found
  269. EXPECT_EQ(TestDomainTree::NOTFOUND, dtree.find(Name("d.e.f"), &cdtnode));
  270. EXPECT_EQ(TestDomainTree::NOTFOUND, dtree.find(Name("y.d.e.f"), &cdtnode));
  271. EXPECT_EQ(TestDomainTree::NOTFOUND, dtree.find(Name("x"), &cdtnode));
  272. EXPECT_EQ(TestDomainTree::NOTFOUND, dtree.find(Name("m.n"), &cdtnode));
  273. // if we expose empty node, we can get the empty node created during insert
  274. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  275. dtree_expose_empty_node.find(Name("d.e.f"), &cdtnode));
  276. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  277. dtree_expose_empty_node.find(Name("w.y.d.e.f"), &cdtnode));
  278. // partial match
  279. EXPECT_EQ(TestDomainTree::PARTIALMATCH, dtree.find(Name("m.b"), &cdtnode));
  280. EXPECT_EQ(Name("b"), cdtnode->getName());
  281. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  282. dtree_expose_empty_node.find(Name("m.d.e.f"), &cdtnode));
  283. // find dtnode
  284. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("q.w.y.d.e.f"),
  285. &dtnode));
  286. EXPECT_EQ(Name("q"), dtnode->getName());
  287. }
  288. TEST_F(DomainTreeTest, findError) {
  289. // For the version that takes a node chain, the chain must be empty.
  290. TestDomainTreeNodeChain chain;
  291. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("a"), &cdtnode,
  292. chain));
  293. // trying to reuse the same chain. it should result in an exception.
  294. EXPECT_THROW(dtree.find(Name("a"), &cdtnode, chain),
  295. BadValue);
  296. }
  297. TEST_F(DomainTreeTest, flags) {
  298. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt_,
  299. Name("flags.example"),
  300. &dtnode));
  301. // by default, flags are all off
  302. EXPECT_FALSE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  303. // set operation, by default it enables the flag
  304. dtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
  305. EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  306. // try disable the flag explicitly
  307. dtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK, false);
  308. EXPECT_FALSE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  309. // try enable the flag explicitly
  310. dtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK, true);
  311. EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  312. // setting an unknown flag will trigger an exception
  313. EXPECT_THROW(dtnode->setFlag(static_cast<TestDomainTreeNode::Flags>(2), true),
  314. isc::InvalidParameter);
  315. }
  316. bool
  317. testCallback(const TestDomainTreeNode&, bool* callback_checker) {
  318. *callback_checker = true;
  319. return (false);
  320. }
  321. template <typename T>
  322. void
  323. performCallbackTest(TestDomainTree& dtree,
  324. util::MemorySegmentLocal& mem_sgmt,
  325. const T& name_called,
  326. const T& name_not_called)
  327. {
  328. TestDomainTreeNode* dtnode;
  329. const TestDomainTreeNode* cdtnode;
  330. // by default callback isn't enabled
  331. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt,
  332. Name("callback.example"),
  333. &dtnode));
  334. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(1)));
  335. EXPECT_FALSE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  336. // enable/re-disable callback
  337. dtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
  338. EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  339. dtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK, false);
  340. EXPECT_FALSE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  341. // enable again for subsequent tests
  342. dtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
  343. // add more levels below and above the callback node for partial match.
  344. TestDomainTreeNode* subdtnode;
  345. EXPECT_EQ(TestDomainTree::SUCCESS, dtree.insert(mem_sgmt,
  346. Name("sub.callback.example"),
  347. &subdtnode));
  348. EXPECT_EQ(static_cast<int*>(NULL), subdtnode->setData(new int(2)));
  349. TestDomainTreeNode* parentdtnode;
  350. EXPECT_EQ(TestDomainTree::ALREADYEXISTS, dtree.insert(mem_sgmt,
  351. Name("example"),
  352. &parentdtnode));
  353. // the child/parent nodes shouldn't "inherit" the callback flag.
  354. // "dtnode" may be invalid due to the insertion, so we need to re-find
  355. // it.
  356. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("callback.example"),
  357. &dtnode));
  358. EXPECT_TRUE(dtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  359. EXPECT_FALSE(subdtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  360. EXPECT_FALSE(parentdtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
  361. // check if the callback is called from find()
  362. TestDomainTreeNodeChain node_path1;
  363. bool callback_called = false;
  364. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  365. dtree.find(name_called, &cdtnode, node_path1,
  366. testCallback, &callback_called));
  367. EXPECT_TRUE(callback_called);
  368. // enable callback at the parent node, but it doesn't have data so
  369. // the callback shouldn't be called.
  370. TestDomainTreeNodeChain node_path2;
  371. parentdtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
  372. callback_called = false;
  373. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  374. dtree.find(name_not_called, &cdtnode, node_path2,
  375. testCallback, &callback_called));
  376. EXPECT_FALSE(callback_called);
  377. }
  378. TEST_F(DomainTreeTest, callbackName) {
  379. const Name n1("sub.callback.example");
  380. const Name n2("callback.example");
  381. performCallbackTest(dtree, mem_sgmt_, n1, n2);
  382. }
  383. TEST_F(DomainTreeTest, callbackLabelSequence) {
  384. const Name n1("sub.callback.example");
  385. const Name n2("callback.example");
  386. const LabelSequence ls1(n1);
  387. const LabelSequence ls2(n2);
  388. performCallbackTest(dtree, mem_sgmt_, ls1, ls2);
  389. }
  390. TEST_F(DomainTreeTest, findInSubTree) {
  391. // For the version that takes a node chain, the chain must be empty.
  392. DomainTreeNodeChain<int> chain;
  393. bool flag;
  394. // Searching for a non-absolute (right-stripped) label sequence when
  395. // chain is empty should throw.
  396. const Name n0("w.y.d.e.f");
  397. LabelSequence ls0(n0);
  398. ls0.stripRight(1);
  399. EXPECT_THROW(dtree_expose_empty_node.find(ls0, &cdtnode, chain,
  400. testCallback, &flag),
  401. isc::BadValue);
  402. // First, find a sub-tree node
  403. chain.clear();
  404. const LabelSequence ls1(n0);
  405. DomainTree<int>::Result result =
  406. dtree_expose_empty_node.find(ls1, &cdtnode, chain,
  407. testCallback, &flag);
  408. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  409. EXPECT_EQ(n0, chain.getAbsoluteName());
  410. // Searching for an absolute label sequence when chain is already
  411. // populated should throw.
  412. const Name n2a("o");
  413. const LabelSequence ls2a(n2a);
  414. EXPECT_THROW(dtree_expose_empty_node.find(ls2a, &cdtnode, chain,
  415. testCallback, &flag),
  416. isc::BadValue);
  417. // Now, find "o.w.y.d.e.f." by right-stripping the "w.y.d.e.f."
  418. // suffix to "o" (non-absolute).
  419. const Name n2("o.w.y.d.e.f");
  420. LabelSequence ls2(n2);
  421. ls2.stripRight(6);
  422. EXPECT_EQ("o", ls2.toText());
  423. result = dtree_expose_empty_node.find(ls2, &cdtnode, chain,
  424. testCallback, &flag);
  425. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  426. EXPECT_EQ(n2, chain.getAbsoluteName());
  427. // Another test. Start with "d.e.f." node.
  428. chain.clear();
  429. const Name n3("d.e.f");
  430. const LabelSequence ls3(n3);
  431. result =
  432. dtree_expose_empty_node.find(ls3, &cdtnode, chain,
  433. testCallback, &flag);
  434. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  435. EXPECT_EQ(n3, chain.getAbsoluteName());
  436. // Now, find "o.w.y.d.e.f." by right-stripping the "w.y.d.e.f."
  437. // suffix to "o.w.y" (non-absolute).
  438. const Name n4("o.w.y.d.e.f");
  439. LabelSequence ls4(n2);
  440. ls4.stripRight(4);
  441. EXPECT_EQ("o.w.y", ls4.toText());
  442. result = dtree_expose_empty_node.find(ls4, &cdtnode, chain,
  443. testCallback, &flag);
  444. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  445. EXPECT_EQ(n4, chain.getAbsoluteName());
  446. }
  447. TEST_F(DomainTreeTest, findInSubTreeSameLabelSequence) {
  448. // For the version that takes a node chain, the chain must be empty.
  449. DomainTreeNodeChain<int> chain;
  450. bool flag;
  451. const Name n1("c.g.h");
  452. // First insert a "c.g.h." node.
  453. dtree_expose_empty_node.insert(mem_sgmt_, n1, &dtnode);
  454. /* Now, the tree looks like:
  455. *
  456. * .
  457. * |
  458. * b
  459. * / \
  460. * a d.e.f
  461. * / | \____
  462. * c | \
  463. * | g.h
  464. * | |
  465. * w.y i
  466. * / | \ / \
  467. * x | z c k
  468. * | |
  469. * p j
  470. * / \
  471. * o q
  472. */
  473. // Make a non-absolute label sequence. We will search for this same
  474. // sequence in two places in the tree.
  475. LabelSequence ls1(n1);
  476. ls1.stripRight(3);
  477. EXPECT_EQ("c", ls1.toText());
  478. // First, find "g.h."
  479. const Name n2("g.h");
  480. const LabelSequence ls2(n2);
  481. DomainTree<int>::Result result =
  482. dtree_expose_empty_node.find(ls2, &cdtnode, chain,
  483. testCallback, &flag);
  484. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  485. EXPECT_EQ(n2, chain.getAbsoluteName());
  486. // Now, find "c.g.h." by searching just the non-absolute ls1 label
  487. // sequence.
  488. result = dtree_expose_empty_node.find(ls1, &cdtnode, chain,
  489. testCallback, &flag);
  490. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  491. EXPECT_EQ(n1, chain.getAbsoluteName());
  492. // Now, find "." (the root node)
  493. chain.clear();
  494. const Name n3(".");
  495. const LabelSequence ls3(n3);
  496. result =
  497. dtree_expose_empty_node.find(ls3, &cdtnode, chain,
  498. testCallback, &flag);
  499. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  500. EXPECT_EQ(n3, chain.getAbsoluteName());
  501. // Now, find "c." by searching just the non-absolute ls1 label
  502. // sequence.
  503. result = dtree_expose_empty_node.find(ls1, &cdtnode, chain,
  504. testCallback, &flag);
  505. EXPECT_EQ(DomainTree<int>::EXACTMATCH, result);
  506. EXPECT_EQ(Name("c."), chain.getAbsoluteName());
  507. }
  508. TEST_F(DomainTreeTest, chainLevel) {
  509. TestDomainTreeNodeChain chain;
  510. // by default there should be no level in the chain.
  511. EXPECT_EQ(0, chain.getLevelCount());
  512. // insert one node to the tree and find it. there should be exactly
  513. // one level in the chain.
  514. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_, true));
  515. TestDomainTree& tree(*tree_holder.get());
  516. Name node_name(Name::ROOT_NAME());
  517. EXPECT_EQ(TestDomainTree::SUCCESS, tree.insert(mem_sgmt_, node_name,
  518. &dtnode));
  519. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  520. tree.find(node_name, &cdtnode, chain));
  521. EXPECT_EQ(1, chain.getLevelCount());
  522. // Check the name of the found node (should have '.' as both non-absolute
  523. // and absolute name
  524. EXPECT_EQ(".", cdtnode->getLabels().toText());
  525. EXPECT_EQ(".", cdtnode->getAbsoluteLabels(buf).toText());
  526. /*
  527. * Now creating a possibly deepest tree with MAX_LABELS levels.
  528. * it should look like:
  529. * (.)
  530. * |
  531. * a
  532. * |
  533. * a
  534. * : (MAX_LABELS - 1) "a"'s
  535. *
  536. * then confirm that find() for the deepest name succeeds without any
  537. * disruption, and the resulting chain has the expected level.
  538. * Note that the root name (".") solely belongs to a single level,
  539. * so the levels begin with 2.
  540. */
  541. for (unsigned int i = 2; i <= Name::MAX_LABELS; ++i) {
  542. node_name = Name("a.").concatenate(node_name);
  543. EXPECT_EQ(TestDomainTree::SUCCESS, tree.insert(mem_sgmt_, node_name,
  544. &dtnode));
  545. TestDomainTreeNodeChain found_chain;
  546. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  547. tree.find(node_name, &cdtnode, found_chain));
  548. EXPECT_EQ(i, found_chain.getLevelCount());
  549. // The non-absolute name should only have the first label
  550. EXPECT_EQ("a", cdtnode->getLabels().toText());
  551. // But the absolute name should have all labels
  552. EXPECT_EQ(node_name.toText(),
  553. cdtnode->getAbsoluteLabels(buf).toText());
  554. }
  555. // Confirm the last inserted name has the possible maximum length with
  556. // maximum label count. This confirms the dtree and chain level cannot
  557. // be larger.
  558. EXPECT_EQ(Name::MAX_LABELS, node_name.getLabelCount());
  559. EXPECT_THROW(node_name.concatenate(Name("a.")), TooLongName);
  560. }
  561. TEST_F(DomainTreeTest, getAbsoluteNameError) {
  562. // an empty chain isn't allowed.
  563. TestDomainTreeNodeChain chain;
  564. EXPECT_THROW(chain.getAbsoluteName(), BadValue);
  565. }
  566. /*
  567. * The domain order should be:
  568. * ., 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,
  569. * q.w.y.d.e.f, z.d.e.f, j.z.d.e.f, g.h, i.g.h, k.g.h
  570. * . (no data, can't be found)
  571. * |
  572. * b
  573. * / \
  574. * a d.e.f
  575. * / | \
  576. * c | g.h
  577. * | |
  578. * w.y i
  579. * / | \ \
  580. * x | z k
  581. * | |
  582. * p j
  583. * / \
  584. * o q
  585. */
  586. const char* const names[] = {
  587. "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f",
  588. "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f",
  589. "g.h", "i.g.h", "k.g.h"};
  590. const size_t name_count(sizeof(names) / sizeof(*names));
  591. const char* const upper_node_names[] = {
  592. ".", ".", ".", ".", "d.e.f", "d.e.f", "w.y.d.e.f",
  593. "w.y.d.e.f", "w.y.d.e.f", "d.e.f", "z.d.e.f",
  594. ".", "g.h", "g.h"};
  595. const char* const subtree_root_node_names[] = {
  596. "b", "b", "b", "b", "w.y.d.e.f", "w.y.d.e.f", "p.w.y.d.e.f",
  597. "p.w.y.d.e.f", "p.w.y.d.e.f", "w.y.d.e.f", "j.z.d.e.f",
  598. "b", "i.g.h", "i.g.h"};
  599. const char* const largest_node_names[] = {
  600. "g.h", "g.h", "g.h", "g.h", "z.d.e.f", "z.d.e.f", "q.w.y.d.e.f",
  601. "q.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f",
  602. "g.h", "k.g.h", "k.g.h"};
  603. TEST_F(DomainTreeTest, getUpperNode) {
  604. TestDomainTreeNodeChain node_path;
  605. const TestDomainTreeNode* node = NULL;
  606. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  607. dtree_expose_empty_node.find(Name(names[0]),
  608. &node,
  609. node_path));
  610. for (int i = 0; i < name_count; ++i) {
  611. EXPECT_NE(static_cast<void*>(NULL), node);
  612. const TestDomainTreeNode* upper_node = node->getUpperNode();
  613. if (upper_node_names[i] != NULL) {
  614. const TestDomainTreeNode* upper_node2 = NULL;
  615. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  616. dtree_expose_empty_node.find(Name(upper_node_names[i]),
  617. &upper_node2));
  618. EXPECT_NE(static_cast<void*>(NULL), upper_node2);
  619. EXPECT_EQ(upper_node, upper_node2);
  620. } else {
  621. EXPECT_EQ(static_cast<void*>(NULL), upper_node);
  622. }
  623. node = dtree_expose_empty_node.nextNode(node_path);
  624. }
  625. // We should have reached the end of the tree.
  626. EXPECT_EQ(static_cast<void*>(NULL), node);
  627. }
  628. TEST_F(DomainTreeTest, getSubTreeRoot) {
  629. TestDomainTreeNodeChain node_path;
  630. const TestDomainTreeNode* node = NULL;
  631. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  632. dtree_expose_empty_node.find(Name(names[0]),
  633. &node,
  634. node_path));
  635. for (int i = 0; i < name_count; ++i) {
  636. EXPECT_NE(static_cast<void*>(NULL), node);
  637. const TestDomainTreeNode* sr_node = node->getSubTreeRoot();
  638. if (subtree_root_node_names[i] != NULL) {
  639. const TestDomainTreeNode* sr_node2 = NULL;
  640. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  641. dtree_expose_empty_node.find(Name(subtree_root_node_names[i]),
  642. &sr_node2));
  643. EXPECT_NE(static_cast<void*>(NULL), sr_node2);
  644. EXPECT_EQ(sr_node, sr_node2);
  645. } else {
  646. EXPECT_EQ(static_cast<void*>(NULL), sr_node);
  647. }
  648. node = dtree_expose_empty_node.nextNode(node_path);
  649. }
  650. // We should have reached the end of the tree.
  651. EXPECT_EQ(static_cast<void*>(NULL), node);
  652. }
  653. TEST_F(DomainTreeTest, getLargestInSubTree) {
  654. TestDomainTreeNodeChain node_path;
  655. const TestDomainTreeNode* node = NULL;
  656. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  657. dtree_expose_empty_node.find(Name(names[0]),
  658. &node,
  659. node_path));
  660. for (int i = 0; i < name_count; ++i) {
  661. EXPECT_NE(static_cast<void*>(NULL), node);
  662. const TestDomainTreeNode* largest_node = node->getLargestInSubTree();
  663. if (largest_node_names[i] != NULL) {
  664. const TestDomainTreeNode* largest_node2 = NULL;
  665. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  666. dtree_expose_empty_node.find(Name(largest_node_names[i]),
  667. &largest_node2));
  668. EXPECT_NE(static_cast<void*>(NULL), largest_node2);
  669. EXPECT_EQ(largest_node, largest_node2);
  670. } else {
  671. EXPECT_EQ(static_cast<void*>(NULL), largest_node);
  672. }
  673. node = dtree_expose_empty_node.nextNode(node_path);
  674. }
  675. // We should have reached the end of the tree.
  676. EXPECT_EQ(static_cast<void*>(NULL), node);
  677. }
  678. TEST_F(DomainTreeTest, nextNode) {
  679. TestDomainTreeNodeChain node_path;
  680. const TestDomainTreeNode* node = NULL;
  681. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  682. dtree.find(Name(names[0]), &node, node_path));
  683. for (int i = 0; i < name_count; ++i) {
  684. EXPECT_NE(static_cast<void*>(NULL), node);
  685. EXPECT_EQ(Name(names[i]), node_path.getAbsoluteName());
  686. node = dtree.nextNode(node_path);
  687. }
  688. // We should have reached the end of the tree.
  689. EXPECT_EQ(static_cast<void*>(NULL), node);
  690. }
  691. // Just walk using previousNode until the beginning of the tree and check it is
  692. // OK
  693. //
  694. // dtree - the tree to walk
  695. // node - result of previous call to find(), starting position of the walk
  696. // node_path - the path from the previous call to find(), will be modified
  697. // chain_length - the number of names that should be in the chain to be walked
  698. // (0 means it should be empty, 3 means 'a', 'b' and 'c' should be there -
  699. // this is always from the beginning of the names[] list).
  700. // skip_first - if this is false, the node should already contain the node with
  701. // the first name of the chain. If it is true, the node should be NULL
  702. // (true is for finds that return no match, false for the ones that return
  703. // match)
  704. void
  705. previousWalk(TestDomainTree& dtree, const TestDomainTreeNode* node,
  706. TestDomainTreeNodeChain& node_path, size_t chain_length,
  707. bool skip_first)
  708. {
  709. if (skip_first) {
  710. // If the first is not found, this is supposed to be NULL and we skip
  711. // it in our checks.
  712. EXPECT_EQ(static_cast<void*>(NULL), node);
  713. node = dtree.previousNode(node_path);
  714. }
  715. for (size_t i(chain_length); i > 0; --i) {
  716. EXPECT_NE(static_cast<void*>(NULL), node);
  717. EXPECT_EQ(Name(names[i - 1]), node_path.getAbsoluteName());
  718. // Find the node at the path and check the value is the same
  719. // (that it really returns the correct corresponding node)
  720. //
  721. // The "empty" nodes can not be found
  722. if (node->getData()) {
  723. const TestDomainTreeNode* node2(NULL);
  724. TestDomainTreeNodeChain node_path2;
  725. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  726. dtree.find(Name(names[i - 1]), &node2, node_path2));
  727. EXPECT_EQ(node, node2);
  728. }
  729. node = dtree.previousNode(node_path);
  730. }
  731. // We should have reached the start of the tree.
  732. ASSERT_NE(static_cast<void*>(NULL), node);
  733. EXPECT_EQ(".", node->getLabels().toText());
  734. // With one more call it results in NULL
  735. node = dtree.previousNode(node_path);
  736. EXPECT_EQ(static_cast<void*>(NULL), node);
  737. // Calling previousNode() yet again should still return NULL without
  738. // fail.
  739. node = dtree.previousNode(node_path);
  740. EXPECT_EQ(static_cast<void*>(NULL), node);
  741. }
  742. // Check the previousNode
  743. TEST_F(DomainTreeTest, previousNode) {
  744. // First, iterate the whole tree from the end to the beginning.
  745. TestDomainTreeNodeChain node_path;
  746. EXPECT_THROW(dtree.previousNode(node_path), isc::BadValue) <<
  747. "Throw before a search was done on the path";
  748. const TestDomainTreeNode* node(NULL);
  749. {
  750. SCOPED_TRACE("Iterate through");
  751. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  752. dtree.find(Name(names[name_count - 1]), &node, node_path));
  753. previousWalk(dtree, node, node_path, name_count, false);
  754. node = NULL;
  755. node_path.clear();
  756. }
  757. {
  758. SCOPED_TRACE("Iterate from the middle");
  759. // Now, start somewhere in the middle, but within the real node.
  760. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  761. dtree.find(Name(names[4]), &node, node_path));
  762. previousWalk(dtree, node, node_path, 5, false);
  763. node = NULL;
  764. node_path.clear();
  765. }
  766. {
  767. SCOPED_TRACE("Start at the first");
  768. // If we start at the lowest (which is "a"), we get to the beginning
  769. // right away.
  770. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  771. dtree.find(Name(names[0]), &node, node_path));
  772. EXPECT_NE(static_cast<void*>(NULL), node);
  773. node = dtree.previousNode(node_path);
  774. ASSERT_NE(static_cast<void*>(NULL), node);
  775. EXPECT_EQ(".", node->getLabels().toText());
  776. node = NULL;
  777. node_path.clear();
  778. }
  779. {
  780. SCOPED_TRACE("Start before the first");
  781. // If we start before the lowest (. < 0. < a.), we should not get a
  782. // node. Its previous node should be the root.
  783. EXPECT_EQ(TestDomainTree::NOTFOUND,
  784. dtree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
  785. EXPECT_EQ(static_cast<void*>(NULL), node);
  786. node = dtree.previousNode(node_path);
  787. ASSERT_NE(static_cast<void*>(NULL), node);
  788. EXPECT_EQ(".", node->getLabels().toText());
  789. node = NULL;
  790. node_path.clear();
  791. }
  792. {
  793. SCOPED_TRACE("Start after the last");
  794. EXPECT_EQ(TestDomainTree::NOTFOUND,
  795. dtree.find(Name("z"), &node, node_path));
  796. previousWalk(dtree, node, node_path, name_count, true);
  797. node = NULL;
  798. node_path.clear();
  799. }
  800. {
  801. SCOPED_TRACE("Start below a leaf");
  802. // We exit a leaf by going down. We should start by the one
  803. // we exited - 'c' (actually, we should get it by the find, as partial
  804. // match).
  805. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  806. dtree.find(Name("b.c"), &node, node_path));
  807. previousWalk(dtree, node, node_path, 3, false);
  808. node = NULL;
  809. node_path.clear();
  810. }
  811. {
  812. SCOPED_TRACE("Start to the right of a leaf");
  813. // When searching for this, we exit the 'x' node to the right side,
  814. // so we should go x afterwards.
  815. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  816. // and not PARTIALMATCH.
  817. EXPECT_EQ(TestDomainTree::NOTFOUND,
  818. dtree.find(Name("xy.d.e.f"), &node, node_path));
  819. previousWalk(dtree, node, node_path, 5, true);
  820. node = NULL;
  821. node_path.clear();
  822. }
  823. {
  824. SCOPED_TRACE("Start to the left of a leaf");
  825. // This is similar to the previous, but we exit the 'z' leaf to the
  826. // left side, so should not visit z at all then.
  827. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  828. // and not PARTIALMATCH.
  829. EXPECT_EQ(TestDomainTree::NOTFOUND,
  830. dtree.find(Name("yz.d.e.f"), &node, node_path));
  831. previousWalk(dtree, node, node_path, 9, true);
  832. node = NULL;
  833. node_path.clear();
  834. }
  835. {
  836. SCOPED_TRACE("Start to the right of a parent");
  837. // When searching for this, we exit the 'g.h' node to the right
  838. // side, so we should go to g.h's children afterwards.
  839. // 'g.h' is an empty node, so we get a NOTFOUND and not
  840. // PARTIALMATCH.
  841. EXPECT_EQ(TestDomainTree::NOTFOUND,
  842. dtree.find(Name("x.h"), &node, node_path));
  843. // 'g.h' is the COMMONANCESTOR.
  844. EXPECT_EQ(node_path.getLastComparedNode()->getName(), Name("g.h"));
  845. EXPECT_EQ(NameComparisonResult::COMMONANCESTOR,
  846. node_path.getLastComparisonResult().getRelation());
  847. // find() exits to the right of 'g.h'
  848. EXPECT_GT(node_path.getLastComparisonResult().getOrder(), 0);
  849. // We then descend into 'i.g.h' and walk all the nodes in the
  850. // tree.
  851. previousWalk(dtree, node, node_path, name_count, true);
  852. node = NULL;
  853. node_path.clear();
  854. }
  855. {
  856. SCOPED_TRACE("Start inside a wrong node");
  857. // The d.e.f is a single node, but we want only part of it. We
  858. // should start iterating before it.
  859. EXPECT_EQ(TestDomainTree::NOTFOUND,
  860. dtree.find(Name("e.f"), &node, node_path));
  861. previousWalk(dtree, node, node_path, 3, true);
  862. node = NULL;
  863. node_path.clear();
  864. }
  865. {
  866. SCOPED_TRACE("Lookup in empty tree");
  867. // Just check it doesn't crash, etc.
  868. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  869. TestDomainTree& empty_tree(*tree_holder.get());
  870. EXPECT_EQ(TestDomainTree::NOTFOUND,
  871. empty_tree.find(Name("x"), &node, node_path));
  872. EXPECT_EQ(static_cast<void*>(NULL), node);
  873. EXPECT_EQ(static_cast<void*>(NULL),
  874. empty_tree.previousNode(node_path));
  875. node = NULL;
  876. node_path.clear();
  877. }
  878. }
  879. TEST_F(DomainTreeTest, largestNode) {
  880. cdtnode = dtree.largestNode();
  881. EXPECT_EQ(Name("k"), cdtnode->getName());
  882. }
  883. TEST_F(DomainTreeTest, nextNodeError) {
  884. // Empty chain for nextNode() is invalid.
  885. TestDomainTreeNodeChain chain;
  886. EXPECT_THROW(dtree.nextNode(chain), BadValue);
  887. }
  888. // A helper function for getLastComparedNode() below.
  889. void
  890. comparisonChecks(const TestDomainTreeNodeChain& chain,
  891. int expected_order, int expected_common_labels,
  892. NameComparisonResult::NameRelation expected_reln)
  893. {
  894. if (expected_order > 0) {
  895. EXPECT_LT(0, chain.getLastComparisonResult().getOrder());
  896. } else if (expected_order < 0) {
  897. EXPECT_GT(0, chain.getLastComparisonResult().getOrder());
  898. } else {
  899. EXPECT_EQ(0, chain.getLastComparisonResult().getOrder());
  900. }
  901. EXPECT_EQ(expected_common_labels,
  902. chain.getLastComparisonResult().getCommonLabels());
  903. EXPECT_EQ(expected_reln,
  904. chain.getLastComparisonResult().getRelation());
  905. }
  906. TEST_F(DomainTreeTest, getLastComparedNode) {
  907. TestDomainTree& tree = dtree_expose_empty_node; // use the "empty OK" mode
  908. TestDomainTreeNodeChain chain;
  909. // initially there should be no 'last compared'.
  910. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  911. // A search for an empty tree should result in no 'last compared', too.
  912. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  913. TestDomainTree& empty_tree(*tree_holder.get());
  914. EXPECT_EQ(TestDomainTree::NOTFOUND,
  915. empty_tree.find(Name("a"), &cdtnode, chain));
  916. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  917. chain.clear();
  918. const TestDomainTreeNode* expected_node = NULL;
  919. // Exact match case. The returned node should be last compared.
  920. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  921. tree.find(Name("x.d.e.f"), &expected_node, chain));
  922. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  923. // 1 = # labels of "x" (note: excluding ".")
  924. comparisonChecks(chain, 0, 1, NameComparisonResult::EQUAL);
  925. chain.clear();
  926. // Partial match, search stopped at the matching node, which should be
  927. // the last compared node.
  928. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  929. tree.find(Name("k.g.h"), &expected_node));
  930. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  931. tree.find(Name("x.k.g.h"), &cdtnode, chain));
  932. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  933. // k.g.h < x.k.g.h, 1 = # labels of "k"
  934. comparisonChecks(chain, 1, 1, NameComparisonResult::SUBDOMAIN);
  935. chain.clear();
  936. // Partial match, search stopped in the subtree below the matching node
  937. // after following a left branch.
  938. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  939. tree.find(Name("x.d.e.f"), &expected_node));
  940. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  941. tree.find(Name("a.d.e.f"), &cdtnode, chain));
  942. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  943. // a < x, no common labels
  944. comparisonChecks(chain, -1, 0, NameComparisonResult::NONE);
  945. chain.clear();
  946. // Partial match, search stopped in the subtree below the matching node
  947. // after following a right branch.
  948. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  949. tree.find(Name("z.d.e.f"), &expected_node));
  950. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  951. tree.find(Name("zz.d.e.f"), &cdtnode, chain));
  952. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  953. // zz > z, no common label
  954. comparisonChecks(chain, 1, 0, NameComparisonResult::NONE);
  955. chain.clear();
  956. // Partial match, search stopped at a node for a super domain of the
  957. // search name in the subtree below the matching node.
  958. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  959. tree.find(Name("w.y.d.e.f"), &expected_node));
  960. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  961. tree.find(Name("y.d.e.f"), &cdtnode, chain));
  962. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  963. // y < w.y, 1 = # labels of "y"
  964. comparisonChecks(chain, -1, 1, NameComparisonResult::SUPERDOMAIN);
  965. chain.clear();
  966. // Partial match, search stopped at a node that share a common ancestor
  967. // with the search name in the subtree below the matching node.
  968. // (the expected node is the same as the previous case)
  969. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  970. tree.find(Name("z.y.d.e.f"), &cdtnode, chain));
  971. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  972. // z.y > w.y, 1 = # labels of "y"
  973. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  974. chain.clear();
  975. // Search stops in the highest level (under ".") after following a left
  976. // branch. (find() still returns PARTIALMATCH due to the top level ".")
  977. EXPECT_EQ(TestDomainTree::EXACTMATCH, tree.find(Name("c"), &expected_node));
  978. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  979. tree.find(Name("bb"), &cdtnode, chain));
  980. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  981. // bb < c, no common label
  982. comparisonChecks(chain, -1, 0, NameComparisonResult::NONE);
  983. chain.clear();
  984. // Search stops in the highest level (under ".") after following a right
  985. // branch. (the expected node is the same as the previous case)
  986. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  987. tree.find(Name("d"), &cdtnode, chain));
  988. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  989. // d > c, no common label
  990. comparisonChecks(chain, 1, 0, NameComparisonResult::NONE);
  991. chain.clear();
  992. }
  993. TEST_F(DomainTreeTest, dumpTree) {
  994. std::ostringstream str;
  995. std::ostringstream str2;
  996. dtree.dumpTree(str);
  997. str2 << "tree has 15 node(s)\n"
  998. ". (black) [invisible] [subtreeroot]\n"
  999. " begin down from .\n"
  1000. " b (black) [subtreeroot]\n"
  1001. " a (black)\n"
  1002. " NULL\n"
  1003. " NULL\n"
  1004. " d.e.f (black) [invisible]\n"
  1005. " begin down from d.e.f\n"
  1006. " w.y (black) [invisible] [subtreeroot]\n"
  1007. " begin down from w.y\n"
  1008. " p (black) [subtreeroot]\n"
  1009. " o (red)\n"
  1010. " NULL\n"
  1011. " NULL\n"
  1012. " q (red)\n"
  1013. " NULL\n"
  1014. " NULL\n"
  1015. " end down from w.y\n"
  1016. " x (red)\n"
  1017. " NULL\n"
  1018. " NULL\n"
  1019. " z (red)\n"
  1020. " begin down from z\n"
  1021. " j (black) [subtreeroot]\n"
  1022. " NULL\n"
  1023. " NULL\n"
  1024. " end down from z\n"
  1025. " NULL\n"
  1026. " NULL\n"
  1027. " end down from d.e.f\n"
  1028. " c (red)\n"
  1029. " NULL\n"
  1030. " NULL\n"
  1031. " g.h (red)\n"
  1032. " begin down from g.h\n"
  1033. " i (black) [subtreeroot]\n"
  1034. " NULL\n"
  1035. " k (red)\n"
  1036. " NULL\n"
  1037. " NULL\n"
  1038. " end down from g.h\n"
  1039. " NULL\n"
  1040. " NULL\n"
  1041. " end down from .\n"
  1042. " NULL\n"
  1043. " NULL\n";
  1044. EXPECT_EQ(str2.str(), str.str());
  1045. }
  1046. TEST_F(DomainTreeTest, swap) {
  1047. // Store info about the first tree
  1048. std::ostringstream str1;
  1049. dtree.dumpTree(str1);
  1050. size_t count1(dtree.getNodeCount());
  1051. // Create second one and store state
  1052. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  1053. TestDomainTree& tree2(*tree_holder.get());
  1054. TestDomainTreeNode* node;
  1055. tree2.insert(mem_sgmt_, Name("second"), &node);
  1056. std::ostringstream str2;
  1057. tree2.dumpTree(str2);
  1058. // Swap them
  1059. ASSERT_NO_THROW(tree2.swap(dtree));
  1060. // Check their sizes
  1061. ASSERT_EQ(1, dtree.getNodeCount());
  1062. ASSERT_EQ(count1, tree2.getNodeCount());
  1063. // And content
  1064. std::ostringstream out;
  1065. dtree.dumpTree(out);
  1066. ASSERT_EQ(str2.str(), out.str());
  1067. out.str("");
  1068. tree2.dumpTree(out);
  1069. ASSERT_EQ(str1.str(), out.str());
  1070. }
  1071. // Matching in the "root zone" may be special (e.g. there's no parent,
  1072. // any domain names should be considered a subdomain of it), so it makes
  1073. // sense to test cases with the root zone explicitly.
  1074. TEST_F(DomainTreeTest, root) {
  1075. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  1076. TestDomainTree& root(*tree_holder.get());
  1077. root.insert(mem_sgmt_, Name::ROOT_NAME(), &dtnode);
  1078. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(1)));
  1079. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  1080. root.find(Name::ROOT_NAME(), &cdtnode));
  1081. EXPECT_EQ(dtnode, cdtnode);
  1082. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1083. root.find(Name("example.com"), &cdtnode));
  1084. EXPECT_EQ(dtnode, cdtnode);
  1085. // Insert a new name that better matches the query name. find() should
  1086. // find the better one.
  1087. root.insert(mem_sgmt_, Name("com"), &dtnode);
  1088. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(2)));
  1089. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1090. root.find(Name("example.com"), &cdtnode));
  1091. EXPECT_EQ(dtnode, cdtnode);
  1092. // Perform the same tests for the tree that allows matching against empty
  1093. // nodes.
  1094. TreeHolder tree_holder_emptyok(mem_sgmt_,
  1095. TestDomainTree::create(mem_sgmt_, true));
  1096. TestDomainTree& root_emptyok(*tree_holder_emptyok.get());
  1097. root_emptyok.insert(mem_sgmt_, Name::ROOT_NAME(), &dtnode);
  1098. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  1099. root_emptyok.find(Name::ROOT_NAME(), &cdtnode));
  1100. EXPECT_EQ(dtnode, cdtnode);
  1101. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1102. root_emptyok.find(Name("example.com"), &cdtnode));
  1103. EXPECT_EQ(dtnode, cdtnode);
  1104. root.insert(mem_sgmt_, Name("com"), &dtnode);
  1105. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1106. root.find(Name("example.com"), &cdtnode));
  1107. EXPECT_EQ(dtnode, cdtnode);
  1108. }
  1109. TEST_F(DomainTreeTest, getAbsoluteLabels) {
  1110. // The full absolute names of the nodes in the tree
  1111. // with the addition of the explicit root node
  1112. const char* const domain_names[] = {
  1113. "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f",
  1114. "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
  1115. // The names of the nodes themselves, as they end up in the tree
  1116. const char* const first_labels[] = {
  1117. "c", "b", "a", "x", "z", "g.h", "i", "o",
  1118. "j", "p", "q", "k"};
  1119. const int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
  1120. for (int i = 0; i < name_count; ++i) {
  1121. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name(domain_names[i]),
  1122. &cdtnode));
  1123. // First make sure the names themselves are not absolute
  1124. const LabelSequence ls(cdtnode->getLabels());
  1125. EXPECT_EQ(first_labels[i], ls.toText());
  1126. EXPECT_FALSE(ls.isAbsolute());
  1127. // Now check the absolute names
  1128. const LabelSequence abs_ls(cdtnode->getAbsoluteLabels(buf));
  1129. EXPECT_EQ(Name(domain_names[i]).toText(), abs_ls.toText());
  1130. EXPECT_TRUE(abs_ls.isAbsolute());
  1131. }
  1132. // Explicitly add and find a root node, to see that getAbsoluteLabels
  1133. // also works when getLabels() already returns an absolute LabelSequence
  1134. dtree.insert(mem_sgmt_, Name("."), &dtnode);
  1135. dtnode->setData(new int(1));
  1136. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("."), &cdtnode));
  1137. EXPECT_TRUE(cdtnode->getLabels().isAbsolute());
  1138. EXPECT_EQ(".", cdtnode->getLabels().toText());
  1139. EXPECT_TRUE(cdtnode->getAbsoluteLabels(buf).isAbsolute());
  1140. EXPECT_EQ(".", cdtnode->getAbsoluteLabels(buf).toText());
  1141. }
  1142. }