Commit 8d844f04 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[master] Merge branch 'master' of ssh://git.bind10.isc.org/var/bind10/git/bind10

parents 4a4642ad 8d8605b6
531. [func] tomek
b10-dhcp6: Added support for expired leases. Leases for IPv6
addresses that are past their valid lifetime may be recycled, i.e.
rellocated to other clients if needed.
(Trac #2327, git 62a23854f619349d319d02c3a385d9bc55442d5e)
530. [func]* team 530. [func]* team
b10-loadzone was fully overhauled. It now uses C++-based zone b10-loadzone was fully overhauled. It now uses C++-based zone
parser and loader library, performing stricter checks, having parser and loader library, performing stricter checks, having
......
...@@ -575,6 +575,9 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) { ...@@ -575,6 +575,9 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
checkClientId(reply, clientid); checkClientId(reply, clientid);
} }
/// @todo: Add a test that client sends hint that is in pool, but currently
/// being used by a different client.
// This test checks that the server is offering different addresses to different // This test checks that the server is offering different addresses to different
// clients in ADVERTISEs. Please note that ADVERTISE is not a guarantee that such // clients in ADVERTISEs. Please note that ADVERTISE is not a guarantee that such
// and address will be assigned. Had the pool was very small and contained only // and address will be assigned. Had the pool was very small and contained only
......
...@@ -44,9 +44,10 @@ AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress& ...@@ -44,9 +44,10 @@ AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress&
// Copy the address. It can be either V4 or V6. // Copy the address. It can be either V4 or V6.
std::memcpy(packed, &vec[0], len); std::memcpy(packed, &vec[0], len);
// Increase the address. // Start increasing the least significant byte
for (int i = len - 1; i >= 0; --i) { for (int i = len - 1; i >= 0; --i) {
++packed[i]; ++packed[i];
// if we haven't overflowed (0xff -> 0x0), than we are done
if (packed[i] != 0) { if (packed[i] != 0) {
break; break;
} }
...@@ -198,9 +199,31 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet, ...@@ -198,9 +199,31 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
if (lease) { if (lease) {
return (lease); return (lease);
} }
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation));
}
} }
} }
// Hint is in the pool but is not available. Search the pool until first of
// the following occurs:
// - we find a free address
// - we find an address for which the lease has expired
// - we exhaust number of tries
//
// @todo: Current code does not handle pool exhaustion well. It will be
// improved. Current problems:
// 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
// 10 addresses), we will iterate over it 100 times before giving up
// 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
// 3. the whole concept of infinite attempts is just asking for infinite loop
// We may consider some form or reference counting (this pool has X addresses
// left), but this has one major problem. We exactly control allocation
// moment, but we currently do not control expiration time at all
unsigned int i = attempts_; unsigned int i = attempts_;
do { do {
IOAddress candidate = allocator_->pickAddress(subnet, duid, hint); IOAddress candidate = allocator_->pickAddress(subnet, duid, hint);
...@@ -209,9 +232,9 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet, ...@@ -209,9 +232,9 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
/// implemented /// implemented
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate); Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate);
if (!existing) {
// there's no existing lease for selected candidate, so it is // there's no existing lease for selected candidate, so it is
// free. Let's allocate it. // free. Let's allocate it.
if (!existing) {
Lease6Ptr lease = createLease(subnet, duid, iaid, candidate, Lease6Ptr lease = createLease(subnet, duid, iaid, candidate,
fake_allocation); fake_allocation);
if (lease) { if (lease) {
...@@ -221,6 +244,11 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet, ...@@ -221,6 +244,11 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
// Although the address was free just microseconds ago, it may have // Although the address was free just microseconds ago, it may have
// been taken just now. If the lease insertion fails, we continue // been taken just now. If the lease insertion fails, we continue
// allocation attempts. // allocation attempts.
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation));
}
} }
// continue trying allocation until we run out of attempts // continue trying allocation until we run out of attempts
...@@ -232,6 +260,46 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet, ...@@ -232,6 +260,46 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
<< " tries"); << " tries");
} }
Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
bool fake_allocation /*= false */ ) {
if (!expired->expired()) {
isc_throw(BadValue, "Attempt to recycle lease that is still valid");
}
// address, lease type and prefixlen (0) stay the same
expired->iaid_ = iaid;
expired->duid_ = duid;
expired->preferred_lft_ = subnet->getPreferred();
expired->valid_lft_ = subnet->getValid();
expired->t1_ = subnet->getT1();
expired->t2_ = subnet->getT2();
expired->cltt_ = time(NULL);
expired->subnet_id_ = subnet->getID();
expired->fixed_ = false;
expired->hostname_ = std::string("");
expired->fqdn_fwd_ = false;
expired->fqdn_rev_ = false;
/// @todo: log here that the lease was reused (there's ticket #2524 for
/// logging in libdhcpsrv)
if (!fake_allocation) {
// for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease6(expired);
}
// We do nothing for SOLICIT. We'll just update database when
// the client gets back to us with REQUEST message.
// it's not really expired at this stage anymore - let's return it as
// an updated lease
return (expired);
}
Lease6Ptr AllocEngine::createLease(const Subnet6Ptr& subnet, Lease6Ptr AllocEngine::createLease(const Subnet6Ptr& subnet,
const DuidPtr& duid, const DuidPtr& duid,
uint32_t iaid, uint32_t iaid,
......
...@@ -216,6 +216,24 @@ private: ...@@ -216,6 +216,24 @@ private:
uint32_t iaid, const isc::asiolink::IOAddress& addr, uint32_t iaid, const isc::asiolink::IOAddress& addr,
bool fake_allocation = false); bool fake_allocation = false);
/// @brief reuses expired lease
///
/// Updates existing expired lease with new information. Lease database
/// is updated if this is real (i.e. REQUEST, fake_allocation = false), not
/// dummy allocation request (i.e. SOLICIT, fake_allocation = true).
///
/// @param expired old, expired lease
/// @param subnet subnet the lease is allocated from
/// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true)
/// @return refreshed lease
/// @throw BadValue if trying to recycle lease that is still valid
Lease6Ptr reuseExpiredLease(Lease6Ptr& expired, const Subnet6Ptr& subnet,
const DuidPtr& duid, uint32_t iaid,
bool fake_allocation = false);
/// @brief a pointer to currently used allocator /// @brief a pointer to currently used allocator
boost::shared_ptr<Allocator> allocator_; boost::shared_ptr<Allocator> allocator_;
......
...@@ -46,6 +46,14 @@ Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, ...@@ -46,6 +46,14 @@ Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr,
cltt_ = time(NULL); cltt_ = time(NULL);
} }
bool Lease6::expired() const {
// Let's use int64 to avoid problems with negative/large uint32 values
int64_t expire_time = cltt_ + valid_lft_;
return (expire_time < time(NULL));
}
std::string LeaseMgr::getParameter(const std::string& name) const { std::string LeaseMgr::getParameter(const std::string& name) const {
ParameterMap::const_iterator param = parameters_.find(name); ParameterMap::const_iterator param = parameters_.find(name);
if (param == parameters_.end()) { if (param == parameters_.end()) {
......
...@@ -379,6 +379,10 @@ struct Lease6 { ...@@ -379,6 +379,10 @@ struct Lease6 {
/// @return String form of the lease /// @return String form of the lease
std::string toText(); std::string toText();
/// @brief returns true if the lease is expired
/// @return true if the lease is expired
bool expired() const;
/// @brief Compare two leases for equality /// @brief Compare two leases for equality
/// ///
/// @param other lease6 object with which to compare /// @param other lease6 object with which to compare
......
...@@ -20,9 +20,8 @@ using namespace isc::dhcp; ...@@ -20,9 +20,8 @@ using namespace isc::dhcp;
Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters) Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
: LeaseMgr(parameters) { : LeaseMgr(parameters) {
std::cout << "Warning: Using memfile database backend. It is usable for" << std::endl; std::cout << "Warning: Using memfile database backend. It is usable for limited"
std::cout << "Warning: limited testing only. File support not implemented yet." << std::endl; << " testing only. Leases will be lost after restart." << std::endl;
std::cout << "Warning: Leases will be lost after restart." << std::endl;
} }
Memfile_LeaseMgr::~Memfile_LeaseMgr() { Memfile_LeaseMgr::~Memfile_LeaseMgr() {
......
...@@ -40,6 +40,7 @@ libdhcpsrv_unittests_SOURCES += pool_unittest.cc ...@@ -40,6 +40,7 @@ libdhcpsrv_unittests_SOURCES += pool_unittest.cc
libdhcpsrv_unittests_SOURCES += schema_copy.h libdhcpsrv_unittests_SOURCES += schema_copy.h
libdhcpsrv_unittests_SOURCES += subnet_unittest.cc libdhcpsrv_unittests_SOURCES += subnet_unittest.cc
libdhcpsrv_unittests_SOURCES += triplet_unittest.cc libdhcpsrv_unittests_SOURCES += triplet_unittest.cc
libdhcpsrv_unittests_SOURCES += test_utils.cc test_utils.h
libdhcpsrv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) libdhcpsrv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
if HAVE_MYSQL if HAVE_MYSQL
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <dhcpsrv/lease_mgr_factory.h> #include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/memfile_lease_mgr.h> #include <dhcpsrv/memfile_lease_mgr.h>
#include <dhcpsrv/tests/test_utils.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
...@@ -29,11 +31,13 @@ ...@@ -29,11 +31,13 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <map> #include <map>
#include <time.h>
using namespace std; using namespace std;
using namespace isc; using namespace isc;
using namespace isc::asiolink; using namespace isc::asiolink;
using namespace isc::dhcp; using namespace isc::dhcp;
using namespace isc::dhcp::test;
namespace { namespace {
...@@ -107,26 +111,6 @@ TEST_F(AllocEngineTest, constructor) { ...@@ -107,26 +111,6 @@ TEST_F(AllocEngineTest, constructor) {
ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100))); ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
} }
/// @todo: This method is taken from mysql_lease_mgr_utilities.cc from ticket
/// #2342. Get rid of one instance once the code is merged
void
detailCompareLease6(const Lease6Ptr& first, const Lease6Ptr& second) {
EXPECT_EQ(first->type_, second->type_);
// Compare address strings - odd things happen when they are different
// as the EXPECT_EQ appears to call the operator uint32_t() function,
// which causes an exception to be thrown for IPv6 addresses.
EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
EXPECT_EQ(first->prefixlen_, second->prefixlen_);
EXPECT_EQ(first->iaid_, second->iaid_);
EXPECT_TRUE(*first->duid_ == *second->duid_);
EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
EXPECT_EQ(first->valid_lft_, second->valid_lft_);
EXPECT_EQ(first->cltt_, second->cltt_);
EXPECT_EQ(first->subnet_id_, second->subnet_id_);
}
// This test checks if the simple allocation can succeed // This test checks if the simple allocation can succeed
TEST_F(AllocEngineTest, simpleAlloc) { TEST_F(AllocEngineTest, simpleAlloc) {
boost::scoped_ptr<AllocEngine> engine; boost::scoped_ptr<AllocEngine> engine;
...@@ -147,7 +131,7 @@ TEST_F(AllocEngineTest, simpleAlloc) { ...@@ -147,7 +131,7 @@ TEST_F(AllocEngineTest, simpleAlloc) {
ASSERT_TRUE(from_mgr); ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease6(lease, from_mgr); detailCompareLease(lease, from_mgr);
} }
// This test checks if the fake allocation (for SOLICIT) can succeed // This test checks if the fake allocation (for SOLICIT) can succeed
...@@ -195,7 +179,7 @@ TEST_F(AllocEngineTest, allocWithValidHint) { ...@@ -195,7 +179,7 @@ TEST_F(AllocEngineTest, allocWithValidHint) {
ASSERT_TRUE(from_mgr); ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease6(lease, from_mgr); detailCompareLease(lease, from_mgr);
} }
// This test checks if the allocation with a hint that is in range, // This test checks if the allocation with a hint that is in range,
...@@ -234,7 +218,7 @@ TEST_F(AllocEngineTest, allocWithUsedHint) { ...@@ -234,7 +218,7 @@ TEST_F(AllocEngineTest, allocWithUsedHint) {
ASSERT_TRUE(from_mgr); ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease6(lease, from_mgr); detailCompareLease(lease, from_mgr);
} }
// This test checks if the allocation with a hint that is out the blue // This test checks if the allocation with a hint that is out the blue
...@@ -264,7 +248,7 @@ TEST_F(AllocEngineTest, allocBogusHint) { ...@@ -264,7 +248,7 @@ TEST_F(AllocEngineTest, allocBogusHint) {
ASSERT_TRUE(from_mgr); ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease6(lease, from_mgr); detailCompareLease(lease, from_mgr);
} }
// This test verifies that the allocator picks addresses that belong to the // This test verifies that the allocator picks addresses that belong to the
...@@ -337,4 +321,156 @@ TEST_F(AllocEngineTest, IterativeAllocator_manyPools) { ...@@ -337,4 +321,156 @@ TEST_F(AllocEngineTest, IterativeAllocator_manyPools) {
delete alloc; delete alloc;
} }
// This test checks if really small pools are working
TEST_F(AllocEngineTest, smallPool) {
boost::scoped_ptr<AllocEngine> engine;
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
IOAddress addr("2001:db8:1::ad");
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
// Create configuration similar to other tests, but with a single address pool
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
subnet_->addPool6(pool_);
cfg_mgr.addSubnet6(subnet_);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
false);
// Check that we got that single lease
ASSERT_TRUE(lease);
EXPECT_EQ("2001:db8:1::ad", lease->addr_.toText());
// do all checks on the lease
checkLease6(lease);
// Check that the lease is indeed in LeaseMgr
Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters
detailCompareLease(lease, from_mgr);
}
// This test checks if all addresses in a pool are currently used, the attempt
// to find out a new lease fails.
TEST_F(AllocEngineTest, outOfAddresses) {
boost::scoped_ptr<AllocEngine> engine;
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
IOAddress addr("2001:db8:1::ad");
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
// Create configuration similar to other tests, but with a single address pool
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
subnet_->addPool6(pool_);
cfg_mgr.addSubnet6(subnet_);
// Just a different duid
DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
const uint32_t other_iaid = 3568;
Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, other_duid, other_iaid,
501, 502, 503, 504, subnet_->getID(), 0));
lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// There is just a single address in the pool and allocated it to someone
// else, so the allocation should fail
EXPECT_THROW(engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),false),
AllocFailed);
}
// This test checks if an expired lease can be reused in SOLICIT (fake allocation)
TEST_F(AllocEngineTest, solicitReuseExpiredLease) {
boost::scoped_ptr<AllocEngine> engine;
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
IOAddress addr("2001:db8:1::ad");
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
// Create configuration similar to other tests, but with a single address pool
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
subnet_->addPool6(pool_);
cfg_mgr.addSubnet6(subnet_);
// Just a different duid
DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
const uint32_t other_iaid = 3568;
Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, other_duid, other_iaid,
501, 502, 503, 504, subnet_->getID(), 0));
lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
lease->valid_lft_ = 495; // Lease was valid for 495 seconds
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// CASE 1: Asking for any address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
true);
// Check that we got that single lease
ASSERT_TRUE(lease);
EXPECT_EQ(addr.toText(), lease->addr_.toText());
// Do all checks on the lease (if subnet-id, preferred/valid times are ok etc.)
checkLease6(lease);
// CASE 2: Asking specifically for this address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress(addr.toText()),
true);
// Check that we got that single lease
ASSERT_TRUE(lease);
EXPECT_EQ(addr.toText(), lease->addr_.toText());
}
// This test checks if an expired lease can be reused in REQUEST (actual allocation)
TEST_F(AllocEngineTest, requestReuseExpiredLease) {
boost::scoped_ptr<AllocEngine> engine;
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
IOAddress addr("2001:db8:1::ad");
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
// Create configuration similar to other tests, but with a single address pool
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
subnet_->addPool6(pool_);
cfg_mgr.addSubnet6(subnet_);
// Let's create an expired lease
DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
const uint32_t other_iaid = 3568;
const SubnetID other_subnetid = 999;
Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, other_duid, other_iaid,
501, 502, 503, 504, other_subnetid, 0));
lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
lease->valid_lft_ = 495; // Lease was valid for 495 seconds
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// A client comes along, asking specifically for this address
lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress(addr.toText()), false);
// Check that he got that single lease
ASSERT_TRUE(lease);
EXPECT_EQ(addr.toText(), lease->addr_.toText());
// Check that the lease is indeed updated in LeaseMgr
Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(addr);
ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters
detailCompareLease(lease, from_mgr);
}
}; // end of anonymous namespace }; // end of anonymous namespace
...@@ -605,4 +605,29 @@ TEST(Lease6, OperatorEquals) { ...@@ -605,4 +605,29 @@ TEST(Lease6, OperatorEquals) {
EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
EXPECT_FALSE(lease1 != lease2); // ... leases equal EXPECT_FALSE(lease1 != lease2); // ... leases equal
} }
// Checks if lease expiration is calculated properly
TEST(Lease6, Lease6Expired) {
const IOAddress addr("2001:db8:1::456");
const uint8_t duid_array[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
const DuidPtr duid(new DUID(duid_array, sizeof(duid_array)));
const uint32_t iaid = 7; // just a number
const SubnetID subnet_id = 8; // just another number
Lease6 lease(Lease6::LEASE_IA_NA, addr, duid, iaid, 100, 200, 50, 80,
subnet_id);
// case 1: a second before expiration
lease.cltt_ = time(NULL) - 100;
lease.valid_lft_ = 101;
EXPECT_FALSE(lease.expired());
// case 2: the lease will expire after this second is concluded
lease.cltt_ = time(NULL) - 101;
EXPECT_FALSE(lease.expired());
// case 3: the lease is expired
lease.cltt_ = time(NULL) - 102;
EXPECT_TRUE(lease.expired());
}
}; // end of anonymous namespace }; // end of anonymous namespace
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <asiolink/io_address.h> #include <asiolink/io_address.h>
#include <dhcpsrv/lease_mgr_factory.h> #include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/mysql_lease_mgr.h> #include <dhcpsrv/mysql_lease_mgr.h>
#include <dhcpsrv/tests/test_utils.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
using namespace isc; using namespace isc;
using namespace isc::asiolink; using namespace isc::asiolink;
using namespace isc::dhcp; using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace std;