2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 22:15:23 +00:00

[5247] Corrected issues with assigned-<lease/nas/pd> stats

doc/guide/dhcp4-srv.xml
doc/guide/dhcp6-srv.xml
    Added entries for reclaimed-leases

src/lib/dhcpsrv/alloc_engine.cc

    AllocEngine::reuseExpiredLease(Lease6Ptr&...) - increment
    assigned-<nas/pds> for real allocations

    AllocEngine::extendLease6() - increment assigned-<nas/pds>
    for real allocations if the lease expired

    AllocEngine::renewLease4(const Lease4Ptr&...)
    - set lease state to STATE_DEFAULT for real allocations
    - increment assigned-leases if lease is expired or reclaimed
      for real allocations

    AllocEngine::reuseExpiredLease4(Lease4Ptr&...)
    - increment assigned-leases for real allocations

src/lib/dhcpsrv/cfg_subnets4.cc
    CfgSubnets4::removeStatistics() - added "reclaimed-leases"

src/lib/dhcpsrv/cfg_subnets6.cc
    CfgSubnets4::removeStatistics() - added "reclaimed-leases"

src/lib/dhcpsrv/lease_mgr.cc
    LeaseMgr::recountLeaseStats4()
    LeaseMgr::recountLeaseStats6()
    - added handling of "reclaimed-leases"
    - fixed name of "reclaimed-declined-addresses"

src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc
    TEST_F(AllocEngine4Test, simpleRenew4)  - new test to verify stats
    on a normal renew, non-expired
    Added EXPECT_TRUE around calls to testStatistics for invocation line numbers
    Added stat checks to several tests

src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc
    Added EXPECT_TRUE around calls to testStatistics for invocation line numbers
    Added stat checks to several tests

src/lib/dhcpsrv/tests/alloc_engine_expiration_unittest.cc
    Added checks of assigned stats

src/lib/dhcpsrv/tests/alloc_engine_utils.cc
    AllocEngine6Test::initSubnet() - removed artificial stat values

    NakedAllocEngine::addHost() - new method to add a host to the
    current configuration, rather than use staging/commit as the latter
This commit is contained in:
Thomas Markwalder
2017-04-21 11:54:45 -04:00
parent 1aceaf3216
commit fe3766aedd
12 changed files with 334 additions and 153 deletions

View File

@@ -3614,7 +3614,25 @@ src/lib/dhcpsrv/cfg_host_operations.cc -->
separately. This statistic is reset during reconfiguration event. separately. This statistic is reset during reconfiguration event.
</entry> </entry>
</row> </row>
<row>
<entry>reclaimed-leases</entry>
<entry>integer</entry>
<entry>This statistic shows the number of expired leases that have
have been reclaimed since server startup. It increases every time an
expired lease undergoes expiration reclamation. This statistic is reset
during reconfiguration event.
</entry>
</row>
<row>
<entry>subnet[id].reclaimed-leases</entry>
<entry>integer</entry>
<entry>This statistic shows the number of expired leases that have
and been reclaimed since server startup. It increases every time an expired
lease undergoes expiration reclamation. The <emphasis>id</emphasis> is
the subnet-id of the subnet. This statistic is exposed for each subnet
separately. This statistic is reset during reconfiguration event.
</entry>
</row>
<row> <row>
<entry>declined-addresses</entry> <entry>declined-addresses</entry>
<entry>integer</entry> <entry>integer</entry>

View File

@@ -3856,6 +3856,29 @@ If not specified, the default value is:
</entry> </entry>
</row> </row>
<row>
<entry>reclaimed-leases</entry>
<entry>integer</entry>
<entry>This statistic shows the number of expired leases that have
and been reclaimed since server startup. It increases every time an
expired lease undergoes expiration reclamation. This statistic is reset
during reconfiguration event. Note it counts both NA and PD reclamations.
This statistic is reset during reconfiguration event.
</entry>
</row>
<row>
<entry>subnet[id].reclaimed-leases</entry>
<entry>integer</entry>
<entry>This statistic shows the number of expired leases that have
and been reclaimed since server startup. It increases every time an expired
lease undergoes expiration reclamation. The <emphasis>id</emphasis> is
the subnet-id of the subnet. This statistic is exposed for each subnet
separately. Note it counts both NA and PD reclamations.
This statistic is reset during reconfiguration event.
</entry>
</row>
<row> <row>
<entry>declined-addresses</entry> <entry>declined-addresses</entry>
<entry>integer</entry> <entry>integer</entry>

View File

@@ -1093,6 +1093,16 @@ AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx,
if (!ctx.fake_allocation_) { if (!ctx.fake_allocation_) {
// for REQUEST we do update the lease // for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease6(expired); LeaseMgrFactory::instance().updateLease6(expired);
// If the lease is in the current subnet we need to account
// for the re-assignment of The lease.
if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
StatsMgr::instance().addValue(
StatsMgr::generateName("subnet", ctx.subnet_->getID(),
ctx.currentIA().type_ == Lease::TYPE_NA ?
"assigned-nas" : "assigned-pds"),
static_cast<int64_t>(1));
}
} }
// We do nothing for SOLICIT. We'll just update database when // We do nothing for SOLICIT. We'll just update database when
@@ -1387,6 +1397,15 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
if (old_data->expired()) { if (old_data->expired()) {
reclaimExpiredLease(old_data, ctx.callout_handle_); reclaimExpiredLease(old_data, ctx.callout_handle_);
// If the lease is in the current subnet we need to account
// for the re-assignment of The lease.
if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
StatsMgr::instance().addValue(
StatsMgr::generateName("subnet", ctx.subnet_->getID(),
ctx.currentIA().type_ == Lease::TYPE_NA ?
"assigned-nas" : "assigned-pds"),
static_cast<int64_t>(1));
}
} else { } else {
if (!lease->hasIdenticalFqdn(*old_data)) { if (!lease->hasIdenticalFqdn(*old_data)) {
// We're not reclaiming the lease but since the FQDN has changed // We're not reclaiming the lease but since the FQDN has changed
@@ -2656,13 +2675,14 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
// involves execution of hooks and DNS update. // involves execution of hooks and DNS update.
if (ctx.old_lease_->expired()) { if (ctx.old_lease_->expired()) {
reclaimExpiredLease(ctx.old_lease_, ctx.callout_handle_); reclaimExpiredLease(ctx.old_lease_, ctx.callout_handle_);
lease->state_ = Lease::STATE_DEFAULT;
} else if (!lease->hasIdenticalFqdn(*ctx.old_lease_)) { } else if (!lease->hasIdenticalFqdn(*ctx.old_lease_)) {
// The lease is not expired but the FQDN information has // The lease is not expired but the FQDN information has
// changed. So, we have to remove the previous DNS entry. // changed. So, we have to remove the previous DNS entry.
queueNCR(CHG_REMOVE, ctx.old_lease_); queueNCR(CHG_REMOVE, ctx.old_lease_);
} }
lease->state_ = Lease::STATE_DEFAULT;
} }
bool skip = false; bool skip = false;
@@ -2710,6 +2730,13 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
if (!ctx.fake_allocation_ && !skip) { if (!ctx.fake_allocation_ && !skip) {
// for REQUEST we do update the lease // for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease4(lease); LeaseMgrFactory::instance().updateLease4(lease);
// We need to account for the re-assignment of The lease.
if (ctx.old_lease_->expired() || ctx.old_lease_->state_ == Lease::STATE_EXPIRED_RECLAIMED) {
StatsMgr::instance().addValue(
StatsMgr::generateName("subnet", ctx.subnet_->getID(), "assigned-addresses"),
static_cast<int64_t>(1));
}
} }
if (skip) { if (skip) {
// Rollback changes (really useful only for memfile) // Rollback changes (really useful only for memfile)
@@ -2796,6 +2823,11 @@ AllocEngine::reuseExpiredLease4(Lease4Ptr& expired,
if (!ctx.fake_allocation_) { if (!ctx.fake_allocation_) {
// for REQUEST we do update the lease // for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease4(expired); LeaseMgrFactory::instance().updateLease4(expired);
// We need to account for the re-assignment of The lease.
StatsMgr::instance().addValue(
StatsMgr::generateName("subnet", ctx.subnet_->getID(), "assigned-addresses"),
static_cast<int64_t>(1));
} }
// We do nothing for SOLICIT. We'll just update database when // We do nothing for SOLICIT. We'll just update database when

View File

@@ -250,6 +250,9 @@ CfgSubnets4::removeStatistics() {
stats_mgr.del(StatsMgr::generateName("subnet", subnet_id, stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
"declined-reclaimed-addresses")); "declined-reclaimed-addresses"));
stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
"reclaimed-leases"));
} }
} }

