mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[master] Merged trac3978 (new leases-reclaim command)
This commit is contained in:
@@ -71,6 +71,32 @@ ControlledDhcpv4Srv::commandConfigReloadHandler(const string&,
|
||||
return (processConfig(args));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
ControlledDhcpv4Srv::commandLeasesReclaimHandler(const string& command,
|
||||
ConstElementPtr args) {
|
||||
int status_code = 1;
|
||||
string message;
|
||||
|
||||
// args must be { "remove": <bool> }
|
||||
if (!args) {
|
||||
message = "Missing mandatory 'remove' parameter.";
|
||||
} else {
|
||||
ConstElementPtr remove_name = args->get("remove");
|
||||
if (!remove_name) {
|
||||
message = "Missing mandatory 'remove' parameter.";
|
||||
} else if (remove_name->getType() != Element::boolean) {
|
||||
message = "'remove' parameter expected to be a boolean.";
|
||||
} else {
|
||||
bool remove_lease = remove_name->boolValue();
|
||||
server_->alloc_engine_->reclaimExpiredLeases4(0, 0, remove_lease);
|
||||
status_code = 0;
|
||||
message = "Reclamation of expired leases is complete.";
|
||||
}
|
||||
}
|
||||
ConstElementPtr answer = isc::config::createAnswer(status_code, message);
|
||||
return (answer);
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
ControlledDhcpv4Srv::processCommand(const string& command,
|
||||
ConstElementPtr args) {
|
||||
@@ -96,6 +122,8 @@ ControlledDhcpv4Srv::processCommand(const string& command,
|
||||
} else if (command == "config-reload") {
|
||||
return (srv->commandConfigReloadHandler(command, args));
|
||||
|
||||
} else if (command == "leases-reclaim") {
|
||||
return (srv->commandLeasesReclaimHandler(command, args));
|
||||
}
|
||||
ConstElementPtr answer = isc::config::createAnswer(1,
|
||||
"Unrecognized command:" + command);
|
||||
@@ -212,6 +240,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
|
||||
/// @todo: register config-reload (see CtrlDhcpv4Srv::commandConfigReloadHandler)
|
||||
/// @todo: register libreload (see CtrlDhcpv4Srv::commandLibReloadHandler)
|
||||
|
||||
CommandMgr::instance().registerCommand("leases-reclaim",
|
||||
boost::bind(&ControlledDhcpv4Srv::commandLeasesReclaimHandler, this, _1, _2));
|
||||
|
||||
// Register statistic related commands
|
||||
CommandMgr::instance().registerCommand("statistic-get",
|
||||
boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
|
||||
@@ -251,6 +282,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
|
||||
|
||||
// Deregister any registered commands
|
||||
CommandMgr::instance().deregisterCommand("shutdown");
|
||||
CommandMgr::instance().deregisterCommand("leases-reclaim");
|
||||
CommandMgr::instance().deregisterCommand("statistic-get");
|
||||
CommandMgr::instance().deregisterCommand("statistic-reset");
|
||||
CommandMgr::instance().deregisterCommand("statistic-remove");
|
||||
|
@@ -70,6 +70,7 @@ public:
|
||||
/// - shutdown
|
||||
/// - libreload
|
||||
/// - config-reload
|
||||
/// - leases-reclaim
|
||||
///
|
||||
/// @note It never throws.
|
||||
///
|
||||
@@ -151,6 +152,23 @@ private:
|
||||
isc::data::ConstElementPtr args);
|
||||
|
||||
|
||||
/// @brief Handler for processing 'leases-reclaim' command
|
||||
///
|
||||
/// This handler processes leases-reclaim command, which triggers
|
||||
/// the leases reclamation immediately.
|
||||
/// No limit for processing time or number of processed leases applies.
|
||||
///
|
||||
/// @param command (parameter ignored)
|
||||
/// @param args arguments map { "remove": <bool> }
|
||||
/// if true a lease is removed when it is reclaimed,
|
||||
/// if false its state is changed to "expired-reclaimed".
|
||||
///
|
||||
/// @return status of the command (should be success unless args
|
||||
/// was not a Bool Element).
|
||||
isc::data::ConstElementPtr
|
||||
commandLeasesReclaimHandler(const std::string& command,
|
||||
isc::data::ConstElementPtr args);
|
||||
|
||||
/// @brief Reclaims expired IPv4 leases and reschedules timer.
|
||||
///
|
||||
/// This is a wrapper method for @c AllocEngine::reclaimExpiredLeases4.
|
||||
|
@@ -69,11 +69,11 @@ void configure(const std::string& file_name) {
|
||||
// works only for map.
|
||||
if (json->getType() != isc::data::Element::map) {
|
||||
isc_throw(isc::BadValue, "Configuration file is expected to be "
|
||||
"a map, i.e., start with { and end with } and contain "
|
||||
"at least an entry called 'Dhcp4' that itself is a map. "
|
||||
<< file_name
|
||||
"a map, i.e., start with { and end with } and contain "
|
||||
"at least an entry called 'Dhcp4' that itself is a map. "
|
||||
<< file_name
|
||||
<< " is a valid JSON, but its top element is not a map."
|
||||
" Did you forget to add { } around your configuration?");
|
||||
" Did you forget to add { } around your configuration?");
|
||||
}
|
||||
|
||||
// If there's no logging element, we'll just pass NULL pointer,
|
||||
|
@@ -3665,7 +3665,7 @@ TEST_F(Dhcp4ParserTest, declineTimerDefault) {
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
// The value of decline-probation-perion must be equal to the
|
||||
// The value of decline-probation-period must be equal to the
|
||||
// default value.
|
||||
EXPECT_EQ(DEFAULT_DECLINE_PROBATION_PERIOD,
|
||||
CfgMgr::instance().getStagingCfg()->getDeclinePeriod());
|
||||
@@ -3687,7 +3687,7 @@ TEST_F(Dhcp4ParserTest, declineTimer) {
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
// The value of decline-probation-perion must be equal to the
|
||||
// The value of decline-probation-period must be equal to the
|
||||
// value specified.
|
||||
EXPECT_EQ(12345,
|
||||
CfgMgr::instance().getStagingCfg()->getDeclinePeriod());
|
||||
@@ -3738,7 +3738,7 @@ TEST_F(Dhcp4ParserTest, expiredLeasesProcessing) {
|
||||
// Returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
// The value of decline-probation-perion must be equal to the
|
||||
// The value of decline-probation-period must be equal to the
|
||||
// value specified.
|
||||
CfgExpirationPtr cfg = CfgMgr::instance().getStagingCfg()->getCfgExpiration();
|
||||
ASSERT_TRUE(cfg);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2013, 2015 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
|
||||
@@ -19,7 +19,10 @@
|
||||
#include <dhcp/dhcp4.h>
|
||||
#include <dhcp4/ctrl_dhcp4_srv.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/lease.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <hooks/hooks_manager.h>
|
||||
#include <stats/stats_mgr.h>
|
||||
#include <testutils/unix_control_client.h>
|
||||
|
||||
#include "marker_file.h"
|
||||
@@ -43,6 +46,7 @@ using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::dhcp::test;
|
||||
using namespace isc::hooks;
|
||||
using namespace isc::stats;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -80,6 +84,8 @@ public:
|
||||
|
||||
/// @brief Destructor
|
||||
~CtrlChannelDhcpv4SrvTest() {
|
||||
LeaseMgrFactory::destroy();
|
||||
StatsMgr::instance().removeAll();
|
||||
server_.reset();
|
||||
reset();
|
||||
};
|
||||
@@ -94,6 +100,11 @@ public:
|
||||
" \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
" },"
|
||||
" \"expired-leases-processing\": {"
|
||||
" \"reclaim-timer-wait-time\": 60,"
|
||||
" \"hold-reclaimed-time\": 500,"
|
||||
" \"flush-reclaimed-timer-wait-time\": 60"
|
||||
" },"
|
||||
" \"rebind-timer\": 2000, "
|
||||
" \"renew-timer\": 1000, "
|
||||
" \"subnet4\": [ ],"
|
||||
@@ -333,6 +344,103 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelShutdown) {
|
||||
EXPECT_EQ("{ \"result\": 0, \"text\": \"Shutting down.\" }",response);
|
||||
}
|
||||
|
||||
// This test verifies that the DHCP server immediately reclaims expired
|
||||
// leases on leases-reclaim command
|
||||
TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaim) {
|
||||
createUnixChannelServer();
|
||||
|
||||
// Create expired leases. Leases are expired by 40 seconds ago
|
||||
// (valid lifetime = 60, cltt = now - 100).
|
||||
HWAddrPtr hwaddr0(new HWAddr(HWAddr::fromText("00:01:02:03:04:05")));
|
||||
Lease4Ptr lease0(new Lease4(IOAddress("10.0.0.1"), hwaddr0,
|
||||
ClientIdPtr(), 60, 10, 20,
|
||||
time(NULL) - 100, SubnetID(1)));
|
||||
HWAddrPtr hwaddr1(new HWAddr(HWAddr::fromText("01:02:03:04:05:06")));
|
||||
Lease4Ptr lease1(new Lease4(IOAddress("10.0.0.2"), hwaddr1,
|
||||
ClientIdPtr(), 60, 10, 20,
|
||||
time(NULL) - 100, SubnetID(1)));
|
||||
|
||||
// Add leases to the database.
|
||||
LeaseMgr& lease_mgr = LeaseMgrFactory().instance();
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease0));
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease1));
|
||||
|
||||
// Make sure they have been added.
|
||||
ASSERT_TRUE(lease_mgr.getLease4(IOAddress("10.0.0.1")));
|
||||
ASSERT_TRUE(lease_mgr.getLease4(IOAddress("10.0.0.2")));
|
||||
|
||||
// No arguments
|
||||
std::string response;
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\" }", response);
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": "
|
||||
"\"Missing mandatory 'remove' parameter.\" }", response);
|
||||
|
||||
// Bad argument name
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"reclaim\": true } }", response);
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": "
|
||||
"\"Missing mandatory 'remove' parameter.\" }", response);
|
||||
|
||||
// Bad remove argument type
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"remove\": \"bogus\" } }", response);
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": "
|
||||
"\"'remove' parameter expected to be a boolean.\" }", response);
|
||||
|
||||
// Send the command
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"remove\": false } }", response);
|
||||
EXPECT_EQ("{ \"result\": 0, \"text\": "
|
||||
"\"Reclamation of expired leases is complete.\" }", response);
|
||||
|
||||
// Leases should be reclaimed, but not removed
|
||||
ASSERT_NO_THROW(lease0 = lease_mgr.getLease4(IOAddress("10.0.0.1")));
|
||||
ASSERT_NO_THROW(lease1 = lease_mgr.getLease4(IOAddress("10.0.0.2")));
|
||||
ASSERT_TRUE(lease0);
|
||||
ASSERT_TRUE(lease1);
|
||||
EXPECT_TRUE(lease0->stateExpiredReclaimed());
|
||||
EXPECT_TRUE(lease1->stateExpiredReclaimed());
|
||||
}
|
||||
|
||||
// Thist test verifies that the DHCP server immediately removed expired
|
||||
// leases on leases-reclaim command with remove = true
|
||||
TEST_F(CtrlChannelDhcpv4SrvTest, controlLeasesReclaimRemove) {
|
||||
createUnixChannelServer();
|
||||
|
||||
// Create expired leases. Leases are expired by 40 seconds ago
|
||||
// (valid lifetime = 60, cltt = now - 100).
|
||||
HWAddrPtr hwaddr0(new HWAddr(HWAddr::fromText("00:01:02:03:04:05")));
|
||||
Lease4Ptr lease0(new Lease4(IOAddress("10.0.0.1"), hwaddr0,
|
||||
ClientIdPtr(), 60, 10, 20,
|
||||
time(NULL) - 100, SubnetID(1)));
|
||||
HWAddrPtr hwaddr1(new HWAddr(HWAddr::fromText("01:02:03:04:05:06")));
|
||||
Lease4Ptr lease1(new Lease4(IOAddress("10.0.0.2"), hwaddr1,
|
||||
ClientIdPtr(), 60, 10, 20,
|
||||
time(NULL) - 100, SubnetID(1)));
|
||||
|
||||
// Add leases to the database.
|
||||
LeaseMgr& lease_mgr = LeaseMgrFactory().instance();
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease0));
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease1));
|
||||
|
||||
// Make sure they have been added.
|
||||
ASSERT_TRUE(lease_mgr.getLease4(IOAddress("10.0.0.1")));
|
||||
ASSERT_TRUE(lease_mgr.getLease4(IOAddress("10.0.0.2")));
|
||||
|
||||
// Send the command
|
||||
std::string response;
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"remove\": true } }", response);
|
||||
EXPECT_EQ("{ \"result\": 0, \"text\": "
|
||||
"\"Reclamation of expired leases is complete.\" }", response);
|
||||
|
||||
// Leases should have been removed.
|
||||
ASSERT_NO_THROW(lease0 = lease_mgr.getLease4(IOAddress("10.0.0.1")));
|
||||
ASSERT_NO_THROW(lease1 = lease_mgr.getLease4(IOAddress("10.0.0.2")));
|
||||
EXPECT_FALSE(lease0);
|
||||
EXPECT_FALSE(lease1);
|
||||
}
|
||||
|
||||
// Tests that the server properly responds to statistics commands. Note this
|
||||
// is really only intended to verify that the appropriate Statistics handler
|
||||
// is called based on the command. It is not intended to be an exhaustive
|
||||
@@ -379,5 +487,4 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) {
|
||||
response);
|
||||
}
|
||||
|
||||
|
||||
} // End of anonymous namespace
|
||||
|
@@ -69,6 +69,32 @@ ControlledDhcpv6Srv::commandConfigReloadHandler(const string&, ConstElementPtr a
|
||||
return (processConfig(args));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
ControlledDhcpv6Srv::commandLeasesReclaimHandler(const string& command,
|
||||
ConstElementPtr args) {
|
||||
int status_code = 1;
|
||||
string message;
|
||||
|
||||
// args must be { "remove": <bool> }
|
||||
if (!args) {
|
||||
message = "Missing mandatory 'remove' parameter.";
|
||||
} else {
|
||||
ConstElementPtr remove_name = args->get("remove");
|
||||
if (!remove_name) {
|
||||
message = "Missing mandatory 'remove' parameter.";
|
||||
} else if (remove_name->getType() != Element::boolean) {
|
||||
message = "'remove' parameter expected to be a boolean.";
|
||||
} else {
|
||||
bool remove_lease = remove_name->boolValue();
|
||||
server_->alloc_engine_->reclaimExpiredLeases6(0, 0, remove_lease);
|
||||
status_code = 0;
|
||||
message = "Reclamation of expired leases is complete.";
|
||||
}
|
||||
}
|
||||
ConstElementPtr answer = isc::config::createAnswer(status_code, message);
|
||||
return (answer);
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
ControlledDhcpv6Srv::processCommand(const std::string& command,
|
||||
isc::data::ConstElementPtr args) {
|
||||
@@ -93,6 +119,9 @@ ControlledDhcpv6Srv::processCommand(const std::string& command,
|
||||
|
||||
} else if (command == "config-reload") {
|
||||
return (srv->commandConfigReloadHandler(command, args));
|
||||
|
||||
} else if (command == "leases-reclaim") {
|
||||
return (srv->commandLeasesReclaimHandler(command, args));
|
||||
}
|
||||
|
||||
return (isc::config::createAnswer(1, "Unrecognized command:"
|
||||
@@ -208,6 +237,9 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port)
|
||||
/// @todo: register config-reload (see CtrlDhcpv4Srv::commandConfigReloadHandler)
|
||||
/// @todo: register libreload (see CtrlDhcpv4Srv::commandLibReloadHandler)
|
||||
|
||||
CommandMgr::instance().registerCommand("leases-reclaim",
|
||||
boost::bind(&ControlledDhcpv6Srv::commandLeasesReclaimHandler, this, _1, _2));
|
||||
|
||||
// Register statistic related commands
|
||||
CommandMgr::instance().registerCommand("statistic-get",
|
||||
boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
|
||||
@@ -247,6 +279,7 @@ ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
|
||||
|
||||
// Deregister any registered commands
|
||||
CommandMgr::instance().deregisterCommand("shutdown");
|
||||
CommandMgr::instance().deregisterCommand("leases-reclaim");
|
||||
CommandMgr::instance().deregisterCommand("statistic-get");
|
||||
CommandMgr::instance().deregisterCommand("statistic-reset");
|
||||
CommandMgr::instance().deregisterCommand("statistic-remove");
|
||||
|
@@ -70,6 +70,7 @@ public:
|
||||
/// - shutdown
|
||||
/// - libreload
|
||||
/// - config-reload
|
||||
/// - leases-reclaim
|
||||
///
|
||||
/// @note It never throws.
|
||||
///
|
||||
@@ -150,6 +151,23 @@ private:
|
||||
commandConfigReloadHandler(const std::string& command,
|
||||
isc::data::ConstElementPtr args);
|
||||
|
||||
/// @brief Handler for processing 'leases-reclaim' command
|
||||
///
|
||||
/// This handler processes leases-reclaim command, which triggers
|
||||
/// the leases reclamation immediately.
|
||||
/// No limit for processing time or number of processed leases applies.
|
||||
///
|
||||
/// @param command (parameter ignored)
|
||||
/// @param args arguments map { "remove": <bool> }
|
||||
/// if true a lease is removed when it is reclaimed,
|
||||
/// if false its state is changed to "expired-reclaimed".
|
||||
///
|
||||
/// @return status of the command (should be success unless args
|
||||
/// was not a Bool Element).
|
||||
isc::data::ConstElementPtr
|
||||
commandLeasesReclaimHandler(const std::string& command,
|
||||
isc::data::ConstElementPtr args);
|
||||
|
||||
/// @brief Reclaims expired IPv6 leases and reschedules timer.
|
||||
///
|
||||
/// This is a wrapper method for @c AllocEngine::reclaimExpiredLeases6.
|
||||
|
@@ -73,11 +73,11 @@ void configure(const std::string& file_name) {
|
||||
// works only for map.
|
||||
if (json->getType() != isc::data::Element::map) {
|
||||
isc_throw(isc::BadValue, "Configuration file is expected to be "
|
||||
"a map, i.e., start with { and end with } and contain "
|
||||
"at least an entry called 'Dhcp6' that itself is a map. "
|
||||
<< file_name
|
||||
"a map, i.e., start with { and end with } and contain "
|
||||
"at least an entry called 'Dhcp6' that itself is a map. "
|
||||
<< file_name
|
||||
<< " is a valid JSON, but its top element is not a map."
|
||||
" Did you forget to add { } around your configuration?");
|
||||
" Did you forget to add { } around your configuration?");
|
||||
}
|
||||
|
||||
// Let's configure logging before applying the configuration,
|
||||
|
@@ -3999,7 +3999,7 @@ TEST_F(Dhcp6ParserTest, declineTimerDefault) {
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
// The value of decline-probation-perion must be equal to the
|
||||
// The value of decline-probation-period must be equal to the
|
||||
// default value.
|
||||
EXPECT_EQ(DEFAULT_DECLINE_PROBATION_PERIOD,
|
||||
CfgMgr::instance().getStagingCfg()->getDeclinePeriod());
|
||||
@@ -4021,7 +4021,7 @@ TEST_F(Dhcp6ParserTest, declineTimer) {
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
// The value of decline-probation-perion must be equal to the
|
||||
// The value of decline-probation-period must be equal to the
|
||||
// value specified.
|
||||
EXPECT_EQ(12345,
|
||||
CfgMgr::instance().getStagingCfg()->getDeclinePeriod());
|
||||
@@ -4072,7 +4072,7 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessing) {
|
||||
// Returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
|
||||
// The value of decline-probation-perion must be equal to the
|
||||
// The value of decline-probation-period must be equal to the
|
||||
// value specified.
|
||||
CfgExpirationPtr cfg = CfgMgr::instance().getStagingCfg()->getCfgExpiration();
|
||||
ASSERT_TRUE(cfg);
|
||||
|
@@ -14,11 +14,15 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <asiolink/io_address.h>
|
||||
#include <cc/command_interpreter.h>
|
||||
#include <config/command_mgr.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/lease.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcp6/ctrl_dhcp6_srv.h>
|
||||
#include <hooks/hooks_manager.h>
|
||||
#include <stats/stats_mgr.h>
|
||||
#include <testutils/unix_control_client.h>
|
||||
|
||||
#include "marker_file.h"
|
||||
@@ -32,11 +36,13 @@
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
using namespace isc::asiolink;
|
||||
using namespace isc::config;
|
||||
using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::dhcp::test;
|
||||
using namespace isc::hooks;
|
||||
using namespace isc::stats;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -59,6 +65,8 @@ public:
|
||||
}
|
||||
|
||||
virtual ~CtrlDhcpv6SrvTest() {
|
||||
LeaseMgrFactory::destroy();
|
||||
StatsMgr::instance().removeAll();
|
||||
reset();
|
||||
};
|
||||
|
||||
@@ -118,6 +126,11 @@ public:
|
||||
" \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
" },"
|
||||
" \"expired-leases-processing\": {"
|
||||
" \"reclaim-timer-wait-time\": 60,"
|
||||
" \"hold-reclaimed-time\": 500,"
|
||||
" \"flush-reclaimed-timer-wait-time\": 60"
|
||||
" },"
|
||||
" \"rebind-timer\": 2000, "
|
||||
" \"renew-timer\": 1000, "
|
||||
" \"subnet6\": [ ],"
|
||||
@@ -406,6 +419,111 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelShutdown) {
|
||||
EXPECT_EQ("{ \"result\": 0, \"text\": \"Shutting down.\" }",response);
|
||||
}
|
||||
|
||||
// This test verifies that the DHCP server immediately reclaims expired
|
||||
// leases on leases-reclaim command
|
||||
TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaim) {
|
||||
createUnixChannelServer();
|
||||
|
||||
// Create expired leases. Leases are expired by 40 seconds ago
|
||||
// (valid lifetime = 60, cltt = now - 100).
|
||||
DuidPtr duid0(new DUID(DUID::fromText("00:01:02:03:04:05:06").getDuid()));
|
||||
Lease6Ptr lease0(new Lease6(Lease::TYPE_NA, IOAddress("3000::1"),
|
||||
duid0, 1, 50, 60, 10, 20, SubnetID(1)));
|
||||
lease0->cltt_ = time(NULL) - 100;
|
||||
DuidPtr duid1(new DUID(DUID::fromText("01:02:03:04:05:06:07").getDuid()));
|
||||
Lease6Ptr lease1(new Lease6(Lease::TYPE_NA, IOAddress("3000::2"),
|
||||
duid1, 1, 50, 60, 10, 20, SubnetID(1)));
|
||||
lease1->cltt_ = time(NULL) - 100;
|
||||
|
||||
// Add leases to the database.
|
||||
LeaseMgr& lease_mgr = LeaseMgrFactory().instance();
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease0));
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease1));
|
||||
|
||||
// Make sure they have been added.
|
||||
ASSERT_TRUE(lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::1")));
|
||||
ASSERT_TRUE(lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::2")));
|
||||
|
||||
// No arguments
|
||||
std::string response;
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\" }", response);
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": "
|
||||
"\"Missing mandatory 'remove' parameter.\" }", response);
|
||||
|
||||
// Bad argument name
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"reclaim\": true } }", response);
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": "
|
||||
"\"Missing mandatory 'remove' parameter.\" }", response);
|
||||
|
||||
// Bad remove argument type
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"remove\": \"bogus\" } }", response);
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": "
|
||||
"\"'remove' parameter expected to be a boolean.\" }", response);
|
||||
|
||||
// Send the command
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"remove\": false } }", response);
|
||||
EXPECT_EQ("{ \"result\": 0, \"text\": "
|
||||
"\"Reclamation of expired leases is complete.\" }", response);
|
||||
|
||||
// Leases should be reclaimed, but not removed
|
||||
ASSERT_NO_THROW(
|
||||
lease0 = lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::1"))
|
||||
);
|
||||
ASSERT_NO_THROW(
|
||||
lease1 = lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::2"))
|
||||
);
|
||||
ASSERT_TRUE(lease0);
|
||||
ASSERT_TRUE(lease1);
|
||||
EXPECT_TRUE(lease0->stateExpiredReclaimed());
|
||||
EXPECT_TRUE(lease1->stateExpiredReclaimed());
|
||||
}
|
||||
|
||||
// This test verifies that the DHCP server immediately reclaims expired
|
||||
// leases on leases-reclaim command with remove = true
|
||||
TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaimRemove) {
|
||||
createUnixChannelServer();
|
||||
|
||||
// Create expired leases. Leases are expired by 40 seconds ago
|
||||
// (valid lifetime = 60, cltt = now - 100).
|
||||
DuidPtr duid0(new DUID(DUID::fromText("00:01:02:03:04:05:06").getDuid()));
|
||||
Lease6Ptr lease0(new Lease6(Lease::TYPE_NA, IOAddress("3000::1"),
|
||||
duid0, 1, 50, 60, 10, 20, SubnetID(1)));
|
||||
lease0->cltt_ = time(NULL) - 100;
|
||||
DuidPtr duid1(new DUID(DUID::fromText("01:02:03:04:05:06:07").getDuid()));
|
||||
Lease6Ptr lease1(new Lease6(Lease::TYPE_NA, IOAddress("3000::2"),
|
||||
duid1, 1, 50, 60, 10, 20, SubnetID(1)));
|
||||
lease1->cltt_ = time(NULL) - 100;
|
||||
|
||||
// Add leases to the database.
|
||||
LeaseMgr& lease_mgr = LeaseMgrFactory().instance();
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease0));
|
||||
ASSERT_NO_THROW(lease_mgr.addLease(lease1));
|
||||
|
||||
// Make sure they have been added.
|
||||
ASSERT_TRUE(lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::1")));
|
||||
ASSERT_TRUE(lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::2")));
|
||||
|
||||
// Send the command
|
||||
std::string response;
|
||||
sendUnixCommand("{ \"command\": \"leases-reclaim\", "
|
||||
"\"arguments\": { \"remove\": true } }", response);
|
||||
EXPECT_EQ("{ \"result\": 0, \"text\": "
|
||||
"\"Reclamation of expired leases is complete.\" }", response);
|
||||
|
||||
// Leases should have been removed.
|
||||
ASSERT_NO_THROW(
|
||||
lease0 = lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::1"))
|
||||
);
|
||||
ASSERT_NO_THROW(
|
||||
lease1 = lease_mgr.getLease6(Lease::TYPE_NA, IOAddress("3000::2"))
|
||||
);
|
||||
ASSERT_FALSE(lease0);
|
||||
ASSERT_FALSE(lease1);
|
||||
}
|
||||
|
||||
// Tests that the server properly responds to statistics commands. Note this
|
||||
// is really only intended to verify that the appropriate Statistics handler
|
||||
// is called based on the command. It is not intended to be an exhaustive
|
||||
|
@@ -65,7 +65,7 @@ public:
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// CommandsMgr does not implement the commands (except one, "commands-list")
|
||||
/// CommandsMgr does not implement the commands (except one, "list-commands")
|
||||
/// itself, but rather provides an interface (see @ref registerCommand,
|
||||
/// @ref deregisterCommand, @ref processCommand) for other components to use
|
||||
/// it. The @ref CommandHandler type is specified in a way to easily use
|
||||
|
Reference in New Issue
Block a user