BIND 10 trac2976, updated. 570fc14873220c13f62e622fd3f227a73ae9a106 [2976] Completed implementation of fromWire test.

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jun 25 11:45:26 UTC 2013


The branch, trac2976 has been updated
       via  570fc14873220c13f62e622fd3f227a73ae9a106 (commit)
      from  010bda2e96f5763e6eec226ac1cee96bce2588e5 (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 570fc14873220c13f62e622fd3f227a73ae9a106
Author: Marcin Siodelski <marcin at isc.org>
Date:   Tue Jun 25 13:45:07 2013 +0200

    [2976] Completed implementation of fromWire test.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/d2/Makefile.am                          |    1 +
 src/bin/d2/d2_update_message.cc                 |   21 ++++-
 src/bin/d2/d2_update_message.h                  |    8 +-
 src/bin/d2/{d2_log.h => d2_zone.cc}             |   22 +++--
 src/bin/d2/d2_zone.h                            |  115 +++++++++++++++++++++++
 src/bin/d2/tests/Makefile.am                    |    2 +
 src/bin/d2/tests/d2_update_message_unittests.cc |   61 ++++++++----
 src/bin/d2/tests/d2_zone_unittests.cc           |   65 +++++++++++++
 8 files changed, 260 insertions(+), 35 deletions(-)
 copy src/bin/d2/{d2_log.h => d2_zone.cc} (71%)
 create mode 100644 src/bin/d2/d2_zone.h
 create mode 100644 src/bin/d2/tests/d2_zone_unittests.cc

-----------------------------------------------------------------------
diff --git a/src/bin/d2/Makefile.am b/src/bin/d2/Makefile.am
index e4307bf..6f889db 100644
--- a/src/bin/d2/Makefile.am
+++ b/src/bin/d2/Makefile.am
@@ -53,6 +53,7 @@ b10_dhcp_ddns_SOURCES += d2_process.cc d2_process.h
 b10_dhcp_ddns_SOURCES += d_controller.cc d_controller.h
 b10_dhcp_ddns_SOURCES += d2_controller.cc d2_controller.h
 b10_dhcp_ddns_SOURCES += d2_update_message.cc d2_update_message.h
+b10_dhcp_ddns_SOURCES += d2_zone.cc d2_zone.h
 
 nodist_b10_dhcp_ddns_SOURCES = d2_messages.h d2_messages.cc
 EXTRA_DIST += d2_messages.mes
diff --git a/src/bin/d2/d2_update_message.cc b/src/bin/d2/d2_update_message.cc
index 19a104f..ab8ff16 100644
--- a/src/bin/d2/d2_update_message.cc
+++ b/src/bin/d2/d2_update_message.cc
@@ -12,13 +12,12 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <d2/d2_update_message.h>
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
 #include <dns/opcode.h>
 #include <dns/question.h>
 
-#include <d2/d2_update_message.h>
-
 namespace isc {
 namespace d2 {
 
@@ -85,7 +84,14 @@ D2UpdateMessage::setZone(const Name& zone, const RRClass& rrclass) {
         message_.clearSection(dns::Message::SECTION_QUESTION);
     }
 
-    message_.addQuestion(Question(zone, rrclass, RRType::SOA()));
+    Question question(zone, rrclass, RRType::SOA());
+    message_.addQuestion(question);
+    zone_.reset(new D2Zone(question.getName(), question.getClass()));
+}
+
+D2ZonePtr
+D2UpdateMessage::getZone() const {
+    return (zone_);
 }
 
 void
@@ -118,6 +124,15 @@ D2UpdateMessage::toWire(AbstractMessageRenderer& renderer) {
 void
 D2UpdateMessage::fromWire(isc::util::InputBuffer& buffer) {
     message_.fromWire(buffer);
+    if (getRRCount(D2UpdateMessage::SECTION_ZONE) > 0) {
+        QuestionPtr question = *message_.beginQuestion();
+        assert(question);
+        zone_.reset(new D2Zone(question->getName(), question->getClass()));
+
+    } else {
+        zone_.reset();
+
+    }
 }
 
 dns::Message::Section
diff --git a/src/bin/d2/d2_update_message.h b/src/bin/d2/d2_update_message.h
index b90e6fb..3979a0a 100644
--- a/src/bin/d2/d2_update_message.h
+++ b/src/bin/d2/d2_update_message.h
@@ -15,6 +15,7 @@
 #ifndef D2_UPDATE_MESSAGE_H
 #define D2_UPDATE_MESSAGE_H
 
+#include <d2/d2_zone.h>
 #include <dns/message.h>
 #include <dns/name.h>
 #include <dns/rcode.h>
@@ -91,16 +92,14 @@ public:
 
     unsigned int getRRCount(const UpdateMsgSection section) const;
 
-    const dns::QuestionIterator beginQuestion() const;
-
-    const dns::QuestionIterator endQuestion() const;
-
     const dns::RRsetIterator beginSection(const UpdateMsgSection section) const;
 
     const dns::RRsetIterator endSection(const UpdateMsgSection section) const;
 
     void setZone(const dns::Name& zone, const dns::RRClass& rrclass);
 
+    D2ZonePtr getZone() const;
+
     void addRRset(const UpdateMsgSection section, const dns::RRsetPtr& rrset);
 
     bool hasRRset(const UpdateMsgSection section, const dns::Name& name,
@@ -122,6 +121,7 @@ private:
     static dns::Message::Section ddnsToDnsSection(const UpdateMsgSection section);
 
     dns::Message message_;
+    D2ZonePtr zone_;
 
 };
 
diff --git a/src/bin/d2/d2_zone.cc b/src/bin/d2/d2_zone.cc
new file mode 100644
index 0000000..96aa2bb
--- /dev/null
+++ b/src/bin/d2/d2_zone.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2013  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 <d2/d2_zone.h>
+
+namespace isc {
+namespace d2 {
+
+D2Zone::D2Zone(const dns::Name& name, const dns::RRClass& rrclass)
+    : name_(name), rrclass_(rrclass) {
+}
+
+std::string D2Zone::toText() const {
+    return (name_.toText() + " " + rrclass_.toText() + " SOA\n");
+}
+
+std::ostream&
+operator<<(std::ostream& os, const D2Zone& zone) {
+    os << zone.toText();
+    return (os);
+}
+
+} // namespace d2
+} // namespace isc
+
diff --git a/src/bin/d2/d2_zone.h b/src/bin/d2/d2_zone.h
new file mode 100644
index 0000000..72e583f
--- /dev/null
+++ b/src/bin/d2/d2_zone.h
@@ -0,0 +1,115 @@
+// Copyright (C) 2013  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 D2_ZONE_H
+#define D2_ZONE_H
+
+#include <dns/name.h>
+#include <dns/rrclass.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace isc {
+namespace d2 {
+
+/// @brief The @c D2Zone encapsulates the Zone section in DNS Update message.
+///
+/// This class is used by the @c D2UpdateMessage to encapsulate the Zone section
+/// of the DNS Update message. Class members hold corresponding values of
+/// section's fields: NAME, CLASS. This class does not hold the RTYPE field value
+/// because RTYPE is always equal to SOA for DNS Update message (see RFC 2136,
+/// section 2.3).
+///
+/// Note, that this @c D2Zone class neither exposes functions to decode messages
+/// from wire format nor to encode to wire format. This is not needed because
+/// @c isc::d2::D2UpdateMessage class uses @c D2Zone only to return the parsed Zone
+/// information to the caller. Internally, D2UpdateMessage parses and stores Zone
+/// section using @c isc::dns::Question class.
+class D2Zone {
+public:
+    /// @brief Constructor from Name and RRClass.
+    ///
+    /// @param name The name of the Zone.
+    /// @param rrclass The RR class of the Zone.
+    D2Zone(const dns::Name& name, const dns::RRClass& rrclass);
+
+    ///
+    /// @name Getters
+    ///
+    //@{
+    /// @brief Returns the Zone name.
+    ///
+    /// @return A reference to the Zone name.
+    const dns::Name& getName() const { return (name_); }
+
+    /// @brief Returns the Zone class.
+    ///
+    /// @return A reference to the Zone class.
+    const dns::RRClass& getClass() const { return (rrclass_); }
+    //@}
+
+    /// @brief Returns text representation of the Zone.
+    ///
+    /// This function concatenates the name of the Zone, Class and Type.
+    /// The type is always SOA.
+    ///
+    /// @return A text representation of the Zone.
+    std::string toText() const;
+
+    ///
+    /// @name Comparison Operators
+    ///
+    //@{
+    /// @brief Equality operator to compare @c D2Zone objects in query and response
+    /// messages.
+    ///
+    /// @param rhs Zone to compare against.
+    ///
+    /// @return true if name and class are equal, false otherwise.
+    bool operator==(const D2Zone& rhs) const {
+        return ((rrclass_ == rhs.rrclass_) && (name_ == rhs.name_));
+    }
+
+    /// @brief Inequality operator to compare @c D2Zone objects in query and
+    /// response messages.
+    ///
+    /// @param rhs Zone to compare against.
+    ///
+    /// @return true if any of name or class are unequal, false otherwise.
+    bool operator!=(const D2Zone& rhs) const {
+        return (!operator==(rhs));
+    }
+    //@}
+
+private:
+    dns::Name name_;       ///< Holds the Zone name.
+    dns::RRClass rrclass_; ///< Holds the Zone class.
+};
+
+typedef boost::shared_ptr<D2Zone> D2ZonePtr;
+
+/// @brief Insert the @c D2Zone as a string into stream.
+///
+/// @param os A @c std::ostream object on which the insertion operation is
+/// performed.
+/// @param zone A reference to the @c D2Zone object output by the
+/// operation.
+/// @param A reference to the same @c std::ostream object referenced by
+/// parameter @c os after the insertion operation.
+std::ostream& operator<<(std::ostream& os, const D2Zone& zone);
+
+} // namespace d2
+} // namespace isc
+
+#endif // D2_ZONE_H
diff --git a/src/bin/d2/tests/Makefile.am b/src/bin/d2/tests/Makefile.am
index c2711c8..a7b37ce 100644
--- a/src/bin/d2/tests/Makefile.am
+++ b/src/bin/d2/tests/Makefile.am
@@ -57,12 +57,14 @@ d2_unittests_SOURCES += ../d_controller.cc ../d2_controller.h
 d2_unittests_SOURCES += ../d2_process.cc ../d2_process.h
 d2_unittests_SOURCES += ../d2_controller.cc ../d2_controller.h
 d2_unittests_SOURCES += ../d2_update_message.cc ../d2_update_message.h
+d2_unittests_SOURCES += ../d2_zone.cc ../d2_zone.h
 d2_unittests_SOURCES += d_test_stubs.cc d_test_stubs.h
 d2_unittests_SOURCES += d2_unittests.cc
 d2_unittests_SOURCES += d2_process_unittests.cc
 d2_unittests_SOURCES += d_controller_unittests.cc
 d2_unittests_SOURCES += d2_controller_unittests.cc
 d2_unittests_SOURCES += d2_update_message_unittests.cc
+d2_unittests_SOURCES += d2_zone_unittests.cc
 nodist_d2_unittests_SOURCES = ../d2_messages.h ../d2_messages.cc
 
 d2_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
diff --git a/src/bin/d2/tests/d2_update_message_unittests.cc b/src/bin/d2/tests/d2_update_message_unittests.cc
index 101110c..5f179ff 100644
--- a/src/bin/d2/tests/d2_update_message_unittests.cc
+++ b/src/bin/d2/tests/d2_update_message_unittests.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013 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
@@ -15,6 +15,7 @@
 #include <config.h>
 
 #include <d2/d2_update_message.h>
+#include <d2/d2_zone.h>
 #include <dns/messagerenderer.h>
 #include <dns/rdataclass.h>
 #include <dns/rdata.h>
@@ -151,50 +152,72 @@ TEST_F(D2UpdateMessageTest, fromWire) {
     };
     InputBuffer buf(bin_msg, sizeof(bin_msg));
 
+    // Create an object to be used to decode the message from the wire format.
     D2UpdateMessage msg(true);
-
+    // Decode the message.
     ASSERT_NO_THROW(msg.fromWire(buf));
 
+    // Check that the message header is valid.
     EXPECT_EQ(0x05AF, msg.getQid());
     EXPECT_EQ(D2UpdateMessage::RESPONSE, msg.getQRFlag());
     EXPECT_EQ(Rcode::YXDOMAIN_CODE, msg.getRcode().getCode());
+
+    // The ZOCOUNT must contain exactly one zone. If it does, we should get
+    // the name, class and type of the zone and verify they are valid.
     ASSERT_EQ(1, msg.getRRCount(D2UpdateMessage::SECTION_ZONE));
-    // Zone section is TBD
+    D2ZonePtr zone = msg.getZone();
+    ASSERT_TRUE(zone);
+    EXPECT_EQ("example.com.", zone->getName().toText());
+    EXPECT_EQ(RRClass::IN().getCode(), zone->getClass().getCode());
 
+    // Check the Prerequisite section. It should contain two records.
     ASSERT_EQ(2, msg.getRRCount(D2UpdateMessage::SECTION_PREREQUISITE));
+
+    // Proceed to the first prerequisite.
     RRsetIterator rrset_it = msg.beginSection(D2UpdateMessage::SECTION_PREREQUISITE);
     RRsetPtr prereq1 = *rrset_it;
     ASSERT_TRUE(prereq1);
-    EXPECT_EQ("foo.example.com.", prereq1->getName().toText());
-    EXPECT_EQ(RRType::AAAA().getCode(), prereq1->getType().getCode());
-    EXPECT_EQ(RRClass::NONE().getCode(), prereq1->getClass().getCode());
-    EXPECT_EQ(0, prereq1->getTTL().getValue());
-    EXPECT_EQ(0, prereq1->getRdataCount());
+    // Check record fields.
+    EXPECT_EQ("foo.example.com.", prereq1->getName().toText()); // NAME
+    EXPECT_EQ(RRType::AAAA().getCode(), prereq1->getType().getCode()); // TYPE
+    EXPECT_EQ(RRClass::NONE().getCode(), prereq1->getClass().getCode()); // CLASS
+    EXPECT_EQ(0, prereq1->getTTL().getValue()); // TTL
+    EXPECT_EQ(0, prereq1->getRdataCount()); // RDLENGTH
 
     // Move to next prerequisite section.
     ++rrset_it;
-
     RRsetPtr prereq2 = *rrset_it;
     ASSERT_TRUE(prereq2);
-    EXPECT_EQ("bar.example.com.", prereq2->getName().toText());
-    EXPECT_EQ(RRType::AAAA().getCode(), prereq2->getType().getCode());
-    EXPECT_EQ(RRClass::ANY().getCode(), prereq2->getClass().getCode());
-    EXPECT_EQ(0, prereq2->getTTL().getValue());
-    EXPECT_EQ(0, prereq2->getRdataCount());
-
+    // Check record fields.
+    EXPECT_EQ("bar.example.com.", prereq2->getName().toText()); // NAME
+    EXPECT_EQ(RRType::AAAA().getCode(), prereq2->getType().getCode()); // TYPE
+    EXPECT_EQ(RRClass::ANY().getCode(), prereq2->getClass().getCode()); // CLASS
+    EXPECT_EQ(0, prereq2->getTTL().getValue()); // TTL
+    EXPECT_EQ(0, prereq2->getRdataCount()); // RDLENGTH
+
+    // Check the Update section. There is only one record, so beginSection()
+    // should return the pointer to this sole record.
     ASSERT_EQ(1, msg.getRRCount(D2UpdateMessage::SECTION_UPDATE));
     rrset_it = msg.beginSection(D2UpdateMessage::SECTION_UPDATE);
     RRsetPtr update = *rrset_it;
     ASSERT_TRUE(update);
-    EXPECT_EQ("foo.example.com.", update->getName().toText());
-    EXPECT_EQ(RRType::AAAA().getCode(), update->getType().getCode());
-    EXPECT_EQ(RRClass::IN().getCode(), update->getClass().getCode());
-    EXPECT_EQ(0xAABBCCDD, update->getTTL().getValue());
+    // Check the record fields.
+    EXPECT_EQ("foo.example.com.", update->getName().toText()); // NAME
+    EXPECT_EQ(RRType::AAAA().getCode(), update->getType().getCode()); // TYPE
+    EXPECT_EQ(RRClass::IN().getCode(), update->getClass().getCode()); // CLASS
+    EXPECT_EQ(0xAABBCCDD, update->getTTL().getValue()); // TTL
+    // There should be exactly one record holding the IPv6 address.
+    // This record can be accessed using RdataIterator. This record
+    // can be compared with the reference record, holding expected IPv6
+    // address using compare function.
     ASSERT_EQ(1, update->getRdataCount());
     RdataIteratorPtr rdata_it = update->getRdataIterator();
     ASSERT_TRUE(rdata_it);
     in::AAAA rdata_ref("2001:db8:1::1");
     EXPECT_EQ(0, rdata_ref.compare(rdata_it->getCurrent()));
+
+    // @todo: at this point we don't test Additional Data records. We may
+    // consider implementing tests for it in the future.
 }
 
 // This test verifies that the wire format of the message is produced
diff --git a/src/bin/d2/tests/d2_zone_unittests.cc b/src/bin/d2/tests/d2_zone_unittests.cc
new file mode 100644
index 0000000..8a7e9d5
--- /dev/null
+++ b/src/bin/d2/tests/d2_zone_unittests.cc
@@ -0,0 +1,65 @@
+// Copyright (C) 2013 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 <config.h>
+#include <d2/d2_zone.h>
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::d2;
+using namespace isc::dns;
+
+namespace {
+
+TEST(D2ZoneTest, constructor) {
+    D2Zone zone1(Name("example.com"), RRClass::ANY());
+    EXPECT_EQ("example.com.", zone1.getName().toText());
+    EXPECT_EQ(RRClass::ANY().getCode(), zone1.getClass().getCode());
+
+    D2Zone zone2(Name("foo.example.com"), RRClass::IN());
+    EXPECT_EQ("foo.example.com.", zone2.getName().toText());
+    EXPECT_EQ(RRClass::IN().getCode(), zone2.getClass().getCode());
+}
+
+TEST(D2ZoneTest, toText) {
+    D2Zone zone1(Name("example.com"), RRClass::ANY());
+    EXPECT_EQ("example.com. ANY SOA\n", zone1.toText());
+
+    D2Zone zone2(Name("foo.example.com"), RRClass::IN());
+    EXPECT_EQ("foo.example.com. IN SOA\n", zone2.toText());
+}
+
+TEST(D2ZoneTest, compare) {
+    const Name a("a"), b("b");
+    const RRClass in(RRClass::IN()), any(RRClass::ANY());
+
+    // Equality check
+    EXPECT_TRUE(D2Zone(a, any) == D2Zone(a, any));
+    EXPECT_FALSE(D2Zone(a, any) != D2Zone(a, any));
+
+    // Inequality check, objects differ by class.
+    EXPECT_FALSE(D2Zone(a, any) == D2Zone(a, in));
+    EXPECT_TRUE(D2Zone(a, any) != D2Zone(a, in));
+
+    // Inequality check, objects differ by name.
+    EXPECT_FALSE(D2Zone(a, any) == D2Zone(b, any));
+    EXPECT_TRUE(D2Zone(a, any) != D2Zone(b, any));
+
+    // Inequality check, objects differ by name and class.
+    EXPECT_FALSE(D2Zone(a, any) == D2Zone(b, in));
+    EXPECT_TRUE(D2Zone(a, any) != D2Zone(b, in));
+}
+
+} // End of anonymous namespace



More information about the bind10-changes mailing list