From: Tomek Mrugalski Date: Wed, 29 Mar 2017 15:55:53 +0000 (-0500) Subject: [5132] host6_identifier unit-test implemented X-Git-Tag: trac5196_base~12^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98831558dafa6b457c7221686d4e2c2211633bb9;p=thirdparty%2Fkea.git [5132] host6_identifier unit-test implemented --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 50b2ca7c55..81a3e10a75 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -289,6 +289,7 @@ void Dhcpv4Exchange::setHostIdentifiers() { const ConstCfgHostOperationsPtr cfg = CfgMgr::instance().getCurrentCfg()->getCfgHostOperations4(); + // Collect host identifiers. The identifiers are stored in order of preference. // The server will use them in that order to search for host reservations. BOOST_FOREACH(const Host::IdentifierType& id_type, @@ -341,7 +342,11 @@ Dhcpv4Exchange::setHostIdentifiers() { } break; case Host::IDENT_FLEX: - if (HooksManager::calloutsPresent(Hooks.hook_index_host4_identifier_)) { + { + if (!HooksManager::calloutsPresent(Hooks.hook_index_host4_identifier_)) { + break; + } + CalloutHandlePtr callout_handle = getCalloutHandle(context_->query_); Host::IdentifierType type = Host::IDENT_FLEX; @@ -355,25 +360,23 @@ Dhcpv4Exchange::setHostIdentifiers() { callout_handle->setArgument("id_type", type); callout_handle->setArgument("id_value", id); - // Call callouts - HooksManager::callCallouts(Hooks.hook_index_host4_identifier_, - *callout_handle); + // Call callouts + HooksManager::callCallouts(Hooks.hook_index_host4_identifier_, + *callout_handle); - callout_handle->getArgument("id_type", type); - callout_handle->getArgument("id_value", id); + callout_handle->getArgument("id_type", type); + callout_handle->getArgument("id_value", id); - if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) && - !id.empty()) { + if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) && + !id.empty()) { - LOG_DEBUG(packet4_logger, DBGLVL_TRACE_BASIC, DHCP4_FLEX_ID) - .arg(Host::getIdentifierAsText(type, &id[0], id.size())); + LOG_DEBUG(packet4_logger, DBGLVL_TRACE_BASIC, DHCP4_FLEX_ID) + .arg(Host::getIdentifierAsText(type, &id[0], id.size())); - context_->addHostIdentifier(type, id); - } + context_->addHostIdentifier(type, id); } break; - - + } default: ; } diff --git a/src/bin/dhcp4/tests/hooks_unittest.cc b/src/bin/dhcp4/tests/hooks_unittest.cc index 656d551b06..d84e291ff1 100644 --- a/src/bin/dhcp4/tests/hooks_unittest.cc +++ b/src/bin/dhcp4/tests/hooks_unittest.cc @@ -547,7 +547,7 @@ public: return (lease4_decline_callout(callout_handle)); } - /// @brief Test host4_identifier by setting identifier to "foo" + /// @brief Test host4_identifier callout by setting identifier to "foo" /// /// @param callout_handle handle passed by the hooks framework /// @return always 0 diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc index 8a550c8de1..82753f4e28 100644 --- a/src/bin/dhcp6/tests/hooks_unittest.cc +++ b/src/bin/dhcp6/tests/hooks_unittest.cc @@ -62,6 +62,8 @@ TEST_F(Dhcpv6SrvTest, Hooks) { int hook_index_pkt6_received = -1; int hook_index_select_subnet = -1; int hook_index_pkt6_send = -1; + int hook_index_host6_identifier= -1; + // check if appropriate indexes are set EXPECT_NO_THROW(hook_index_buffer6_receive = ServerHooks::getServerHooks() @@ -82,6 +84,9 @@ TEST_F(Dhcpv6SrvTest, Hooks) { .getIndex("subnet6_select")); EXPECT_NO_THROW(hook_index_pkt6_send = ServerHooks::getServerHooks() .getIndex("pkt6_send")); + EXPECT_NO_THROW(hook_index_host6_identifier = ServerHooks::getServerHooks() + .getIndex("host6_identifier")); + EXPECT_TRUE(hook_index_pkt6_received > 0); EXPECT_TRUE(hook_index_select_subnet > 0); @@ -92,6 +97,7 @@ TEST_F(Dhcpv6SrvTest, Hooks) { EXPECT_TRUE(hook_index_lease6_release > 0); EXPECT_TRUE(hook_index_lease6_rebind > 0); EXPECT_TRUE(hook_index_lease6_decline > 0); + EXPECT_TRUE(hook_index_host6_identifier > 0); } /// @brief a class dedicated to Hooks testing in DHCPv6 server @@ -644,6 +650,25 @@ public: return (lease6_decline_callout(callout_handle)); } + /// @brief Test host6_identifier by setting identifier to "foo" + /// + /// @param callout_handle handle passed by the hooks framework + /// @return always 0 + static int + host6_identifier_foo_callout(CalloutHandle& handle) { + callback_name_ = string("host4_identifier"); + + std::vector id(3); + id[0] = 0x66; // f + id[1] = 0x6f; // o + id[2] = 0x6f; // o + handle.setArgument("id_value", id); + handle.setArgument("id_type", Host::IDENT_FLEX); + + return (0); + } + + /// Resets buffers used to store data received by callouts void resetCalloutBuffers() { callback_name_ = string(""); @@ -2228,6 +2253,80 @@ TEST_F(HooksDhcpv6SrvTest, lease6DeclineDrop) { EXPECT_EQ(Lease::STATE_DEFAULT, from_mgr->state_); } + +// Checks if callout installed on host6_identifier can generate an +// identifier and whether that identifier is actually used. +TEST_F(HooksDhcpv6SrvTest, host6Identifier) { + + // Configure 2 subnets, both directly reachable over local interface + // (let's not complicate the matter with relays) + string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8::/64\" } ]," + " \"subnet\": \"2001:db8::/48\", " + " \"interface\": \"" + valid_iface_ + "\", " + " \"reservations\": [" + " {" + " \"flex-id\": \"'foo'\"," + " \"ip-addresses\": \"2001:db8::f00\"" + " }" + " ]" + " } ]," + "\"valid-lifetime\": 4000 }"; + + ConstElementPtr json; + EXPECT_NO_THROW(json = parseDHCP6(config)); + ConstElementPtr status; + + // Configure the server and make sure the config is accepted + EXPECT_NO_THROW(status = configureDhcp6Server(*srv_, json)); + ASSERT_TRUE(status); + comment_ = isc::config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + CfgMgr::instance().commit(); + + // Install host6_identifier_foo_callout + EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout( + "host6_identifier", host6_identifier_foo_callout)); + + // 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(D6O_IA_NA, 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("host6_identifier", callback_name_); + + // Check that pkt6 argument passing was successful and returned proper value + EXPECT_TRUE(callback_qry_pkt6_.get() == sol.get()); + + // Now check if we got the reserved address + OptionPtr tmp = adv->getOption(D6O_IA_NA); + ASSERT_TRUE(tmp); + + // Check that IA_NA was returned and that there's an address included + boost::shared_ptr addr_opt = checkIA_NA(adv, 234, 1000, 2000); + + ASSERT_TRUE(addr_opt); + ASSERT_EQ("2001:db8::f00", addr_opt->getAddress().toText()); +} + + // Verifies that libraries are unloaded by server destruction // The callout libraries write their library index number to a marker // file upon load and unload, making it simple to test whether or not