BIND 10 trac2304, updated. f4f708e4e93579989bf716d5851311a2b5aff6b5 [2304] Added unit tests for Option6Int option.

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Oct 9 16:35:07 UTC 2012


The branch, trac2304 has been updated
       via  f4f708e4e93579989bf716d5851311a2b5aff6b5 (commit)
      from  71e12e0bc1d27327a0f3f520ae80041af38ce657 (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 f4f708e4e93579989bf716d5851311a2b5aff6b5
Author: Marcin Siodelski <marcin at isc.org>
Date:   Tue Oct 9 18:34:42 2012 +0200

    [2304] Added unit tests for Option6Int option.

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

Summary of changes:
 src/lib/dhcp/option6_int.h                 |   15 +-
 src/lib/dhcp/tests/Makefile.am             |    1 +
 src/lib/dhcp/tests/option6_int_unittest.cc |  329 ++++++++++++++++++++++++++++
 3 files changed, 341 insertions(+), 4 deletions(-)
 create mode 100644 src/lib/dhcp/tests/option6_int_unittest.cc

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/option6_int.h b/src/lib/dhcp/option6_int.h
index 1ecf3dc..e0df4c5 100644
--- a/src/lib/dhcp/option6_int.h
+++ b/src/lib/dhcp/option6_int.h
@@ -92,6 +92,7 @@ public:
         default:
             isc_throw(dhcp::InvalidDataType, "non-numeric type");
         }
+        LibDHCP::packOptions6(buf, options_);
     }
 
     /// @brief Parses received buffer
@@ -110,20 +111,26 @@ public:
             value_ = *begin;
             break;
         case 2:
-            value_ = isc::util::readUint16( &(*begin) );
+            value_ = isc::util::readUint16(&(*begin));
             break;
         case 4:
-            value_ = isc::util::readUint32( &(*begin) );
+            value_ = isc::util::readUint32(&(*begin));
             break;
         default:
             isc_throw(dhcp::InvalidDataType, "non-numeric type");
         }
-
+        begin += OptionDataTypes<T>::len;
         LibDHCP::unpackOptions6(OptionBuffer(begin, end), options_);
     }
 
+    /// @brief Set option value.
+    ///
+    /// @param value new option value.
     void setValue(T value) { value_ = value; }
 
+    /// @brief Return option value.
+    ///
+    /// @return option value.
     T getValue() const { return value_; }
 
     /// @brief returns complete length of option
@@ -144,7 +151,7 @@ public:
 
 private:
 
-    T value_; ///< Value cabveyed by the option.
+    T value_;  ///< Value cabveyed by the option.
 };
 
 } // isc::dhcp namespace
diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am
index 308d3eb..e676834 100644
--- a/src/lib/dhcp/tests/Makefile.am
+++ b/src/lib/dhcp/tests/Makefile.am
@@ -32,6 +32,7 @@ libdhcp___unittests_SOURCES += option6_iaaddr_unittest.cc
 libdhcp___unittests_SOURCES += option6_ia_unittest.cc
 libdhcp___unittests_SOURCES += option6_addrlst_unittest.cc
 libdhcp___unittests_SOURCES += option4_addrlst_unittest.cc
+libdhcp___unittests_SOURCES += option6_int_unittest.cc
 libdhcp___unittests_SOURCES += option_unittest.cc
 libdhcp___unittests_SOURCES += option_definition_unittest.cc
 libdhcp___unittests_SOURCES += pkt6_unittest.cc
