2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-01 14:35:29 +00:00

[295-min-max-lease-time-configuration-options] Revamped Renew*Lifetime tests

This commit is contained in:
Francis Dupont
2019-06-19 16:07:55 +02:00
parent 8732c7a011
commit c0ada53a8b

View File

@@ -1446,349 +1446,263 @@ TEST_F(Dhcpv4SrvTest, RenewBasic) {
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr));
} }
// This test verifies that renewal returns the default valid lifetime // Renew*Lifetime common code.
// when the client does not specify a value. namespace {
TEST_F(Dhcpv4SrvTest, RenewDefaultLifetime) {
struct ctx {
Dhcpv4SrvTest* test;
NakedDhcpv4Srv* srv;
const IOAddress& addr;
const uint32_t temp_valid;
const time_t temp_timestamp;
OptionPtr clientid;
HWAddrPtr hwaddr;
Lease4Ptr used;
Lease4Ptr l;
OptionPtr opt;
Pkt4Ptr req;
Pkt4Ptr ack;
};
void prepare(struct ctx& c) {
IfaceMgrTestConfig test_config(true); IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4(); IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
const IOAddress addr("192.0.2.106");
const uint32_t temp_valid = 100;
const time_t temp_timestamp = time(NULL) - 10;
// Generate client-id also sets client_id_ member
OptionPtr clientid = generateClientId();
// Check that the address we are about to use is indeed in pool // Check that the address we are about to use is indeed in pool
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr)); ASSERT_TRUE(c.test->subnet_->inPool(Lease::TYPE_V4, c.addr));
// let's create a lease and put it in the LeaseMgr // let's create a lease and put it in the LeaseMgr
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}; uint8_t hwaddr_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER)); c.hwaddr.reset(new HWAddr(hwaddr_data, sizeof(hwaddr_data), HTYPE_ETHER));
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(), c.used.reset(new Lease4(c.addr, c.hwaddr,
temp_valid, temp_timestamp, subnet_->getID())); &c.test->client_id_->getDuid()[0],
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used)); c.test->client_id_->getDuid().size(),
c.temp_valid, c.temp_timestamp,
c.test->subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(c.used));
// Check that the lease is really in the database // Check that the lease is really in the database
Lease4Ptr l = LeaseMgrFactory::instance().getLease4(addr); c.l = LeaseMgrFactory::instance().getLease4(c.addr);
ASSERT_TRUE(l); ASSERT_TRUE(c.l);
// Check that valid and cltt really set. // Check that valid and cltt really set.
// Constructed lease looks as if it was assigned 10 seconds ago // Constructed lease looks as if it was assigned 10 seconds ago
EXPECT_EQ(l->valid_lft_, temp_valid); EXPECT_EQ(c.l->valid_lft_, c.temp_valid);
EXPECT_EQ(l->cltt_, temp_timestamp); EXPECT_EQ(c.l->cltt_, c.temp_timestamp);
// Set the valid lifetime interval. // Set the valid lifetime interval.
subnet_->setValid(Triplet<uint32_t>(2000, 3000, 4000)); c.test->subnet_->setValid(Triplet<uint32_t>(2000, 3000, 4000));
// Let's create a RENEW // Let's create a RENEW
Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234)); c.req.reset(new Pkt4(DHCPREQUEST, 1234));
req->setRemoteAddr(IOAddress(addr)); c.req->setRemoteAddr(IOAddress(c.addr));
req->setYiaddr(addr); c.req->setYiaddr(c.addr);
req->setCiaddr(addr); // client's address c.req->setCiaddr(c.addr); // client's address
req->setIface("eth0"); c.req->setIface("eth0");
req->setHWAddr(hwaddr2); c.req->setHWAddr(c.hwaddr);
req->addOption(clientid); c.req->addOption(c.clientid);
req->addOption(srv->getServerID()); c.req->addOption(c.srv->getServerID());
if (c.opt) {
c.req->addOption(c.opt);
}
// Pass it to the server and hope for a REPLY
c.ack = c.srv->processRequest(c.req);
// Check if we get response at all
c.test->checkResponse(c.ack, DHCPACK, 1234);
EXPECT_EQ(c.addr, c.ack->getYiaddr());
// Check identifiers
c.test->checkServerId(c.ack, c.srv->getServerID());
c.test->checkClientId(c.ack, c.clientid);
// Check that the lease is really in the database
c.l = c.test->checkLease(c.ack, c.clientid, c.req->getHWAddr(), c.addr);
ASSERT_TRUE(c.l);
}
// This test verifies that renewal returns the default valid lifetime
// when the client does not specify a value.
TEST_F(Dhcpv4SrvTest, RenewDefaultLifetime) {
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
struct ctx c = {
this, // test
srv.get(), // srv
IOAddress("192.0.2.106"), // addr
100, // temp_valid
time(NULL) - 10, // temp_timestamp
// Generate client-id also sets client_id_ member
generateClientId(), // clientid
HWAddrPtr(), // hwaddr
Lease4Ptr(), // used
Lease4Ptr(), // l
OptionPtr(), // opt
Pkt4Ptr(), // req
Pkt4Ptr() // acka
};
prepare(c);
// There is no valid lifetime hint so the default will be returned. // There is no valid lifetime hint so the default will be returned.
// Pass it to the server and hope for a REPLY
Pkt4Ptr ack = srv->processRequest(req);
// Check if we get response at all
checkResponse(ack, DHCPACK, 1234);
EXPECT_EQ(addr, ack->getYiaddr());
// Check that address was returned from proper range, that its lease // Check that address was returned from proper range, that its lease
// lifetime is correct, that T1 and T2 are returned properly // lifetime is correct, that T1 and T2 are returned properly
checkAddressParams(ack, subnet_, true, true, subnet_->getValid()); checkAddressParams(c.ack, subnet_, true, true, subnet_->getValid());
// Check identifiers
checkServerId(ack, srv->getServerID());
checkClientId(ack, clientid);
// Check that the lease is really in the database
l = checkLease(ack, clientid, req->getHWAddr(), addr);
ASSERT_TRUE(l);
// Check that valid and cltt were really updated // Check that valid and cltt were really updated
EXPECT_EQ(l->valid_lft_, subnet_->getValid()); EXPECT_EQ(c.l->valid_lft_, subnet_->getValid());
// Checking for CLTT is a bit tricky if we want to avoid off by 1 errors // Checking for CLTT is a bit tricky if we want to avoid off by 1 errors
int32_t cltt = static_cast<int32_t>(l->cltt_); int32_t cltt = static_cast<int32_t>(c.l->cltt_);
int32_t expected = static_cast<int32_t>(time(NULL)); int32_t expected = static_cast<int32_t>(time(NULL));
// Equality or difference by 1 between cltt and expected is ok. // Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected)); EXPECT_GE(1, abs(cltt - expected));
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(c.addr));
} }
// This test verifies that renewal returns the specified valid lifetime // This test verifies that renewal returns the specified valid lifetime
// when the client adds an in-bound hint in the DISCOVER. // when the client adds an in-bound hint in the DISCOVER.
TEST_F(Dhcpv4SrvTest, RenewHintLifetime) { TEST_F(Dhcpv4SrvTest, RenewHintLifetime) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv; boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0))); ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
const IOAddress addr("192.0.2.106"); struct ctx c = {
const uint32_t temp_valid = 100; this, // test
const time_t temp_timestamp = time(NULL) - 10; srv.get(), // srv
IOAddress("192.0.2.106"), // addr
100, // temp_valid
time(NULL) - 10, // temp_timestamp
// Generate client-id also sets client_id_ member // Generate client-id also sets client_id_ member
OptionPtr clientid = generateClientId(); generateClientId(), // clientid
HWAddrPtr(), // hwaddr
// Check that the address we are about to use is indeed in pool Lease4Ptr(), // used
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr)); Lease4Ptr(), // l
OptionPtr(), // opt
// let's create a lease and put it in the LeaseMgr Pkt4Ptr(), // req
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}; Pkt4Ptr() // acka
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER)); };
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_timestamp, subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
// Check that the lease is really in the database
Lease4Ptr l = LeaseMgrFactory::instance().getLease4(addr);
ASSERT_TRUE(l);
// Check that valid and cltt really set.
// Constructed lease looks as if it was assigned 10 seconds ago
EXPECT_EQ(l->valid_lft_, temp_valid);
EXPECT_EQ(l->cltt_, temp_timestamp);
// Set the valid lifetime interval.
subnet_->setValid(Triplet<uint32_t>(2000, 3000, 4000));
// Let's create a RENEW
Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234));
req->setRemoteAddr(IOAddress(addr));
req->setYiaddr(addr);
req->setCiaddr(addr); // client's address
req->setIface("eth0");
req->setHWAddr(hwaddr2);
req->addOption(clientid);
req->addOption(srv->getServerID());
// Add a dhcp-lease-time with an in-bound valid lifetime hint // Add a dhcp-lease-time with an in-bound valid lifetime hint
// which will be returned in the OFFER. // which will be returned in the OFFER.
uint32_t hint = 3001; uint32_t hint = 3001;
OptionPtr opt(new OptionUint32(Option::V4, DHO_DHCP_LEASE_TIME, hint)); c.opt.reset(new OptionUint32(Option::V4, DHO_DHCP_LEASE_TIME, hint));
req->addOption(opt);
// Pass it to the server and hope for a REPLY prepare(c);
Pkt4Ptr ack = srv->processRequest(req);
// Check if we get response at all
checkResponse(ack, DHCPACK, 1234);
EXPECT_EQ(addr, ack->getYiaddr());
// Check that address was returned from proper range, that its lease // Check that address was returned from proper range, that its lease
// lifetime is correct, that T1 and T2 are returned properly // lifetime is correct, that T1 and T2 are returned properly
checkAddressParams(ack, subnet_, true, true, hint); checkAddressParams(c.ack, subnet_, true, true, hint);
// Check identifiers
checkServerId(ack, srv->getServerID());
checkClientId(ack, clientid);
// Check that the lease is really in the database
l = checkLease(ack, clientid, req->getHWAddr(), addr);
ASSERT_TRUE(l);
// Check that valid and cltt were really updated // Check that valid and cltt were really updated
EXPECT_EQ(l->valid_lft_, hint); EXPECT_EQ(c.l->valid_lft_, hint);
// Checking for CLTT is a bit tricky if we want to avoid off by 1 errors // Checking for CLTT is a bit tricky if we want to avoid off by 1 errors
int32_t cltt = static_cast<int32_t>(l->cltt_); int32_t cltt = static_cast<int32_t>(c.l->cltt_);
int32_t expected = static_cast<int32_t>(time(NULL)); int32_t expected = static_cast<int32_t>(time(NULL));
// Equality or difference by 1 between cltt and expected is ok. // Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected)); EXPECT_GE(1, abs(cltt - expected));
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(c.addr));
} }
// This test verifies that renewal returns the min valid lifetime // This test verifies that renewal returns the min valid lifetime
// when the client adds a too small hint in the DISCOVER. // when the client adds a too small hint in the DISCOVER.
TEST_F(Dhcpv4SrvTest, RenewMinLifetime) { TEST_F(Dhcpv4SrvTest, RenewMinLifetime) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv; boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0))); ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
const IOAddress addr("192.0.2.106"); struct ctx c = {
const uint32_t temp_valid = 100; this, // test
const time_t temp_timestamp = time(NULL) - 10; srv.get(), // srv
IOAddress("192.0.2.106"), // addr
100, // temp_valid
time(NULL) - 10, // temp_timestamp
// Generate client-id also sets client_id_ member // Generate client-id also sets client_id_ member
OptionPtr clientid = generateClientId(); generateClientId(), // clientid
HWAddrPtr(), // hwaddr
// Check that the address we are about to use is indeed in pool Lease4Ptr(), // used
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr)); Lease4Ptr(), // l
OptionPtr(), // opt
// let's create a lease and put it in the LeaseMgr Pkt4Ptr(), // req
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}; Pkt4Ptr() // acka
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER)); };
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_timestamp, subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
// Check that the lease is really in the database
Lease4Ptr l = LeaseMgrFactory::instance().getLease4(addr);
ASSERT_TRUE(l);
// Check that valid and cltt really set.
// Constructed lease looks as if it was assigned 10 seconds ago
EXPECT_EQ(l->valid_lft_, temp_valid);
EXPECT_EQ(l->cltt_, temp_timestamp);
// Set the valid lifetime interval.
subnet_->setValid(Triplet<uint32_t>(2000, 3000, 4000));
// Let's create a RENEW
Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234));
req->setRemoteAddr(IOAddress(addr));
req->setYiaddr(addr);
req->setCiaddr(addr); // client's address
req->setIface("eth0");
req->setHWAddr(hwaddr2);
req->addOption(clientid);
req->addOption(srv->getServerID());
// Add a dhcp-lease-time with too small valid lifetime hint. // Add a dhcp-lease-time with too small valid lifetime hint.
// The min valid lifetime will be returned in the OFFER. // The min valid lifetime will be returned in the OFFER.
OptionPtr opt(new OptionUint32(Option::V4, DHO_DHCP_LEASE_TIME, 1000)); c.opt.reset(new OptionUint32(Option::V4, DHO_DHCP_LEASE_TIME, 1000));
req->addOption(opt);
// Pass it to the server and hope for a REPLY prepare(c);
Pkt4Ptr ack = srv->processRequest(req);
// Check if we get response at all
checkResponse(ack, DHCPACK, 1234);
EXPECT_EQ(addr, ack->getYiaddr());
// Check that address was returned from proper range, that its lease // Check that address was returned from proper range, that its lease
// lifetime is correct, that T1 and T2 are returned properly // lifetime is correct, that T1 and T2 are returned properly
// Note that T2 should be false for a reason which does not matter... // Note that T2 should be false for a reason which does not matter...
checkAddressParams(ack, subnet_, true, false, subnet_->getValid().getMin()); checkAddressParams(c.ack, subnet_, true, false, subnet_->getValid().getMin());
// Check identifiers
checkServerId(ack, srv->getServerID());
checkClientId(ack, clientid);
// Check that the lease is really in the database
l = checkLease(ack, clientid, req->getHWAddr(), addr);
ASSERT_TRUE(l);
// Check that valid and cltt were really updated // Check that valid and cltt were really updated
EXPECT_EQ(l->valid_lft_, subnet_->getValid().getMin()); EXPECT_EQ(c.l->valid_lft_, subnet_->getValid().getMin());
// Checking for CLTT is a bit tricky if we want to avoid off by 1 errors // Checking for CLTT is a bit tricky if we want to avoid off by 1 errors
int32_t cltt = static_cast<int32_t>(l->cltt_); int32_t cltt = static_cast<int32_t>(c.l->cltt_);
int32_t expected = static_cast<int32_t>(time(NULL)); int32_t expected = static_cast<int32_t>(time(NULL));
// Equality or difference by 1 between cltt and expected is ok. // Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected)); EXPECT_GE(1, abs(cltt - expected));
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(c.addr));
} }
// This test verifies that renewal returns the max valid lifetime // This test verifies that renewal returns the max valid lifetime
// when the client adds a too large hint in the DISCOVER. // when the client adds a too large hint in the DISCOVER.
TEST_F(Dhcpv4SrvTest, RenewMaxLifetime) { TEST_F(Dhcpv4SrvTest, RenewMaxLifetime) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv; boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0))); ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
const IOAddress addr("192.0.2.106"); struct ctx c = {
const uint32_t temp_valid = 100; this, // test
const time_t temp_timestamp = time(NULL) - 10; srv.get(), // srv
IOAddress("192.0.2.106"), // addr
100, // temp_valid
time(NULL) - 10, // temp_timestamp
// Generate client-id also sets client_id_ member // Generate client-id also sets client_id_ member
OptionPtr clientid = generateClientId(); generateClientId(), // clientid
HWAddrPtr(), // hwaddr
// Check that the address we are about to use is indeed in pool Lease4Ptr(), // used
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr)); Lease4Ptr(), // l
OptionPtr(), // opt
// let's create a lease and put it in the LeaseMgr Pkt4Ptr(), // req
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}; Pkt4Ptr() // acka
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER)); };
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_timestamp, subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
// Check that the lease is really in the database
Lease4Ptr l = LeaseMgrFactory::instance().getLease4(addr);
ASSERT_TRUE(l);
// Check that valid and cltt really set.
// Constructed lease looks as if it was assigned 10 seconds ago
EXPECT_EQ(l->valid_lft_, temp_valid);
EXPECT_EQ(l->cltt_, temp_timestamp);
// Set the valid lifetime interval.
subnet_->setValid(Triplet<uint32_t>(2000, 3000, 4000));
// Let's create a RENEW
Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234));
req->setRemoteAddr(IOAddress(addr));
req->setYiaddr(addr);
req->setCiaddr(addr); // client's address
req->setIface("eth0");
req->setHWAddr(hwaddr2);
req->addOption(clientid);
req->addOption(srv->getServerID());
// Add a dhcp-lease-time with too large valid lifetime hint. // Add a dhcp-lease-time with too large valid lifetime hint.
// The max valid lifetime will be returned in the OFFER. // The max valid lifetime will be returned in the OFFER.
OptionPtr opt(new OptionUint32(Option::V4, DHO_DHCP_LEASE_TIME, 5000)); c.opt.reset(new OptionUint32(Option::V4, DHO_DHCP_LEASE_TIME, 5000));
req->addOption(opt);
// Pass it to the server and hope for a REPLY prepare(c);
Pkt4Ptr ack = srv->processRequest(req);
// Check if we get response at all
checkResponse(ack, DHCPACK, 1234);
EXPECT_EQ(addr, ack->getYiaddr());
// Check that address was returned from proper range, that its lease // Check that address was returned from proper range, that its lease
// lifetime is correct, that T1 and T2 are returned properly // lifetime is correct, that T1 and T2 are returned properly
checkAddressParams(ack, subnet_, true, true, subnet_->getValid().getMax()); checkAddressParams(c.ack, subnet_, true, true, subnet_->getValid().getMax());
// Check identifiers
checkServerId(ack, srv->getServerID());
checkClientId(ack, clientid);
// Check that the lease is really in the database
l = checkLease(ack, clientid, req->getHWAddr(), addr);
ASSERT_TRUE(l);
// Check that valid and cltt were really updated // Check that valid and cltt were really updated
EXPECT_EQ(l->valid_lft_, subnet_->getValid().getMax()); EXPECT_EQ(c.l->valid_lft_, subnet_->getValid().getMax());
// Checking for CLTT is a bit tricky if we want to avoid off by 1 errors // Checking for CLTT is a bit tricky if we want to avoid off by 1 errors
int32_t cltt = static_cast<int32_t>(l->cltt_); int32_t cltt = static_cast<int32_t>(c.l->cltt_);
int32_t expected = static_cast<int32_t>(time(NULL)); int32_t expected = static_cast<int32_t>(time(NULL));
// Equality or difference by 1 between cltt and expected is ok. // Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected)); EXPECT_GE(1, abs(cltt - expected));
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(c.addr));
} }
} // end of Renew*Lifetime
// This test verifies that the logic which matches server identifier in the // This test verifies that the logic which matches server identifier in the
// received message with server identifiers used by a server works correctly: // received message with server identifiers used by a server works correctly:
// - a message with no server identifier is accepted, // - a message with no server identifier is accepted,