View File

@@ -201,6 +201,9 @@ CfgSubnets6::removeStatistics() {
stats_mgr.del(StatsMgr::generateName("subnet", subnet_id, stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
"declined-reclaimed-addresses")); "declined-reclaimed-addresses"));
stats_mgr.del(StatsMgr::generateName("subnet", subnet_id,
"reclaimed-leases"));
} }
} }

View File

@@ -62,7 +62,8 @@ LeaseMgr::recountLeaseStats4() {
// Zero out the global stats. // Zero out the global stats.
int64_t zero = 0; int64_t zero = 0;
stats_mgr.setValue("declined-addresses", zero); stats_mgr.setValue("declined-addresses", zero);
stats_mgr.setValue("declined-reclaimed-addresses", zero); stats_mgr.setValue("reclaimed-declined-addresses", zero);
stats_mgr.setValue("reclaimed-leases", zero);
// Clear subnet level stats. This ensures we don't end up with corner // Clear subnet level stats. This ensures we don't end up with corner
// cases that leave stale values in place. // cases that leave stale values in place.
@@ -79,8 +80,13 @@ LeaseMgr::recountLeaseStats4() {
stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id, stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
"declined-addresses"), "declined-addresses"),
zero); zero);
stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id, stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
"declined-reclaimed-addresses"), "reclaimed-declined-addresses"),
zero);
stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
"reclaimed-leases"),
zero); zero);
} }
@@ -133,7 +139,8 @@ LeaseMgr::recountLeaseStats6() {
// clearing it when we clear the rest. // clearing it when we clear the rest.
int64_t zero = 0; int64_t zero = 0;
stats_mgr.setValue("declined-addresses", zero); stats_mgr.setValue("declined-addresses", zero);
stats_mgr.setValue("declined-reclaimed-addresses", zero); stats_mgr.setValue("reclaimed-declined-addresses", zero);
stats_mgr.setValue("reclaimed-leases", zero);
// Clear subnet level stats. This ensures we don't end up with corner // Clear subnet level stats. This ensures we don't end up with corner
// cases that leave stale values in place. // cases that leave stale values in place.
@@ -153,12 +160,16 @@ LeaseMgr::recountLeaseStats6() {
stats_mgr.setValue(StatsMgr:: stats_mgr.setValue(StatsMgr::
generateName("subnet", subnet_id, generateName("subnet", subnet_id,
"declined-reclaimed-addresses"), "reclaimed-declined-addresses"),
zero); zero);
stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id, stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
"assigned-pds"), "assigned-pds"),
zero); zero);
stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
"reclaimed-leases"),
zero);
} }
// Get counts per state per subnet. Iterate over the result set // Get counts per state per subnet. Iterate over the result set

View File

