BIND 10 trac2995, updated. ef242ca52d93c62bfc2ef42260ebf5069d31cde5 [2995] Remaining test for subnet6_select implemented.

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Jun 26 15:55:25 UTC 2013


The branch, trac2995 has been updated
       via  ef242ca52d93c62bfc2ef42260ebf5069d31cde5 (commit)
       via  5e4b2f06b8dfe4cf1eb7f26836942d10e3c719e4 (commit)
      from  cdb34f7debacbbbc4adec956f682c07e0a77d706 (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 ef242ca52d93c62bfc2ef42260ebf5069d31cde5
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Wed Jun 26 17:55:13 2013 +0200

    [2995] Remaining test for subnet6_select implemented.

commit 5e4b2f06b8dfe4cf1eb7f26836942d10e3c719e4
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Wed Jun 26 17:36:48 2013 +0200

    [2995] First unit-test for subnet6_select hook implemented.

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

Summary of changes:
 src/bin/dhcp6/tests/dhcp6_srv_unittest.cc |  195 +++++++++++++++++++++++++++++
 1 file changed, 195 insertions(+)

-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index e43479c..277b749 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -24,6 +24,7 @@
 #include <dhcp/option6_ia.h>
 #include <dhcp/option6_iaaddr.h>
 #include <dhcp/option_int_array.h>
+#include <dhcp/iface_mgr.h>
 #include <dhcp6/config_parser.h>
 #include <dhcp6/dhcp6_srv.h>
 #include <dhcp/dhcp6.h>
@@ -148,6 +149,16 @@ public:
     NakedDhcpv6SrvTest() : rcode_(-1) {
         // it's ok if that fails. There should not be such a file anyway
         unlink(DUID_FILE);
+
+        const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
+
+        // There must be some interface detected
+        if (ifaces.empty()) {
+            // We can't use ASSERT in constructor
+            ADD_FAILURE() << "No interfaces detected.";
+        }
+
+        valid_iface_ = ifaces.begin()->getName();
     }
 
     // Generate IA_NA option with specified parameters
@@ -296,6 +307,9 @@ public:
 
     int rcode_;
     ConstElementPtr comment_;
+
+    // Name of a valid network interface
+    string valid_iface_;
 };
 
 // Provides suport for tests against a preconfigured subnet6
@@ -2027,9 +2041,45 @@ public:
         return pkt6_send_callout(callout_handle);
     }
 
+    // Callback that stores received callout name and subnet6 values
+    static int
+    subnet6_select_callout(CalloutHandle& callout_handle) {
+        callback_name_ = string("subnet6_select");
+
+        callout_handle.getArgument("pkt6", callback_pkt6_);
+        callout_handle.getArgument("subnet6", callback_subnet6_);
+        callout_handle.getArgument("subnet6collection", callback_subnet6collection_);
+
+        callback_argument_names_ = callout_handle.getArgumentNames();
+        return (0);
+    }
+
+    // Callback that picks the other subnet if possible.
+    static int
+    subnet6_select_different_subnet_callout(CalloutHandle& callout_handle) {
+
+        // Call the basic calllout to record all passed values
+        subnet6_select_callout(callout_handle);
+
+        Subnet6Collection subnets;
+        Subnet6Ptr subnet;
+        callout_handle.getArgument("subnet6", subnet);
+        callout_handle.getArgument("subnet6collection", subnets);
+
+        // Let's change to a different subnet
+        if (subnets.size() > 1) {
+            subnet = subnets[1]; // Let's pick the other subnet
+            callout_handle.setArgument("subnet6", subnet);
+        }
+
+        return (0);
+    }
+
     void resetCalloutBuffers() {
         callback_name_ = string("");
         callback_pkt6_.reset();
+        callback_subnet6_.reset();
+        callback_subnet6collection_.clear();
         callback_argument_names_.clear();
     }
 
@@ -2040,6 +2090,10 @@ public:
 
     static Pkt6Ptr callback_pkt6_; ///< Pkt6 structure returned in the callout
 
+    static Subnet6Ptr callback_subnet6_;
+
+    static Subnet6Collection callback_subnet6collection_;
+
     static vector<string> callback_argument_names_;
 };
 
@@ -2047,6 +2101,10 @@ string HooksDhcpv6SrvTest::callback_name_;
 
 Pkt6Ptr HooksDhcpv6SrvTest::callback_pkt6_;
 
+Subnet6Ptr HooksDhcpv6SrvTest::callback_subnet6_;
+
+Subnet6Collection HooksDhcpv6SrvTest::callback_subnet6collection_;
+
 vector<string> HooksDhcpv6SrvTest::callback_argument_names_;
 
 
@@ -2299,6 +2357,143 @@ TEST_F(HooksDhcpv6SrvTest, skip_pkt6_send) {
     ASSERT_EQ(0, srv_->fake_sent_.size());
 }
 