diff --git a/src/lib/dhcp/tests/option6_int_unittest.cc b/src/lib/dhcp/tests/option6_int_unittest.cc
new file mode 100644
index 0000000..fad615d
--- /dev/null
+++ b/src/lib/dhcp/tests/option6_int_unittest.cc
@@ -0,0 +1,329 @@
+// 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 <config.h>
+#include <dhcp/dhcp6.h>
+#include <dhcp/option.h>
+#include <dhcp/option6_int.h>
+#include <dhcp/option6_iaaddr.h>
+#include <util/buffer.h>
+
+#include <iostream>
+#include <sstream>
+#include <arpa/inet.h>
+#include <boost/pointer_cast.hpp>
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::dhcp;
+using namespace isc::asiolink;
+using namespace isc::util;
+
+namespace {
+
+/// @brief Option6Int test class.
+class Option6IntTest : public ::testing::Test {
+public:
+    /// @brief Constructor.
+    ///
+    /// Initializes the option buffer with some data.
+    Option6IntTest(): buf_(255), out_buf_(255) {
+        for (int i = 0; i < 255; i++) {
+            buf_[i] = 255 - i;
+        }
+    }
+
+    OptionBuffer buf_;     ///< Option buffer
+    OutputBuffer out_buf_; ///< Output buffer
+};
+
+/// @todo: below, there is a bunch of tests for options that
+/// convey unsigned value. We should maybe extend these tests for
+/// signed types too.
+
+TEST_F(Option6IntTest, useInvalidType) {
+    EXPECT_THROW(
+        boost::scoped_ptr<Option6Int<bool> >(new Option6Int<bool>(D6O_ELAPSED_TIME, 10)),
+        InvalidDataType
+    );
+
+    EXPECT_THROW(
+        boost::scoped_ptr<Option6Int<int64_t> >(new Option6Int<int64_t>(D6O_ELAPSED_TIME, 10)),
+        InvalidDataType
+    );
+
+}
+
+TEST_F(Option6IntTest, basicUint8) {
+    // Create option that conveys single uint8_t value.
+    boost::shared_ptr<Option6Int<uint8_t> > opt;
+    // Initialize buffer with this value.
+    buf_[0] = 0xa1;
+    // Constructor may throw in case provided buffer is too short.
+    ASSERT_NO_THROW(
+        opt = boost::shared_ptr<Option6Int<uint8_t> >(new Option6Int<uint8_t>(D6O_PREFERENCE,
+                                                                              buf_.begin(),
+                                                                              buf_.end()))
+    );
+
+    EXPECT_EQ(Option::V6, opt->getUniverse());
+    EXPECT_EQ(D6O_PREFERENCE, opt->getType());
+    // Option should return the same value that we initialized the first
+    // byte of the buffer with.
+    EXPECT_EQ(buf_[0], opt->getValue());
+
+    // test for pack()
+    opt->pack(out_buf_);
+
+    // Data length is 1 byte.
+    EXPECT_EQ(1, opt->len() - opt->getHeaderLen());
+    EXPECT_EQ(D6O_PREFERENCE, opt->getType());
+    // The total length is 1 byte for data and 4 bytes for header.
+    EXPECT_EQ(5, out_buf_.getLength());
+
+    // Check if pack worked properly:
+    InputBuffer out(out_buf_.getData(), out_buf_.getLength());
+    // if option type is correct
+    EXPECT_EQ(D6O_PREFERENCE, out.readUint16());
+    // if option length is correct
+    EXPECT_EQ(1, out.readUint16());
+    // if data is correct
+    EXPECT_EQ(0xa1, out.readUint8() );
+}
+
+TEST_F(Option6IntTest, basicUint16) {
+    // Create option that conveys single uint16_t value.
+    boost::shared_ptr<Option6Int<uint16_t> > opt;
+    // Initialize buffer with uint16_t value.
+    buf_[0] = 0xa1;
+    buf_[1] = 0xa2;
+    // Constructor may throw in case provided buffer is too short.
+    ASSERT_NO_THROW(
+        opt = boost::shared_ptr<Option6Int<uint16_t> >(new Option6Int<uint16_t>(D6O_ELAPSED_TIME,
+                                                                                buf_.begin(),
+                                                                                buf_.end()))
+    );
+
+    EXPECT_EQ(Option::V6, opt->getUniverse());
+    EXPECT_EQ(D6O_ELAPSED_TIME, opt->getType());
+    // Option should return the value equal to the contents of first
+    // and second byte of the buffer.
+    EXPECT_EQ(0xa1a2, opt->getValue());
+
+    // Test for pack()
+    opt->pack(out_buf_);
+
+    // Data length is 2 bytes.
+    EXPECT_EQ(2, opt->len() - opt->getHeaderLen());
+    EXPECT_EQ(D6O_ELAPSED_TIME, opt->getType());
+    // The total length is 2 byte for data and 4 bytes for header.
+    EXPECT_EQ(6, out_buf_.getLength());
+
+    // Check if pack worked properly:
+    InputBuffer out(out_buf_.getData(), out_buf_.getLength());
+    // if option type is correct
+    EXPECT_EQ(D6O_ELAPSED_TIME, out.readUint16());
+    // if option length is correct
+    EXPECT_EQ(2, out.readUint16());
+    // if data is correct
+    EXPECT_EQ(0xa1a2, out.readUint16() );
+}
+
+TEST_F(Option6IntTest, basicUint32) {
+    // Create option that conveys single uint32_t value.
+    boost::shared_ptr<Option6Int<uint32_t> > opt;
+    // Initialize buffer with uint32_t value.
+    buf_[0] = 0xa1;
+    buf_[1] = 0xa2;
+    buf_[2] = 0xa3;
+    buf_[3] = 0xa4;
+    // Constructor may throw in case provided buffer is too short.
+    ASSERT_NO_THROW(
+        opt = boost::shared_ptr<Option6Int<uint32_t> >(new Option6Int<uint32_t>(D6O_CLT_TIME,
+                                                                                buf_.begin(),
+                                                                                buf_.end()))
+    );
+
+    EXPECT_EQ(Option::V6, opt->getUniverse());
+    EXPECT_EQ(D6O_CLT_TIME, opt->getType());
+    // Option should return the value equal to the value made of
+    // first 4 bytes of the buffer.
+    EXPECT_EQ(0xa1a2a3a4, opt->getValue());
+
+    // Test for pack()
+    opt->pack(out_buf_);
+
+    // Data length is 4 bytes.
+    EXPECT_EQ(4, opt->len() - opt->getHeaderLen());
+    EXPECT_EQ(D6O_CLT_TIME, opt->getType());
+    // The total length is 4 bytes for data and 4 bytes for header.
+    EXPECT_EQ(8, out_buf_.getLength());
+
+    // Check if pack worked properly:
+    InputBuffer out(out_buf_.getData(), out_buf_.getLength());
+    // if option type is correct
+    EXPECT_EQ(D6O_CLT_TIME, out.readUint16());
+    // if option length is correct
+    EXPECT_EQ(4, out.readUint16());
+    // if data is correct
+    EXPECT_EQ(0xa1a2a3a4, out.readUint32());
+}
+
+
+TEST_F(Option6IntTest, simpleUint8) {
+    boost::shared_ptr<Option6Int<uint8_t> > opt(new Option6Int<uint8_t>(D6O_PREFERENCE, 123));
+    // Check if constructor intitialized the option value correctly.
+    EXPECT_EQ(123, opt->getValue());
+    // Override the value.
+    opt->setValue(111);
+
+    EXPECT_EQ(Option::V6, opt->getUniverse());
+    EXPECT_EQ(D6O_PREFERENCE, opt->getType());
+    // Check if the value has been overriden.
+    EXPECT_EQ(111, opt->getValue());
+}
+
+TEST_F(Option6IntTest, simpleUint16) {
+    boost::shared_ptr<Option6Int<uint16_t> > opt(new Option6Int<uint16_t>(D6O_ELAPSED_TIME, 123));
+    // Check if constructor intitialized the option value correctly.
+    EXPECT_EQ(123, opt->getValue());
+    // Override the value.
+    opt->setValue(0x0102);
+
+    EXPECT_EQ(Option::V6, opt->getUniverse());
+    EXPECT_EQ(D6O_ELAPSED_TIME, opt->getType());
+    // Check if the value has been overriden.
+    EXPECT_EQ(0x0102, opt->getValue());
+}
+
+TEST_F(Option6IntTest, simpleUint32) {
+    boost::shared_ptr<Option6Int<uint32_t> > opt(new Option6Int<uint32_t>(D6O_CLT_TIME, 123));
+    // Check if constructor intitialized the option value correctly.
+    EXPECT_EQ(123, opt->getValue());
+    // Override the value.
+    opt->setValue(0x01020304);
+
+    EXPECT_EQ(Option::V6, opt->getUniverse());
+    EXPECT_EQ(D6O_CLT_TIME, opt->getType());
+    // Check if the value has been overriden.
+    EXPECT_EQ(0x01020304, opt->getValue());
+}
+
+TEST_F(Option6IntTest, packSuboptions) {
+    uint16_t opt_code = 80;
+
+    boost::shared_ptr<Option6Int<uint32_t> > opt(new Option6Int<uint32_t>(opt_code, 0x01020304));
+    OptionPtr sub1(new Option(Option::V6, 0xcafe));
+
+    boost::shared_ptr<Option6IAAddr> addr1(
+        new Option6IAAddr(D6O_IAADDR, IOAddress("2001:db8:1234:5678::abcd"), 0x5000, 0x7000));
+
+    opt->addOption(sub1);
+    opt->addOption(addr1);
+
+    ASSERT_EQ(28, addr1->len());
+    ASSERT_EQ(4, sub1->len());
+    ASSERT_EQ(40, opt->len());
+
+    uint8_t expected[] = {
+        opt_code / 256, opt_code % 256, // type
+        0, 36, // length
+        0x01, 0x02, 0x03, 0x04, // uint32_t value
+
+        // iaaddr suboption
+        D6O_IAADDR / 256, D6O_IAADDR % 256, // type
+        0, 24, // len
+        0x20, 0x01, 0xd, 0xb8, 0x12,0x34, 0x56, 0x78,
+        0, 0, 0, 0, 0, 0, 0xab, 0xcd, // IP address
+        0, 0, 0x50, 0, // preferred-lifetime
+        0, 0, 0x70, 0, // valid-lifetime
+
+        // suboption
+        0xca, 0xfe, // type
+        0, 0 // len
+    };
+
+    // Create on-wire format of option and suboptions.
+    opt->pack(out_buf_);
+    // Compare the on-wire data with the reference buffer.
+    ASSERT_EQ(40, out_buf_.getLength());
+    EXPECT_EQ(0, memcmp(out_buf_.getData(), expected, 40));
+}
+
+
+TEST_F(Option6IntTest, unpackSuboptions) {
+    // Create some dummy option.
+    const uint16_t opt_code = 80;
+    // Prepare reference data.
+    uint8_t expected[] = {
+        opt_code / 256, opt_code % 256, // type
+        0, 34, // length
+        0x01, 0x02, // uint16_t value
+
+        // iaaddr suboption
+        D6O_IAADDR / 256, D6O_IAADDR % 256, // type
+        0, 24, // len
+        0x20, 0x01, 0xd, 0xb8, 0x12,0x34, 0x56, 0x78,
+        0, 0, 0, 0, 0, 0, 0xab, 0xcd, // IP address
+        0, 0, 0x50, 0, // preferred-lifetime
+        0, 0, 0x70, 0, // valid-lifetime
+
+        // suboption
+        0xca, 0xfe, // type
+        0, 0 // len
+    };
+    ASSERT_EQ(38, sizeof(expected));
+
+    memcpy(&buf_[0], expected, sizeof(expected));
+
+    boost::shared_ptr<Option6Int<uint16_t> > opt;
+    EXPECT_NO_THROW(
+        opt = boost::shared_ptr<
+            Option6Int<uint16_t> >(new Option6Int<uint16_t>(opt_code, buf_.begin() + 4,
+                                                            buf_.begin() + sizeof(expected)));
+    );
+    ASSERT_TRUE(opt);
+
+    EXPECT_EQ(opt_code, opt->getType());
+    EXPECT_EQ(0x0102, opt->getValue());
+
+    // Checks for address option
+    OptionPtr subopt = opt->getOption(D6O_IAADDR);
+    ASSERT_TRUE(subopt);
+    boost::shared_ptr<Option6IAAddr> addr(boost::dynamic_pointer_cast<Option6IAAddr>(subopt));
+    ASSERT_TRUE(addr);
+
+    EXPECT_EQ(D6O_IAADDR, addr->getType());
+    EXPECT_EQ(28, addr->len());
+    EXPECT_EQ(0x5000, addr->getPreferred());
+    EXPECT_EQ(0x7000, addr->getValid());
+    EXPECT_EQ("2001:db8:1234:5678::abcd", addr->getAddress().toText());
+
+    // Checks for dummy option
+    subopt = opt->getOption(0xcafe);
+    ASSERT_TRUE(subopt); // should be non-NULL
+
+    EXPECT_EQ(0xcafe, subopt->getType());
+    EXPECT_EQ(4, subopt->len());
+    // There should be no data at all
+    EXPECT_EQ(0, subopt->getData().size());
+
+    // Try to get non-existent option.
+    subopt = opt->getOption(1);
+    // Expecting NULL which means that option does not exist.
+    ASSERT_FALSE(subopt);
+} 
+
+} // anonymous namespace



More information about the bind10-changes mailing list