From: Tomek Mrugalski Date: Mon, 17 Dec 2012 17:08:57 +0000 (+0100) Subject: [2327] Unittests added for expired lease recycling. X-Git-Tag: bind10-1.0.0-beta-release~6^2^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6f27e6fc9819b5807703ff141e31a0d7a6800a26;p=thirdparty%2Fkea.git [2327] Unittests added for expired lease recycling. --- diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index de0dc28d2a..526dc09779 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -575,6 +575,9 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) { 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 // 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 diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc index b71b16618d..79cf1c76eb 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@ -20,9 +20,8 @@ using namespace isc::dhcp; Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters) : LeaseMgr(parameters) { - std::cout << "Warning: Using memfile database backend. It is usable for" << std::endl; - std::cout << "Warning: limited testing only. File support not implemented yet." << std::endl; - std::cout << "Warning: Leases will be lost after restart." << std::endl; + std::cout << "Warning: Using memfile database backend. It is usable for limited" + << " testing only. Leases will be lost after restart." << std::endl; } Memfile_LeaseMgr::~Memfile_LeaseMgr() { diff --git a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc index dcfb68b94a..72d6ecea8d 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc @@ -29,6 +29,7 @@ #include #include #include +#include using namespace std; using namespace isc; @@ -337,4 +338,156 @@ TEST_F(AllocEngineTest, IterativeAllocator_manyPools) { delete alloc; } +// This test checks if really small pools are working +TEST_F(AllocEngineTest, smallPool) { + boost::scoped_ptr 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 + detailCompareLease6(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 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(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 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(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 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(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 + detailCompareLease6(lease, from_mgr); +} + }; // end of anonymous namespace diff --git a/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc index a812811488..38c955583c 100644 --- a/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc @@ -258,7 +258,7 @@ TEST(Lease4, Lease4Constructor) { // ...and a time const time_t current_time = time(NULL); - // Other random constants. + // Other random constants. const uint32_t SUBNET_ID = 42; const uint32_t VALID_LIFETIME = 500; @@ -605,4 +605,29 @@ TEST(Lease6, OperatorEquals) { EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the 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