labelsequence_unittest.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. // Copyright (C) 2012 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 <dns/labelsequence.h>
  15. #include <dns/name.h>
  16. #include <exceptions/exceptions.h>
  17. #include <gtest/gtest.h>
  18. #include <boost/functional/hash.hpp>
  19. #include <string>
  20. #include <vector>
  21. #include <utility>
  22. #include <set>
  23. using namespace isc::dns;
  24. using namespace std;
  25. // XXX: this is defined as class static constants, but some compilers
  26. // seemingly cannot find the symbols when used in the EXPECT_xxx macros.
  27. const size_t LabelSequence::MAX_SERIALIZED_LENGTH;
  28. namespace {
  29. class LabelSequenceTest : public ::testing::Test {
  30. public:
  31. LabelSequenceTest() : n1("example.org"), n2("example.com"),
  32. n3("example.org"), n4("foo.bar.test.example"),
  33. n5("example.ORG"), n6("ExAmPlE.org"),
  34. n7("."), n8("foo.example.org.bar"),
  35. n9("\\000xample.org"),
  36. n10("\\000xample.org"),
  37. n11("\\000xample.com"),
  38. n12("\\000xamplE.com"),
  39. n_maxlabel("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  40. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  41. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  42. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  43. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  44. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  45. "0.1.2.3.4.5.6"),
  46. ls1(n1), ls2(n2), ls3(n3), ls4(n4), ls5(n5),
  47. ls6(n6), ls7(n7), ls8(n8),
  48. ls9(n9), ls10(n10), ls11(n11), ls12(n12)
  49. {};
  50. // Need to keep names in scope for at least the lifetime of
  51. // the labelsequences
  52. Name n1, n2, n3, n4, n5, n6, n7, n8;
  53. Name n9, n10, n11, n12;
  54. const Name n_maxlabel;
  55. LabelSequence ls1, ls2, ls3, ls4, ls5, ls6, ls7, ls8;
  56. LabelSequence ls9, ls10, ls11, ls12;
  57. };
  58. // Basic equality tests
  59. TEST_F(LabelSequenceTest, equals_sensitive) {
  60. EXPECT_TRUE(ls1.equals(ls1, true));
  61. EXPECT_FALSE(ls1.equals(ls2, true));
  62. EXPECT_TRUE(ls1.equals(ls3, true));
  63. EXPECT_FALSE(ls1.equals(ls4, true));
  64. EXPECT_FALSE(ls1.equals(ls5, true));
  65. EXPECT_FALSE(ls1.equals(ls6, true));
  66. EXPECT_FALSE(ls1.equals(ls7, true));
  67. EXPECT_FALSE(ls1.equals(ls8, true));
  68. EXPECT_FALSE(ls2.equals(ls1, true));
  69. EXPECT_TRUE(ls2.equals(ls2, true));
  70. EXPECT_FALSE(ls2.equals(ls3, true));
  71. EXPECT_FALSE(ls2.equals(ls4, true));
  72. EXPECT_FALSE(ls2.equals(ls5, true));
  73. EXPECT_FALSE(ls2.equals(ls6, true));
  74. EXPECT_FALSE(ls2.equals(ls7, true));
  75. EXPECT_FALSE(ls2.equals(ls8, true));
  76. EXPECT_FALSE(ls4.equals(ls1, true));
  77. EXPECT_FALSE(ls4.equals(ls2, true));
  78. EXPECT_FALSE(ls4.equals(ls3, true));
  79. EXPECT_TRUE(ls4.equals(ls4, true));
  80. EXPECT_FALSE(ls4.equals(ls5, true));
  81. EXPECT_FALSE(ls4.equals(ls6, true));
  82. EXPECT_FALSE(ls4.equals(ls7, true));
  83. EXPECT_FALSE(ls4.equals(ls8, true));
  84. EXPECT_FALSE(ls5.equals(ls1, true));
  85. EXPECT_FALSE(ls5.equals(ls2, true));
  86. EXPECT_FALSE(ls5.equals(ls3, true));
  87. EXPECT_FALSE(ls5.equals(ls4, true));
  88. EXPECT_TRUE(ls5.equals(ls5, true));
  89. EXPECT_FALSE(ls5.equals(ls6, true));
  90. EXPECT_FALSE(ls5.equals(ls7, true));
  91. EXPECT_FALSE(ls5.equals(ls8, true));
  92. EXPECT_TRUE(ls9.equals(ls10, true));
  93. EXPECT_FALSE(ls9.equals(ls11, true));
  94. EXPECT_FALSE(ls9.equals(ls12, true));
  95. EXPECT_FALSE(ls11.equals(ls12, true));
  96. }
  97. TEST_F(LabelSequenceTest, equals_insensitive) {
  98. EXPECT_TRUE(ls1.equals(ls1));
  99. EXPECT_FALSE(ls1.equals(ls2));
  100. EXPECT_TRUE(ls1.equals(ls3));
  101. EXPECT_FALSE(ls1.equals(ls4));
  102. EXPECT_TRUE(ls1.equals(ls5));
  103. EXPECT_TRUE(ls1.equals(ls6));
  104. EXPECT_FALSE(ls1.equals(ls7));
  105. EXPECT_FALSE(ls2.equals(ls1));
  106. EXPECT_TRUE(ls2.equals(ls2));
  107. EXPECT_FALSE(ls2.equals(ls3));
  108. EXPECT_FALSE(ls2.equals(ls4));
  109. EXPECT_FALSE(ls2.equals(ls5));
  110. EXPECT_FALSE(ls2.equals(ls6));
  111. EXPECT_FALSE(ls2.equals(ls7));
  112. EXPECT_TRUE(ls3.equals(ls1));
  113. EXPECT_FALSE(ls3.equals(ls2));
  114. EXPECT_TRUE(ls3.equals(ls3));
  115. EXPECT_FALSE(ls3.equals(ls4));
  116. EXPECT_TRUE(ls3.equals(ls5));
  117. EXPECT_TRUE(ls3.equals(ls6));
  118. EXPECT_FALSE(ls3.equals(ls7));
  119. EXPECT_FALSE(ls4.equals(ls1));
  120. EXPECT_FALSE(ls4.equals(ls2));
  121. EXPECT_FALSE(ls4.equals(ls3));
  122. EXPECT_TRUE(ls4.equals(ls4));
  123. EXPECT_FALSE(ls4.equals(ls5));
  124. EXPECT_FALSE(ls4.equals(ls6));
  125. EXPECT_FALSE(ls4.equals(ls7));
  126. EXPECT_TRUE(ls5.equals(ls1));
  127. EXPECT_FALSE(ls5.equals(ls2));
  128. EXPECT_TRUE(ls5.equals(ls3));
  129. EXPECT_FALSE(ls5.equals(ls4));
  130. EXPECT_TRUE(ls5.equals(ls5));
  131. EXPECT_TRUE(ls5.equals(ls6));
  132. EXPECT_FALSE(ls5.equals(ls7));
  133. EXPECT_TRUE(ls9.equals(ls10));
  134. EXPECT_FALSE(ls9.equals(ls11));
  135. EXPECT_FALSE(ls9.equals(ls12));
  136. EXPECT_TRUE(ls11.equals(ls12));
  137. }
  138. // Compare tests
  139. TEST_F(LabelSequenceTest, compare) {
  140. // "example.org." and "example.org.", case sensitive
  141. NameComparisonResult result = ls1.compare(ls3, true);
  142. EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL,
  143. result.getRelation());
  144. EXPECT_EQ(0, result.getOrder());
  145. EXPECT_EQ(3, result.getCommonLabels());
  146. // "example.org." and "example.ORG.", case sensitive
  147. result = ls3.compare(ls5, true);
  148. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  149. result.getRelation());
  150. EXPECT_LT(0, result.getOrder());
  151. EXPECT_EQ(1, result.getCommonLabels());
  152. // "example.org." and "example.ORG.", case in-sensitive
  153. result = ls3.compare(ls5);
  154. EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL,
  155. result.getRelation());
  156. EXPECT_EQ(0, result.getOrder());
  157. EXPECT_EQ(3, result.getCommonLabels());
  158. Name na("a.example.org");
  159. Name nb("b.example.org");
  160. LabelSequence lsa(na);
  161. LabelSequence lsb(nb);
  162. // "a.example.org." and "b.example.org.", case in-sensitive
  163. result = lsa.compare(lsb);
  164. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  165. result.getRelation());
  166. EXPECT_GT(0, result.getOrder());
  167. EXPECT_EQ(3, result.getCommonLabels());
  168. // "example.org." and "b.example.org.", case in-sensitive
  169. lsa.stripLeft(1);
  170. result = lsa.compare(lsb);
  171. EXPECT_EQ(isc::dns::NameComparisonResult::SUPERDOMAIN,
  172. result.getRelation());
  173. EXPECT_GT(0, result.getOrder());
  174. EXPECT_EQ(3, result.getCommonLabels());
  175. Name nc("g.f.e.d.c.example.org");
  176. LabelSequence lsc(nc);
  177. // "g.f.e.d.c.example.org." and "b.example.org" (not absolute), case
  178. // in-sensitive; the absolute one is always smaller.
  179. lsb.stripRight(1);
  180. result = lsc.compare(lsb);
  181. EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation());
  182. EXPECT_GT(0, result.getOrder());
  183. EXPECT_EQ(0, result.getCommonLabels());
  184. // "g.f.e.d.c.example.org." and "example.org.", case in-sensitive
  185. result = lsc.compare(ls1);
  186. EXPECT_EQ(isc::dns::NameComparisonResult::SUBDOMAIN,
  187. result.getRelation());
  188. EXPECT_LT(0, result.getOrder());
  189. EXPECT_EQ(3, result.getCommonLabels());
  190. // "e.d.c.example.org." and "example.org.", case in-sensitive
  191. lsc.stripLeft(2);
  192. result = lsc.compare(ls1);
  193. EXPECT_EQ(isc::dns::NameComparisonResult::SUBDOMAIN,
  194. result.getRelation());
  195. EXPECT_LT(0, result.getOrder());
  196. EXPECT_EQ(3, result.getCommonLabels());
  197. // "example.org." and "example.org.", case in-sensitive
  198. lsc.stripLeft(3);
  199. result = lsc.compare(ls1);
  200. EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL,
  201. result.getRelation());
  202. EXPECT_EQ(0, result.getOrder());
  203. EXPECT_EQ(3, result.getCommonLabels());
  204. // "." and "example.org.", case in-sensitive
  205. lsc.stripLeft(2);
  206. result = lsc.compare(ls1);
  207. EXPECT_EQ(isc::dns::NameComparisonResult::SUPERDOMAIN,
  208. result.getRelation());
  209. EXPECT_GT(0, result.getOrder());
  210. EXPECT_EQ(1, result.getCommonLabels());
  211. Name nd("a.b.c.isc.example.org");
  212. LabelSequence lsd(nd);
  213. Name ne("w.x.y.isc.EXAMPLE.org");
  214. LabelSequence lse(ne);
  215. // "a.b.c.isc.example.org." and "w.x.y.isc.EXAMPLE.org.",
  216. // case sensitive
  217. result = lsd.compare(lse, true);
  218. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  219. result.getRelation());
  220. EXPECT_LT(0, result.getOrder());
  221. EXPECT_EQ(2, result.getCommonLabels());
  222. // "a.b.c.isc.example.org." and "w.x.y.isc.EXAMPLE.org.",
  223. // case in-sensitive
  224. result = lsd.compare(lse);
  225. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  226. result.getRelation());
  227. EXPECT_GT(0, result.getOrder());
  228. EXPECT_EQ(4, result.getCommonLabels());
  229. // "isc.example.org." and "isc.EXAMPLE.org.", case sensitive
  230. lsd.stripLeft(3);
  231. lse.stripLeft(3);
  232. result = lsd.compare(lse, true);
  233. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  234. result.getRelation());
  235. EXPECT_LT(0, result.getOrder());
  236. EXPECT_EQ(2, result.getCommonLabels());
  237. // "isc.example.org." and "isc.EXAMPLE.org.", case in-sensitive
  238. result = lsd.compare(lse);
  239. EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL,
  240. result.getRelation());
  241. EXPECT_EQ(0, result.getOrder());
  242. EXPECT_EQ(4, result.getCommonLabels());
  243. Name nf("a.b.c.isc.example.org");
  244. LabelSequence lsf(nf);
  245. Name ng("w.x.y.isc.EXAMPLE.org");
  246. LabelSequence lsg(ng);
  247. // lsf: "a.b.c.isc.example.org."
  248. // lsg: "w.x.y.isc.EXAMPLE.org" (not absolute), case in-sensitive.
  249. // the absolute one is always smaller.
  250. lsg.stripRight(1);
  251. result = lsg.compare(lsf); // lsg > lsf
  252. EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation());
  253. EXPECT_LT(0, result.getOrder());
  254. EXPECT_EQ(0, result.getCommonLabels());
  255. // "a.b.c.isc.example.org" (not absolute) and
  256. // "w.x.y.isc.EXAMPLE.org" (not absolute), case in-sensitive
  257. lsf.stripRight(1);
  258. result = lsg.compare(lsf);
  259. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  260. result.getRelation());
  261. EXPECT_LT(0, result.getOrder());
  262. EXPECT_EQ(3, result.getCommonLabels());
  263. // "a.b.c.isc.example" (not absolute) and
  264. // "w.x.y.isc.EXAMPLE" (not absolute), case in-sensitive
  265. lsf.stripRight(1);
  266. lsg.stripRight(1);
  267. result = lsg.compare(lsf);
  268. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  269. result.getRelation());
  270. EXPECT_LT(0, result.getOrder());
  271. EXPECT_EQ(2, result.getCommonLabels());
  272. // lsf: "a.b.c" (not absolute) and
  273. // lsg: "w.x.y" (not absolute), case in-sensitive; a.b.c < w.x.y;
  274. // no common labels.
  275. lsf.stripRight(2);
  276. lsg.stripRight(2);
  277. result = lsf.compare(lsg);
  278. EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation());
  279. EXPECT_GT(0, result.getOrder());
  280. EXPECT_EQ(0, result.getCommonLabels());
  281. // lsf2: a.b.cc (not absolute); a.b.c < a.b.cc, no common labels.
  282. const Name nf2("a.b.cc");
  283. LabelSequence lsf2(nf2);
  284. lsf2.stripRight(1);
  285. result = lsf.compare(lsf2);
  286. EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation());
  287. EXPECT_GT(0, result.getOrder());
  288. EXPECT_EQ(0, result.getCommonLabels());
  289. Name nh("aexample.org");
  290. LabelSequence lsh(nh);
  291. Name ni("bexample.org");
  292. LabelSequence lsi(ni);
  293. // "aexample.org" (not absolute) and
  294. // "bexample.org" (not absolute), case in-sensitive
  295. lsh.stripRight(1);
  296. lsi.stripRight(1);
  297. result = lsh.compare(lsi);
  298. EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR,
  299. result.getRelation());
  300. EXPECT_GT(0, result.getOrder());
  301. EXPECT_EQ(1, result.getCommonLabels());
  302. // "aexample" (not absolute) and
  303. // "bexample" (not absolute), case in-sensitive;
  304. // aexample < bexample; no common labels.
  305. lsh.stripRight(1);
  306. lsi.stripRight(1);
  307. result = lsh.compare(lsi);
  308. EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation());
  309. EXPECT_GT(0, result.getOrder());
  310. EXPECT_EQ(0, result.getCommonLabels());
  311. Name nj("example.org");
  312. LabelSequence lsj(nj);
  313. Name nk("example.org");
  314. LabelSequence lsk(nk);
  315. // "example.org" (not absolute) and
  316. // "example.org" (not absolute), case in-sensitive
  317. lsj.stripRight(1);
  318. lsk.stripRight(1);
  319. result = lsj.compare(lsk);
  320. EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL,
  321. result.getRelation());
  322. EXPECT_EQ(0, result.getOrder());
  323. EXPECT_EQ(2, result.getCommonLabels());
  324. // "example" (not absolute) and
  325. // "example" (not absolute), case in-sensitive
  326. lsj.stripRight(1);
  327. lsk.stripRight(1);
  328. result = lsj.compare(lsk);
  329. EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL,
  330. result.getRelation());
  331. EXPECT_EQ(0, result.getOrder());
  332. EXPECT_EQ(1, result.getCommonLabels());
  333. }
  334. void
  335. getDataCheck(const uint8_t* expected_data, size_t expected_len,
  336. const LabelSequence& ls)
  337. {
  338. size_t len;
  339. const uint8_t* data = ls.getData(&len);
  340. ASSERT_EQ(expected_len, len) << "Expected data: " << expected_data <<
  341. ", label sequence: " << ls;
  342. EXPECT_EQ(expected_len, ls.getDataLength()) <<
  343. "Expected data: " << expected_data <<
  344. ", label sequence: " << ls;
  345. for (size_t i = 0; i < len; ++i) {
  346. EXPECT_EQ(expected_data[i], data[i]) <<
  347. "Difference at pos " << i << ": Expected data: " << expected_data <<
  348. ", label sequence: " << ls;
  349. }
  350. }
  351. // Convenient data converter for expected data. Label data must be of
  352. // uint8_t*, while it's convenient if we can specify some test data in
  353. // plain string (which is of char*). This wrapper converts the latter to
  354. // the former in a safer way.
  355. void
  356. getDataCheck(const char* expected_char_data, size_t expected_len,
  357. const LabelSequence& ls)
  358. {
  359. const vector<uint8_t> expected_data(expected_char_data,
  360. expected_char_data + expected_len);
  361. getDataCheck(&expected_data[0], expected_len, ls);
  362. }
  363. TEST_F(LabelSequenceTest, getData) {
  364. getDataCheck("\007example\003org\000", 13, ls1);
  365. getDataCheck("\007example\003com\000", 13, ls2);
  366. getDataCheck("\007example\003org\000", 13, ls3);
  367. getDataCheck("\003foo\003bar\004test\007example\000", 22, ls4);
  368. getDataCheck("\007example\003ORG\000", 13, ls5);
  369. getDataCheck("\007ExAmPlE\003org\000", 13, ls6);
  370. getDataCheck("\000", 1, ls7);
  371. };
  372. TEST_F(LabelSequenceTest, stripLeft) {
  373. EXPECT_TRUE(ls1.equals(ls3));
  374. ls1.stripLeft(0);
  375. getDataCheck("\007example\003org\000", 13, ls1);
  376. EXPECT_TRUE(ls1.equals(ls3));
  377. ls1.stripLeft(1);
  378. getDataCheck("\003org\000", 5, ls1);
  379. EXPECT_FALSE(ls1.equals(ls3));
  380. ls1.stripLeft(1);
  381. getDataCheck("\000", 1, ls1);
  382. EXPECT_TRUE(ls1.equals(ls7));
  383. ls2.stripLeft(2);
  384. getDataCheck("\000", 1, ls2);
  385. EXPECT_TRUE(ls2.equals(ls7));
  386. }
  387. TEST_F(LabelSequenceTest, stripRight) {
  388. EXPECT_TRUE(ls1.equals(ls3));
  389. ls1.stripRight(1);
  390. getDataCheck("\007example\003org", 12, ls1);
  391. EXPECT_FALSE(ls1.equals(ls3));
  392. ls1.stripRight(1);
  393. getDataCheck("\007example", 8, ls1);
  394. EXPECT_FALSE(ls1.equals(ls3));
  395. ASSERT_FALSE(ls1.equals(ls2));
  396. ls2.stripRight(2);
  397. getDataCheck("\007example", 8, ls2);
  398. EXPECT_TRUE(ls1.equals(ls2));
  399. }
  400. TEST_F(LabelSequenceTest, stripOutOfRange) {
  401. EXPECT_THROW(ls1.stripLeft(100), isc::OutOfRange);
  402. EXPECT_THROW(ls1.stripLeft(5), isc::OutOfRange);
  403. EXPECT_THROW(ls1.stripLeft(4), isc::OutOfRange);
  404. EXPECT_THROW(ls1.stripLeft(3), isc::OutOfRange);
  405. getDataCheck("\007example\003org\000", 13, ls1);
  406. EXPECT_THROW(ls1.stripRight(100), isc::OutOfRange);
  407. EXPECT_THROW(ls1.stripRight(5), isc::OutOfRange);
  408. EXPECT_THROW(ls1.stripRight(4), isc::OutOfRange);
  409. EXPECT_THROW(ls1.stripRight(3), isc::OutOfRange);
  410. getDataCheck("\007example\003org\000", 13, ls1);
  411. }
  412. TEST_F(LabelSequenceTest, getLabelCount) {
  413. EXPECT_EQ(3, ls1.getLabelCount());
  414. ls1.stripLeft(0);
  415. EXPECT_EQ(3, ls1.getLabelCount());
  416. ls1.stripLeft(1);
  417. EXPECT_EQ(2, ls1.getLabelCount());
  418. ls1.stripLeft(1);
  419. EXPECT_EQ(1, ls1.getLabelCount());
  420. EXPECT_EQ(3, ls2.getLabelCount());
  421. ls2.stripRight(1);
  422. EXPECT_EQ(2, ls2.getLabelCount());
  423. ls2.stripRight(1);
  424. EXPECT_EQ(1, ls2.getLabelCount());
  425. EXPECT_EQ(3, ls3.getLabelCount());
  426. ls3.stripRight(2);
  427. EXPECT_EQ(1, ls3.getLabelCount());
  428. EXPECT_EQ(5, ls4.getLabelCount());
  429. ls4.stripRight(3);
  430. EXPECT_EQ(2, ls4.getLabelCount());
  431. EXPECT_EQ(3, ls5.getLabelCount());
  432. ls5.stripLeft(2);
  433. EXPECT_EQ(1, ls5.getLabelCount());
  434. }
  435. TEST_F(LabelSequenceTest, comparePart) {
  436. EXPECT_FALSE(ls1.equals(ls8));
  437. // strip root label from example.org.
  438. ls1.stripRight(1);
  439. // strip foo from foo.example.org.bar.
  440. ls8.stripLeft(1);
  441. // strip bar. (i.e. bar and root) too
  442. ls8.stripRight(2);
  443. EXPECT_TRUE(ls1.equals(ls8));
  444. // Data comparison
  445. size_t len;
  446. const uint8_t* data = ls1.getData(&len);
  447. getDataCheck(data, len, ls8);
  448. }
  449. TEST_F(LabelSequenceTest, isAbsolute) {
  450. ASSERT_TRUE(ls1.isAbsolute());
  451. ls1.stripLeft(1);
  452. ASSERT_TRUE(ls1.isAbsolute());
  453. ls1.stripRight(1);
  454. ASSERT_FALSE(ls1.isAbsolute());
  455. ASSERT_TRUE(ls2.isAbsolute());
  456. ls2.stripRight(1);
  457. ASSERT_FALSE(ls2.isAbsolute());
  458. ASSERT_TRUE(ls3.isAbsolute());
  459. ls3.stripLeft(2);
  460. ASSERT_TRUE(ls3.isAbsolute());
  461. }
  462. TEST_F(LabelSequenceTest, toText) {
  463. EXPECT_EQ(".", ls7.toText());
  464. EXPECT_EQ("example.org.", ls1.toText());
  465. ls1.stripLeft(1);
  466. EXPECT_EQ("org.", ls1.toText());
  467. ls1.stripLeft(1);
  468. EXPECT_EQ(".", ls1.toText());
  469. EXPECT_EQ("example.com.", ls2.toText());
  470. ls2.stripRight(1);
  471. EXPECT_EQ("example.com", ls2.toText());
  472. ls2.stripRight(1);
  473. EXPECT_EQ("example", ls2.toText());
  474. EXPECT_EQ("foo.example.org.bar.", ls8.toText());
  475. ls8.stripRight(2);
  476. EXPECT_EQ("foo.example.org", ls8.toText());
  477. EXPECT_EQ(".", ls7.toText());
  478. EXPECT_THROW(ls7.stripLeft(1), isc::OutOfRange);
  479. Name n_long1("012345678901234567890123456789"
  480. "012345678901234567890123456789012."
  481. "012345678901234567890123456789"
  482. "012345678901234567890123456789012."
  483. "012345678901234567890123456789"
  484. "012345678901234567890123456789012."
  485. "012345678901234567890123456789"
  486. "0123456789012345678901234567890");
  487. LabelSequence ls_long1(n_long1);
  488. EXPECT_EQ("012345678901234567890123456789"
  489. "012345678901234567890123456789012."
  490. "012345678901234567890123456789"
  491. "012345678901234567890123456789012."
  492. "012345678901234567890123456789"
  493. "012345678901234567890123456789012."
  494. "012345678901234567890123456789"
  495. "0123456789012345678901234567890.", ls_long1.toText());
  496. ls_long1.stripRight(1);
  497. EXPECT_EQ("012345678901234567890123456789"
  498. "012345678901234567890123456789012."
  499. "012345678901234567890123456789"
  500. "012345678901234567890123456789012."
  501. "012345678901234567890123456789"
  502. "012345678901234567890123456789012."
  503. "012345678901234567890123456789"
  504. "0123456789012345678901234567890", ls_long1.toText());
  505. LabelSequence ls_long2(n_maxlabel);
  506. EXPECT_EQ("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  507. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  508. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  509. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  510. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  511. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  512. "0.1.2.3.4.5.6.", ls_long2.toText());
  513. ls_long2.stripRight(1);
  514. EXPECT_EQ("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  515. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  516. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  517. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  518. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  519. "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
  520. "0.1.2.3.4.5.6", ls_long2.toText());
  521. ls_long2.stripRight(125);
  522. EXPECT_EQ("0.1", ls_long2.toText());
  523. }
  524. // The following are test data used in the getHash test below. Normally
  525. // we use example/documentation domain names for testing, but in this case
  526. // we'd specifically like to use more realistic data, and are intentionally
  527. // using real-world samples: They are the NS names of root and some top level
  528. // domains as of this test.
  529. const char* const root_servers[] = {
  530. "a.root-servers.net", "b.root-servers.net", "c.root-servers.net",
  531. "d.root-servers.net", "e.root-servers.net", "f.root-servers.net",
  532. "g.root-servers.net", "h.root-servers.net", "i.root-servers.net",
  533. "j.root-servers.net", "k.root-servers.net", "l.root-servers.net",
  534. "m.root-servers.net", NULL
  535. };
  536. const char* const gtld_servers[] = {
  537. "a.gtld-servers.net", "b.gtld-servers.net", "c.gtld-servers.net",
  538. "d.gtld-servers.net", "e.gtld-servers.net", "f.gtld-servers.net",
  539. "g.gtld-servers.net", "h.gtld-servers.net", "i.gtld-servers.net",
  540. "j.gtld-servers.net", "k.gtld-servers.net", "l.gtld-servers.net",
  541. "m.gtld-servers.net", NULL
  542. };
  543. const char* const jp_servers[] = {
  544. "a.dns.jp", "b.dns.jp", "c.dns.jp", "d.dns.jp", "e.dns.jp",
  545. "f.dns.jp", "g.dns.jp", NULL
  546. };
  547. const char* const cn_servers[] = {
  548. "a.dns.cn", "b.dns.cn", "c.dns.cn", "d.dns.cn", "e.dns.cn",
  549. "ns.cernet.net", NULL
  550. };
  551. const char* const ca_servers[] = {
  552. "k.ca-servers.ca", "e.ca-servers.ca", "a.ca-servers.ca", "z.ca-servers.ca",
  553. "tld.isc-sns.net", "c.ca-servers.ca", "j.ca-servers.ca", "l.ca-servers.ca",
  554. "sns-pb.isc.org", "f.ca-servers.ca", NULL
  555. };
  556. // A helper function used in the getHash test below.
  557. void
  558. hashDistributionCheck(const char* const* servers) {
  559. const size_t BUCKETS = 64; // constant used in the MessageRenderer
  560. set<Name> names;
  561. vector<size_t> hash_counts(BUCKETS);
  562. // Store all test names and their super domain names (excluding the
  563. // "root" label) in the set, calculates their hash values, and increments
  564. // the counter for the corresponding hash "bucket".
  565. for (size_t i = 0; servers[i] != NULL; ++i) {
  566. const Name name(servers[i]);
  567. for (size_t l = 0; l < name.getLabelCount() - 1; ++l) {
  568. pair<set<Name>::const_iterator, bool> ret =
  569. names.insert(name.split(l));
  570. if (ret.second) {
  571. hash_counts[LabelSequence((*ret.first)).getHash(false) %
  572. BUCKETS]++;
  573. }
  574. }
  575. }
  576. // See how many conflicts we have in the buckets. For the testing purpose
  577. // we expect there's at most 2 conflicts in each set, which is an
  578. // arbitrary choice (it should happen to succeed with the hash function
  579. // and data we are using; if it's not the case, maybe with an update to
  580. // the hash implementation, we should revise the test).
  581. for (size_t i = 0; i < BUCKETS; ++i) {
  582. EXPECT_GE(3, hash_counts[i]);
  583. }
  584. }
  585. TEST_F(LabelSequenceTest, getHash) {
  586. // Trivial case. The same sequence should have the same hash.
  587. EXPECT_EQ(ls1.getHash(true), ls1.getHash(true));
  588. // Check the case-insensitive mode behavior.
  589. EXPECT_EQ(ls1.getHash(false), ls5.getHash(false));
  590. // Check that the distribution of hash values is "not too bad" (such as
  591. // everything has the same hash value due to a stupid bug). It's
  592. // difficult to check such things reliably. We do some ad hoc tests here.
  593. hashDistributionCheck(root_servers);
  594. hashDistributionCheck(jp_servers);
  595. hashDistributionCheck(cn_servers);
  596. hashDistributionCheck(ca_servers);
  597. }
  598. // test operator<<. We simply confirm it appends the result of toText().
  599. TEST_F(LabelSequenceTest, LeftShiftOperator) {
  600. ostringstream oss;
  601. oss << ls1;
  602. EXPECT_EQ(ls1.toText(), oss.str());
  603. }
  604. TEST_F(LabelSequenceTest, serialize) {
  605. // placeholder for serialized data
  606. uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH];
  607. // vector to store expected and actual data
  608. vector<LabelSequence> actual_labelseqs;
  609. typedef pair<size_t, const uint8_t*> DataPair;
  610. vector<DataPair> expected;
  611. // An absolute sequence directly constructed from a valid name.
  612. // labels = 3, offset sequence = 0, 8, 12, data = "example.com."
  613. actual_labelseqs.push_back(ls1);
  614. const uint8_t const expected_data1[] = {
  615. 3, 0, 8, 12, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  616. 3, 'o', 'r', 'g', 0 };
  617. expected.push_back(DataPair(sizeof(expected_data1), expected_data1));
  618. // Strip the original one from right.
  619. // labels = 2, offset sequence = 0, 8, data = "example.com" (non absolute)
  620. LabelSequence ls_rstripped = ls1;
  621. ls_rstripped.stripRight(1);
  622. actual_labelseqs.push_back(ls_rstripped);
  623. const uint8_t const expected_data2[] = {
  624. 2, 0, 8, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  625. 3, 'o', 'r', 'g'};
  626. expected.push_back(DataPair(sizeof(expected_data2), expected_data2));
  627. // Strip the original one from left.
  628. // labels = 2, offset sequence = 0, 4, data = "com."
  629. // Note that offsets are adjusted so that they begin with 0.
  630. LabelSequence ls_lstripped = ls1;
  631. ls_lstripped.stripLeft(1);
  632. actual_labelseqs.push_back(ls_lstripped);
  633. const uint8_t const expected_data3[] = {
  634. 2, 0, 4, 3, 'o', 'r', 'g', 0 };
  635. expected.push_back(DataPair(sizeof(expected_data3), expected_data3));
  636. // Root label.
  637. LabelSequence ls_root(Name::ROOT_NAME());
  638. actual_labelseqs.push_back(ls_root);
  639. const uint8_t const expected_data4[] = { 1, 0, 0 };
  640. expected.push_back(DataPair(sizeof(expected_data4), expected_data4));
  641. // Non absolute single-label.
  642. LabelSequence ls_single = ls_rstripped;
  643. ls_single.stripRight(1);
  644. actual_labelseqs.push_back(ls_single);
  645. const uint8_t const expected_data5[] = {
  646. 1, 0, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e' };
  647. expected.push_back(DataPair(sizeof(expected_data5), expected_data5));
  648. // For each data set, serialize the labels and compare the data to the
  649. // expected one.
  650. vector<DataPair>::const_iterator it = expected.begin();
  651. vector<LabelSequence>::const_iterator itl = actual_labelseqs.begin();
  652. for (; it != expected.end(); ++it, ++itl) {
  653. SCOPED_TRACE(itl->toText());
  654. const size_t serialized_len = itl->getSerializedLength();
  655. ASSERT_GE(LabelSequence::MAX_SERIALIZED_LENGTH, serialized_len);
  656. itl->serialize(labels_buf, serialized_len);
  657. EXPECT_EQ(it->first, serialized_len);
  658. EXPECT_EQ(0, memcmp(it->second, labels_buf, serialized_len));
  659. EXPECT_EQ(NameComparisonResult::EQUAL,
  660. LabelSequence(labels_buf).compare(*itl).getRelation());
  661. }
  662. EXPECT_THROW(ls1.serialize(labels_buf, ls1.getSerializedLength() - 1),
  663. isc::BadValue);
  664. }
  665. TEST_F(LabelSequenceTest, badDeserialize) {
  666. EXPECT_THROW(LabelSequence(NULL), isc::BadValue);
  667. const uint8_t const zero_offsets[] = { 0 };
  668. EXPECT_THROW(LabelSequence ls(zero_offsets), isc::BadValue);
  669. const uint8_t const toomany_offsets[] = { Name::MAX_LABELS + 1 };
  670. EXPECT_THROW(LabelSequence ls(toomany_offsets), isc::BadValue);
  671. // exceed MAX_LABEL_LEN
  672. const uint8_t const offsets_toolonglabel[] = { 2, 0, 64 };
  673. EXPECT_THROW(LabelSequence ls(offsets_toolonglabel), isc::BadValue);
  674. // Inconsistent data: an offset is lower than the previous offset
  675. const uint8_t const offsets_lower[] = { 3, // # of offsets
  676. 0, 2, 1, // offsets
  677. 1, 'a', 1, 'b', 0};
  678. EXPECT_THROW(LabelSequence ls(offsets_lower), isc::BadValue);
  679. // Inconsistent data: an offset is equal to the previous offset
  680. const uint8_t const offsets_noincrease[] = { 2, 0, 0, 0, 0 };
  681. EXPECT_THROW(LabelSequence ls(offsets_noincrease), isc::BadValue);
  682. }
  683. }