123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
- //
- // Permission to use, copy, modify, and/or distribute this software for any
- // purpose with or without fee is hereby granted, provided that the above
- // copyright notice and this permission notice appear in all copies.
- //
- // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- #include <util/buffer.h>
- #include <dns/messagerenderer.h>
- #include <dns/name.h>
- #include <dns/rdata.h>
- #include <dns/rdataclass.h>
- #include <dns/rrclass.h>
- #include <dns/rrtype.h>
- #include <dns/rrttl.h>
- #include <dns/rrset.h>
- #include <dns/tests/unittest_util.h>
- #include <gtest/gtest.h>
- #include <stdexcept>
- #include <sstream>
- using isc::UnitTestUtil;
- using namespace std;
- using namespace isc::dns;
- using namespace isc::util;
- using namespace isc::dns::rdata;
- namespace {
- class RRsetTest : public ::testing::Test {
- protected:
- RRsetTest() : buffer(0),
- test_name("test.example.com"),
- test_domain("example.com"),
- test_nsname("ns.example.com"),
- rrset_a(test_name, RRClass::IN(), RRType::A(), RRTTL(3600)),
- rrset_a_empty(test_name, RRClass::IN(), RRType::A(),
- RRTTL(3600)),
- rrset_any_a_empty(test_name, RRClass::ANY(), RRType::A(),
- RRTTL(3600)),
- rrset_none_a_empty(test_name, RRClass::NONE(), RRType::A(),
- RRTTL(3600)),
- rrset_ns(test_domain, RRClass::IN(), RRType::NS(),
- RRTTL(86400)),
- rrset_ch_txt(test_domain, RRClass::CH(), RRType::TXT(),
- RRTTL(0))
- {
- rrset_a.addRdata(in::A("192.0.2.1"));
- rrset_a.addRdata(in::A("192.0.2.2"));
- }
- OutputBuffer buffer;
- MessageRenderer renderer;
- Name test_name;
- Name test_domain;
- Name test_nsname;
- RRset rrset_a;
- RRset rrset_a_empty;
- RRset rrset_any_a_empty;
- RRset rrset_none_a_empty;
- RRset rrset_ns;
- RRset rrset_ch_txt;
- std::vector<unsigned char> wiredata;
- // max number of Rdata objects added to a test RRset object.
- // this is an arbitrary chosen limit, but should be sufficiently large
- // in practice and reasonable even as an extreme test case.
- static const int MAX_RDATA_COUNT = 100;
- };
- TEST_F(RRsetTest, getRdataCount) {
- for (int i = 0; i < MAX_RDATA_COUNT; ++i) {
- EXPECT_EQ(i, rrset_a_empty.getRdataCount());
- rrset_a_empty.addRdata(in::A("192.0.2.1"));
- }
- }
- TEST_F(RRsetTest, getName) {
- EXPECT_EQ(test_name, rrset_a.getName());
- EXPECT_EQ(test_domain, rrset_ns.getName());
- }
- TEST_F(RRsetTest, getClass) {
- EXPECT_EQ(RRClass("IN"), rrset_a.getClass());
- EXPECT_EQ(RRClass("CH"), rrset_ch_txt.getClass());
- }
- TEST_F(RRsetTest, getType) {
- EXPECT_EQ(RRType("A"), rrset_a.getType());
- EXPECT_EQ(RRType("NS"), rrset_ns.getType());
- EXPECT_EQ(RRType("TXT"), rrset_ch_txt.getType());
- }
- TEST_F(RRsetTest, getTTL) {
- EXPECT_EQ(RRTTL(3600), rrset_a.getTTL());
- EXPECT_EQ(RRTTL(86400), rrset_ns.getTTL());
- EXPECT_EQ(RRTTL(0), rrset_ch_txt.getTTL());
- }
- TEST_F(RRsetTest, setTTL) {
- rrset_a.setTTL(RRTTL(86400));
- EXPECT_EQ(RRTTL(86400), rrset_a.getTTL());
- rrset_a.setTTL(RRTTL(0));
- EXPECT_EQ(RRTTL(0), rrset_a.getTTL());
- }
- TEST_F(RRsetTest, setName) {
- rrset_a.setName(test_nsname);
- EXPECT_EQ(test_nsname, rrset_a.getName());
- }
- TEST_F(RRsetTest, isSameKind) {
- RRset rrset_w(test_name, RRClass::IN(), RRType::A(), RRTTL(3600));
- RRset rrset_x(test_name, RRClass::IN(), RRType::A(), RRTTL(3600));
- RRset rrset_y(test_name, RRClass::IN(), RRType::NS(), RRTTL(3600));
- RRset rrset_z(test_name, RRClass::CH(), RRType::A(), RRTTL(3600));
- RRset rrset_p(test_nsname, RRClass::IN(), RRType::A(), RRTTL(3600));
- EXPECT_TRUE(rrset_w.isSameKind(rrset_w));
- EXPECT_TRUE(rrset_w.isSameKind(rrset_x));
- EXPECT_FALSE(rrset_w.isSameKind(rrset_y));
- EXPECT_FALSE(rrset_w.isSameKind(rrset_z));
- EXPECT_FALSE(rrset_w.isSameKind(rrset_p));
- }
- void
- addRdataTestCommon(const RRset& rrset) {
- EXPECT_EQ(2, rrset.getRdataCount());
- RdataIteratorPtr it = rrset.getRdataIterator(); // cursor is set to the 1st
- EXPECT_FALSE(it->isLast());
- EXPECT_EQ(0, it->getCurrent().compare(in::A("192.0.2.1")));
- it->next();
- EXPECT_FALSE(it->isLast());
- EXPECT_EQ(0, it->getCurrent().compare(in::A("192.0.2.2")));
- it->next();
- EXPECT_TRUE(it->isLast());
- }
- TEST_F(RRsetTest, addRdata) {
- addRdataTestCommon(rrset_a);
- // Reference version of addRdata() doesn't allow to add a different
- // type of Rdata.
- EXPECT_THROW(rrset_a.addRdata(generic::NS(test_nsname)), std::bad_cast);
- }
- TEST_F(RRsetTest, addRdataPtr) {
- rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(),
- rrset_a_empty.getClass(),
- "192.0.2.1"));
- rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(),
- rrset_a_empty.getClass(),
- "192.0.2.2"));
- addRdataTestCommon(rrset_a);
- // Pointer version of addRdata() doesn't type check and does allow to
- //add a different type of Rdata as a result.
- rrset_a_empty.addRdata(createRdata(RRType::NS(), RRClass::IN(),
- "ns.example.com"));
- EXPECT_EQ(3, rrset_a_empty.getRdataCount());
- }
- TEST_F(RRsetTest, iterator) {
- // Iterator for an empty RRset.
- RdataIteratorPtr it = rrset_a_empty.getRdataIterator();
- EXPECT_TRUE(it->isLast());
- // Normal case (already tested, but do it again just in case)
- rrset_a_empty.addRdata(in::A("192.0.2.1"));
- rrset_a_empty.addRdata(in::A("192.0.2.2"));
- addRdataTestCommon(rrset_a_empty);
- // Rewind test: should be repeat the iteration by calling first().
- for (int i = 0; i < 2; ++i) {
- it = rrset_a_empty.getRdataIterator();
- it->first();
- EXPECT_FALSE(it->isLast());
- it->next();
- EXPECT_FALSE(it->isLast());
- it->next();
- EXPECT_TRUE(it->isLast());
- }
- }
- TEST_F(RRsetTest, toText) {
- EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
- "test.example.com. 3600 IN A 192.0.2.2\n",
- rrset_a.toText());
- // toText() cannot be performed for an empty RRset
- EXPECT_THROW(rrset_a_empty.toText(), EmptyRRset);
- // Unless it is type ANY or NONE
- EXPECT_EQ("test.example.com. 3600 ANY A\n",
- rrset_any_a_empty.toText());
- EXPECT_EQ("test.example.com. 3600 NONE A\n",
- rrset_none_a_empty.toText());
- }
- TEST_F(RRsetTest, toWireBuffer) {
- rrset_a.toWire(buffer);
- UnitTestUtil::readWireData("rrset_toWire1", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &wiredata[0], wiredata.size());
- // toWire() cannot be performed for an empty RRset.
- buffer.clear();
- EXPECT_THROW(rrset_a_empty.toWire(buffer), EmptyRRset);
- // Unless it is type ANY or None
- buffer.clear();
- rrset_any_a_empty.toWire(buffer);
- wiredata.clear();
- UnitTestUtil::readWireData("rrset_toWire3", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &wiredata[0], wiredata.size());
- buffer.clear();
- rrset_none_a_empty.toWire(buffer);
- wiredata.clear();
- UnitTestUtil::readWireData("rrset_toWire4", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &wiredata[0], wiredata.size());
- }
- TEST_F(RRsetTest, toWireRenderer) {
- rrset_ns.addRdata(generic::NS(test_nsname));
- rrset_a.toWire(renderer);
- rrset_ns.toWire(renderer);
- UnitTestUtil::readWireData("rrset_toWire2", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
- renderer.getLength(), &wiredata[0], wiredata.size());
- // toWire() cannot be performed for an empty RRset.
- buffer.clear();
- EXPECT_THROW(rrset_a_empty.toWire(buffer), EmptyRRset);
- // Unless it is type ANY or None
- // toWire() can also be performed for an empty RRset.
- buffer.clear();
- rrset_any_a_empty.toWire(buffer);
- wiredata.clear();
- UnitTestUtil::readWireData("rrset_toWire3", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &wiredata[0], wiredata.size());
- buffer.clear();
- rrset_none_a_empty.toWire(buffer);
- wiredata.clear();
- UnitTestUtil::readWireData("rrset_toWire4", wiredata);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
- buffer.getLength(), &wiredata[0], wiredata.size());
- }
- // test operator<<. We simply confirm it appends the result of toText().
- TEST_F(RRsetTest, LeftShiftOperator) {
- ostringstream oss;
- oss << rrset_a;
- EXPECT_EQ(rrset_a.toText(), oss.str());
- }
- class RRsetRRSIGTest : public ::testing::Test {
- protected:
- RRsetRRSIGTest() : test_name("test.example.com")
- {
- rrset_a = RRsetPtr(new RRset(test_name, RRClass::IN(),
- RRType::A(), RRTTL(3600)));
- rrset_a->addRdata(in::A("192.0.2.1"));
- rrset_a->addRdata(in::A("192.0.2.2"));
- rrset_aaaa = RRsetPtr(new RRset(test_name, RRClass::IN(),
- RRType::AAAA(), RRTTL(3600)));
- rrset_aaaa->addRdata(in::AAAA("2001:db8::1234"));
- rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
- RRType::RRSIG(), RRTTL(3600)));
- rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
- "20100220084538 1 example.com "
- "FAKEFAKEFAKEFAKE"));
- rrset_aaaa->addRRsig(rrset_rrsig);
- }
- const Name test_name;
- RRsetPtr rrset_a; // A RRset with two RDATAs
- RRsetPtr rrset_aaaa; // AAAA RRset with one RDATA with RRSIG
- RRsetPtr rrset_rrsig; // RRSIG for the AAAA RRset
- };
- TEST_F(RRsetRRSIGTest, getRRsig) {
- RRsetPtr sp = rrset_a->getRRsig();
- EXPECT_EQ(static_cast<void*>(NULL), sp.get());
- sp = rrset_aaaa->getRRsig();
- EXPECT_NE(static_cast<void*>(NULL), sp.get());
- }
- TEST_F(RRsetRRSIGTest, addRRsig) {
- RRsetPtr sp = rrset_a->getRRsig();
- EXPECT_EQ(static_cast<void*>(NULL), sp.get());
- rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
- RRType::RRSIG(), RRTTL(3600)));
- // one signature algorithm (5 = RSA/SHA-1)
- rrset_rrsig->addRdata(generic::RRSIG("A 5 3 3600 "
- "20000101000000 20000201000000 "
- "12345 example.com. FAKEFAKEFAKE"));
- // another signature algorithm (3 = DSA/SHA-1)
- rrset_rrsig->addRdata(generic::RRSIG("A 3 3 3600 "
- "20000101000000 20000201000000 "
- "12345 example.com. FAKEFAKEFAKE"));
- rrset_a->addRRsig(rrset_rrsig);
- sp = rrset_a->getRRsig();
- EXPECT_NE(static_cast<void*>(NULL), sp.get());
- EXPECT_EQ(2, sp->getRdataCount());
- // add to existing RRSIG
- rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
- RRType::RRSIG(), RRTTL(3600)));
- // another signature algorithm (4 = ECC)
- rrset_rrsig->addRdata(generic::RRSIG("A 4 3 3600 "
- "20000101000000 20000201000000 "
- "12345 example.com. FAKEFAKEFAKE"));
- rrset_a->addRRsig(rrset_rrsig);
- EXPECT_EQ(3, sp->getRdataCount());
- }
- TEST_F(RRsetRRSIGTest, getRRsigDataCount) {
- EXPECT_EQ(1, rrset_aaaa->getRRsigDataCount());
- EXPECT_EQ(0, rrset_a->getRRsigDataCount());
- rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
- RRType::RRSIG(), RRTTL(3600)));
- // one signature algorithm (5 = RSA/SHA-1)
- rrset_rrsig->addRdata(generic::RRSIG("A 5 3 3600 "
- "20000101000000 20000201000000 "
- "12345 example.com. FAKEFAKEFAKE"));
- // another signature algorithm (3 = DSA/SHA-1)
- rrset_rrsig->addRdata(generic::RRSIG("A 3 3 3600 "
- "20000101000000 20000201000000 "
- "12345 example.com. FAKEFAKEFAKE"));
- rrset_a->addRRsig(rrset_rrsig);
- EXPECT_EQ(2, rrset_a->getRRsigDataCount());
- rrset_a->removeRRsig();
- EXPECT_EQ(0, rrset_a->getRRsigDataCount());
- }
- TEST_F(RRsetRRSIGTest, toText) {
- // toText() should also return the associated RRSIG.
- EXPECT_EQ("test.example.com. 3600 IN AAAA 2001:db8::1234\n"
- "test.example.com. 3600 IN RRSIG AAAA 5 3 7200 "
- "20100322084538 20100220084538 1 example.com. FAKEFAKEFAKEFAKE\n",
- rrset_aaaa->toText());
- }
- }
|