rrset_collection_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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/rrset_collection.h>
  15. #include <dns/rrttl.h>
  16. #include <dns/rdataclass.h>
  17. #include <gtest/gtest.h>
  18. #include <list>
  19. #include <fstream>
  20. using namespace isc::dns;
  21. using namespace isc::dns::rdata;
  22. using namespace std;
  23. namespace {
  24. class RRsetCollectionTest : public ::testing::Test {
  25. public:
  26. RRsetCollectionTest() :
  27. rrclass("IN"),
  28. origin("example.org"),
  29. collection(TEST_DATA_SRCDIR "/example.org", origin, rrclass)
  30. {}
  31. const RRClass rrclass;
  32. const Name origin;
  33. RRsetCollection collection;
  34. };
  35. TEST_F(RRsetCollectionTest, istreamConstructor) {
  36. std::ifstream fs(TEST_DATA_SRCDIR "/example.org");
  37. RRsetCollection collection2(fs, origin, rrclass);
  38. RRsetCollectionBase::Iterator iter = collection.begin();
  39. RRsetCollectionBase::Iterator iter2 = collection2.begin();
  40. while (iter != collection.end()) {
  41. ASSERT_TRUE(iter2 != collection2.end());
  42. EXPECT_EQ((*iter).toText(), (*iter2).toText());
  43. ++iter;
  44. ++iter2;
  45. }
  46. ASSERT_TRUE(iter2 == collection2.end());
  47. }
  48. template <typename T, typename TP>
  49. void doFind(T& collection, const RRClass& rrclass) {
  50. // Test the find() that returns ConstRRsetPtr
  51. TP rrset = collection.find(Name("www.example.org"), rrclass, RRType::A());
  52. EXPECT_TRUE(rrset);
  53. EXPECT_EQ(RRType::A(), rrset->getType());
  54. EXPECT_EQ(RRTTL(3600), rrset->getTTL());
  55. EXPECT_EQ(RRClass("IN"), rrset->getClass());
  56. EXPECT_EQ(Name("www.example.org"), rrset->getName());
  57. // foo.example.org doesn't exist
  58. rrset = collection.find(Name("foo.example.org"), rrclass, RRType::A());
  59. EXPECT_FALSE(rrset);
  60. // www.example.org exists, but not with MX
  61. rrset = collection.find(Name("www.example.org"), rrclass, RRType::MX());
  62. EXPECT_FALSE(rrset);
  63. // www.example.org exists, with AAAA
  64. rrset = collection.find(Name("www.example.org"), rrclass, RRType::AAAA());
  65. EXPECT_TRUE(rrset);
  66. // www.example.org with AAAA does not exist in RRClass::CH()
  67. rrset = collection.find(Name("www.example.org"), RRClass::CH(),
  68. RRType::AAAA());
  69. EXPECT_FALSE(rrset);
  70. }
  71. TEST_F(RRsetCollectionTest, findConst) {
  72. // Test the find() that returns ConstRRsetPtr
  73. const RRsetCollection& ccln = collection;
  74. doFind<const RRsetCollection, ConstRRsetPtr>(ccln, rrclass);
  75. }
  76. TEST_F(RRsetCollectionTest, find) {
  77. // Test the find() that returns RRsetPtr
  78. doFind<RRsetCollection, RRsetPtr>(collection, rrclass);
  79. }
  80. void
  81. doAddAndRemove(RRsetCollection& collection, const RRClass& rrclass) {
  82. // foo.example.org/A doesn't exist
  83. RRsetPtr rrset_found = collection.find(Name("foo.example.org"), rrclass,
  84. RRType::A());
  85. EXPECT_FALSE(rrset_found);
  86. // Add foo.example.org/A
  87. RRsetPtr rrset(new BasicRRset(Name("foo.example.org"), rrclass, RRType::A(),
  88. RRTTL(7200)));
  89. rrset->addRdata(in::A("192.0.2.1"));
  90. collection.addRRset(rrset);
  91. // foo.example.org/A should now exist
  92. rrset_found = collection.find(Name("foo.example.org"), rrclass,
  93. RRType::A());
  94. EXPECT_TRUE(rrset_found);
  95. EXPECT_EQ(RRType::A(), rrset_found->getType());
  96. EXPECT_EQ(RRTTL(7200), rrset_found->getTTL());
  97. EXPECT_EQ(RRClass("IN"), rrset_found->getClass());
  98. EXPECT_EQ(Name("foo.example.org"), rrset_found->getName());
  99. // The collection must not be empty.
  100. EXPECT_TRUE(collection.end() != collection.begin());
  101. // Adding a duplicate RRset must throw.
  102. EXPECT_THROW({
  103. collection.addRRset(rrset);
  104. }, isc::InvalidParameter);
  105. // Remove foo.example.org/A, which should pass
  106. EXPECT_TRUE(collection.removeRRset(Name("foo.example.org"),
  107. rrclass, RRType::A()));
  108. // foo.example.org/A should not exist now
  109. rrset_found = collection.find(Name("foo.example.org"), rrclass,
  110. RRType::A());
  111. EXPECT_FALSE(rrset_found);
  112. // Removing foo.example.org/A should fail now
  113. EXPECT_FALSE(collection.removeRRset(Name("foo.example.org"),
  114. rrclass, RRType::A()));
  115. }
  116. TEST_F(RRsetCollectionTest, addAndRemove) {
  117. doAddAndRemove(collection, rrclass);
  118. }
  119. TEST_F(RRsetCollectionTest, empty) {
  120. RRsetCollection cln;
  121. // Here, cln is empty.
  122. EXPECT_TRUE(cln.end() == cln.begin());
  123. doAddAndRemove(cln, rrclass);
  124. // cln should be empty again here, after the add and remove
  125. // operations.
  126. EXPECT_TRUE(cln.end() == cln.begin());
  127. }
  128. TEST_F(RRsetCollectionTest, iteratorTest) {
  129. // The collection must not be empty.
  130. EXPECT_TRUE(collection.end() != collection.begin());
  131. // Here, we just count the records and do some basic tests on them.
  132. size_t count = 0;
  133. for (RRsetCollection::Iterator it = collection.begin();
  134. it != collection.end(); ++it) {
  135. ++count;
  136. const AbstractRRset& rrset = *it;
  137. EXPECT_EQ(rrclass, rrset.getClass());
  138. EXPECT_EQ(RRTTL(3600), rrset.getTTL());
  139. }
  140. // example.org master file has SOA, NS, A, AAAA
  141. EXPECT_EQ(4, count);
  142. }
  143. // This is a dummy class which is used in iteratorCompareDifferent test
  144. // to compare iterators from different RRsetCollectionBase
  145. // implementations.
  146. class MyRRsetCollection : public RRsetCollectionBase {
  147. public:
  148. MyRRsetCollection()
  149. {}
  150. virtual isc::dns::ConstRRsetPtr find(const isc::dns::Name&,
  151. const isc::dns::RRClass&,
  152. const isc::dns::RRType&) const {
  153. return (ConstRRsetPtr());
  154. }
  155. typedef std::list<isc::dns::RRset> MyCollection;
  156. protected:
  157. class MyIter : public RRsetCollectionBase::Iter {
  158. public:
  159. MyIter(MyCollection::iterator& iter) :
  160. iter_(iter)
  161. {}
  162. virtual const isc::dns::AbstractRRset& getValue() {
  163. return (*iter_);
  164. }
  165. virtual IterPtr getNext() {
  166. MyCollection::iterator it = iter_;
  167. ++it;
  168. return (RRsetCollectionBase::IterPtr(new MyIter(it)));
  169. }
  170. virtual bool equals(Iter& other) {
  171. const MyIter* other_real = dynamic_cast<MyIter*>(&other);
  172. if (other_real == NULL) {
  173. return (false);
  174. }
  175. return (iter_ == other_real->iter_);
  176. }
  177. private:
  178. MyCollection::iterator iter_;
  179. };
  180. virtual RRsetCollectionBase::IterPtr getBeginning() {
  181. MyCollection::iterator it = dummy_list_.begin();
  182. return (RRsetCollectionBase::IterPtr(new MyIter(it)));
  183. }
  184. virtual RRsetCollectionBase::IterPtr getEnd() {
  185. MyCollection::iterator it = dummy_list_.end();
  186. return (RRsetCollectionBase::IterPtr(new MyIter(it)));
  187. }
  188. private:
  189. MyCollection dummy_list_;
  190. };
  191. TEST_F(RRsetCollectionTest, iteratorCompareDifferent) {
  192. // Create objects of two different RRsetCollectionBase
  193. // implementations.
  194. RRsetCollection cln1;
  195. MyRRsetCollection cln2;
  196. // Comparing two iterators from different RRsetCollectionBase
  197. // implementations must not throw.
  198. EXPECT_TRUE(cln2.begin() != cln1.begin());
  199. EXPECT_TRUE(cln1.end() != cln2.end());
  200. }
  201. } // namespace