@@ -44,7 +44,6 @@ TEST_F(AllocEngine4Test, constructor) {
EXPECT_THROW(x->getAllocator(Lease::TYPE_PD), BadValue); EXPECT_THROW(x->getAllocator(Lease::TYPE_PD), BadValue);
} }
// This test checks if the simple IPv4 allocation can succeed // This test checks if the simple IPv4 allocation can succeed
TEST_F(AllocEngine4Test, simpleAlloc4) { TEST_F(AllocEngine4Test, simpleAlloc4) {
boost::scoped_ptr<AllocEngine> engine; boost::scoped_ptr<AllocEngine> engine;
@@ -52,6 +51,9 @@ TEST_F(AllocEngine4Test, simpleAlloc4) {
100, false))); 100, false)));
ASSERT_TRUE(engine); ASSERT_TRUE(engine);
// Assigned addresses should be zero.
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"), AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
false, true, "somehost.example.com.", false); false, true, "somehost.example.com.", false);
ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234)); ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
@@ -72,6 +74,9 @@ TEST_F(AllocEngine4Test, simpleAlloc4) {
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease(lease, from_mgr); detailCompareLease(lease, from_mgr);
// Assigned addresses should have incremented.
EXPECT_TRUE(testStatistics("assigned-addresses", 1, subnet_->getID()));
} }
// This test checks if the fake allocation (for DHCPDISCOVER) can succeed // This test checks if the fake allocation (for DHCPDISCOVER) can succeed
@@ -81,6 +86,9 @@ TEST_F(AllocEngine4Test, fakeAlloc4) {
100, false))); 100, false)));
ASSERT_TRUE(engine); ASSERT_TRUE(engine);
// Assigned addresses should be zero.
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
IOAddress("0.0.0.0"), false, true, IOAddress("0.0.0.0"), false, true,
"host.example.com.", true); "host.example.com.", true);
@@ -100,6 +108,9 @@ TEST_F(AllocEngine4Test, fakeAlloc4) {
// Check that the lease is NOT in LeaseMgr // Check that the lease is NOT in LeaseMgr
Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_); Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
ASSERT_FALSE(from_mgr); ASSERT_FALSE(from_mgr);
// Assigned addresses should still be zero.
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
} }
@@ -267,7 +278,45 @@ TEST_F(AllocEngine4Test, allocateLease4Nulls) {
detailCompareLease(lease, from_mgr); detailCompareLease(lease, from_mgr);
} }
// This test checks if a returning client can renew an
// an existing lease and assigned-leases increments accordingly
TEST_F(AllocEngine4Test, simpleRenew4) {
boost::scoped_ptr<AllocEngine> engine;
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
100, false)));
ASSERT_TRUE(engine);
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
false, true, "somehost.example.com.", false);
ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
Lease4Ptr lease = engine->allocateLease4(ctx);
// Check that we got a lease and it's sane
ASSERT_TRUE(lease);
checkLease4(lease);
// The new lease has been allocated, so the old lease should not exist.
EXPECT_FALSE(ctx.old_lease_);
// We should have incremented assigned-addresses
EXPECT_TRUE(testStatistics("assigned-addresses", 1, subnet_->getID()));
// Do it again, this should amount to the renew of an existing lease
Lease4Ptr lease2 = engine->allocateLease4(ctx);
// Check that we got a lease and it's sane
ASSERT_TRUE(lease2);
checkLease4(lease2);
// Lease already existsed, so old_lease should be set.
EXPECT_TRUE(ctx.old_lease_);
// Should NOT have bumped assigned-addresses
EXPECT_TRUE(testStatistics("assigned-addresses", 1, subnet_->getID()));
}
// This test verifies that the allocator picks addresses that belong to the // This test verifies that the allocator picks addresses that belong to the
// pool // pool
@@ -504,14 +553,18 @@ TEST_F(AllocEngine4Test, requestReuseExpiredLease4) {
IOAddress addr("192.0.2.105"); IOAddress addr("192.0.2.105");
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
EXPECT_TRUE(testStatistics("reclaimed-leases", 0));
EXPECT_TRUE(testStatistics("reclaimed-leases", 0, subnet_->getID()));
// Just a different hw/client-id for the second client // Just a different hw/client-id for the second client
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}; uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER)); HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 }; uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
time_t now = time(NULL) - 500; // Allocated 500 seconds ago time_t now = time(NULL) - 500; // Allocated 500 seconds ago
Lease4Ptr lease(new Lease4(addr, hwaddr2, clientid2, sizeof(clientid2), Lease4Ptr lease(new Lease4(addr, hwaddr2, clientid2, sizeof(clientid2),
sizeof(hwaddr2), 495, 100, 200, now, 495, 100, 200, now, subnet_->getID()));
subnet_->getID()));
// Make a copy of the lease, so as we can compare that with the old lease // Make a copy of the lease, so as we can compare that with the old lease
// instance returned by the allocation engine. // instance returned by the allocation engine.
Lease4 original_lease(*lease); Lease4 original_lease(*lease);
@@ -543,6 +596,13 @@ TEST_F(AllocEngine4Test, requestReuseExpiredLease4) {
// lease should be equal to the original lease. // lease should be equal to the original lease.
ASSERT_TRUE(ctx.old_lease_); ASSERT_TRUE(ctx.old_lease_);
EXPECT_TRUE(*ctx.old_lease_ == original_lease); EXPECT_TRUE(*ctx.old_lease_ == original_lease);
// Check that the stats declined stats were modified correctly. Note, because
// added the lease directly, assigned-leases never bumped to one, so when we
// reclaime it gets decremented to -1, then on assignment back to 0.
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
EXPECT_TRUE(testStatistics("reclaimed-leases", 1));
EXPECT_TRUE(testStatistics("reclaimed-leases", 1, subnet_->getID()));
} }
// This test checks if an expired declined lease can be reused when responding // This test checks if an expired declined lease can be reused when responding
@@ -599,35 +659,23 @@ TEST_F(AllocEngine4Test, discoverReuseDeclinedLease4Stats) {
pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
subnet_->addPool(pool_); subnet_->addPool(pool_);
cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_); cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
cfg_mgr.commit(); // so we will recalc stats
// Now create a declined lease, decline it and rewind its cltt, so it // Now create a declined lease, decline it and rewind its cltt, so it
// is expired. // is expired.
Lease4Ptr declined = generateDeclinedLease("192.0.2.15", 100, -10); Lease4Ptr declined = generateDeclinedLease("192.0.2.15", 100, -10);
// Let's fix some global stats...
StatsMgr& stats_mgr = StatsMgr::instance();
stats_mgr.setValue("declined-addresses", static_cast<int64_t>(1000));
stats_mgr.setValue("reclaimed-declined-addresses", static_cast<int64_t>(1000));
// ...and subnet specific stats as well.
string stat1 = StatsMgr::generateName("subnet", subnet_->getID(),
"declined-addresses");
string stat2 = StatsMgr::generateName("subnet", subnet_->getID(),
"reclaimed-declined-addresses");
stats_mgr.setValue(stat1, static_cast<int64_t>(1000));
stats_mgr.setValue(stat2, static_cast<int64_t>(1000));
// Ask for any address. There's only one address in the pool, so it doesn't // Ask for any address. There's only one address in the pool, so it doesn't
// matter much. // matter much.
Lease4Ptr assigned; Lease4Ptr assigned;
testReuseLease4(engine, declined, "0.0.0.0", true, SHOULD_PASS, assigned); testReuseLease4(engine, declined, "0.0.0.0", true, SHOULD_PASS, assigned);
// Check that the stats were not modified // Check that the stats declined stats were not modified
testStatistics("declined-addresses", 1000); EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
testStatistics("reclaimed-declined-addresses", 1000); EXPECT_TRUE(testStatistics("declined-addresses", 0));
EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 0));
testStatistics(stat1, 1000); EXPECT_TRUE(testStatistics("declined-addresses", 0, subnet_->getID()));
testStatistics(stat2, 1000); EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 0, subnet_->getID()));
} }
// This test checks if an expired declined lease can be reused when responding // This test checks if an expired declined lease can be reused when responding
@@ -682,36 +730,26 @@ TEST_F(AllocEngine4Test, requestReuseDeclinedLease4Stats) {
pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
subnet_->addPool(pool_); subnet_->addPool(pool_);
cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_); cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
cfg_mgr.commit();
// Now create a declined lease, decline it and rewind its cltt, so it // Now create a declined lease, decline it and rewind its cltt, so it
// is expired. // is expired.
Lease4Ptr declined = generateDeclinedLease("192.0.2.15", 100, -10); Lease4Ptr declined = generateDeclinedLease("192.0.2.15", 100, -10);
// Let's fix some global stats...
StatsMgr& stats_mgr = StatsMgr::instance();
stats_mgr.setValue("declined-addresses", static_cast<int64_t>(1000));
stats_mgr.setValue("reclaimed-declined-addresses", static_cast<int64_t>(1000));
// ...and subnet specific stats as well.
string stat1 = StatsMgr::generateName("subnet", subnet_->getID(),
"declined-addresses");
string stat2 = StatsMgr::generateName("subnet", subnet_->getID(),
"reclaimed-declined-addresses");
stats_mgr.setValue(stat1, static_cast<int64_t>(1000));
stats_mgr.setValue(stat2, static_cast<int64_t>(1000));
// Asking specifically for this address // Asking specifically for this address
Lease4Ptr assigned; Lease4Ptr assigned;
testReuseLease4(engine, declined, "192.0.2.15", false, SHOULD_PASS, assigned); testReuseLease4(engine, declined, "192.0.2.15", false, SHOULD_PASS, assigned);
// Check that we got it. // Check that we got it.
ASSERT_TRUE(assigned); ASSERT_TRUE(assigned);
// Check that the stats were modified // Check that the stats are correct. Note that assigned-addresses does
testStatistics("declined-addresses", 999); // not get decremented when a lease is declined, ergo not incremented
testStatistics("reclaimed-declined-addresses", 1001); // when it is reused.
EXPECT_TRUE(testStatistics("assigned-addresses", 0, subnet_->getID()));
testStatistics(stat1, 999); EXPECT_TRUE(testStatistics("declined-addresses", -1));
testStatistics(stat2, 1001); EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 1));
EXPECT_TRUE(testStatistics("declined-addresses", -1, subnet_->getID()));
EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 1, subnet_->getID()));
} }
// This test checks that the Allocation Engine correctly identifies the // This test checks that the Allocation Engine correctly identifies the

