domaintree_unittest.cc 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  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"), &cdtnode));
  226. EXPECT_FALSE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
  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->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
  234. // "g.h" should be a subtree root now.
  235. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  236. dtree_expose_empty_node.find(Name("g.h"), &cdtnode));
  237. EXPECT_TRUE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
  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"), &cdtnode));
  250. EXPECT_FALSE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
  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->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
  258. // "t.0" should be a subtree root now.
  259. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  260. dtree_expose_empty_node.find(Name("t.0"), &cdtnode));
  261. EXPECT_TRUE(cdtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
  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 cdtnode
  284. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("q.w.y.d.e.f"),
  285. &cdtnode));
  286. EXPECT_EQ(Name("q"), cdtnode->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. // "cdtnode" 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. &cdtnode));
  358. EXPECT_TRUE(cdtnode->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. // Copy should be consistent
  513. TestDomainTreeNodeChain chain2(chain);
  514. EXPECT_EQ(chain.getLevelCount(), chain2.getLevelCount());
  515. // insert one node to the tree and find it. there should be exactly
  516. // one level in the chain.
  517. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_, true));
  518. TestDomainTree& tree(*tree_holder.get());
  519. Name node_name(Name::ROOT_NAME());
  520. EXPECT_EQ(TestDomainTree::SUCCESS, tree.insert(mem_sgmt_, node_name,
  521. &dtnode));
  522. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  523. tree.find(node_name, &cdtnode, chain));
  524. EXPECT_EQ(1, chain.getLevelCount());
  525. // Copy should be consistent
  526. TestDomainTreeNodeChain chain3(chain);
  527. EXPECT_EQ(chain.getLevelCount(), chain3.getLevelCount());
  528. EXPECT_EQ(chain.getAbsoluteName(), chain3.getAbsoluteName());
  529. // Check the name of the found node (should have '.' as both non-absolute
  530. // and absolute name
  531. EXPECT_EQ(".", cdtnode->getLabels().toText());
  532. EXPECT_EQ(".", cdtnode->getAbsoluteLabels(buf).toText());
  533. /*
  534. * Now creating a possibly deepest tree with MAX_LABELS levels.
  535. * it should look like:
  536. * (.)
  537. * |
  538. * a
  539. * |
  540. * a
  541. * : (MAX_LABELS - 1) "a"'s
  542. *
  543. * then confirm that find() for the deepest name succeeds without any
  544. * disruption, and the resulting chain has the expected level.
  545. * Note that the root name (".") solely belongs to a single level,
  546. * so the levels begin with 2.
  547. */
  548. for (unsigned int i = 2; i <= Name::MAX_LABELS; ++i) {
  549. node_name = Name("a.").concatenate(node_name);
  550. EXPECT_EQ(TestDomainTree::SUCCESS, tree.insert(mem_sgmt_, node_name,
  551. &dtnode));
  552. TestDomainTreeNodeChain found_chain;
  553. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  554. tree.find(node_name, &cdtnode, found_chain));
  555. EXPECT_EQ(i, found_chain.getLevelCount());
  556. // The non-absolute name should only have the first label
  557. EXPECT_EQ("a", cdtnode->getLabels().toText());
  558. // But the absolute name should have all labels
  559. EXPECT_EQ(node_name.toText(),
  560. cdtnode->getAbsoluteLabels(buf).toText());
  561. }
  562. // Confirm the last inserted name has the possible maximum length with
  563. // maximum label count. This confirms the dtree and chain level cannot
  564. // be larger.
  565. EXPECT_EQ(Name::MAX_LABELS, node_name.getLabelCount());
  566. EXPECT_THROW(node_name.concatenate(Name("a.")), TooLongName);
  567. }
  568. TEST_F(DomainTreeTest, getAbsoluteNameError) {
  569. // an empty chain isn't allowed.
  570. TestDomainTreeNodeChain chain;
  571. EXPECT_THROW(chain.getAbsoluteName(), BadValue);
  572. }
  573. /*
  574. * The domain order should be:
  575. * ., 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,
  576. * q.w.y.d.e.f, z.d.e.f, j.z.d.e.f, g.h, i.g.h, k.g.h
  577. * . (no data, can't be found)
  578. * |
  579. * b
  580. * / \
  581. * a d.e.f
  582. * / | \
  583. * c | g.h
  584. * | |
  585. * w.y i
  586. * / | \ \
  587. * x | z k
  588. * | |
  589. * p j
  590. * / \
  591. * o q
  592. */
  593. const char* const names[] = {
  594. "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f",
  595. "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f",
  596. "g.h", "i.g.h", "k.g.h"};
  597. const size_t name_count(sizeof(names) / sizeof(*names));
  598. const char* const upper_node_names[] = {
  599. ".", ".", ".", ".", "d.e.f", "d.e.f", "w.y.d.e.f",
  600. "w.y.d.e.f", "w.y.d.e.f", "d.e.f", "z.d.e.f",
  601. ".", "g.h", "g.h"};
  602. TEST_F(DomainTreeTest, getUpperNode) {
  603. TestDomainTreeNodeChain node_path;
  604. const TestDomainTreeNode* node = NULL;
  605. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  606. dtree_expose_empty_node.find(Name(names[0]),
  607. &node,
  608. node_path));
  609. for (int i = 0; i < name_count; ++i) {
  610. EXPECT_NE(static_cast<void*>(NULL), node);
  611. const TestDomainTreeNode* upper_node = node->getUpperNode();
  612. if (upper_node_names[i] != NULL) {
  613. const TestDomainTreeNode* upper_node2 = NULL;
  614. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  615. dtree_expose_empty_node.find(Name(upper_node_names[i]),
  616. &upper_node2));
  617. EXPECT_NE(static_cast<void*>(NULL), upper_node2);
  618. EXPECT_EQ(upper_node, upper_node2);
  619. } else {
  620. EXPECT_EQ(static_cast<void*>(NULL), upper_node);
  621. }
  622. node = dtree_expose_empty_node.nextNode(node_path);
  623. }
  624. // We should have reached the end of the tree.
  625. EXPECT_EQ(static_cast<void*>(NULL), node);
  626. }
  627. #if 0
  628. // Disabled and kept still, for use in case we make getSubTreeRoot() a
  629. // public function again.
  630. const char* const subtree_root_node_names[] = {
  631. "b", "b", "b", "b", "w.y.d.e.f", "w.y.d.e.f", "p.w.y.d.e.f",
  632. "p.w.y.d.e.f", "p.w.y.d.e.f", "w.y.d.e.f", "j.z.d.e.f",
  633. "b", "i.g.h", "i.g.h"};
  634. TEST_F(DomainTreeTest, getSubTreeRoot) {
  635. TestDomainTreeNodeChain node_path;
  636. const TestDomainTreeNode* node = NULL;
  637. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  638. dtree_expose_empty_node.find(Name(names[0]),
  639. &node,
  640. node_path));
  641. for (int i = 0; i < name_count; ++i) {
  642. EXPECT_NE(static_cast<void*>(NULL), node);
  643. const TestDomainTreeNode* sr_node = node->getSubTreeRoot();
  644. if (subtree_root_node_names[i] != NULL) {
  645. const TestDomainTreeNode* sr_node2 = NULL;
  646. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  647. dtree_expose_empty_node.find(Name(subtree_root_node_names[i]),
  648. &sr_node2));
  649. EXPECT_NE(static_cast<void*>(NULL), sr_node2);
  650. EXPECT_EQ(sr_node, sr_node2);
  651. } else {
  652. EXPECT_EQ(static_cast<void*>(NULL), sr_node);
  653. }
  654. node = dtree_expose_empty_node.nextNode(node_path);
  655. }
  656. // We should have reached the end of the tree.
  657. EXPECT_EQ(static_cast<void*>(NULL), node);
  658. }
  659. #endif // disabled getSubTreeRoot()
  660. TEST_F(DomainTreeTest, nextNode) {
  661. TestDomainTreeNodeChain node_path;
  662. const TestDomainTreeNode* node = NULL;
  663. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  664. dtree.find(Name(names[0]), &node, node_path));
  665. for (int i = 0; i < name_count; ++i) {
  666. EXPECT_NE(static_cast<void*>(NULL), node);
  667. EXPECT_EQ(Name(names[i]), node_path.getAbsoluteName());
  668. node = dtree.nextNode(node_path);
  669. }
  670. // We should have reached the end of the tree.
  671. EXPECT_EQ(static_cast<void*>(NULL), node);
  672. }
  673. // Just walk using previousNode until the beginning of the tree and check it is
  674. // OK
  675. //
  676. // dtree - the tree to walk
  677. // node - result of previous call to find(), starting position of the walk
  678. // node_path - the path from the previous call to find(), will be modified
  679. // chain_length - the number of names that should be in the chain to be walked
  680. // (0 means it should be empty, 3 means 'a', 'b' and 'c' should be there -
  681. // this is always from the beginning of the names[] list).
  682. // skip_first - if this is false, the node should already contain the node with
  683. // the first name of the chain. If it is true, the node should be NULL
  684. // (true is for finds that return no match, false for the ones that return
  685. // match)
  686. void
  687. previousWalk(TestDomainTree& dtree, const TestDomainTreeNode* node,
  688. TestDomainTreeNodeChain& node_path, size_t chain_length,
  689. bool skip_first)
  690. {
  691. if (skip_first) {
  692. // If the first is not found, this is supposed to be NULL and we skip
  693. // it in our checks.
  694. EXPECT_EQ(static_cast<void*>(NULL), node);
  695. node = dtree.previousNode(node_path);
  696. }
  697. for (size_t i(chain_length); i > 0; --i) {
  698. EXPECT_NE(static_cast<void*>(NULL), node);
  699. EXPECT_EQ(Name(names[i - 1]), node_path.getAbsoluteName());
  700. // Find the node at the path and check the value is the same
  701. // (that it really returns the correct corresponding node)
  702. //
  703. // The "empty" nodes can not be found
  704. if (node->getData()) {
  705. const TestDomainTreeNode* node2(NULL);
  706. TestDomainTreeNodeChain node_path2;
  707. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  708. dtree.find(Name(names[i - 1]), &node2, node_path2));
  709. EXPECT_EQ(node, node2);
  710. }
  711. node = dtree.previousNode(node_path);
  712. }
  713. // We should have reached the start of the tree.
  714. ASSERT_NE(static_cast<void*>(NULL), node);
  715. EXPECT_EQ(".", node->getLabels().toText());
  716. // With one more call it results in NULL
  717. node = dtree.previousNode(node_path);
  718. EXPECT_EQ(static_cast<void*>(NULL), node);
  719. // Calling previousNode() yet again should still return NULL without
  720. // fail.
  721. node = dtree.previousNode(node_path);
  722. EXPECT_EQ(static_cast<void*>(NULL), node);
  723. }
  724. // Check the previousNode
  725. TEST_F(DomainTreeTest, previousNode) {
  726. // First, iterate the whole tree from the end to the beginning.
  727. TestDomainTreeNodeChain node_path;
  728. EXPECT_THROW(dtree.previousNode(node_path), isc::BadValue) <<
  729. "Throw before a search was done on the path";
  730. const TestDomainTreeNode* node(NULL);
  731. {
  732. SCOPED_TRACE("Iterate through");
  733. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  734. dtree.find(Name(names[name_count - 1]), &node, node_path));
  735. previousWalk(dtree, node, node_path, name_count, false);
  736. node = NULL;
  737. node_path.clear();
  738. }
  739. {
  740. SCOPED_TRACE("Iterate from the middle");
  741. // Now, start somewhere in the middle, but within the real node.
  742. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  743. dtree.find(Name(names[4]), &node, node_path));
  744. previousWalk(dtree, node, node_path, 5, false);
  745. node = NULL;
  746. node_path.clear();
  747. }
  748. {
  749. SCOPED_TRACE("Start at the first");
  750. // If we start at the lowest (which is "a"), we get to the beginning
  751. // right away.
  752. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  753. dtree.find(Name(names[0]), &node, node_path));
  754. EXPECT_NE(static_cast<void*>(NULL), node);
  755. node = dtree.previousNode(node_path);
  756. ASSERT_NE(static_cast<void*>(NULL), node);
  757. EXPECT_EQ(".", node->getLabels().toText());
  758. node = NULL;
  759. node_path.clear();
  760. }
  761. {
  762. SCOPED_TRACE("Start before the first");
  763. // If we start before the lowest (. < 0. < a.), we should not get a
  764. // node. Its previous node should be the root.
  765. EXPECT_EQ(TestDomainTree::NOTFOUND,
  766. dtree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
  767. EXPECT_EQ(static_cast<void*>(NULL), node);
  768. node = dtree.previousNode(node_path);
  769. ASSERT_NE(static_cast<void*>(NULL), node);
  770. EXPECT_EQ(".", node->getLabels().toText());
  771. node = NULL;
  772. node_path.clear();
  773. }
  774. {
  775. SCOPED_TRACE("Start after the last");
  776. EXPECT_EQ(TestDomainTree::NOTFOUND,
  777. dtree.find(Name("z"), &node, node_path));
  778. previousWalk(dtree, node, node_path, name_count, true);
  779. node = NULL;
  780. node_path.clear();
  781. }
  782. {
  783. SCOPED_TRACE("Start below a leaf");
  784. // We exit a leaf by going down. We should start by the one
  785. // we exited - 'c' (actually, we should get it by the find, as partial
  786. // match).
  787. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  788. dtree.find(Name("b.c"), &node, node_path));
  789. previousWalk(dtree, node, node_path, 3, false);
  790. node = NULL;
  791. node_path.clear();
  792. }
  793. {
  794. SCOPED_TRACE("Start to the right of a leaf");
  795. // When searching for this, we exit the 'x' node to the right side,
  796. // so we should go x afterwards.
  797. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  798. // and not PARTIALMATCH.
  799. EXPECT_EQ(TestDomainTree::NOTFOUND,
  800. dtree.find(Name("xy.d.e.f"), &node, node_path));
  801. previousWalk(dtree, node, node_path, 5, true);
  802. node = NULL;
  803. node_path.clear();
  804. }
  805. {
  806. SCOPED_TRACE("Start to the left of a leaf");
  807. // This is similar to the previous, but we exit the 'z' leaf to the
  808. // left side, so should not visit z at all then.
  809. // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
  810. // and not PARTIALMATCH.
  811. EXPECT_EQ(TestDomainTree::NOTFOUND,
  812. dtree.find(Name("yz.d.e.f"), &node, node_path));
  813. previousWalk(dtree, node, node_path, 9, true);
  814. node = NULL;
  815. node_path.clear();
  816. }
  817. {
  818. SCOPED_TRACE("Start to the right of a parent");
  819. // When searching for this, we exit the 'g.h' node to the right
  820. // side, so we should go to g.h's children afterwards.
  821. // 'g.h' is an empty node, so we get a NOTFOUND and not
  822. // PARTIALMATCH.
  823. EXPECT_EQ(TestDomainTree::NOTFOUND,
  824. dtree.find(Name("x.h"), &node, node_path));
  825. // 'g.h' is the COMMONANCESTOR.
  826. EXPECT_EQ(node_path.getLastComparedNode()->getName(), Name("g.h"));
  827. EXPECT_EQ(NameComparisonResult::COMMONANCESTOR,
  828. node_path.getLastComparisonResult().getRelation());
  829. // find() exits to the right of 'g.h'
  830. EXPECT_GT(node_path.getLastComparisonResult().getOrder(), 0);
  831. // We then descend into 'i.g.h' and walk all the nodes in the
  832. // tree.
  833. previousWalk(dtree, node, node_path, name_count, true);
  834. node = NULL;
  835. node_path.clear();
  836. }
  837. {
  838. SCOPED_TRACE("Start inside a wrong node");
  839. // The d.e.f is a single node, but we want only part of it. We
  840. // should start iterating before it.
  841. EXPECT_EQ(TestDomainTree::NOTFOUND,
  842. dtree.find(Name("e.f"), &node, node_path));
  843. previousWalk(dtree, node, node_path, 3, true);
  844. node = NULL;
  845. node_path.clear();
  846. }
  847. {
  848. SCOPED_TRACE("Lookup in empty tree");
  849. // Just check it doesn't crash, etc.
  850. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  851. TestDomainTree& empty_tree(*tree_holder.get());
  852. EXPECT_EQ(TestDomainTree::NOTFOUND,
  853. empty_tree.find(Name("x"), &node, node_path));
  854. EXPECT_EQ(static_cast<void*>(NULL), node);
  855. EXPECT_EQ(static_cast<void*>(NULL),
  856. empty_tree.previousNode(node_path));
  857. node = NULL;
  858. node_path.clear();
  859. }
  860. }
  861. TEST_F(DomainTreeTest, largestNode) {
  862. cdtnode = dtree.largestNode();
  863. EXPECT_EQ(Name("k"), cdtnode->getName());
  864. // Check for largest node in an empty tree.
  865. TreeHolder empty_tree_holder
  866. (mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  867. TestDomainTree& empty_tree(*empty_tree_holder.get());
  868. EXPECT_EQ(static_cast<void*>(NULL), empty_tree.largestNode());
  869. }
  870. TEST_F(DomainTreeTest, nextNodeError) {
  871. // Empty chain for nextNode() is invalid.
  872. TestDomainTreeNodeChain chain;
  873. EXPECT_THROW(dtree.nextNode(chain), BadValue);
  874. }
  875. // A helper function for getLastComparedNode() below.
  876. void
  877. comparisonChecks(const TestDomainTreeNodeChain& chain,
  878. int expected_order, int expected_common_labels,
  879. NameComparisonResult::NameRelation expected_reln)
  880. {
  881. if (expected_order > 0) {
  882. EXPECT_LT(0, chain.getLastComparisonResult().getOrder());
  883. } else if (expected_order < 0) {
  884. EXPECT_GT(0, chain.getLastComparisonResult().getOrder());
  885. } else {
  886. EXPECT_EQ(0, chain.getLastComparisonResult().getOrder());
  887. }
  888. EXPECT_EQ(expected_common_labels,
  889. chain.getLastComparisonResult().getCommonLabels());
  890. EXPECT_EQ(expected_reln,
  891. chain.getLastComparisonResult().getRelation());
  892. }
  893. TEST_F(DomainTreeTest, getLastComparedNode) {
  894. TestDomainTree& tree = dtree_expose_empty_node; // use the "empty OK" mode
  895. TestDomainTreeNodeChain chain;
  896. // initially there should be no 'last compared'.
  897. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  898. // A search for an empty tree should result in no 'last compared', too.
  899. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  900. TestDomainTree& empty_tree(*tree_holder.get());
  901. EXPECT_EQ(TestDomainTree::NOTFOUND,
  902. empty_tree.find(Name("a"), &cdtnode, chain));
  903. EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
  904. chain.clear();
  905. const TestDomainTreeNode* expected_node = NULL;
  906. // Exact match case. The returned node should be last compared.
  907. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  908. tree.find(Name("x.d.e.f"), &expected_node, chain));
  909. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  910. // 1 = # labels of "x" (note: excluding ".")
  911. comparisonChecks(chain, 0, 1, NameComparisonResult::EQUAL);
  912. chain.clear();
  913. // Partial match, search stopped at the matching node, which should be
  914. // the last compared node.
  915. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  916. tree.find(Name("k.g.h"), &expected_node));
  917. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  918. tree.find(Name("x.k.g.h"), &cdtnode, chain));
  919. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  920. // k.g.h < x.k.g.h, 1 = # labels of "k"
  921. comparisonChecks(chain, 1, 1, NameComparisonResult::SUBDOMAIN);
  922. chain.clear();
  923. // Partial match, search stopped in the subtree below the matching node
  924. // after following a left branch.
  925. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  926. tree.find(Name("x.d.e.f"), &expected_node));
  927. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  928. tree.find(Name("a.d.e.f"), &cdtnode, chain));
  929. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  930. // a < x, no common labels
  931. comparisonChecks(chain, -1, 0, NameComparisonResult::NONE);
  932. chain.clear();
  933. // Partial match, search stopped in the subtree below the matching node
  934. // after following a right branch.
  935. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  936. tree.find(Name("z.d.e.f"), &expected_node));
  937. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  938. tree.find(Name("zz.d.e.f"), &cdtnode, chain));
  939. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  940. // zz > z, no common label
  941. comparisonChecks(chain, 1, 0, NameComparisonResult::NONE);
  942. chain.clear();
  943. // Partial match, search stopped at a node for a super domain of the
  944. // search name in the subtree below the matching node.
  945. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  946. tree.find(Name("w.y.d.e.f"), &expected_node));
  947. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  948. tree.find(Name("y.d.e.f"), &cdtnode, chain));
  949. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  950. // y < w.y, 1 = # labels of "y"
  951. comparisonChecks(chain, -1, 1, NameComparisonResult::SUPERDOMAIN);
  952. chain.clear();
  953. // Partial match, search stopped at a node that share a common ancestor
  954. // with the search name in the subtree below the matching node.
  955. // (the expected node is the same as the previous case)
  956. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  957. tree.find(Name("z.y.d.e.f"), &cdtnode, chain));
  958. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  959. // z.y > w.y, 1 = # labels of "y"
  960. comparisonChecks(chain, 1, 1, NameComparisonResult::COMMONANCESTOR);
  961. chain.clear();
  962. // Search stops in the highest level (under ".") after following a left
  963. // branch. (find() still returns PARTIALMATCH due to the top level ".")
  964. EXPECT_EQ(TestDomainTree::EXACTMATCH, tree.find(Name("c"), &expected_node));
  965. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  966. tree.find(Name("bb"), &cdtnode, chain));
  967. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  968. // bb < c, no common label
  969. comparisonChecks(chain, -1, 0, NameComparisonResult::NONE);
  970. chain.clear();
  971. // Search stops in the highest level (under ".") after following a right
  972. // branch. (the expected node is the same as the previous case)
  973. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  974. tree.find(Name("d"), &cdtnode, chain));
  975. EXPECT_EQ(expected_node, chain.getLastComparedNode());
  976. // d > c, no common label
  977. comparisonChecks(chain, 1, 0, NameComparisonResult::NONE);
  978. chain.clear();
  979. }
  980. TEST_F(DomainTreeTest, dumpTree) {
  981. std::ostringstream str;
  982. std::ostringstream str2;
  983. dtree.dumpTree(str);
  984. str2 << "tree has 15 node(s)\n"
  985. ". (black) [invisible] [subtreeroot]\n"
  986. " begin down from .\n"
  987. " b (black) [subtreeroot]\n"
  988. " a (black)\n"
  989. " NULL\n"
  990. " NULL\n"
  991. " d.e.f (black) [invisible]\n"
  992. " begin down from d.e.f\n"
  993. " w.y (black) [invisible] [subtreeroot]\n"
  994. " begin down from w.y\n"
  995. " p (black) [subtreeroot]\n"
  996. " o (red)\n"
  997. " NULL\n"
  998. " NULL\n"
  999. " q (red)\n"
  1000. " NULL\n"
  1001. " NULL\n"
  1002. " end down from w.y\n"
  1003. " x (red)\n"
  1004. " NULL\n"
  1005. " NULL\n"
  1006. " z (red)\n"
  1007. " begin down from z\n"
  1008. " j (black) [subtreeroot]\n"
  1009. " NULL\n"
  1010. " NULL\n"
  1011. " end down from z\n"
  1012. " NULL\n"
  1013. " NULL\n"
  1014. " end down from d.e.f\n"
  1015. " c (red)\n"
  1016. " NULL\n"
  1017. " NULL\n"
  1018. " g.h (red)\n"
  1019. " begin down from g.h\n"
  1020. " i (black) [subtreeroot]\n"
  1021. " NULL\n"
  1022. " k (red)\n"
  1023. " NULL\n"
  1024. " NULL\n"
  1025. " end down from g.h\n"
  1026. " NULL\n"
  1027. " NULL\n"
  1028. " end down from .\n"
  1029. " NULL\n"
  1030. " NULL\n";
  1031. EXPECT_EQ(str2.str(), str.str());
  1032. }
  1033. TEST_F(DomainTreeTest, swap) {
  1034. // Store info about the first tree
  1035. std::ostringstream str1;
  1036. dtree.dumpTree(str1);
  1037. size_t count1(dtree.getNodeCount());
  1038. // Create second one and store state
  1039. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  1040. TestDomainTree& tree2(*tree_holder.get());
  1041. TestDomainTreeNode* node;
  1042. tree2.insert(mem_sgmt_, Name("second"), &node);
  1043. std::ostringstream str2;
  1044. tree2.dumpTree(str2);
  1045. // Swap them
  1046. ASSERT_NO_THROW(tree2.swap(dtree));
  1047. // Check their sizes
  1048. ASSERT_EQ(1, dtree.getNodeCount());
  1049. ASSERT_EQ(count1, tree2.getNodeCount());
  1050. // And content
  1051. std::ostringstream out;
  1052. dtree.dumpTree(out);
  1053. ASSERT_EQ(str2.str(), out.str());
  1054. out.str("");
  1055. tree2.dumpTree(out);
  1056. ASSERT_EQ(str1.str(), out.str());
  1057. }
  1058. // Matching in the "root zone" may be special (e.g. there's no parent,
  1059. // any domain names should be considered a subdomain of it), so it makes
  1060. // sense to test cases with the root zone explicitly.
  1061. TEST_F(DomainTreeTest, root) {
  1062. TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
  1063. TestDomainTree& root(*tree_holder.get());
  1064. root.insert(mem_sgmt_, Name::ROOT_NAME(), &dtnode);
  1065. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(1)));
  1066. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  1067. root.find(Name::ROOT_NAME(), &cdtnode));
  1068. EXPECT_EQ(dtnode, cdtnode);
  1069. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1070. root.find(Name("example.com"), &cdtnode));
  1071. EXPECT_EQ(dtnode, cdtnode);
  1072. // Insert a new name that better matches the query name. find() should
  1073. // find the better one.
  1074. root.insert(mem_sgmt_, Name("com"), &dtnode);
  1075. EXPECT_EQ(static_cast<int*>(NULL), dtnode->setData(new int(2)));
  1076. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1077. root.find(Name("example.com"), &cdtnode));
  1078. EXPECT_EQ(dtnode, cdtnode);
  1079. // Perform the same tests for the tree that allows matching against empty
  1080. // nodes.
  1081. TreeHolder tree_holder_emptyok(mem_sgmt_,
  1082. TestDomainTree::create(mem_sgmt_, true));
  1083. TestDomainTree& root_emptyok(*tree_holder_emptyok.get());
  1084. root_emptyok.insert(mem_sgmt_, Name::ROOT_NAME(), &dtnode);
  1085. EXPECT_EQ(TestDomainTree::EXACTMATCH,
  1086. root_emptyok.find(Name::ROOT_NAME(), &cdtnode));
  1087. EXPECT_EQ(dtnode, cdtnode);
  1088. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1089. root_emptyok.find(Name("example.com"), &cdtnode));
  1090. EXPECT_EQ(dtnode, cdtnode);
  1091. root.insert(mem_sgmt_, Name("com"), &dtnode);
  1092. EXPECT_EQ(TestDomainTree::PARTIALMATCH,
  1093. root.find(Name("example.com"), &cdtnode));
  1094. EXPECT_EQ(dtnode, cdtnode);
  1095. }
  1096. TEST_F(DomainTreeTest, getAbsoluteLabels) {
  1097. // The full absolute names of the nodes in the tree
  1098. // with the addition of the explicit root node
  1099. const char* const domain_names[] = {
  1100. "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f",
  1101. "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
  1102. // The names of the nodes themselves, as they end up in the tree
  1103. const char* const first_labels[] = {
  1104. "c", "b", "a", "x", "z", "g.h", "i", "o",
  1105. "j", "p", "q", "k"};
  1106. const int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
  1107. for (int i = 0; i < name_count; ++i) {
  1108. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name(domain_names[i]),
  1109. &cdtnode));
  1110. // First make sure the names themselves are not absolute
  1111. const LabelSequence ls(cdtnode->getLabels());
  1112. EXPECT_EQ(first_labels[i], ls.toText());
  1113. EXPECT_FALSE(ls.isAbsolute());
  1114. // Now check the absolute names
  1115. const LabelSequence abs_ls(cdtnode->getAbsoluteLabels(buf));
  1116. EXPECT_EQ(Name(domain_names[i]).toText(), abs_ls.toText());
  1117. EXPECT_TRUE(abs_ls.isAbsolute());
  1118. }
  1119. // Explicitly add and find a root node, to see that getAbsoluteLabels
  1120. // also works when getLabels() already returns an absolute LabelSequence
  1121. dtree.insert(mem_sgmt_, Name("."), &dtnode);
  1122. dtnode->setData(new int(1));
  1123. EXPECT_EQ(TestDomainTree::EXACTMATCH, dtree.find(Name("."), &cdtnode));
  1124. EXPECT_TRUE(cdtnode->getLabels().isAbsolute());
  1125. EXPECT_EQ(".", cdtnode->getLabels().toText());
  1126. EXPECT_TRUE(cdtnode->getAbsoluteLabels(buf).isAbsolute());
  1127. EXPECT_EQ(".", cdtnode->getAbsoluteLabels(buf).toText());
  1128. }
  1129. }