+// This test checks if subnet6_select callout is triggered and reports
+// valid parameters
+TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
+
+    // Install pkt6_receive_callout
+    EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("subnet6_select",
+                    subnet6_select_callout));
+
+    // Configure 2 subnets, both directly reachable over local interface
+    // (let's not complicate the matter with relays)
+    string config = "{ \"interface\": [ \"all\" ],"
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"pool\": [ \"2001:db8:1::/64\" ],"
+        "    \"subnet\": \"2001:db8:1::/48\", "
+        "    \"interface\": \"" + valid_iface_ + "\" "
+        " }, {"
+        "    \"pool\": [ \"2001:db8:2::/64\" ],"
+        "    \"subnet\": \"2001:db8:2::/48\" "
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr status;
+
+    // Configure the server and make sure the config is accepted
+    EXPECT_NO_THROW(status = configureDhcp6Server(*srv_, json));
+    ASSERT_TRUE(status);
+    comment_ = parseAnswer(rcode_, status);
+    ASSERT_EQ(0, rcode_);
+
+    // Prepare solicit packet. Server should select first subnet for it
+    Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+    sol->setRemoteAddr(IOAddress("fe80::abcd"));
+    sol->setIface(valid_iface_);
+    sol->addOption(generateIA(234, 1500, 3000));
+    OptionPtr clientid = generateClientId();
+    sol->addOption(clientid);
+
+    // Pass it to the server and get an advertise
+    Pkt6Ptr adv = srv_->processSolicit(sol);
+
+    // check if we get response at all
+    ASSERT_TRUE(adv);
+
+    // Check that the callback called is indeed the one we installed
+    EXPECT_EQ("subnet6_select", callback_name_);
+
+    // Check that pkt6 argument passing was successful and returned proper value
+    EXPECT_TRUE(callback_pkt6_.get() == sol.get());
+
+    Subnet6Collection exp_subnets = CfgMgr::instance().getSubnets6();
+
+    // The server is supposed to pick the first subnet, because of matching
+    // interface. Check that the value is reported properly.
+    ASSERT_TRUE(callback_subnet6_);
+    EXPECT_EQ(callback_subnet6_.get(), exp_subnets.front().get());
+
+    // Server is supposed to report two subnets
+    ASSERT_EQ(exp_subnets.size(), callback_subnet6collection_.size());
+
+    // Compare that the available subnets are reported as expected
+    EXPECT_TRUE(exp_subnets[0].get() == callback_subnet6collection_[0].get());
+    EXPECT_TRUE(exp_subnets[1].get() == callback_subnet6collection_[1].get());
+}
+
+// This test checks if callout installed on subnet6_select hook point can pick
+// a different subnet.
+TEST_F(HooksDhcpv6SrvTest, subnet_select_change) {
+
+    // Install pkt6_receive_callout
+    EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("subnet6_select",
+                    subnet6_select_different_subnet_callout));
+
+    // Configure 2 subnets, both directly reachable over local interface
+    // (let's not complicate the matter with relays)
+    string config = "{ \"interface\": [ \"all\" ],"
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"pool\": [ \"2001:db8:1::/64\" ],"
+        "    \"subnet\": \"2001:db8:1::/48\", "
+        "    \"interface\": \"" + valid_iface_ + "\" "
+        " }, {"
+        "    \"pool\": [ \"2001:db8:2::/64\" ],"
+        "    \"subnet\": \"2001:db8:2::/48\" "
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ElementPtr json = Element::fromJSON(config);
+    ConstElementPtr status;
+
+    // Configure the server and make sure the config is accepted
+    EXPECT_NO_THROW(status = configureDhcp6Server(*srv_, json));
+    ASSERT_TRUE(status);
+    comment_ = parseAnswer(rcode_, status);
+    ASSERT_EQ(0, rcode_);
+
+    // Prepare solicit packet. Server should select first subnet for it
+    Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+    sol->setRemoteAddr(IOAddress("fe80::abcd"));
+    sol->setIface(valid_iface_);
+    sol->addOption(generateIA(234, 1500, 3000));
+    OptionPtr clientid = generateClientId();
+    sol->addOption(clientid);
+
+    // Pass it to the server and get an advertise
+    Pkt6Ptr adv = srv_->processSolicit(sol);
+
+    // check if we get response at all
+    ASSERT_TRUE(adv);
+
+    // The response should have an address from second pool, so let's check it
+    OptionPtr tmp = adv->getOption(D6O_IA_NA);
+    ASSERT_TRUE(tmp);
+    boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(tmp);
+    ASSERT_TRUE(ia);
+    tmp = ia->getOption(D6O_IAADDR);
+    ASSERT_TRUE(tmp);
+    boost::shared_ptr<Option6IAAddr> addr_opt =
+        boost::dynamic_pointer_cast<Option6IAAddr>(tmp);
+    ASSERT_TRUE(addr_opt);
+
+    // Get all subnets and use second subnet for verification
+    Subnet6Collection subnets = CfgMgr::instance().getSubnets6();
+    ASSERT_EQ(2, subnets.size());
+
+    // Advertised address must belong to the second pool (in subnet's range,
+    // in dynamic pool)
+    EXPECT_TRUE(subnets[1]->inRange(addr_opt->getAddress()));
+    EXPECT_TRUE(subnets[1]->inPool(addr_opt->getAddress()));
+}
+
+
 /// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
 /// to call processX() methods.
 



More information about the bind10-changes mailing list