View File

@@ -77,7 +77,7 @@ TEST_F(AllocEngine6Test, simpleAlloc6) {
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"); string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas");
ObservationPtr stat = StatsMgr::instance().getObservation(name); ObservationPtr stat = StatsMgr::instance().getObservation(name);
ASSERT_TRUE(stat); ASSERT_TRUE(stat);
EXPECT_EQ(101, stat->getInteger().first); EXPECT_EQ(1, stat->getInteger().first);
} }
// This test checks if the simple PD allocation (REQUEST) can succeed // This test checks if the simple PD allocation (REQUEST) can succeed
@@ -90,7 +90,7 @@ TEST_F(AllocEngine6Test, pdSimpleAlloc6) {
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-pds"); string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-pds");
ObservationPtr stat = StatsMgr::instance().getObservation(name); ObservationPtr stat = StatsMgr::instance().getObservation(name);
ASSERT_TRUE(stat); ASSERT_TRUE(stat);
EXPECT_EQ(101, stat->getInteger().first); EXPECT_EQ(1, stat->getInteger().first);
} }
// This test checks if the fake allocation (for SOLICIT) can succeed // This test checks if the fake allocation (for SOLICIT) can succeed
@@ -103,7 +103,7 @@ TEST_F(AllocEngine6Test, fakeAlloc6) {
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"); string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas");
ObservationPtr stat = StatsMgr::instance().getObservation(name); ObservationPtr stat = StatsMgr::instance().getObservation(name);
ASSERT_TRUE(stat); ASSERT_TRUE(stat);
EXPECT_EQ(100, stat->getInteger().first); EXPECT_EQ(0, stat->getInteger().first);
} }
// This test checks if the fake PD allocation (for SOLICIT) can succeed // This test checks if the fake PD allocation (for SOLICIT) can succeed
@@ -115,7 +115,7 @@ TEST_F(AllocEngine6Test, pdFakeAlloc6) {
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-pds"); string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-pds");
ObservationPtr stat = StatsMgr::instance().getObservation(name); ObservationPtr stat = StatsMgr::instance().getObservation(name);
ASSERT_TRUE(stat); ASSERT_TRUE(stat);
EXPECT_EQ(100, stat->getInteger().first); EXPECT_EQ(0, stat->getInteger().first);
}; };
// This test checks if the allocation with a hint that is valid (in range, // This test checks if the allocation with a hint that is valid (in range,
@@ -545,6 +545,11 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
// Check that we got that single lease // Check that we got that single lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
EXPECT_EQ(addr, lease->addr_); EXPECT_EQ(addr, lease->addr_);
// Verify the none of relelvant stats were altered.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
EXPECT_TRUE(testStatistics("reclaimed-leases", 0));
EXPECT_TRUE(testStatistics("reclaimed-leases", 0, subnet_->getID()));
} }
// This test checks if an expired lease can be reused in REQUEST (actual allocation) // This test checks if an expired lease can be reused in REQUEST (actual allocation)
@@ -567,10 +572,12 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
// Let's create an expired lease // Let's create an expired lease
DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff))); DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
const uint32_t other_iaid = 3568; const uint32_t other_iaid = 3568;
const SubnetID other_subnetid = 999; const SubnetID other_subnetid = 999;
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, other_duid, other_iaid, Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, other_duid, other_iaid,
501, 502, 503, 504, other_subnetid, HWAddrPtr(), 501, 502, 503, 504, other_subnetid, HWAddrPtr(),
0)); 0));
lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
lease->valid_lft_ = 495; // Lease was valid for 495 seconds lease->valid_lft_ = 495; // Lease was valid for 495 seconds
lease->fqdn_fwd_ = true; lease->fqdn_fwd_ = true;
@@ -578,10 +585,6 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
lease->hostname_ = "myhost.example.com."; lease->hostname_ = "myhost.example.com.";
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease)); ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// By default we pretend our subnet has 100 addresses
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas");
StatsMgr::instance().setValue(name, static_cast<int64_t>(100));
// A client comes along, asking specifically for this address // A client comes along, asking specifically for this address
AllocEngine::ClientContext6 ctx(subnet_, duid_, false, false, "", false, AllocEngine::ClientContext6 ctx(subnet_, duid_, false, false, "", false,
Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234))); Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234)));
@@ -615,12 +618,12 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease(lease, from_mgr); detailCompareLease(lease, from_mgr);
// We should not have bumped the address counter // Verify the stats got adjusted correctly
// NOTE: when we start expiring addresses and removing them from EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
// the stats this will no longer be true. EXPECT_TRUE(testStatistics("assigned-nas", -1, other_subnetid));
ObservationPtr stat = StatsMgr::instance().getObservation(name); EXPECT_TRUE(testStatistics("reclaimed-leases", 1));
ASSERT_TRUE(stat); EXPECT_TRUE(testStatistics("reclaimed-leases", 0, subnet_->getID()));
EXPECT_EQ(100, stat->getInteger().first); EXPECT_TRUE(testStatistics("reclaimed-leases", 1, other_subnetid));
} }
// Checks if the lease lifetime is extended when the client sends the // Checks if the lease lifetime is extended when the client sends the
@@ -776,18 +779,15 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolRequestNoHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// By default we pretend our subnet has 100 addresses // Assigned count should be zero.
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"); EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
StatsMgr::instance().setValue(name, static_cast<int64_t>(100));
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
// We should have bumped the address counter // Assigned count should have been incremented by one.
ObservationPtr stat = StatsMgr::instance().getObservation(name); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
ASSERT_TRUE(stat);
EXPECT_EQ(101, stat->getInteger().first);
} }
// Checks that a client gets the address reserved (in-pool case) // Checks that a client gets the address reserved (in-pool case)
@@ -807,12 +807,18 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolSolicitValidHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), true); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), true);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
// Assigned count should not have been incremented.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// Checks that a client gets the address reserved (in-pool case) // Checks that a client gets the address reserved (in-pool case)
@@ -832,12 +838,18 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolRequestValidHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
// Assigned count should have been incremented.
EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
} }
// Checks that a client gets the address reserved (in-pool case) // Checks that a client gets the address reserved (in-pool case)
@@ -857,12 +869,18 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolSolicitMatchingHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), true); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), true);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
// Assigned count should not have been incremented.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// Checks that a client gets the address reserved (in-pool case) // Checks that a client gets the address reserved (in-pool case)
@@ -882,12 +900,18 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolRequestMatchingHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText());
// Assigned count should have been incremented.
EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
} }
// Checks that a client gets the address reserved (out-of-pool case) // Checks that a client gets the address reserved (out-of-pool case)
@@ -907,10 +931,16 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolSolicitNoHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), true, false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), true, false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
EXPECT_EQ("2001:db8::abcd", lease->addr_.toText()); EXPECT_EQ("2001:db8::abcd", lease->addr_.toText());
// Assigned count should not have been incremented.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// Checks that a client gets the address reserved (out-of-pool case) // Checks that a client gets the address reserved (out-of-pool case)
@@ -930,18 +960,15 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolRequestNoHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// By default we pretend our subnet has 100 addresses // Assigned count should be zero.
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"); EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
StatsMgr::instance().setValue(name, static_cast<int64_t>(100));
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), false, false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), false, false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
EXPECT_EQ("2001:db8::abcd", lease->addr_.toText()); EXPECT_EQ("2001:db8::abcd", lease->addr_.toText());
// We should not have bumped the address counter // We should not have bumped the address counter
ObservationPtr stat = StatsMgr::instance().getObservation(name); EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
ASSERT_TRUE(stat);
EXPECT_EQ(100, stat->getInteger().first);
} }
// Checks that a client gets the address reserved (in-pool case) // Checks that a client gets the address reserved (in-pool case)
@@ -961,12 +988,18 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolSolicitValidHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), true, false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), true, false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8::abcd", lease->addr_.toText()); EXPECT_EQ("2001:db8::abcd", lease->addr_.toText());
// We should not have bumped the address counter
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// Checks that a client gets the address reserved (out-of-pool case) // Checks that a client gets the address reserved (out-of-pool case)
@@ -986,12 +1019,18 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolRequestValidHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), false, false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::10"), false, false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8::abcd", lease->addr_.toText()); EXPECT_EQ("2001:db8::abcd", lease->addr_.toText());
// We should not have bumped the address counter
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// Checks that a client gets the address reserved (out-of-pool case) // Checks that a client gets the address reserved (out-of-pool case)
@@ -1011,12 +1050,18 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolSolicitMatchingHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), true, false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), true, false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8::abcd", lease->addr_.toText()); EXPECT_EQ("2001:db8::abcd", lease->addr_.toText());
// We should not have bumped the address counter
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// Checks that a client gets the address reserved (out-of-pool case) // Checks that a client gets the address reserved (out-of-pool case)
@@ -1036,12 +1081,18 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolRequestMatchingHint) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Let's pretend the client sends hint 2001:db8:1::10. // Let's pretend the client sends hint 2001:db8:1::10.
Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), false, false); Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::1c"), false, false);
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
// The hint should be ignored and the reserved address should be assigned // The hint should be ignored and the reserved address should be assigned
EXPECT_EQ("2001:db8::abcd", lease->addr_.toText()); EXPECT_EQ("2001:db8::abcd", lease->addr_.toText());
// We should not have bumped the address counter
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
} }
// In the following situation: // In the following situation:
@@ -1054,15 +1105,15 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolRequestMatchingHint) {
TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) { TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Client gets an address // Client gets an address
Lease6Ptr lease1 = simpleAlloc6Test(pool_, IOAddress("::"), false); Lease6Ptr lease1 = simpleAlloc6Test(pool_, IOAddress("::"), false);
ASSERT_TRUE(lease1); ASSERT_TRUE(lease1);
// We should have bumped the address counter // We should have bumped the address counter
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
ObservationPtr stat = StatsMgr::instance().getObservation(name);
ASSERT_TRUE(stat);
EXPECT_EQ(101, stat->getInteger().first);
// Just check that if the client requests again, it will get the same // Just check that if the client requests again, it will get the same
// address. // address.
@@ -1071,7 +1122,7 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) {
detailCompareLease(lease1, lease2); detailCompareLease(lease1, lease2);
// We should not have bumped the address counter again // We should not have bumped the address counter again
EXPECT_EQ(101, stat->getInteger().first); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
// Now admin creates a reservation for this client. This is in-pool // Now admin creates a reservation for this client. This is in-pool
// reservation, as the pool is 2001:db8:1::10 - 2001:db8:1::20. // reservation, as the pool is 2001:db8:1::10 - 2001:db8:1::20.
@@ -1101,9 +1152,9 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) {
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease(lease3, from_mgr); detailCompareLease(lease3, from_mgr);
// Lastly check to see that the address counter is still 101 we should have // Lastly check to see that the address counter is still 1, we should have
// have decremented it on the implied release and incremented it on the reserved // have decremented it on the implied release and incremented it on the reserved
EXPECT_EQ(101, stat->getInteger().first); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
} }
// In the following situation: // In the following situation:
// - client X is assigned an address A // - client X is assigned an address A
@@ -1114,15 +1165,15 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) {
TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedOther) { TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedOther) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Assigned count should be zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
// Client gets an address // Client gets an address
Lease6Ptr lease1 = simpleAlloc6Test(pool_, IOAddress("::"), false); Lease6Ptr lease1 = simpleAlloc6Test(pool_, IOAddress("::"), false);
ASSERT_TRUE(lease1); ASSERT_TRUE(lease1);
// We should have bumped the address counter // We should have bumped the address counter
string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
ObservationPtr stat = StatsMgr::instance().getObservation(name);
ASSERT_TRUE(stat);
EXPECT_EQ(101, stat->getInteger().first);
// Just check that if the client requests again, it will get the same // Just check that if the client requests again, it will get the same
// address. // address.
@@ -1131,7 +1182,7 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedOther) {
detailCompareLease(lease1, lease2); detailCompareLease(lease1, lease2);
// We should not have bumped the address counter again // We should not have bumped the address counter again
EXPECT_EQ(101, stat->getInteger().first); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
// Now admin creates a reservation for this client. Let's use the // Now admin creates a reservation for this client. Let's use the
// address client X just received. Let's generate a host, but don't add it // address client X just received. Let's generate a host, but don't add it
@@ -1143,8 +1194,7 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedOther) {
host->setIdentifier(&other_duid[0], other_duid.size(), Host::IDENT_DUID); host->setIdentifier(&other_duid[0], other_duid.size(), Host::IDENT_DUID);
// Ok, now add it to the HostMgr // Ok, now add it to the HostMgr
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host); addHost(host);
CfgMgr::instance().commit();
// Just check that this time the client will get a different lease. // Just check that this time the client will get a different lease.
Lease6Ptr lease3 = simpleAlloc6Test(pool_, lease1->addr_, false); Lease6Ptr lease3 = simpleAlloc6Test(pool_, lease1->addr_, false);
@@ -1167,9 +1217,9 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedOther) {
// Now check that the lease in LeaseMgr has the same parameters // Now check that the lease in LeaseMgr has the same parameters
detailCompareLease(lease3, from_mgr); detailCompareLease(lease3, from_mgr);
// Lastly check to see that the address counter is still 101 we should have // Lastly check to see that the address counter is still 1 we should have
// have decremented it on the implied release and incremented it on the reserved // have decremented it on the implied release and incremented it on the reserved
EXPECT_EQ(101, stat->getInteger().first); EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
} }
// Checks that a reserved address for client A is not assigned when // Checks that a reserved address for client A is not assigned when
@@ -1267,11 +1317,17 @@ TEST_F(AllocEngine6Test, allocateLeasesInvalidData) {
TEST_F(AllocEngine6Test, addressRenewal) { TEST_F(AllocEngine6Test, addressRenewal) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100);
// Assigned count should zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
Lease6Collection leases; Lease6Collection leases;
leases = allocateTest(engine, pool_, IOAddress("::"), false, true); leases = allocateTest(engine, pool_, IOAddress("::"), false, true);
ASSERT_EQ(1, leases.size()); ASSERT_EQ(1, leases.size());
// Assigned count should be one.
EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
// This is what the client will send in his renew message. // This is what the client will send in his renew message.
AllocEngine::HintContainer hints; AllocEngine::HintContainer hints;
hints.push_back(make_pair(leases[0]->addr_, 128)); hints.push_back(make_pair(leases[0]->addr_, 128));
@@ -1287,6 +1343,9 @@ TEST_F(AllocEngine6Test, addressRenewal) {
EXPECT_EQ(leases[0]->type_, renewed[0]->type_); EXPECT_EQ(leases[0]->type_, renewed[0]->type_);
EXPECT_EQ(leases[0]->preferred_lft_, renewed[0]->preferred_lft_); EXPECT_EQ(leases[0]->preferred_lft_, renewed[0]->preferred_lft_);
EXPECT_EQ(leases[0]->valid_lft_, renewed[0]->valid_lft_); EXPECT_EQ(leases[0]->valid_lft_, renewed[0]->valid_lft_);
// Assigned count should still be one.
EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
} }
// Checks whether an address can be renewed (in-pool reservation) // Checks whether an address can be renewed (in-pool reservation)
@@ -1297,12 +1356,18 @@ TEST_F(AllocEngine6Test, reservedAddressRenewal) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100); AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100);
// Assigned count should zero.
EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
Lease6Collection leases; Lease6Collection leases;
leases = allocateTest(engine, pool_, IOAddress("::"), false, true); leases = allocateTest(engine, pool_, IOAddress("::"), false, true);
ASSERT_EQ(1, leases.size()); ASSERT_EQ(1, leases.size());
ASSERT_EQ("2001:db8:1::1c", leases[0]->addr_.toText()); ASSERT_EQ("2001:db8:1::1c", leases[0]->addr_.toText());
// Assigned count should be one.
EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
// This is what the client will send in his renew message. // This is what the client will send in his renew message.
AllocEngine::HintContainer hints; AllocEngine::HintContainer hints;
hints.push_back(make_pair(leases[0]->addr_, 128)); hints.push_back(make_pair(leases[0]->addr_, 128));
@@ -1310,6 +1375,9 @@ TEST_F(AllocEngine6Test, reservedAddressRenewal) {
Lease6Collection renewed = renewTest(engine, pool_, hints, true); Lease6Collection renewed = renewTest(engine, pool_, hints, true);
ASSERT_EQ(1, renewed.size()); ASSERT_EQ(1, renewed.size());
ASSERT_EQ("2001:db8:1::1c", leases[0]->addr_.toText()); ASSERT_EQ("2001:db8:1::1c", leases[0]->addr_.toText());
// Assigned count should still be one.
EXPECT_TRUE(testStatistics("assigned-nas", 1, subnet_->getID()));
} }
// Checks whether a single host can have more than one reservation. // Checks whether a single host can have more than one reservation.
@@ -1775,30 +1843,17 @@ TEST_F(AllocEngine6Test, solicitReuseDeclinedLease6Stats) {
// is expired. // is expired.
Lease6Ptr declined = generateDeclinedLease(addr_txt, 100, -10); Lease6Ptr declined = generateDeclinedLease(addr_txt, 100, -10);
// Let's fix some global stats...
StatsMgr& stats_mgr = StatsMgr::instance();
stats_mgr.setValue("declined-addresses", static_cast<int64_t>(1000));
stats_mgr.setValue("reclaimed-declined-addresses", static_cast<int64_t>(1000));
// ...and subnet specific stats as well.
string stat1 = StatsMgr::generateName("subnet", subnet_->getID(),
"declined-addresses");
string stat2 = StatsMgr::generateName("subnet", subnet_->getID(),
"reclaimed-declined-addresses");
stats_mgr.setValue(stat1, static_cast<int64_t>(1000));
stats_mgr.setValue(stat2, static_cast<int64_t>(1000));
// Ask for any address. There's only one address in the pool, so it doesn't // Ask for any address. There's only one address in the pool, so it doesn't
// matter much. // matter much.
Lease6Ptr assigned; Lease6Ptr assigned;
testReuseLease6(engine, declined, "::", true, SHOULD_PASS, assigned); testReuseLease6(engine, declined, "::", true, SHOULD_PASS, assigned);
// Check that the stats were not modified // Check that the stats were not modified
testStatistics("declined-addresses", 1000); EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
testStatistics("reclaimed-declined-addresses", 1000); EXPECT_TRUE(testStatistics("declined-addresses", 0));
EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 0));
testStatistics(stat1, 1000); EXPECT_TRUE(testStatistics("declined-addresses", 0, subnet_->getID()));
testStatistics(stat2, 1000); EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 0, subnet_->getID()));
} }
// This test checks if statistics are not updated when expired declined lease // This test checks if statistics are not updated when expired declined lease
@@ -1819,30 +1874,18 @@ TEST_F(AllocEngine6Test, requestReuseDeclinedLease6Stats) {
// is expired. // is expired.
Lease6Ptr declined = generateDeclinedLease(addr_txt, 100, -10); Lease6Ptr declined = generateDeclinedLease(addr_txt, 100, -10);
// Let's fix some global stats...
StatsMgr& stats_mgr = StatsMgr::instance();
stats_mgr.setValue("declined-addresses", static_cast<int64_t>(1000));
stats_mgr.setValue("reclaimed-declined-addresses", static_cast<int64_t>(1000));
// ...and subnet specific stats as well.
string stat1 = StatsMgr::generateName("subnet", subnet_->getID(),
"declined-addresses");
string stat2 = StatsMgr::generateName("subnet", subnet_->getID(),
"reclaimed-declined-addresses");
stats_mgr.setValue(stat1, static_cast<int64_t>(1000));
stats_mgr.setValue(stat2, static_cast<int64_t>(1000));
// Ask for any address. There's only one address in the pool, so it doesn't // Ask for any address. There's only one address in the pool, so it doesn't
// matter much. // matter much.
Lease6Ptr assigned; Lease6Ptr assigned;
testReuseLease6(engine, declined, "::", false, SHOULD_PASS, assigned); testReuseLease6(engine, declined, "::", false, SHOULD_PASS, assigned);
// Check that the stats were not modified // Check that the stats were modified as expected.
testStatistics("declined-addresses", 999); EXPECT_TRUE(testStatistics("assigned-nas", 0, subnet_->getID()));
testStatistics("reclaimed-declined-addresses", 1001); EXPECT_TRUE(testStatistics("declined-addresses", -1));
EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 1));
EXPECT_TRUE(testStatistics("declined-addresses", -1, subnet_->getID()));
EXPECT_TRUE(testStatistics("reclaimed-declined-addresses", 1, subnet_->getID()));
testStatistics(stat1, 999);
testStatistics(stat2, 1001);
} }
}; // namespace test }; // namespace test

