rbnode_rrset_unittest.cc 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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 <exceptions/exceptions.h>
  15. #include <dns/rdataclass.h>
  16. #include <datasrc/rbnode_rrset.h>
  17. #include <testutils/dnsmessage_test.h>
  18. #include <dns/tests/unittest_util.h>
  19. #include <gtest/gtest.h>
  20. #include <sstream>
  21. #include <stdexcept>
  22. using isc::UnitTestUtil;
  23. using namespace isc;
  24. using namespace isc::datasrc;
  25. using namespace isc::datasrc::internal;
  26. using namespace isc::dns;
  27. using namespace isc::dns::rdata;
  28. using namespace isc::testutils;
  29. using namespace isc::util;
  30. using namespace std;
  31. // These tests are very similar to those for RRset - indeed, this file was
  32. // created from those tests. However, the significant difference in behaviour
  33. // between RRset and RBNodeRRset - that the "set" methods in the latter mostly
  34. // result in exceptions being thrown - preclude use of full type
  35. // parameterisation of the tests.
  36. namespace {
  37. const char* const RRSIG_TXT =
  38. "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
  39. "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
  40. "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
  41. "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
  42. "f49t+sXKPzbipN9g+s1ZPiIyofc=";
  43. class RBNodeRRsetTest : public ::testing::Test {
  44. protected:
  45. RBNodeRRsetTest() :
  46. test_name("test.example.com"),
  47. test_domain("example.com"),
  48. test_nsname("ns.example.com"),
  49. rrset_a(ConstRRsetPtr(new RRset(
  50. test_name, RRClass::IN(), RRType::A(), RRTTL(3600)))),
  51. rrset_a_empty(ConstRRsetPtr(new RRset(
  52. test_name, RRClass::IN(), RRType::A(), RRTTL(3600)))),
  53. rrset_ns(ConstRRsetPtr(new RRset(
  54. test_domain, RRClass::IN(), RRType::NS(), RRTTL(86400)))),
  55. rrset_ch_txt(ConstRRsetPtr(new RRset(
  56. test_domain, RRClass::CH(), RRType::TXT(), RRTTL(0)))),
  57. rrset_siga(new RRset(test_name, RRClass::IN(), RRType::RRSIG(),
  58. RRTTL(3600)))
  59. {
  60. // Add a couple of Rdata elements to the A RRset. The easiest way to
  61. // do this is to override the "const" restrictions. As this is a test,
  62. // we don't feel too bad about doing so.
  63. AbstractRRset* a_rrset =
  64. const_cast<AbstractRRset*>(rrset_a.getUnderlyingRRset().get());
  65. a_rrset->addRdata(in::A("192.0.2.1"));
  66. a_rrset->addRdata(in::A("192.0.2.2"));
  67. // Create the RRSIG corresponding to the rrset_a record. The RDATA
  68. // won't match the A record it covers, although it is internally
  69. // self-consistent.
  70. AbstractRRset* sig_rrset =
  71. const_cast<AbstractRRset*>(rrset_siga.get());
  72. sig_rrset->addRdata(generic::RRSIG(RRSIG_TXT));
  73. }
  74. const Name test_name;
  75. const Name test_domain;
  76. const Name test_nsname;
  77. RBNodeRRset rrset_a;
  78. RBNodeRRset rrset_a_empty;
  79. const RBNodeRRset rrset_ns;
  80. const RBNodeRRset rrset_ch_txt;
  81. ConstRRsetPtr rrset_siga;
  82. };
  83. TEST_F(RBNodeRRsetTest, getRdataCount) {
  84. EXPECT_EQ(0, rrset_a_empty.getRdataCount());
  85. EXPECT_EQ(2, rrset_a.getRdataCount());
  86. }
  87. TEST_F(RBNodeRRsetTest, getName) {
  88. EXPECT_EQ(test_name, rrset_a.getName());
  89. EXPECT_EQ(test_domain, rrset_ns.getName());
  90. }
  91. TEST_F(RBNodeRRsetTest, getClass) {
  92. EXPECT_EQ(RRClass("IN"), rrset_a.getClass());
  93. EXPECT_EQ(RRClass("CH"), rrset_ch_txt.getClass());
  94. }
  95. TEST_F(RBNodeRRsetTest, getType) {
  96. EXPECT_EQ(RRType("A"), rrset_a.getType());
  97. EXPECT_EQ(RRType("NS"), rrset_ns.getType());
  98. EXPECT_EQ(RRType("TXT"), rrset_ch_txt.getType());
  99. }
  100. TEST_F(RBNodeRRsetTest, getTTL) {
  101. EXPECT_EQ(RRTTL(3600), rrset_a.getTTL());
  102. EXPECT_EQ(RRTTL(86400), rrset_ns.getTTL());
  103. EXPECT_EQ(RRTTL(0), rrset_ch_txt.getTTL());
  104. }
  105. TEST_F(RBNodeRRsetTest, setName) {
  106. EXPECT_THROW(rrset_a.setName(test_nsname), NotImplemented);
  107. }
  108. TEST_F(RBNodeRRsetTest, setTTL) {
  109. EXPECT_THROW(rrset_a.setTTL(RRTTL(86400)), NotImplemented);
  110. }
  111. TEST_F(RBNodeRRsetTest, toText) {
  112. EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
  113. "test.example.com. 3600 IN A 192.0.2.2\n",
  114. rrset_a.toText());
  115. // toText() cannot be performed for an empty RRset.
  116. EXPECT_THROW(rrset_a_empty.toText(), EmptyRRset);
  117. }
  118. TEST_F(RBNodeRRsetTest, isSameKind) {
  119. RBNodeRRset rrset_p(ConstRRsetPtr(new RRset(test_name, RRClass::IN(), RRType::A(), RRTTL(3600))));
  120. RBNodeRRset rrset_q(ConstRRsetPtr(new RRset(test_name, RRClass::IN(), RRType::A(), RRTTL(3600))));
  121. RRset rrset_w(test_name, RRClass::IN(), RRType::A(), RRTTL(3600));
  122. RRset rrset_x(test_nsname, RRClass::IN(), RRType::A(), RRTTL(3600));
  123. RRset rrset_y(test_name, RRClass::IN(), RRType::NS(), RRTTL(3600));
  124. RRset rrset_z(test_name, RRClass::CH(), RRType::A(), RRTTL(3600));
  125. EXPECT_TRUE(rrset_p.isSameKind(rrset_p));
  126. EXPECT_FALSE(rrset_p.isSameKind(rrset_q));
  127. EXPECT_TRUE(rrset_p.isSameKind(rrset_w));
  128. EXPECT_FALSE(rrset_p.isSameKind(rrset_x));
  129. EXPECT_FALSE(rrset_p.isSameKind(rrset_y));
  130. EXPECT_FALSE(rrset_p.isSameKind(rrset_z));
  131. }
  132. // Note: although the next two tests are essentially the same and used common
  133. // test code, they use different test data: the MessageRenderer produces
  134. // compressed wire data whereas the OutputBuffer does not.
  135. template <typename T>
  136. void
  137. performToWireTest(T& dataHolder, const RBNodeRRset& rrset,
  138. const RBNodeRRset& rrset_empty, const char* testdata)
  139. {
  140. rrset.toWire(dataHolder);
  141. std::vector<unsigned char> wiredata;
  142. UnitTestUtil::readWireData(testdata, wiredata);
  143. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, dataHolder.getData(),
  144. dataHolder.getLength(), &wiredata[0], wiredata.size());
  145. // toWire() cannot be performed for an empty RRset.
  146. dataHolder.clear();
  147. EXPECT_THROW(rrset_empty.toWire(dataHolder), EmptyRRset);
  148. }
  149. TEST_F(RBNodeRRsetTest, toWireRenderer) {
  150. MessageRenderer renderer;
  151. performToWireTest(renderer, rrset_a, rrset_a_empty, "rrset_toWire2");
  152. }
  153. TEST_F(RBNodeRRsetTest, toWireBuffer) {
  154. OutputBuffer buffer(0);
  155. performToWireTest(buffer, rrset_a, rrset_a_empty, "rrset_toWire1");
  156. }
  157. TEST_F(RBNodeRRsetTest, addRdata) {
  158. EXPECT_THROW(rrset_a.addRdata(in::A("192.0.2.3")), NotImplemented);
  159. // Check the same goes for trying to add the wrong type of data
  160. EXPECT_THROW(rrset_a.addRdata(generic::NS(test_nsname)), NotImplemented);
  161. }
  162. TEST_F(RBNodeRRsetTest, addRdataPtr) {
  163. EXPECT_THROW(rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(),
  164. rrset_a_empty.getClass(),
  165. "192.0.2.1")),
  166. NotImplemented);
  167. }
  168. TEST_F(RBNodeRRsetTest, getRDataIterator) {
  169. RdataIteratorPtr it = rrset_a.getRdataIterator();
  170. for (int i = 0; i < 2; ++i) {
  171. ASSERT_FALSE(it->isLast());
  172. ASSERT_EQ(0, it->getCurrent().compare(in::A("192.0.2.1")));
  173. it->next();
  174. ASSERT_FALSE(it->isLast());
  175. ASSERT_EQ(0, it->getCurrent().compare(in::A("192.0.2.2")));
  176. it->next();
  177. ASSERT_TRUE(it->isLast());
  178. // Should be able repeat the iteration by calling first().
  179. it->first();
  180. }
  181. }
  182. // test operator<<. We simply confirm it appends the result of toText().
  183. TEST_F(RBNodeRRsetTest, LeftShiftOperator) {
  184. ostringstream oss;
  185. oss << rrset_a;
  186. EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
  187. "test.example.com. 3600 IN A 192.0.2.2\n", oss.str());
  188. }
  189. // addRRSIG tests.
  190. TEST_F(RBNodeRRsetTest, addRRsigConstRdataPointer) {
  191. EXPECT_FALSE(rrset_a.getRRsig());
  192. ConstRdataPtr data = createRdata(rrset_siga->getType(),
  193. rrset_siga->getClass(), RRSIG_TXT);
  194. rrset_a.addRRsig(data);
  195. rrsetCheck(rrset_siga, rrset_a.getRRsig());
  196. }
  197. TEST_F(RBNodeRRsetTest, addRRsigRdataPointer) {
  198. EXPECT_FALSE(rrset_a.getRRsig());
  199. RdataPtr data = createRdata(rrset_siga->getType(), rrset_siga->getClass(),
  200. RRSIG_TXT);
  201. rrset_a.addRRsig(data);
  202. rrsetCheck(rrset_siga, rrset_a.getRRsig());
  203. }
  204. TEST_F(RBNodeRRsetTest, addRRsigAbstractRRset) {
  205. EXPECT_FALSE(rrset_a.getRRsig());
  206. rrset_a.addRRsig(*(rrset_siga.get()));
  207. rrsetCheck(rrset_siga, rrset_a.getRRsig());
  208. }
  209. TEST_F(RBNodeRRsetTest, addRRsigConstantRRsetPointer) {
  210. EXPECT_FALSE(rrset_a.getRRsig());
  211. rrset_a.addRRsig(rrset_siga);
  212. rrsetCheck(rrset_siga, rrset_a.getRRsig());
  213. }
  214. TEST_F(RBNodeRRsetTest, addRRsigRRsetPointer) {
  215. EXPECT_FALSE(rrset_a.getRRsig());
  216. RRsetPtr rrsig(new RRset(test_name, RRClass::IN(), RRType::RRSIG(),
  217. RRTTL(3600)));
  218. rrsig->addRdata(generic::RRSIG(RRSIG_TXT));
  219. rrset_a.addRRsig(rrsig);
  220. rrsetCheck(rrset_siga, rrset_a.getRRsig());
  221. }
  222. TEST_F(RBNodeRRsetTest, removeRRsig) {
  223. EXPECT_FALSE(rrset_a.getRRsig());
  224. rrset_a.addRRsig(*(rrset_siga.get()));
  225. EXPECT_TRUE(rrset_a.getRRsig());
  226. rrset_a.removeRRsig();
  227. EXPECT_FALSE(rrset_a.getRRsig());
  228. }
  229. } // Anonymous namespace