memory_datasrc_unittest.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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 <exceptions/exceptions.h>
  15. #include <dns/name.h>
  16. #include <dns/rdata.h>
  17. #include <dns/rdataclass.h>
  18. #include <dns/rrclass.h>
  19. #include <dns/rrttl.h>
  20. #include <dns/masterload.h>
  21. #include <datasrc/memory_datasrc.h>
  22. #include <gtest/gtest.h>
  23. using namespace isc::dns;
  24. using namespace isc::dns::rdata;
  25. using namespace isc::datasrc;
  26. namespace {
  27. // Commonly used result codes (Who should write the prefix all the time)
  28. using result::SUCCESS;
  29. using result::EXIST;
  30. class MemoryDataSrcTest : public ::testing::Test {
  31. protected:
  32. MemoryDataSrcTest() : rrclass(RRClass::IN())
  33. {}
  34. RRClass rrclass;
  35. MemoryDataSrc memory_datasrc;
  36. };
  37. TEST_F(MemoryDataSrcTest, add_find_Zone) {
  38. // test add zone
  39. // Bogus zone (NULL)
  40. EXPECT_THROW(memory_datasrc.addZone(ZonePtr()), isc::InvalidParameter);
  41. // add zones with different names one by one
  42. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  43. ZonePtr(new MemoryZone(RRClass::IN(), Name("a")))));
  44. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  45. ZonePtr(new MemoryZone(RRClass::CH(), Name("b")))));
  46. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  47. ZonePtr(new MemoryZone(RRClass::IN(), Name("c")))));
  48. // add zones with the same name suffix
  49. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  50. ZonePtr(new MemoryZone(RRClass::CH(),
  51. Name("x.d.e.f")))));
  52. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  53. ZonePtr(new MemoryZone(RRClass::CH(),
  54. Name("o.w.y.d.e.f")))));
  55. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  56. ZonePtr(new MemoryZone(RRClass::CH(),
  57. Name("p.w.y.d.e.f")))));
  58. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  59. ZonePtr(new MemoryZone(RRClass::IN(),
  60. Name("q.w.y.d.e.f")))));
  61. // add super zone and its subzone
  62. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  63. ZonePtr(new MemoryZone(RRClass::CH(), Name("g.h")))));
  64. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  65. ZonePtr(new MemoryZone(RRClass::IN(), Name("i.g.h")))));
  66. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  67. ZonePtr(new MemoryZone(RRClass::IN(),
  68. Name("z.d.e.f")))));
  69. EXPECT_EQ(result::SUCCESS, memory_datasrc.addZone(
  70. ZonePtr(new MemoryZone(RRClass::IN(),
  71. Name("j.z.d.e.f")))));
  72. // different zone class isn't allowed.
  73. EXPECT_EQ(result::EXIST, memory_datasrc.addZone(
  74. ZonePtr(new MemoryZone(RRClass::CH(),
  75. Name("q.w.y.d.e.f")))));
  76. // names are compared in a case insensitive manner.
  77. EXPECT_EQ(result::EXIST, memory_datasrc.addZone(
  78. ZonePtr(new MemoryZone(RRClass::IN(),
  79. Name("Q.W.Y.d.E.f")))));
  80. // test find zone
  81. EXPECT_EQ(result::SUCCESS, memory_datasrc.findZone(Name("a")).code);
  82. EXPECT_EQ(Name("a"),
  83. memory_datasrc.findZone(Name("a")).zone->getOrigin());
  84. EXPECT_EQ(result::SUCCESS,
  85. memory_datasrc.findZone(Name("j.z.d.e.f")).code);
  86. EXPECT_EQ(Name("j.z.d.e.f"),
  87. memory_datasrc.findZone(Name("j.z.d.e.f")).zone->getOrigin());
  88. // NOTFOUND
  89. EXPECT_EQ(result::NOTFOUND, memory_datasrc.findZone(Name("d.e.f")).code);
  90. EXPECT_EQ(ConstZonePtr(), memory_datasrc.findZone(Name("d.e.f")).zone);
  91. EXPECT_EQ(result::NOTFOUND,
  92. memory_datasrc.findZone(Name("w.y.d.e.f")).code);
  93. EXPECT_EQ(ConstZonePtr(),
  94. memory_datasrc.findZone(Name("w.y.d.e.f")).zone);
  95. // there's no exact match. the result should be the longest match,
  96. // and the code should be PARTIALMATCH.
  97. EXPECT_EQ(result::PARTIALMATCH,
  98. memory_datasrc.findZone(Name("j.g.h")).code);
  99. EXPECT_EQ(Name("g.h"),
  100. memory_datasrc.findZone(Name("g.h")).zone->getOrigin());
  101. EXPECT_EQ(result::PARTIALMATCH,
  102. memory_datasrc.findZone(Name("z.i.g.h")).code);
  103. EXPECT_EQ(Name("i.g.h"),
  104. memory_datasrc.findZone(Name("z.i.g.h")).zone->getOrigin());
  105. }
  106. TEST_F(MemoryDataSrcTest, getZoneCount) {
  107. EXPECT_EQ(0, memory_datasrc.getZoneCount());
  108. memory_datasrc.addZone(
  109. ZonePtr(new MemoryZone(rrclass, Name("example.com"))));
  110. EXPECT_EQ(1, memory_datasrc.getZoneCount());
  111. // duplicate add. counter shouldn't change
  112. memory_datasrc.addZone(
  113. ZonePtr(new MemoryZone(rrclass, Name("example.com"))));
  114. EXPECT_EQ(1, memory_datasrc.getZoneCount());
  115. // add one more
  116. memory_datasrc.addZone(
  117. ZonePtr(new MemoryZone(rrclass, Name("example.org"))));
  118. EXPECT_EQ(2, memory_datasrc.getZoneCount());
  119. }
  120. /// \brief Test fixture for the MemoryZone class
  121. class MemoryZoneTest : public ::testing::Test {
  122. public:
  123. MemoryZoneTest() :
  124. class_(RRClass::IN()),
  125. origin_("example.org"),
  126. ns_name_("ns.example.org"),
  127. cname_name_("cname.example.org"),
  128. child_ns_name_("child.example.org"),
  129. child_glue_name_("ns.child.example.org"),
  130. grandchild_ns_name_("grand.child.example.org"),
  131. grandchild_glue_name_("ns.grand.child.example.org"),
  132. zone_(class_, origin_),
  133. rr_out_(new RRset(Name("example.com"), class_, RRType::A(),
  134. RRTTL(300))),
  135. rr_ns_(new RRset(origin_, class_, RRType::NS(), RRTTL(300))),
  136. rr_ns_a_(new RRset(ns_name_, class_, RRType::A(), RRTTL(300))),
  137. rr_ns_aaaa_(new RRset(ns_name_, class_, RRType::AAAA(), RRTTL(300))),
  138. rr_a_(new RRset(origin_, class_, RRType::A(), RRTTL(300))),
  139. rr_cname_(new RRset(cname_name_, class_, RRType::CNAME(), RRTTL(300))),
  140. rr_cname_a_(new RRset(cname_name_, class_, RRType::A(), RRTTL(300))),
  141. rr_child_ns_(new RRset(child_ns_name_, class_, RRType::NS(),
  142. RRTTL(300))),
  143. rr_child_glue_(new RRset(child_glue_name_, class_, RRType::A(),
  144. RRTTL(300))),
  145. rr_grandchild_ns_(new RRset(grandchild_ns_name_, class_, RRType::NS(),
  146. RRTTL(300))),
  147. rr_grandchild_glue_(new RRset(grandchild_glue_name_, class_,
  148. RRType::AAAA(), RRTTL(300)))
  149. {
  150. }
  151. // Some data to test with
  152. const RRClass class_;
  153. const Name origin_, ns_name_, cname_name_, child_ns_name_,
  154. child_glue_name_, grandchild_ns_name_, grandchild_glue_name_;
  155. // The zone to torture by tests
  156. MemoryZone zone_;
  157. /*
  158. * Some RRsets to put inside the zone.
  159. * They are empty, but the MemoryZone does not have a reason to look
  160. * inside anyway. We will check it finds them and does not change
  161. * the pointer.
  162. */
  163. ConstRRsetPtr
  164. // Out of zone RRset
  165. rr_out_,
  166. // NS of example.org
  167. rr_ns_,
  168. // A of ns.example.org
  169. rr_ns_a_,
  170. // AAAA of ns.example.org
  171. rr_ns_aaaa_,
  172. // A of example.org
  173. rr_a_;
  174. RRsetPtr rr_cname_; // CNAME in example.org (RDATA will be added)
  175. ConstRRsetPtr rr_cname_a_; // for mixed CNAME + A case
  176. ConstRRsetPtr rr_child_ns_; // NS of a child domain (for delegation)
  177. ConstRRsetPtr rr_child_glue_; // glue RR of the child domain
  178. ConstRRsetPtr rr_grandchild_ns_; // NS below a zone cut (unusual)
  179. ConstRRsetPtr rr_grandchild_glue_; // glue RR below a deeper zone cut
  180. /**
  181. * \brief Test one find query to the zone.
  182. *
  183. * Asks a query to the zone and checks it does not throw and returns
  184. * expected results. It returns nothing, it just signals failures
  185. * to GTEST.
  186. *
  187. * \param name The name to ask for.
  188. * \param rrtype The RRType to ask of.
  189. * \param result The expected code of the result.
  190. * \param check_answer Should a check against equality of the answer be
  191. * done?
  192. * \param answer The expected rrset, if any should be returned.
  193. * \param zone Check different MemoryZone object than zone_ (if NULL,
  194. * uses zone_)
  195. */
  196. void findTest(const Name& name, const RRType& rrtype, Zone::Result result,
  197. bool check_answer = true,
  198. const ConstRRsetPtr& answer = ConstRRsetPtr(),
  199. MemoryZone *zone = NULL,
  200. Zone::FindOptions options = Zone::FIND_DEFAULT)
  201. {
  202. if (!zone) {
  203. zone = &zone_;
  204. }
  205. // The whole block is inside, because we need to check the result and
  206. // we can't assign to FindResult
  207. EXPECT_NO_THROW({
  208. Zone::FindResult find_result(zone->find(name, rrtype,
  209. options));
  210. // Check it returns correct answers
  211. EXPECT_EQ(result, find_result.code);
  212. if (check_answer) {
  213. EXPECT_EQ(answer, find_result.rrset);
  214. }
  215. });
  216. }
  217. };
  218. /**
  219. * \brief Test MemoryZone::MemoryZone constructor.
  220. *
  221. * Takes the created zone and checks its properties they are the same
  222. * as passed parameters.
  223. */
  224. TEST_F(MemoryZoneTest, constructor) {
  225. ASSERT_EQ(class_, zone_.getClass());
  226. ASSERT_EQ(origin_, zone_.getOrigin());
  227. }
  228. /**
  229. * \brief Test adding.
  230. *
  231. * We test that it throws at the correct moments and the correct exceptions.
  232. * And we test the return value.
  233. */
  234. TEST_F(MemoryZoneTest, add) {
  235. // This one does not belong to this zone
  236. EXPECT_THROW(zone_.add(rr_out_), MemoryZone::OutOfZone);
  237. // Test null pointer
  238. EXPECT_THROW(zone_.add(ConstRRsetPtr()), MemoryZone::NullRRset);
  239. // Now put all the data we have there. It should throw nothing
  240. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_)));
  241. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_a_)));
  242. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_aaaa_)));
  243. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_a_)));
  244. // Try putting there something twice, it should be rejected
  245. EXPECT_NO_THROW(EXPECT_EQ(EXIST, zone_.add(rr_ns_)));
  246. EXPECT_NO_THROW(EXPECT_EQ(EXIST, zone_.add(rr_ns_a_)));
  247. }
  248. TEST_F(MemoryZoneTest, addMultipleCNAMEs) {
  249. rr_cname_->addRdata(generic::CNAME("canonical1.example.org."));
  250. rr_cname_->addRdata(generic::CNAME("canonical2.example.org."));
  251. EXPECT_THROW(zone_.add(rr_cname_), MemoryZone::AddError);
  252. }
  253. TEST_F(MemoryZoneTest, addCNAMEThenOther) {
  254. rr_cname_->addRdata(generic::CNAME("canonical.example.org."));
  255. EXPECT_EQ(SUCCESS, zone_.add(rr_cname_));
  256. EXPECT_THROW(zone_.add(rr_cname_a_), MemoryZone::AddError);
  257. }
  258. TEST_F(MemoryZoneTest, addOtherThenCNAME) {
  259. rr_cname_->addRdata(generic::CNAME("canonical.example.org."));
  260. EXPECT_EQ(SUCCESS, zone_.add(rr_cname_a_));
  261. EXPECT_THROW(zone_.add(rr_cname_), MemoryZone::AddError);
  262. }
  263. TEST_F(MemoryZoneTest, findCNAME) {
  264. // install CNAME RR
  265. rr_cname_->addRdata(generic::CNAME("canonical.example.org."));
  266. EXPECT_EQ(SUCCESS, zone_.add(rr_cname_));
  267. // Find A RR of the same. Should match the CNAME
  268. findTest(cname_name_, RRType::NS(), Zone::CNAME, true, rr_cname_);
  269. // Find the CNAME itself. Should result in normal SUCCESS
  270. findTest(cname_name_, RRType::CNAME(), Zone::SUCCESS, true, rr_cname_);
  271. }
  272. TEST_F(MemoryZoneTest, findCNAMEUnderZoneCut) {
  273. // There's nothing special when we find a CNAME under a zone cut
  274. // (with FIND_GLUE_OK). The behavior is different from BIND 9,
  275. // so we test this case explicitly.
  276. EXPECT_EQ(SUCCESS, zone_.add(rr_child_ns_));
  277. RRsetPtr rr_cname_under_cut_(new RRset(Name("cname.child.example.org"),
  278. class_, RRType::CNAME(),
  279. RRTTL(300)));
  280. EXPECT_EQ(SUCCESS, zone_.add(rr_cname_under_cut_));
  281. findTest(Name("cname.child.example.org"), RRType::AAAA(),
  282. Zone::CNAME, true, rr_cname_under_cut_, NULL, Zone::FIND_GLUE_OK);
  283. }
  284. // Test adding child zones and zone cut handling
  285. TEST_F(MemoryZoneTest, delegationNS) {
  286. // add in-zone data
  287. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_)));
  288. // install a zone cut
  289. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_child_ns_)));
  290. // below the zone cut
  291. findTest(Name("www.child.example.org"), RRType::A(), Zone::DELEGATION,
  292. true, rr_child_ns_);
  293. // at the zone cut
  294. findTest(Name("child.example.org"), RRType::A(), Zone::DELEGATION,
  295. true, rr_child_ns_);
  296. findTest(Name("child.example.org"), RRType::NS(), Zone::DELEGATION,
  297. true, rr_child_ns_);
  298. // finding NS for the apex (origin) node. This must not be confused
  299. // with delegation due to the existence of an NS RR.
  300. findTest(origin_, RRType::NS(), Zone::SUCCESS, true, rr_ns_);
  301. // unusual case of "nested delegation": the highest cut should be used.
  302. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_grandchild_ns_)));
  303. findTest(Name("www.grand.child.example.org"), RRType::A(),
  304. Zone::DELEGATION, true, rr_child_ns_); // note: !rr_grandchild_ns_
  305. }
  306. TEST_F(MemoryZoneTest, glue) {
  307. // install zone data:
  308. // a zone cut
  309. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_child_ns_)));
  310. // glue for this cut
  311. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_child_glue_)));
  312. // a nested zone cut (unusual)
  313. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_grandchild_ns_)));
  314. // glue under the deeper zone cut
  315. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_grandchild_glue_)));
  316. // by default glue is hidden due to the zone cut
  317. findTest(child_glue_name_, RRType::A(), Zone::DELEGATION, true,
  318. rr_child_ns_);
  319. // If we do it in the "glue OK" mode, we should find the exact match.
  320. findTest(child_glue_name_, RRType::A(), Zone::SUCCESS, true,
  321. rr_child_glue_, NULL, Zone::FIND_GLUE_OK);
  322. // glue OK + NXRRSET case
  323. findTest(child_glue_name_, RRType::AAAA(), Zone::NXRRSET, true,
  324. ConstRRsetPtr(), NULL, Zone::FIND_GLUE_OK);
  325. // glue OK + NXDOMAIN case
  326. findTest(Name("www.child.example.org"), RRType::A(), Zone::DELEGATION,
  327. true, rr_child_ns_, NULL, Zone::FIND_GLUE_OK);
  328. // TODO:
  329. // glue name would match a wildcard under a zone cut: wildcard match
  330. // shouldn't happen under a cut and result must be PARTIALMATCH
  331. // (This case cannot be tested yet)
  332. // nested cut case. The glue should be found.
  333. findTest(grandchild_glue_name_, RRType::AAAA(), Zone::SUCCESS,
  334. true, rr_grandchild_glue_, NULL, Zone::FIND_GLUE_OK);
  335. // A non-existent name in nested cut. This should result in delegation
  336. // at the highest zone cut.
  337. findTest(Name("www.grand.child.example.org"), RRType::TXT(),
  338. Zone::DELEGATION, true, rr_child_ns_, NULL, Zone::FIND_GLUE_OK);
  339. }
  340. // Test adding DNAMEs and resulting delegation handling
  341. // Listing ideas only for now
  342. TEST_F(MemoryZoneTest, delegationDNAME) {
  343. // apex DNAME: allowed by spec. No DNAME delegation at the apex;
  344. // descendants are subject to delegation.
  345. // Other cases of NS and DNAME mixture are prohibited.
  346. // BIND 9 doesn't reject such cases at load time, however.
  347. // DNAME and ordinary types (allowed by spec)
  348. }
  349. /**
  350. * \brief Test searching.
  351. *
  352. * Check it finds or does not find correctly and does not throw exceptions.
  353. * \todo This doesn't do any kind of CNAME and so on. If it isn't
  354. * directly there, it just tells it doesn't exist.
  355. */
  356. TEST_F(MemoryZoneTest, find) {
  357. // Fill some data inside
  358. // Now put all the data we have there. It should throw nothing
  359. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_)));
  360. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_a_)));
  361. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_aaaa_)));
  362. EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_a_)));
  363. // These two should be successful
  364. findTest(origin_, RRType::NS(), Zone::SUCCESS, true, rr_ns_);
  365. findTest(ns_name_, RRType::A(), Zone::SUCCESS, true, rr_ns_a_);
  366. // These domain exist but don't have the provided RRType
  367. findTest(origin_, RRType::AAAA(), Zone::NXRRSET);
  368. findTest(ns_name_, RRType::NS(), Zone::NXRRSET);
  369. // These domains don't exist (and one is out of the zone)
  370. findTest(Name("nothere.example.org"), RRType::A(), Zone::NXDOMAIN);
  371. findTest(Name("example.net"), RRType::A(), Zone::NXDOMAIN);
  372. }
  373. TEST_F(MemoryZoneTest, load) {
  374. // Put some data inside the zone
  375. EXPECT_NO_THROW(EXPECT_EQ(result::SUCCESS, zone_.add(rr_ns_)));
  376. // Loading with different origin should fail
  377. EXPECT_THROW(zone_.load(TEST_DATA_DIR "/root.zone"), MasterLoadError);
  378. // See the original data is still there, survived the exception
  379. findTest(origin_, RRType::NS(), Zone::SUCCESS, true, rr_ns_);
  380. // Create correct zone
  381. MemoryZone rootzone(class_, Name("."));
  382. // Try putting something inside
  383. EXPECT_NO_THROW(EXPECT_EQ(result::SUCCESS, rootzone.add(rr_ns_aaaa_)));
  384. // Load the zone. It should overwrite/remove the above RRset
  385. EXPECT_NO_THROW(rootzone.load(TEST_DATA_DIR "/root.zone"));
  386. // Now see there are some rrsets (we don't look inside, though)
  387. findTest(Name("."), RRType::SOA(), Zone::SUCCESS, false, ConstRRsetPtr(),
  388. &rootzone);
  389. findTest(Name("."), RRType::NS(), Zone::SUCCESS, false, ConstRRsetPtr(),
  390. &rootzone);
  391. findTest(Name("a.root-servers.net."), RRType::A(), Zone::SUCCESS, false,
  392. ConstRRsetPtr(), &rootzone);
  393. // But this should no longer be here
  394. findTest(ns_name_, RRType::AAAA(), Zone::NXDOMAIN, true, ConstRRsetPtr(),
  395. &rootzone);
  396. // Try loading zone that is wrong in a different way
  397. EXPECT_THROW(zone_.load(TEST_DATA_DIR "/duplicate_rrset.zone"),
  398. MasterLoadError);
  399. }
  400. TEST_F(MemoryZoneTest, swap) {
  401. // build one zone with some data
  402. MemoryZone zone1(class_, origin_);
  403. EXPECT_EQ(result::SUCCESS, zone1.add(rr_ns_));
  404. EXPECT_EQ(result::SUCCESS, zone1.add(rr_ns_aaaa_));
  405. // build another zone of a different RR class with some other data
  406. const Name other_origin("version.bind");
  407. ASSERT_NE(origin_, other_origin); // make sure these two are different
  408. MemoryZone zone2(RRClass::CH(), other_origin);
  409. EXPECT_EQ(result::SUCCESS,
  410. zone2.add(RRsetPtr(new RRset(Name("version.bind"),
  411. RRClass::CH(), RRType::TXT(),
  412. RRTTL(0)))));
  413. zone1.swap(zone2);
  414. EXPECT_EQ(other_origin, zone1.getOrigin());
  415. EXPECT_EQ(origin_, zone2.getOrigin());
  416. EXPECT_EQ(RRClass::CH(), zone1.getClass());
  417. EXPECT_EQ(RRClass::IN(), zone2.getClass());
  418. // make sure the zone data is swapped, too
  419. findTest(origin_, RRType::NS(), Zone::NXDOMAIN, false, ConstRRsetPtr(),
  420. &zone1);
  421. findTest(other_origin, RRType::TXT(), Zone::SUCCESS, false,
  422. ConstRRsetPtr(), &zone1);
  423. findTest(origin_, RRType::NS(), Zone::SUCCESS, false, ConstRRsetPtr(),
  424. &zone2);
  425. findTest(other_origin, RRType::TXT(), Zone::NXDOMAIN, false,
  426. ConstRRsetPtr(), &zone2);
  427. }
  428. TEST_F(MemoryZoneTest, getFileName) {
  429. // for an empty zone the file name should also be empty.
  430. EXPECT_TRUE(zone_.getFileName().empty());
  431. // if loading a zone fails the file name shouldn't be set.
  432. EXPECT_THROW(zone_.load(TEST_DATA_DIR "/root.zone"), MasterLoadError);
  433. EXPECT_TRUE(zone_.getFileName().empty());
  434. // after a successful load, the specified file name should be set
  435. MemoryZone rootzone(class_, Name("."));
  436. EXPECT_NO_THROW(rootzone.load(TEST_DATA_DIR "/root.zone"));
  437. EXPECT_EQ(TEST_DATA_DIR "/root.zone", rootzone.getFileName());
  438. // overriding load, which will fail
  439. EXPECT_THROW(rootzone.load(TEST_DATA_DIR "/duplicate_rrset.zone"),
  440. MasterLoadError);
  441. // the file name should be intact.
  442. EXPECT_EQ(TEST_DATA_DIR "/root.zone", rootzone.getFileName());
  443. // After swap, file names should also be swapped.
  444. zone_.swap(rootzone);
  445. EXPECT_EQ(TEST_DATA_DIR "/root.zone", zone_.getFileName());
  446. EXPECT_TRUE(rootzone.getFileName().empty());
  447. }
  448. }