[svn] commit: r4031 - in /trunk: ./ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/recurse/tests/ src/lib/asiolink/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/log/ src/lib/python/isc/utils/ src/lib/testutils/
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Dec 28 11:49:31 UTC 2010
Author: vorner
Date: Tue Dec 28 11:49:31 2010
New Revision: 4031
Log:
Merge #447 (MemoryZone::find)
Modified:
trunk/ (props changed)
trunk/src/bin/auth/tests/testdata/ (props changed)
trunk/src/bin/bind10/bind10.py.in (props changed)
trunk/src/bin/recurse/tests/ (props changed)
trunk/src/lib/asiolink/ (props changed)
trunk/src/lib/datasrc/memory_datasrc.cc
trunk/src/lib/datasrc/memory_datasrc.h
trunk/src/lib/datasrc/tests/memory_datasrc_unittest.cc
trunk/src/lib/log/ (props changed)
trunk/src/lib/python/isc/utils/ (props changed)
trunk/src/lib/testutils/ (props changed)
Modified: trunk/src/lib/datasrc/memory_datasrc.cc
==============================================================================
--- trunk/src/lib/datasrc/memory_datasrc.cc (original)
+++ trunk/src/lib/datasrc/memory_datasrc.cc Tue Dec 28 11:49:31 2010
@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <map>
+#include <cassert>
#include <boost/shared_ptr.hpp>
#include <dns/name.h>
@@ -51,12 +52,98 @@
* that.
*/
typedef map<RRType, ConstRRsetPtr> Domain;
+ typedef Domain::value_type DomainPair;
typedef boost::shared_ptr<Domain> DomainPtr;
// The tree stores domains
typedef RBTree<Domain> DomainTree;
typedef RBNode<Domain> DomainNode;
// The actual zone data
DomainTree domains_;
+
+ /*
+ * Implementation of longer methods. We put them here, because the
+ * access is without the impl_-> and it will get inlined anyway.
+ */
+ // Implementation of MemoryZone::add
+ result::Result add(const ConstRRsetPtr& rrset) {
+ // Sanitize input
+ if (!rrset) {
+ isc_throw(NullRRset, "The rrset provided is NULL");
+ }
+ Name name(rrset->getName());
+ NameComparisonResult compare(origin_.compare(name));
+ if (compare.getRelation() != NameComparisonResult::SUPERDOMAIN &&
+ compare.getRelation() != NameComparisonResult::EQUAL)
+ {
+ isc_throw(OutOfZone, "The name " << name <<
+ " is not contained in zone " << origin_);
+ }
+ // Get the node
+ DomainNode* node;
+ switch (domains_.insert(name, &node)) {
+ // Just check it returns reasonable results
+ case DomainTree::SUCCEED:
+ case DomainTree::ALREADYEXIST:
+ break;
+ // Something odd got out
+ default:
+ assert(0);
+ }
+ assert(node);
+
+ // Now get the domain
+ DomainPtr domain;
+ // It didn't exist yet, create it
+ if (node->isEmpty()) {
+ domain.reset(new Domain);
+ node->setData(domain);
+ } else { // Get existing one
+ domain = node->getData();
+ }
+
+ // Try inserting the rrset there
+ if (domain->insert(DomainPair(rrset->getType(), rrset)).second) {
+ // Ok, we just put it in
+ return (result::SUCCESS);
+ } else {
+ // The RRSet of given type was already there
+ return (result::EXIST);
+ }
+ }
+
+ // Implementation of MemoryZone::find
+ FindResult find(const Name& name, RRType type) const {
+ // Get the node
+ DomainNode* node;
+ switch (domains_.find(name, &node)) {
+ case DomainTree::PARTIALMATCH:
+ // Pretend it was not found for now
+ // TODO: Implement real delegation. Currently, not having
+ // the the domain can cause a partialmatch as well, so
+ // better check.
+ case DomainTree::NOTFOUND:
+ return (FindResult(NXDOMAIN, ConstRRsetPtr()));
+ case DomainTree::EXACTMATCH: // This one is OK, handle it
+ break;
+ default:
+ assert(0);
+ }
+ assert(node);
+ assert(!node->isEmpty());
+
+ Domain::const_iterator found(node->getData()->find(type));
+ if (found != node->getData()->end()) {
+ // Good, it is here
+ return (FindResult(SUCCESS, found->second));
+ } else {
+ /*
+ * TODO Look for CNAME and DNAME (it should be OK to do so when
+ * the value is not found, as CNAME/DNAME domain should be
+ * empty otherwise.)
+ */
+ return (FindResult(NXRRSET, ConstRRsetPtr()));
+ }
+ }
};
MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
@@ -79,9 +166,13 @@
}
Zone::FindResult
-MemoryZone::find(const Name&, const RRType&) const {
- // This is a tentative implementation that always returns NXDOMAIN.
- return (FindResult(NXDOMAIN, RRsetPtr()));
+MemoryZone::find(const Name& name, const RRType& type) const {
+ return (impl_->find(name, type));
+}
+
+result::Result
+MemoryZone::add(const ConstRRsetPtr& rrset) {
+ return (impl_->add(rrset));
}
/// Implementation details for \c MemoryDataSrc hidden from the public
Modified: trunk/src/lib/datasrc/memory_datasrc.h
==============================================================================
--- trunk/src/lib/datasrc/memory_datasrc.h (original)
+++ trunk/src/lib/datasrc/memory_datasrc.h Tue Dec 28 11:49:31 2010
@@ -58,8 +58,44 @@
/// \brief Looks up an RRset in the zone.
///
/// See documentation in \c Zone.
+ ///
+ /// It returns NULL pointer in case of NXDOMAIN and NXRRSET
+ /// (the base class documentation does not seem to require that).
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type) const;
+
+ /// \brief Inserts an rrset into the zone.
+ ///
+ /// It puts another RRset into the zone.
+ ///
+ /// It throws NullRRset or OutOfZone if the provided rrset is invalid. It
+ /// might throw standard allocation exceptions, in which case this function
+ /// does not guarantee strong exception safety (it is currently not needed,
+ /// if it is needed in future, it should be implemented).
+ ///
+ /// \param rrset The set to add.
+ /// \return SUCCESS or EXIST (if an rrset for given name and type already
+ /// exists).
+ result::Result add(const isc::dns::ConstRRsetPtr& rrset);
+
+ /// \brief RRSet out of zone exception.
+ ///
+ /// This is thrown if addition of an RRset that doesn't belong under the
+ /// zone's origin is requested.
+ struct OutOfZone : public InvalidParameter {
+ OutOfZone(const char* file, size_t line, const char* what) :
+ InvalidParameter(file, line, what)
+ { }
+ };
+
+ /// \brief RRset is NULL exception.
+ ///
+ /// This is thrown if the provided RRset parameter is NULL.
+ struct NullRRset : public InvalidParameter {
+ NullRRset(const char* file, size_t line, const char* what) :
+ InvalidParameter(file, line, what)
+ { }
+ };
private:
/// \name Hidden private data
Modified: trunk/src/lib/datasrc/tests/memory_datasrc_unittest.cc
==============================================================================
--- trunk/src/lib/datasrc/tests/memory_datasrc_unittest.cc (original)
+++ trunk/src/lib/datasrc/tests/memory_datasrc_unittest.cc Tue Dec 28 11:49:31 2010
@@ -16,6 +16,7 @@
#include <dns/name.h>
#include <dns/rrclass.h>
+#include <dns/rrttl.h>
#include <datasrc/memory_datasrc.h>
@@ -136,13 +137,64 @@
MemoryZoneTest() :
class_(RRClass::IN()),
origin_("example.org"),
- zone_(class_, origin_)
- { }
+ ns_name_("ns.example.org"),
+ zone_(class_, origin_),
+ rr_out_(new RRset(Name("example.com"), class_, RRType::A(),
+ RRTTL(300))),
+ rr_ns_(new RRset(origin_, class_, RRType::NS(), RRTTL(300))),
+ rr_ns_a_(new RRset(ns_name_, class_, RRType::A(), RRTTL(300))),
+ rr_ns_aaaa_(new RRset(ns_name_, class_, RRType::AAAA(), RRTTL(300))),
+ rr_a_(new RRset(origin_, class_, RRType::A(), RRTTL(300)))
+ {
+ }
// Some data to test with
RRClass class_;
- Name origin_;
+ Name origin_, ns_name_;
// The zone to torture by tests
MemoryZone zone_;
+
+ /*
+ * Some RRsets to put inside the zone.
+ * They are empty, but the MemoryZone does not have a reason to look
+ * inside anyway. We will check it finds them and does not change
+ * the pointer.
+ */
+ RRsetPtr
+ // Out of zone RRset
+ rr_out_,
+ // NS of example.org
+ rr_ns_,
+ // A of ns.example.org
+ rr_ns_a_,
+ // AAAA of ns.example.org
+ rr_ns_aaaa_,
+ // A of example.org
+ rr_a_;
+
+ /**
+ * \brief Test one find query to the zone.
+ *
+ * Asks a query to the zone and checks it does not throw and returns
+ * expected results. It returns nothing, it just signals failures
+ * to GTEST.
+ *
+ * \param name The name to ask for.
+ * \param rrtype The RRType to ask of.
+ * \param result The expected code of the result.
+ * \param answer The expected rrset, if any should be returned.
+ */
+ void findTest(const Name& name, const RRType& rrtype, Zone::Result result,
+ const ConstRRsetPtr& answer = ConstRRsetPtr())
+ {
+ // The whole block is inside, because we need to check the result and
+ // we can't assign to FindResult
+ EXPECT_NO_THROW({
+ Zone::FindResult find_result(zone_.find(name, rrtype));
+ // Check it returns correct answers
+ EXPECT_EQ(result, find_result.code);
+ EXPECT_EQ(answer, find_result.rrset);
+ });
+ }
};
/**
@@ -151,8 +203,61 @@
* Takes the created zone and checks its properties they are the same
* as passed parameters.
*/
-TEST_F(MemoryZoneTest, Constructor) {
+TEST_F(MemoryZoneTest, constructor) {
ASSERT_EQ(class_, zone_.getClass());
ASSERT_EQ(origin_, zone_.getOrigin());
}
-}
+/**
+ * \brief Test adding.
+ *
+ * We test that it throws at the correct moments and the correct exceptions.
+ * And we test the return value.
+ */
+TEST_F(MemoryZoneTest, add) {
+ // This one does not belong to this zone
+ EXPECT_THROW(zone_.add(rr_out_), MemoryZone::OutOfZone);
+ // Test null pointer
+ EXPECT_THROW(zone_.add(ConstRRsetPtr()), MemoryZone::NullRRset);
+
+ using namespace result; // Who should write the prefix all the time
+ // Now put all the data we have there. It should throw nothing
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_)));
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_a_)));
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_aaaa_)));
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_a_)));
+
+ // Try putting there something twice, it should be rejected
+ EXPECT_NO_THROW(EXPECT_EQ(EXIST, zone_.add(rr_ns_)));
+ EXPECT_NO_THROW(EXPECT_EQ(EXIST, zone_.add(rr_ns_a_)));
+}
+
+/**
+ * \brief Test searching.
+ *
+ * Check it finds or does not find correctly and does not throw exceptions.
+ * \todo This doesn't do any kind of CNAME and so on. If it isn't
+ * directly there, it just tells it doesn't exist.
+ */
+TEST_F(MemoryZoneTest, find) {
+ // Fill some data inside
+ using namespace result; // Who should write the prefix all the time
+ // Now put all the data we have there. It should throw nothing
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_)));
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_a_)));
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_ns_aaaa_)));
+ EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_.add(rr_a_)));
+
+ // These two should be successful
+ findTest(origin_, RRType::NS(), Zone::SUCCESS, rr_ns_);
+ findTest(ns_name_, RRType::A(), Zone::SUCCESS, rr_ns_a_);
+
+ // These domain exist but don't have the provided RRType
+ findTest(origin_, RRType::AAAA(), Zone::NXRRSET);
+ findTest(ns_name_, RRType::NS(), Zone::NXRRSET);
+
+ // These domains don't exist (and one is out of the zone)
+ findTest(Name("nothere.example.org"), RRType::A(), Zone::NXDOMAIN);
+ findTest(Name("example.net"), RRType::A(), Zone::NXDOMAIN);
+}
+
+}
More information about the bind10-changes
mailing list