Browse Source

[2995] Remaining test for subnet6_select implemented.

Tomek Mrugalski 12 years ago
parent
commit
ef242ca52d
1 changed files with 90 additions and 12 deletions
  1. 90 12
      src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

+ 90 - 12
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -2050,16 +2050,28 @@ public:
         callout_handle.getArgument("subnet6", callback_subnet6_);
         callout_handle.getArgument("subnet6collection", callback_subnet6collection_);
 
-        if (callback_subnet6_) {
-            cout << "#### subnet6_select: subnet6=" << callback_subnet6_->toText()
-                 << ", subnet6collection.size=" << callback_subnet6collection_.size()
-                 << endl;
-        } else {
-            cout << "#### subnet6 empty!" << endl;
-        }
+        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);
+        }
 
-        callback_argument_names_ = callout_handle.getArgumentNames();
         return (0);
     }
 
@@ -2345,10 +2357,9 @@ TEST_F(HooksDhcpv6SrvTest, skip_pkt6_send) {
     ASSERT_EQ(0, srv_->fake_sent_.size());
 }
 
-
-// This test checks if Option Request Option (ORO) is parsed correctly
-// and the requested options are actually assigned.
-TEST_F(HooksDhcpv6SrvTest, subnet_select) {
+// 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",
@@ -2412,7 +2423,74 @@ TEST_F(HooksDhcpv6SrvTest, subnet_select) {
     // 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()));
 }