View File

@@ -1437,13 +1437,12 @@ ExpirationAllocEngine6Test::testReclaimReusedLeases(const uint16_t msg_type,
// initially reclaimed. // initially reclaimed.
if (use_reclaimed || (msg_type == DHCPV6_SOLICIT)) { if (use_reclaimed || (msg_type == DHCPV6_SOLICIT)) {
EXPECT_TRUE(testStatistics("reclaimed-leases", 0)); EXPECT_TRUE(testStatistics("reclaimed-leases", 0));
} else { } else {
EXPECT_TRUE(testStatistics("reclaimed-leases", TEST_LEASES_NUM)); EXPECT_TRUE(testStatistics("reclaimed-leases", TEST_LEASES_NUM));
EXPECT_TRUE(testStatistics("assigned-nas", TEST_LEASES_NUM, subnet->getID()));
// Leases should have been updated in the lease database and their // Leases should have been updated in the lease database and their
// state should not be 'expired-reclaimed' anymore. // state should not be 'expired-reclaimed' anymore.
EXPECT_TRUE(testLeases(&leaseNotReclaimed, &allLeaseIndexes)); EXPECT_TRUE(testLeases(&leaseNotReclaimed, &allLeaseIndexes));
} }
} }
@@ -2099,6 +2098,7 @@ ExpirationAllocEngine4Test::testReclaimReusedLeases(const uint8_t msg_type,
} else if (msg_type == DHCPREQUEST) { } else if (msg_type == DHCPREQUEST) {
// Re-allocation of expired leases should result in reclamations. // Re-allocation of expired leases should result in reclamations.
EXPECT_TRUE(testStatistics("reclaimed-leases", TEST_LEASES_NUM)); EXPECT_TRUE(testStatistics("reclaimed-leases", TEST_LEASES_NUM));
EXPECT_TRUE(testStatistics("assigned-addresses", TEST_LEASES_NUM, subnet->getID()));
// Leases should have been updated in the lease database and their // Leases should have been updated in the lease database and their
// state should not be 'expired-reclaimed' anymore. // state should not be 'expired-reclaimed' anymore.
EXPECT_TRUE(testLeases(&leaseNotReclaimed, &allLeaseIndexes)); EXPECT_TRUE(testLeases(&leaseNotReclaimed, &allLeaseIndexes));

View File

@@ -39,20 +39,23 @@ namespace isc {
namespace dhcp { namespace dhcp {
namespace test { namespace test {
bool testStatistics(const std::string& stat_name, const int64_t exp_value) { bool testStatistics(const std::string& stat_name, const int64_t exp_value,
const SubnetID subnet_id) {
try { try {
ObservationPtr observation = StatsMgr::instance().getObservation(stat_name); std::string name = (!subnet_id ? stat_name :
StatsMgr::generateName("subnet", subnet_id, stat_name));
ObservationPtr observation = StatsMgr::instance().getObservation(name);
if (observation) { if (observation) {
if (observation->getInteger().first != exp_value) { if (observation->getInteger().first != exp_value) {
ADD_FAILURE() ADD_FAILURE()
<< "value of the observed statistics '" << "value of the observed statistics '"
<< stat_name << "' " << "(" << name << "' " << "("
<< observation->getInteger().first << ") " << observation->getInteger().first << ") "
<< "doesn't match expected value (" << exp_value << ")"; << "doesn't match expected value (" << exp_value << ")";
} }
return (observation->getInteger().first == exp_value); return (observation->getInteger().first == exp_value);
} else { } else {
ADD_FAILURE() << "Expected statistic " << stat_name ADD_FAILURE() << "Expected statistic " << name
<< " not found."; << " not found.";
} }
@@ -136,7 +139,6 @@ AllocEngine6Test::AllocEngine6Test() {
// hardcoded anywhere. // hardcoded anywhere.
const uint8_t mac[] = { 0, 1, 22, 33, 44, 55}; const uint8_t mac[] = { 0, 1, 22, 33, 44, 55};
hwaddr_ = HWAddrPtr(new HWAddr(mac, sizeof(mac), HTYPE_FDDI)); hwaddr_ = HWAddrPtr(new HWAddr(mac, sizeof(mac), HTYPE_FDDI));
// Initialize a subnet and short address pool. // Initialize a subnet and short address pool.
initSubnet(IOAddress("2001:db8:1::"), initSubnet(IOAddress("2001:db8:1::"),
IOAddress("2001:db8:1::10"), IOAddress("2001:db8:1::10"),
@@ -145,7 +147,6 @@ AllocEngine6Test::AllocEngine6Test() {
64, 80); 64, 80);
initFqdn("", false, false); initFqdn("", false, false);
} }
void void
@@ -170,14 +171,6 @@ AllocEngine6Test::initSubnet(const asiolink::IOAddress& subnet,
cfg_mgr.getStagingCfg()->getCfgSubnets6()->add(subnet_); cfg_mgr.getStagingCfg()->getCfgSubnets6()->add(subnet_);
cfg_mgr.commit(); cfg_mgr.commit();
// By default we pretend our subnet has 100 addresses and prefixes allocated.
StatsMgr::instance().setValue(
StatsMgr::generateName("subnet", subnet_->getID(), "assigned-nas"),
static_cast<int64_t>(100));
StatsMgr::instance().setValue(
StatsMgr::generateName("subnet", subnet_->getID(), "assigned-pds"),
static_cast<int64_t>(100));
} }
void void

View File

@@ -1,7 +1,6 @@
// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef LIBDHCPSRV_ALLOC_ENGINE_UTILS_H #ifndef LIBDHCPSRV_ALLOC_ENGINE_UTILS_H
@@ -39,10 +38,12 @@ namespace test {
/// ///
/// @param stat_name Statistic name. /// @param stat_name Statistic name.
/// @param exp_value Expected value. /// @param exp_value Expected value.
/// @param subnet_id subnet_id of the desired subnet, if not zero
/// ///
/// @return true if the statistic manager holds a particular value, /// @return true if the statistic manager holds a particular value,
/// false otherwise. /// false otherwise.
bool testStatistics(const std::string& stat_name, const int64_t exp_value); bool testStatistics(const std::string& stat_name, const int64_t exp_value,
const SubnetID subnet_id = 0);
/// @brief Allocation engine with some internal methods exposed /// @brief Allocation engine with some internal methods exposed
class NakedAllocEngine : public AllocEngine { class NakedAllocEngine : public AllocEngine {
@@ -360,12 +361,26 @@ public:
host->addReservation(resv); host->addReservation(resv);
if (add_to_host_mgr) { if (add_to_host_mgr) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host); addHost(host);
CfgMgr::instance().commit();
} }
return (host); return (host);
} }
/// @brief Add a host reservation to the curent configuration
///
/// Adds the given host reservation to the current configuration by
/// casting it to non-const. We do it this way rather than adding it to
/// staging and then committing as that wipes out the current configuration
/// such as subnets.
///
/// @param host host reservation to add
void
addHost(HostPtr& host) {
SrvConfigPtr cfg = boost::const_pointer_cast<SrvConfig>(CfgMgr::instance().getCurrentCfg());
cfg->getCfgHosts()->add(host);
}
/// @brief Utility function that creates a host reservation (hwaddr) /// @brief Utility function that creates a host reservation (hwaddr)
/// ///
/// @param add_to_host_mgr true if the reservation should be added /// @param add_to_host_mgr true if the reservation should be added

View File

@@ -2404,7 +2404,7 @@ void
GenericLeaseMgrTest::checkLeaseStats(const StatValMapList& expectedStats) { GenericLeaseMgrTest::checkLeaseStats(const StatValMapList& expectedStats) {
// Global accumulators // Global accumulators
int64_t declined_addresses = 0; int64_t declined_addresses = 0;
int64_t declined_reclaimed_addresses = 0; int64_t reclaimed_declined_addresses = 0;
// Iterate over all stats for each subnet // Iterate over all stats for each subnet
for (int subnet_idx = 0; subnet_idx < expectedStats.size(); ++subnet_idx) { for (int subnet_idx = 0; subnet_idx < expectedStats.size(); ++subnet_idx) {
@@ -2417,15 +2417,15 @@ GenericLeaseMgrTest::checkLeaseStats(const StatValMapList& expectedStats) {
// Add the value to globals as needed. // Add the value to globals as needed.
if (expectedStat.first == "declined-addresses") { if (expectedStat.first == "declined-addresses") {
declined_addresses += expectedStat.second; declined_addresses += expectedStat.second;
} else if (expectedStat.first == "declined-reclaimed-addresses") { } else if (expectedStat.first == "reclaimed-declined-addresses") {
declined_reclaimed_addresses += expectedStat.second; reclaimed_declined_addresses += expectedStat.second;
} }
} }
} }
// Verify the globals. // Verify the globals.
checkStat("declined-addresses", declined_addresses); checkStat("declined-addresses", declined_addresses);
checkStat("declined-reclaimed-addresses", declined_reclaimed_addresses); checkStat("reclaimed-declined-addresses", reclaimed_declined_addresses);
} }
void void
@@ -2501,7 +2501,8 @@ GenericLeaseMgrTest::testRecountLeaseStats4() {
expectedStats[i]["total-addresses"] = 256; expectedStats[i]["total-addresses"] = 256;
expectedStats[i]["assigned-addresses"] = 0; expectedStats[i]["assigned-addresses"] = 0;
expectedStats[i]["declined-addresses"] = 0; expectedStats[i]["declined-addresses"] = 0;
expectedStats[i]["declined-reclaimed-addresses"] = 0; expectedStats[i]["reclaimed-declined-addresses"] = 0;
expectedStats[i]["reclaimed-leases"] = 0;
} }
// Make sure stats are as expected. // Make sure stats are as expected.
@@ -2604,8 +2605,9 @@ GenericLeaseMgrTest::testRecountLeaseStats6() {
for (int i = 0; i < num_subnets; ++i) { for (int i = 0; i < num_subnets; ++i) {
expectedStats[i]["assigned-nas"] = 0; expectedStats[i]["assigned-nas"] = 0;
expectedStats[i]["declined-addresses"] = 0; expectedStats[i]["declined-addresses"] = 0;
expectedStats[i]["declined-reclaimed-addresses"] = 0; expectedStats[i]["reclaimed-declined-addresses"] = 0;
expectedStats[i]["assigned-pds"] = 0; expectedStats[i]["assigned-pds"] = 0;
expectedStats[i]["reclaimed-leases"] = 0;
} }
// Make sure stats are as expected. // Make sure stats are as expected.