BIND 10 trac1605, updated. e07c5a1459d94b1c7c24debdbc05f23a5c79b4f0 [1605] Get in-memory data source to use RBNodeRRset objects
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Feb 22 13:57:35 UTC 2012
The branch, trac1605 has been updated
via e07c5a1459d94b1c7c24debdbc05f23a5c79b4f0 (commit)
via f161f37c16c1ce2b84ca467b6f6302e0d7d7a462 (commit)
via 9e60ca625be2c1875e65e360fd2b06c9ee8c4a57 (commit)
via bcf5e635365f60d79e5b7d28b9280482fbe1529a (commit)
via 7626330333e85f0f0e3d63530681b3708932e7a5 (commit)
from aacfc3fee9cbf5a2b7945c165cace1af81877f5f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit e07c5a1459d94b1c7c24debdbc05f23a5c79b4f0
Author: Stephen Morris <stephen at isc.org>
Date: Wed Feb 22 13:55:58 2012 +0000
[1605] Get in-memory data source to use RBNodeRRset objects
commit f161f37c16c1ce2b84ca467b6f6302e0d7d7a462
Author: Stephen Morris <stephen at isc.org>
Date: Wed Feb 22 12:37:23 2012 +0000
[1605] RBNodeRRset tests now pass
commit 9e60ca625be2c1875e65e360fd2b06c9ee8c4a57
Author: Stephen Morris <stephen at isc.org>
Date: Wed Feb 22 12:01:36 2012 +0000
[1605] Added (failing) RRSIG-related tests
commit bcf5e635365f60d79e5b7d28b9280482fbe1529a
Author: Stephen Morris <stephen at isc.org>
Date: Tue Feb 21 13:53:14 2012 +0000
[1605] Get all tests (apart from RRSIG-related tests) working
commit 7626330333e85f0f0e3d63530681b3708932e7a5
Author: Stephen Morris <stephen at isc.org>
Date: Tue Feb 21 13:35:19 2012 +0000
[1605] Added basic class and tests (all of which fail)
Currently no RRSIG-related methods added yet.
-----------------------------------------------------------------------
Summary of changes:
src/lib/datasrc/Makefile.am | 1 +
src/lib/datasrc/memory_datasrc.cc | 13 +-
src/lib/datasrc/rbnode_rrset.h | 192 ++++++++++++++
src/lib/datasrc/tests/Makefile.am | 11 +-
src/lib/datasrc/tests/memory_datasrc_unittest.cc | 11 +-
src/lib/datasrc/tests/rbnode_rrset_unittest.cc | 263 ++++++++++++++++++++
.../{dns => datasrc}/tests/testdata/rrset_toWire1 | 0
.../tests/testdata/rrset_toWire2} | 9 +-
8 files changed, 487 insertions(+), 13 deletions(-)
create mode 100644 src/lib/datasrc/rbnode_rrset.h
create mode 100644 src/lib/datasrc/tests/rbnode_rrset_unittest.cc
copy src/lib/{dns => datasrc}/tests/testdata/rrset_toWire1 (100%)
copy src/lib/{dns/tests/testdata/rrset_toWire1 => datasrc/tests/testdata/rrset_toWire2} (64%)
-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/Makefile.am b/src/lib/datasrc/Makefile.am
index b6c314c..9c1405e 100644
--- a/src/lib/datasrc/Makefile.am
+++ b/src/lib/datasrc/Makefile.am
@@ -21,6 +21,7 @@ libdatasrc_la_SOURCES += static_datasrc.h static_datasrc.cc
libdatasrc_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
libdatasrc_la_SOURCES += query.h query.cc
libdatasrc_la_SOURCES += cache.h cache.cc
+libdatasrc_la_SOURCES += rbnode_rrset.h
libdatasrc_la_SOURCES += rbtree.h
libdatasrc_la_SOURCES += zonetable.h zonetable.cc
libdatasrc_la_SOURCES += zone.h
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index 5137727..d36d952 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -34,6 +34,8 @@
#include <datasrc/memory_datasrc.h>
#include <datasrc/rbtree.h>
+#include <datasrc/rbnode_rrset.h>
+#include <datasrc/rbnode_rrset.h>
#include <datasrc/logger.h>
#include <datasrc/iterator.h>
#include <datasrc/data_source.h>
@@ -419,14 +421,19 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
* access is without the impl_-> and it will get inlined anyway.
*/
// Implementation of InMemoryZoneFinder::add
- result::Result add(const ConstRRsetPtr& rrset, ZoneData& zone_data) {
+ result::Result add(const ConstRRsetPtr& rawrrset, ZoneData& zone_data) {
// Sanitize input. This will cause an exception to be thrown
// if the input RRset is empty.
- addValidation(rrset);
+ addValidation(rawrrset);
// OK, can add the RRset.
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ADD_RRSET).
- arg(rrset->getName()).arg(rrset->getType()).arg(origin_);
+ arg(rawrrset->getName()).arg(rawrrset->getType()).arg(origin_);
+
+ // ... although instead of loading the RRset directly, we encapsulate
+ // it within an RBNodeRRset. This contains additional information that
+ // speeds up queries.
+ ConstRRsetPtr rrset(new RBNodeRRset(rawrrset));
if (rrset->getType() == RRType::NSEC3()) {
return (addNSEC3(rrset, zone_data));
diff --git a/src/lib/datasrc/rbnode_rrset.h b/src/lib/datasrc/rbnode_rrset.h
new file mode 100644
index 0000000..f34685e
--- /dev/null
+++ b/src/lib/datasrc/rbnode_rrset.h
@@ -0,0 +1,192 @@
+// Copyright (C) 2012 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.
+
+#ifndef __RBNODE_RRSET_H
+#define __RBNODE_RRSET_H
+
+#include <dns/messagerenderer.h>
+#include <dns/name.h>
+#include <dns/rrclass.h>
+#include <dns/rrset.h>
+#include <dns/rrttl.h>
+#include <dns/rrtype.h>
+#include <util/buffer.h>
+
+#include <string>
+
+namespace isc {
+namespace datasrc {
+
+/// \brief Special RRset for optimiing memory datasource requirement
+///
+/// To speed up the performance of the in-memory data source, at load time
+/// associate relevant "additional section" data with each RRset in the
+/// data source.
+///
+/// This class, derived from AbstractRRset, holds a "const" pointer to the
+/// underlying RRset object. All calls to methods on the class are passed to
+/// the underlying object. However, there are some restrictions:
+///
+/// - Calls to methods that change attributes of the underlying RRset (such as
+/// TTL or Name) cause an exception to be thrown. The in-memory data source
+/// does not allow modification of these attributes.
+/// - Calls that modify the associated RRSIGs of the RRset are allowed (even
+/// though the pointer is to a "const" object). The reason here is because
+/// RRSIGs are added to the in-memory data source after the RBNodeRRset
+/// objects have been created. Thus there has to be the capability of
+/// modifying this information.
+///
+/// The class is not derived from RRset itself to simplify coding: part of the
+/// loading of the memory data source is handled in the BIND 10 "libdns++"
+/// code, which creates RRsets and passes them to the data source code. This
+/// does not have to be altered if encapsulation, rather than inheritcance, is
+/// used.
+
+// Note: non-Doxygen-documented methods are documented in the base class.
+
+class RBNodeRRset : public isc::dns::AbstractRRset {
+
+private:
+ // Note: The copy constructor and the assignment operator are intentionally
+ // defined as private as we would normally not duplicate a RBNodeRRset.
+ // (We use the "private" method instead of inheriting from boost::noncopyable
+ // so as to avoid multiple inheritance.)
+ RBNodeRRset(const RBNodeRRset& source);
+ RBNodeRRset& operator=(const RBNodeRRset& source);
+
+public:
+ /// \brief Usual Constructor
+ ///
+ /// Creates an RBNodeRRset from the pointer to the RRset passed to it.
+ ///
+ /// \param rrset Pointer to underlying RRset encapsulated by this object.
+ RBNodeRRset(const isc::dns::ConstRRsetPtr& rrset) : rrset_(rrset) {}
+
+ /// \brief Destructor
+ virtual ~RBNodeRRset() {}
+
+ // Getter and Setter Methods
+ //
+ // The getter methods pass the call through to the underlying RRset. The
+ // setter methods thrown an exception - this specialisation of the RRset
+ // object does not expect the underlying RRset to be modified.
+
+ virtual unsigned int getRdataCount() const {
+ return (rrset_->getRdataCount());
+ }
+
+ virtual const isc::dns::Name& getName() const {
+ return (rrset_->getName());
+ }
+
+ virtual const isc::dns::RRClass& getClass() const {
+ return (rrset_->getClass());
+ }
+
+ virtual const isc::dns::RRType& getType() const {
+ return (rrset_->getType());
+ }
+
+ virtual const isc::dns::RRTTL& getTTL() const {
+ return (rrset_->getTTL());
+ }
+
+ virtual void setName(const isc::dns::Name&) {
+ isc_throw(isc::NotImplemented, "RBNodeRRset::setName() not supported");
+ }
+
+ virtual void setTTL(const isc::dns::RRTTL&) {
+ isc_throw(isc::NotImplemented, "RBNodeRRset::setTTL() not supported");
+ }
+
+ virtual std::string toText() const {
+ return (rrset_->toText());
+ }
+
+ virtual unsigned int toWire(
+ isc::dns::AbstractMessageRenderer& renderer) const {
+ return (rrset_->toWire(renderer));
+ }
+
+ virtual unsigned int toWire(isc::util::OutputBuffer& buffer) const {
+ return (rrset_->toWire(buffer));
+ }
+
+ virtual void addRdata(isc::dns::rdata::ConstRdataPtr) {
+ isc_throw(isc::NotImplemented, "RBNodeRRset::addRdata() not supported");
+ }
+
+ virtual void addRdata(const isc::dns::rdata::Rdata&) {
+ isc_throw(isc::NotImplemented, "RBNodeRRset::addRdata() not supported");
+ }
+
+ virtual isc::dns::RdataIteratorPtr getRdataIterator() const {
+ return (rrset_->getRdataIterator());
+ }
+
+ virtual isc::dns::RRsetPtr getRRsig() const {
+ return (rrset_->getRRsig());
+ }
+
+ // With all the RRsig methods, we have the problem that we store the
+ // underlying RRset using a ConstRRsetPtr - a pointer to a "const" RRset -
+ // but we need to modify it by adding or removing an RRSIG. We overcome
+ // this by temporarily violating the "const" nature of the RRset to add the
+ // data.
+
+ virtual void addRRsig(const isc::dns::rdata::ConstRdataPtr& rdata) {
+ AbstractRRset* p = const_cast<AbstractRRset*>(rrset_.get());
+ p->addRRsig(rdata);
+ }
+
+ virtual void addRRsig(const isc::dns::rdata::RdataPtr& rdata) {
+ AbstractRRset* p = const_cast<AbstractRRset*>(rrset_.get());
+ p->addRRsig(rdata);
+ }
+
+ virtual void addRRsig(const AbstractRRset& sigs) {
+ AbstractRRset* p = const_cast<AbstractRRset*>(rrset_.get());
+ p->addRRsig(sigs);
+ }
+
+ virtual void addRRsig(const isc::dns::ConstRRsetPtr& sigs) {
+ AbstractRRset* p = const_cast<AbstractRRset*>(rrset_.get());
+ p->addRRsig(sigs);
+ }
+
+ virtual void addRRsig(const isc::dns::RRsetPtr& sigs) {
+ AbstractRRset* p = const_cast<AbstractRRset*>(rrset_.get());
+ p->addRRsig(sigs);
+ }
+
+ virtual void removeRRsig() {
+ AbstractRRset* p = const_cast<AbstractRRset*>(rrset_.get());
+ p->removeRRsig();
+ }
+
+ /// \brief Return underlying RRset pointer
+ ///
+ /// ... mainly for testing.
+ virtual isc::dns::ConstRRsetPtr getUnderlyingRRset() const {
+ return (rrset_);
+ }
+
+private:
+ isc::dns::ConstRRsetPtr rrset_; ///< Underlying RRset
+};
+
+} // namespace datasrc
+} // namespace isc
+
+#endif // __RBNODE_RRSET_H
diff --git a/src/lib/datasrc/tests/Makefile.am b/src/lib/datasrc/tests/Makefile.am
index bfb0037..8eaf9ab 100644
--- a/src/lib/datasrc/tests/Makefile.am
+++ b/src/lib/datasrc/tests/Makefile.am
@@ -79,6 +79,7 @@ run_unittests_sqlite3_LDADD = $(common_ldadd)
# In-memory datasource tests
run_unittests_memory_SOURCES = $(common_sources)
run_unittests_memory_SOURCES += memory_datasrc_unittest.cc
+run_unittests_memory_SOURCES += rbnode_rrset_unittest.cc
run_unittests_memory_SOURCES += $(top_srcdir)/src/lib/datasrc/memory_datasrc.cc
run_unittests_memory_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
@@ -109,19 +110,21 @@ endif
endif
EXTRA_DIST = testdata/brokendb.sqlite3
+EXTRA_DIST += testdata/diffs.sqlite3
+EXTRA_DIST += testdata/example2.com
+EXTRA_DIST += testdata/example2.com.sqlite3
EXTRA_DIST += testdata/example.com.signed
EXTRA_DIST += testdata/example.org
EXTRA_DIST += testdata/example.org.nsec3-signed
EXTRA_DIST += testdata/example.org.nsec3-signed-noparam
EXTRA_DIST += testdata/example.org.sqlite3
-EXTRA_DIST += testdata/example2.com
-EXTRA_DIST += testdata/example2.com.sqlite3
EXTRA_DIST += testdata/mkbrokendb.c
EXTRA_DIST += testdata/root.zone
+EXTRA_DIST += testdata/rrset_toWire1
+EXTRA_DIST += testdata/rrset_toWire2
+EXTRA_DIST += testdata/rwtest.sqlite3
EXTRA_DIST += testdata/sql1.example.com.signed
EXTRA_DIST += testdata/sql2.example.com.signed
EXTRA_DIST += testdata/test-root.sqlite3
EXTRA_DIST += testdata/test.sqlite3
EXTRA_DIST += testdata/test.sqlite3.nodiffs
-EXTRA_DIST += testdata/rwtest.sqlite3
-EXTRA_DIST += testdata/diffs.sqlite3
diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
index abf6090..e8a62fc 100644
--- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
@@ -175,10 +175,15 @@ TEST_F(InMemoryClientTest, iterator) {
// Check it with full zone, one by one.
// It should be in ascending order in case of InMemory data source
// (isn't guaranteed in general)
+ // Since the in-memory data source uses objects that encapsulate the
+ // RRsets stored, the iterator does not iterate over the RRsets stored -
+ // it iterates over the encapsulating objects. This means that we cannot
+ // directly compare pointer values: instead, we compare the actual data
+ // stored.
iterator = memory_client.getIterator(Name("a"));
- EXPECT_EQ(aRRsetA, iterator->getNextRRset());
- EXPECT_EQ(aRRsetAAAA, iterator->getNextRRset());
- EXPECT_EQ(subRRsetA, iterator->getNextRRset());
+ EXPECT_EQ(aRRsetA->toText(), iterator->getNextRRset()->toText());
+ EXPECT_EQ(aRRsetAAAA->toText(), iterator->getNextRRset()->toText());
+ EXPECT_EQ(subRRsetA->toText(), iterator->getNextRRset()->toText());
EXPECT_EQ(ConstRRsetPtr(), iterator->getNextRRset());
}
diff --git a/src/lib/datasrc/tests/rbnode_rrset_unittest.cc b/src/lib/datasrc/tests/rbnode_rrset_unittest.cc
new file mode 100644
index 0000000..db2b7f8
--- /dev/null
+++ b/src/lib/datasrc/tests/rbnode_rrset_unittest.cc
@@ -0,0 +1,263 @@
+// Copyright (C) 2012 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 <stdexcept>
+
+#include <exceptions/exceptions.h>
+#include <dns/rdataclass.h>
+#include <datasrc/rbnode_rrset.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+
+using isc::UnitTestUtil;
+
+using namespace std;
+using namespace isc;
+using namespace isc::datasrc;
+using namespace isc::dns;
+using namespace isc::dns::rdata;
+using namespace isc::util;
+
+// These tests are very similar to those for RRset - indeed, this file was
+// created from those tests. However, the significant difference in behaviour
+// between RRset and RBNodeRRset - that the "set" methods in the latter mostly
+// result in exceptions being thrown - preclude use of full type
+// parameterisation of the tests.
+
+namespace {
+const char* RRSIG_TXT =
+ "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
+ "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+ "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+ "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+ "f49t+sXKPzbipN9g+s1ZPiIyofc=";
+
+class RBNodeRRsetTest : public ::testing::Test {
+protected:
+ RBNodeRRsetTest() :
+ test_name("test.example.com"),
+ test_domain("example.com"),
+ test_nsname("ns.example.com"),
+ rrset_a(ConstRRsetPtr(new RRset(
+ test_name, RRClass::IN(), RRType::A(), RRTTL(3600)))),
+ rrset_a_empty(ConstRRsetPtr(new RRset(
+ test_name, RRClass::IN(), RRType::A(), RRTTL(3600)))),
+ rrset_ns(ConstRRsetPtr(new RRset(
+ test_domain, RRClass::IN(), RRType::NS(), RRTTL(86400)))),
+ rrset_ch_txt(ConstRRsetPtr(new RRset(
+ test_domain, RRClass::CH(), RRType::TXT(), RRTTL(0)))),
+ rrset_siga(new RRset(test_name, RRClass::IN(), RRType::RRSIG(),
+ RRTTL(3600)))
+
+ {
+ // Add a couple of Rdata elements to the A RRset. The easiest way to
+ // do this is to override the "const" restrictions. As this is a test,
+ // we don't feel too bad about doing so.
+ AbstractRRset* a_rrset =
+ const_cast<AbstractRRset*>(rrset_a.getUnderlyingRRset().get());
+ a_rrset->addRdata(in::A("192.0.2.1"));
+ a_rrset->addRdata(in::A("192.0.2.2"));
+
+ // Create the RRSIG corresponding to the rrset_a record. The RDATA
+ // won't match the A record it covers, although it is internally
+ // self-consistent.
+ AbstractRRset* sig_rrset = const_cast<AbstractRRset*>(rrset_siga.get());
+ sig_rrset->addRdata(generic::RRSIG(RRSIG_TXT));
+ }
+
+ Name test_name;
+ Name test_domain;
+ Name test_nsname;
+
+ RBNodeRRset rrset_a;
+ RBNodeRRset rrset_a_empty;
+ RBNodeRRset rrset_ns;
+ RBNodeRRset rrset_ch_txt;
+
+ ConstRRsetPtr rrset_siga;
+};
+
+TEST_F(RBNodeRRsetTest, getRdataCount) {
+ EXPECT_EQ(0, rrset_a_empty.getRdataCount());
+ EXPECT_EQ(2, rrset_a.getRdataCount());
+}
+
+TEST_F(RBNodeRRsetTest, getName) {
+ EXPECT_EQ(test_name, rrset_a.getName());
+ EXPECT_EQ(test_domain, rrset_ns.getName());
+}
+
+TEST_F(RBNodeRRsetTest, getClass) {
+ EXPECT_EQ(RRClass("IN"), rrset_a.getClass());
+ EXPECT_EQ(RRClass("CH"), rrset_ch_txt.getClass());
+}
+
+TEST_F(RBNodeRRsetTest, 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(RBNodeRRsetTest, 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(RBNodeRRsetTest, setName) {
+ EXPECT_THROW(rrset_a.setName(test_nsname), NotImplemented);
+}
+
+TEST_F(RBNodeRRsetTest, setTTL) {
+ EXPECT_THROW(rrset_a.setTTL(RRTTL(86400)), NotImplemented);
+}
+
+TEST_F(RBNodeRRsetTest, 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);
+}
+
+TEST_F(RBNodeRRsetTest, toWireRenderer) {
+ OutputBuffer buffer(0);
+ MessageRenderer renderer(buffer);
+ rrset_a.toWire(renderer);
+
+ std::vector<unsigned char> wiredata;
+ UnitTestUtil::readWireData("rrset_toWire2", wiredata);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
+ buffer.getLength(), &wiredata[0], wiredata.size());
+
+ // toWire() cannot be performed for an empty RRset.
+ renderer.clear();
+ EXPECT_THROW(rrset_a_empty.toWire(renderer), EmptyRRset);
+}
+
+TEST_F(RBNodeRRsetTest, toWireBuffer) {
+ OutputBuffer buffer(0);
+ rrset_a.toWire(buffer);
+
+ std::vector<unsigned char> wiredata;
+ 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);
+}
+
+TEST_F(RBNodeRRsetTest, addRdata) {
+ EXPECT_THROW(rrset_a.addRdata(in::A("192.0.2.3")), NotImplemented);
+
+ // Check the same goes for trying to add the wrong type of data
+ EXPECT_THROW(rrset_a.addRdata(generic::NS(test_nsname)), NotImplemented);
+}
+
+TEST_F(RBNodeRRsetTest, addRdataPtr) {
+ EXPECT_THROW(rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(),
+ rrset_a_empty.getClass(),
+ "192.0.2.1")),
+ NotImplemented);
+}
+
+TEST_F(RBNodeRRsetTest, getRDataIterator) {
+ RdataIteratorPtr it = rrset_a.getRdataIterator();
+ for (int i = 0; i < 2; ++i) {
+ ASSERT_FALSE(it->isLast());
+ ASSERT_EQ(0, it->getCurrent().compare(in::A("192.0.2.1")));
+
+ it->next();
+ ASSERT_FALSE(it->isLast());
+ ASSERT_EQ(0, it->getCurrent().compare(in::A("192.0.2.2")));
+
+ it->next();
+ ASSERT_TRUE(it->isLast());
+
+ // Should be able repeat the iteration by calling first().
+ it->first();
+ }
+}
+
+// test operator<<. We simply confirm it appends the result of toText().
+TEST_F(RBNodeRRsetTest, LeftShiftOperator) {
+ ostringstream oss;
+ oss << rrset_a;
+ EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
+ "test.example.com. 3600 IN A 192.0.2.2\n", oss.str());
+}
+
+// General RRSIG check function. Get the RRSIG from the RRset and check that
+// the RDATA is what we expect.
+void
+checkSignature(const RBNodeRRset& rrset) {
+ RRsetPtr rrsig = rrset.getRRsig();
+ ASSERT_TRUE(rrsig);
+ RdataIteratorPtr it = rrsig->getRdataIterator();
+ EXPECT_EQ(RRSIG_TXT, it->getCurrent().toText());
+}
+
+// addRRSIG tests.
+TEST_F(RBNodeRRsetTest, addRRsigConstRdataPointer) {
+ EXPECT_FALSE(rrset_a.getRRsig());
+ RdataPtr data = createRdata(rrset_siga->getType(), rrset_siga->getClass(),
+ RRSIG_TXT);
+ ConstRdataPtr cdata(data);
+ rrset_a.addRRsig(cdata);
+ checkSignature(rrset_a);
+}
+
+TEST_F(RBNodeRRsetTest, addRRsigRdataPointer) {
+ EXPECT_FALSE(rrset_a.getRRsig());
+ RdataPtr data = createRdata(rrset_siga->getType(), rrset_siga->getClass(),
+ RRSIG_TXT);
+ rrset_a.addRRsig(data);
+ checkSignature(rrset_a);
+}
+
+TEST_F(RBNodeRRsetTest, addRRsigAbstractRRset) {
+ EXPECT_FALSE(rrset_a.getRRsig());
+ rrset_a.addRRsig(*(rrset_siga.get()));
+ checkSignature(rrset_a);
+}
+
+TEST_F(RBNodeRRsetTest, addRRsigConstantRRsetPointer) {
+ EXPECT_FALSE(rrset_a.getRRsig());
+ rrset_a.addRRsig(rrset_siga);
+ checkSignature(rrset_a);
+}
+
+TEST_F(RBNodeRRsetTest, addRRsigRRsetPointer) {
+ EXPECT_FALSE(rrset_a.getRRsig());
+ RRsetPtr rrsig(new RRset(test_name, RRClass::IN(), RRType::RRSIG(),
+ RRTTL(3600)));
+ rrsig->addRdata(generic::RRSIG(RRSIG_TXT));
+ rrset_a.addRRsig(rrsig);
+ checkSignature(rrset_a);
+}
+
+TEST_F(RBNodeRRsetTest, removeRRsig) {
+ EXPECT_FALSE(rrset_a.getRRsig());
+ rrset_a.addRRsig(*(rrset_siga.get()));
+ EXPECT_TRUE(rrset_a.getRRsig());
+ rrset_a.removeRRsig();
+ EXPECT_FALSE(rrset_a.getRRsig());
+}
+
+} // Anonymous namespace
diff --git a/src/lib/datasrc/tests/testdata/rrset_toWire1 b/src/lib/datasrc/tests/testdata/rrset_toWire1
new file mode 100644
index 0000000..8f81a0e
--- /dev/null
+++ b/src/lib/datasrc/tests/testdata/rrset_toWire1
@@ -0,0 +1,23 @@
+#
+# Rendering an IN/A RRset containing 2 RRs:
+# test.example.com. 3600 IN A 192.0.2.1
+# test.example.com. 3600 IN A 192.0.2.2
+#
+#(4) t e s t (7) e x a m p l e (3) c o m .
+ 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+# type/class: A = 1, IN = 1
+00 01 00 01
+# TTL: 3600
+00 00 0e 10
+#6 7
+# RDLENGTH: 4
+00 04
+# RDATA: 192.0.2.1
+c0 00 02 01
+#
+# 2nd RR: mostly the same except the RDATA
+04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+00 01 00 01
+00 00 0e 10
+00 04
+c0 00 02 02
diff --git a/src/lib/datasrc/tests/testdata/rrset_toWire2 b/src/lib/datasrc/tests/testdata/rrset_toWire2
new file mode 100644
index 0000000..b9a6a15
--- /dev/null
+++ b/src/lib/datasrc/tests/testdata/rrset_toWire2
@@ -0,0 +1,26 @@
+#
+# Rendering an IN/A RRset and NS RRset as follows:
+# test.example.com. 3600 IN A 192.0.2.1
+# test.example.com. 3600 IN A 192.0.2.2
+# example.com. 1D IN NS ns.example.com.
+# Names will be compressed when possible.
+#
+# 0 1 2 3 4 5
+#(4) t e s t (7) e x a m p l e (3) c o m .
+ 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+# type/class: A = 1, IN = 1
+00 01 00 01
+# TTL: 3600
+00 00 0e 10
+#6 7
+# RDLENGTH: 4
+00 04
+# RDATA: 192.0.2.1
+c0 00 02 01
+#
+# 2nd RR: the owner name is compresed
+c0 00
+00 01 00 01
+00 00 0e 10
+00 04
+c0 00 02 02
More information about the bind10-changes
mailing list