From: Shawn Routhier Date: Wed, 17 Jun 2015 08:50:41 +0000 (-0700) Subject: [3799] Add v6 subnet statistics X-Git-Tag: trac3910_base~1^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f8a84bd134a0048c973bd33fba207af38c88037;p=thirdparty%2Fkea.git [3799] Add v6 subnet statistics Using the v4 changes as a guide (3798) add statistics for subnets for v6. The four stats are total addresses and addresses used for both NA and PD. --- diff --git a/doc/guide/dhcp6-srv.xml b/doc/guide/dhcp6-srv.xml index c0472a69ff..466a2ccbf9 100644 --- a/doc/guide/dhcp6-srv.xml +++ b/doc/guide/dhcp6-srv.xml @@ -2579,6 +2579,94 @@ should include options from the isc option space: +
+ Statistics in DHCPv6 server + + This section describes DHCPv6-specific statistics. For a general + overview and usage of statistics, see . + + + + The DHCPv6 server supports the following statistics: + + + DHCPv6 Statistics + + + + + + + Statistic + Data Type + Description + + + + + + subnet[id].total-NAs + integer + + This statistic shows the total number of NA addresses available for the + DHCPv6 management. In other words, this is the sum of all addresses in + all configured pools. This statistic changes only during configuration + changes. Note it does not take into account any addresses that may be + reserved due to host reservation. The id is the + subnet-id of a given subnet. This statistic is exposed for each subnet + separately. This statistic is reset during reconfiguration event. + + + + + subnet[id].assigned-NAs + integer + + This statistic shows the number of assigned NA addresses in a given subnet. + This statistic increases every time a new lease is allocated (as a result + of receiving a REQUEST message) and is decreased every time a lease is + released (a RELEASE message is received). When lease expiration + is implemented (planned for Kea 1.0), it will also decrease when a lease + is expired. The id is the subnet-id of a given + subnet. This statistic is exposed for each subnet separately. This + statistic is reset during reconfiguration event. + + + + + subnet[id].total-PDs + integer + + This statistic shows the total number of PD prefixes available for the + DHCPv6 management. In other words, this is the sum of all prefixes in + all configured pools. This statistic changes only during configuration + changes. Note it does not take into account any prefixes that may be + reserved due to host reservation. The id is the + subnet-id of a given subnet. This statistic is exposed for each subnet + separately. This statistic is reset during reconfiguration event. + + + + + subnet[id].assigned-NAs + integer + + This statistic shows the number of assigned PD prefixes in a given subnet. + This statistic increases every time a new lease is allocated (as a result + of receiving a REQUEST message) and is decreased every time a lease is + released (a RELEASE message is received). When lease expiration + is implemented (planned for Kea 1.0), it will also decrease when a lease + is expired. The id is the subnet-id of a given + subnet. This statistic is exposed for each subnet separately. This + statistic is reset during reconfiguration event. + + + + + +
+
+
Supported DHCPv6 Standards The following standards are currently diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am index a899787db7..af5b558f24 100644 --- a/src/bin/dhcp6/Makefile.am +++ b/src/bin/dhcp6/Makefile.am @@ -78,6 +78,7 @@ kea_dhcp6_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la kea_dhcp6_LDADD += $(top_builddir)/src/lib/log/libkea-log.la kea_dhcp6_LDADD += $(top_builddir)/src/lib/util/libkea-util.la kea_dhcp6_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la +kea_dhcp6_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la kea_dhcp6_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la kea_dhcp6_LDADD += $(top_builddir)/src/bin/cfgrpt/libcfgrpt.la diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 24bdfce800..7a853b91cf 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,7 @@ using namespace isc::dhcp_ddns; using namespace isc::hooks; using namespace isc::log; using namespace isc::util; +using namespace isc::stats; using namespace std; namespace { @@ -2210,6 +2212,11 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query, ia_rsp->addOption(createStatusCode(*query, *ia_rsp, STATUS_Success, "Lease released. Thank you, please come again.")); + // Need to decrease statistic for assigned addresses. + StatsMgr::instance().addValue( + StatsMgr::generateName("subnet", lease->subnet_id_, "assigned-NAs"), + static_cast(-1)); + // Check if a lease has flags indicating that the FQDN update has // been performed. If so, create NameChangeRequest which removes // the entries. @@ -2360,6 +2367,11 @@ Dhcpv6Srv::releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query, ia_rsp->addOption(createStatusCode(*query, *ia_rsp, STATUS_Success, "Lease released. Thank you, please come again.")); + + // Need to decrease statistic for assigned prefixes. + StatsMgr::instance().addValue( + StatsMgr::generateName("subnet", lease->subnet_id_, "assigned-PDs"), + static_cast(-1)); } return (ia_rsp); diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am index ed16e00a60..396c298e31 100644 --- a/src/bin/dhcp6/tests/Makefile.am +++ b/src/bin/dhcp6/tests/Makefile.am @@ -105,6 +105,7 @@ dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la +dhcp6_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/util/io/libkea-util-io.la diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index f52a679924..d441a2c4ba 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -812,6 +812,13 @@ AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx, // Remove this lease from LeaseMgr LeaseMgrFactory::instance().deleteLease((*candidate)->addr_); + // Need to decrease statistic for assigned addresses. + StatsMgr::instance().addValue( + StatsMgr::generateName("subnet", ctx.subnet_->getID(), + ctx.type_ == Lease::TYPE_NA ? "assigned-NAs" : + "assigned-PDs"), + static_cast(-1)); + // In principle, we could trigger a hook here, but we will do this // only if we get serious complaints from actual users. We want the // conflict resolution procedure to really work and user libraries @@ -868,6 +875,13 @@ AllocEngine::removeNonreservedLeases6(ClientContext6& ctx, // Remove this lease from LeaseMgr LeaseMgrFactory::instance().deleteLease((*lease)->addr_); + // Need to decrease statistic for assigned addresses. + StatsMgr::instance().addValue( + StatsMgr::generateName("subnet", ctx.subnet_->getID(), + ctx.type_ == Lease::TYPE_NA ? "assigned-NAs" : + "assigned-PDs"), + static_cast(-1)); + /// @todo: Probably trigger a hook here // Add this to the list of removed leases. @@ -1024,6 +1038,12 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx, bool status = LeaseMgrFactory::instance().addLease(lease); if (status) { + // The lease insertion succeeded, let's bump up the statistic. + StatsMgr::instance().addValue( + StatsMgr::generateName("subnet", ctx.subnet_->getID(), + ctx.type_ == Lease::TYPE_NA ? "assigned-NAs" : + "assigned-PDs"), + static_cast(1)); return (lease); } else { @@ -1140,6 +1160,11 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) { // Remove this lease from LeaseMgr LeaseMgrFactory::instance().deleteLease(lease->addr_); + // Need to decrease statistic for assigned addresses. + StatsMgr::instance().addValue( + StatsMgr::generateName("subnet", ctx.subnet_->getID(), "assigned-NAs"), + static_cast(-1)); + // Add it to the removed leases list. ctx.old_leases_.push_back(lease); @@ -1779,7 +1804,7 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr) { if (status) { // The lease insertion succeeded, let's bump up the statistic. - isc::stats::StatsMgr::instance().addValue( + StatsMgr::instance().addValue( StatsMgr::generateName("subnet", ctx.subnet_->getID(), "assigned-addresses"), static_cast(1)); diff --git a/src/lib/dhcpsrv/cfg_subnets6.cc b/src/lib/dhcpsrv/cfg_subnets6.cc index 8031f3f653..cc9c439263 100644 --- a/src/lib/dhcpsrv/cfg_subnets6.cc +++ b/src/lib/dhcpsrv/cfg_subnets6.cc @@ -16,6 +16,7 @@ #include #include #include +#include using namespace isc::asiolink; @@ -179,5 +180,52 @@ CfgSubnets6::isDuplicate(const Subnet6& subnet) const { return (false); } +void +CfgSubnets6::removeStatistics() { + using namespace isc::stats; + + // For each v6 subnet currently configured, remove the statistic. + /// @todo: May move this to CfgSubnets6 class if there will be more + /// statistics here. + for (Subnet6Collection::const_iterator subnet6 = subnets_.begin(); + subnet6 != subnets_.end(); ++subnet6) { + + StatsMgr::instance().del(StatsMgr::generateName("subnet", + (*subnet6)->getID(), + "total-NAs")); + + StatsMgr::instance().del(StatsMgr::generateName("subnet", + (*subnet6)->getID(), + "assigned-NAs")); + + StatsMgr::instance().del(StatsMgr::generateName("subnet", + (*subnet6)->getID(), + "total-PDs")); + + StatsMgr::instance().del(StatsMgr::generateName("subnet", + (*subnet6)->getID(), + "assigned-PDs")); + } +} + +void +CfgSubnets6::updateStatistics() { + using namespace isc::stats; + + /// @todo: May move this to CfgSubnets6 class if there will be more + /// statistics here. + for (Subnet6Collection::const_iterator subnet = subnets_.begin(); + subnet != subnets_.end(); ++subnet) { + + StatsMgr::instance().setValue( + StatsMgr::generateName("subnet", (*subnet)->getID(), "total-NAs"), + static_cast((*subnet)->getPoolCapacity(Lease::TYPE_NA))); + + StatsMgr::instance().setValue( + StatsMgr::generateName("subnet", (*subnet)->getID(), "total-PDs"), + static_cast((*subnet)->getPoolCapacity(Lease::TYPE_PD))); + } +} + } // end of namespace isc::dhcp } // end of namespace isc diff --git a/src/lib/dhcpsrv/cfg_subnets6.h b/src/lib/dhcpsrv/cfg_subnets6.h index 6f631849f8..67db975ba7 100644 --- a/src/lib/dhcpsrv/cfg_subnets6.h +++ b/src/lib/dhcpsrv/cfg_subnets6.h @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -132,6 +132,23 @@ public: const ClientClasses& client_classes = ClientClasses(), const bool is_relay_address = false) const; + /// @brief Updates statistics. + /// + /// This method updates statistics that are affected by the newly committed + /// configuration. In particular, it updates the number of available addresses + /// and prefixes in each subnet. Other statistics may be added in the future. In + /// general, these are statistics that are dependant only on configuration, so + /// they are not expected to change until the next reconfiguration event. + void updateStatistics(); + + /// @brief Removes statistics. + /// + /// During commitment of a new configuration, we need to get rid of the old + /// statistics for the old configuration. In particular, we need to remove + /// anything related to subnets, as there may be fewer subnets in the new + /// configuration and also subnet-ids may change. + void removeStatistics(); + private: /// @brief Selects a subnet using the interface name. diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index 577deca404..823c6708b4 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -148,16 +148,19 @@ SrvConfig::equals(const SrvConfig& other) const { void SrvConfig::removeStatistics() { - // For now, this method only removes statistics for v4 subnets, but in the - // near future, we'll also get statistics for v6 subnets. + // Removes statistics for v4 and v6 subnets getCfgSubnets4()->removeStatistics(); + + getCfgSubnets6()->removeStatistics(); } void SrvConfig::updateStatistics() { - // For now, this method only updates statistics for v4 subnets, but in the - // near future, we'll also get statistics for v6 subnets. + + // Updates statistics for v4 and v6 subnets getCfgSubnets4()->updateStatistics(); + + getCfgSubnets6()->updateStatistics(); } } diff --git a/src/lib/dhcpsrv/srv_config.h b/src/lib/dhcpsrv/srv_config.h index d13c48add0..770371b00b 100644 --- a/src/lib/dhcpsrv/srv_config.h +++ b/src/lib/dhcpsrv/srv_config.h @@ -352,13 +352,15 @@ public: /// @brief Updates statistics. /// /// This method calls appropriate methods in child objects that update - /// related statistics. See @ref CfgSubnets4::updateStatistics for details. + /// related statistics. See @ref CfgSubnets4::updateStatistics and + /// @ref CfgSubnets6::updateStatistics for details. void updateStatistics(); /// @brief Removes statistics. /// /// This method calls appropriate methods in child objects that remove - /// related statistics. See @ref CfgSubnets4::removeStatistics for details. + /// related statistics. See @ref CfgSubnets4::removeStatistics and + /// @ref CfgSubnets6::removeStatistics for details. void removeStatistics(); private: diff --git a/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc index f6ca2c485c..c0c8fb64e2 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc @@ -17,10 +17,12 @@ #include #include #include +#include using namespace std; using namespace isc::hooks; using namespace isc::asiolink; +using namespace isc::stats; namespace isc { namespace dhcp { @@ -52,23 +54,61 @@ TEST_F(AllocEngine6Test, constructor) { // This test checks if the simple allocation (REQUEST) can succeed TEST_F(AllocEngine6Test, simpleAlloc6) { + + // Pretend our pool has allocated 100 addresses + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-NAs"); + StatsMgr::instance().addValue(name, static_cast(100)); + simpleAlloc6Test(pool_, IOAddress("::"), false); + + // We should have bumped the address counter by 1 + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + EXPECT_EQ(101, stat->getInteger().first); } // This test checks if the simple PD allocation (REQUEST) can succeed TEST_F(AllocEngine6Test, pdSimpleAlloc6) { + + // Pretend our pool has allocated 100 prefixes + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-PDs"); + StatsMgr::instance().addValue(name, static_cast(100)); + simpleAlloc6Test(pd_pool_, IOAddress("::"), false); + + // We should have bumped the address counter by 1 + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + EXPECT_EQ(101, stat->getInteger().first); } // This test checks if the fake allocation (for SOLICIT) can succeed TEST_F(AllocEngine6Test, fakeAlloc6) { + // Pretend our pool has allocated 100 prefixes + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-NAs"); + StatsMgr::instance().addValue(name, static_cast(100)); + simpleAlloc6Test(pool_, IOAddress("::"), true); + + // We should not have bumped the address counter + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + EXPECT_EQ(100, stat->getInteger().first); } // This test checks if the fake PD allocation (for SOLICIT) can succeed TEST_F(AllocEngine6Test, pdFakeAlloc6) { + // Pretend our pool has allocated 100 prefixes + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-PDs"); + StatsMgr::instance().addValue(name, static_cast(100)); + simpleAlloc6Test(pd_pool_, IOAddress("::"), true); + + // We should not have bumped the address counter + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + EXPECT_EQ(100, stat->getInteger().first); }; // This test checks if the allocation with a hint that is valid (in range, @@ -568,7 +608,7 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) { // - Client sends SOLICIT without any hints. // - Client is allocated a reserved address. // -// Note that DHCPv6 client can, but don't have to send any hints in its +// Note that a DHCPv6 client can, but doesn't have to send any hints in its // Solicit message. TEST_F(AllocEngine6Test, reservedAddressInPoolSolicitNoHint) { // Create reservation for the client. This is in-pool reservation, @@ -599,9 +639,18 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolRequestNoHint) { AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); + // Pretend our pool has allocated 100 addresses + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-NAs"); + StatsMgr::instance().addValue(name, static_cast(100)); + Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("::"), false); ASSERT_TRUE(lease); EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); + + // We should have bumped the address counter + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + EXPECT_EQ(101, stat->getInteger().first); } // Checks that a client gets the address reserved (in-pool case) @@ -857,16 +906,28 @@ TEST_F(AllocEngine6Test, reservedAddressOutOfPoolRequestMatchingHint) { TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) { AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false); + // Pretend our pool has allocated 100 addresses + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-NAs"); + StatsMgr::instance().addValue(name, static_cast(100)); + // Client gets an address Lease6Ptr lease1 = simpleAlloc6Test(pool_, IOAddress("::"), false); ASSERT_TRUE(lease1); + // We should have bumped the address counter + 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 // address. Lease6Ptr lease2 = simpleAlloc6Test(pool_, lease1->addr_, false); ASSERT_TRUE(lease2); detailCompareLease(lease1, lease2); + // We should not have bumped the address counter again + EXPECT_EQ(101, stat->getInteger().first); + // 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. createHost6(true, IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::1c"), 128); @@ -894,6 +955,11 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) { // Now check that the lease in LeaseMgr has the same parameters detailCompareLease(lease3, from_mgr); + + // Lastly check to see that the address counter is still 101 we should have + // have decremented it on the implied release and incremented it on the reserved + EXPECT_EQ(101, stat->getInteger().first); + } // In the following situation: @@ -1363,6 +1429,31 @@ TEST_F(AllocEngine6Test, reservedAddressByMacInPoolRequestValidHint) { EXPECT_EQ("2001:db8:1::1c", lease->addr_.toText()); } + +// This test checks that NULL values are handled properly +TEST_F(AllocEngine6Test, allocateAddress6Stats) { + boost::scoped_ptr engine; + ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100))); + ASSERT_TRUE(engine); + + // Verify our pool hasn't allocated any addresses + string name = StatsMgr::generateName("subnet", subnet_->getID(), "assigned-NAs"); + StatsMgr::instance().addValue(name, static_cast(100)); + + Lease6Ptr lease; + AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"), + Lease::TYPE_NA, false, false, "", false); + ctx1.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234)); + EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx1))); + ASSERT_TRUE(lease); + + // We should have bumped the address counter by 1 + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + EXPECT_EQ(101, stat->getInteger().first); +} + + }; // namespace test }; // namespace dhcp }; // namespace isc diff --git a/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc b/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc index 38328a27af..c43ea6cf71 100644 --- a/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc @@ -578,12 +578,12 @@ TEST_F(CfgMgrTest, verbosity) { // This test verifies that once the configuration is committed, statistics // are updated appropriately. -TEST_F(CfgMgrTest, commitStats) { +TEST_F(CfgMgrTest, commitStats4) { CfgMgr& cfg_mgr = CfgMgr::instance(); StatsMgr& stats_mgr = StatsMgr::instance(); // Let's prepare the "old" configuration: a subnet with id 123 - // and pretent there ware addresses assigned, so statistics are non-zero. + // and pretend there ware addresses assigned, so statistics are non-zero. Subnet4Ptr subnet1(new Subnet4(IOAddress("192.1.2.0"), 24, 1, 2, 3, 123)); CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4(); subnets->add(subnet1); @@ -617,12 +617,12 @@ TEST_F(CfgMgrTest, commitStats) { // This test verifies that once the configuration is cleared, the statistics // are removed. -TEST_F(CfgMgrTest, clearStats) { +TEST_F(CfgMgrTest, clearStats4) { CfgMgr& cfg_mgr = CfgMgr::instance(); StatsMgr& stats_mgr = StatsMgr::instance(); // Let's prepare the "old" configuration: a subnet with id 123 - // and pretent there ware addresses assigned, so statistics are non-zero. + // and pretend there ware addresses assigned, so statistics are non-zero. Subnet4Ptr subnet1(new Subnet4(IOAddress("192.1.2.0"), 24, 1, 2, 3, 123)); CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4(); subnets->add(subnet1); @@ -642,6 +642,93 @@ TEST_F(CfgMgrTest, clearStats) { EXPECT_FALSE(stats_mgr.getObservation("subnet[123].assigned-addresses")); } +// This test verifies that once the configuration is committed, statistics +// are updated appropriately. +TEST_F(CfgMgrTest, commitStats6) { + CfgMgr& cfg_mgr = CfgMgr::instance(); + StatsMgr& stats_mgr = StatsMgr::instance(); + + // Let's prepare the "old" configuration: a subnet with id 123 + // and pretend there ware addresses assigned, so statistics are non-zero. + Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4, 123)); + CfgSubnets6Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets6(); + subnets->add(subnet1); + cfg_mgr.commit(); + stats_mgr.addValue("subnet[123].total-NAs", static_cast(256)); + stats_mgr.setValue("subnet[123].assigned-NAs", static_cast(150)); + + stats_mgr.addValue("subnet[123].total-PDs", static_cast(256)); + stats_mgr.setValue("subnet[123].assigned-PDs", static_cast(150)); + + // Now, let's change the configuration to something new. + + // There's a subnet 2001:db8:2::/48 with ID=42 + Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4, 42)); + + // Let's make pools with 128 addresses and 65536 prefixes available. + PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:2::"), 121)); // 128 addrs + PoolPtr pool2(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:3::"), 96, 112)); // 65536 prefixes + subnet2->addPool(pool1); + subnet2->addPool(pool2); + + subnets = cfg_mgr.getStagingCfg()->getCfgSubnets6(); + subnets->add(subnet2); + + // Let's commit it + cfg_mgr.commit(); + + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].total-NAs")); + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].assigned-NAs")); + + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].total-PDs")); + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].assigned-PDs")); + + ObservationPtr total_addrs; + EXPECT_NO_THROW(total_addrs = stats_mgr.getObservation("subnet[42].total-NAs")); + ASSERT_TRUE(total_addrs); + EXPECT_EQ(128, total_addrs->getInteger().first); + + EXPECT_NO_THROW(total_addrs = stats_mgr.getObservation("subnet[42].total-PDs")); + ASSERT_TRUE(total_addrs); + EXPECT_EQ(65536, total_addrs->getInteger().first); +} + +// This test verifies that once the configuration is cleared, the v6 statistics +// are removed. +TEST_F(CfgMgrTest, clearStats6) { + CfgMgr& cfg_mgr = CfgMgr::instance(); + StatsMgr& stats_mgr = StatsMgr::instance(); + + // Let's prepare the "old" configuration: a subnet with id 123 + // and pretend there ware addresses assigned, so statistics are non-zero. + Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4, 123)); + CfgSubnets6Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets6(); + subnets->add(subnet1); + cfg_mgr.commit(); + stats_mgr.addValue("subnet[123].total-NAs", static_cast(256)); + stats_mgr.setValue("subnet[123].assigned-NAs", static_cast(150)); + + stats_mgr.addValue("subnet[123].total-PDs", static_cast(256)); + stats_mgr.setValue("subnet[123].assigned-PDs", static_cast(150)); + + // The stats should be there. + EXPECT_TRUE(stats_mgr.getObservation("subnet[123].total-NAs")); + EXPECT_TRUE(stats_mgr.getObservation("subnet[123].assigned-NAs")); + + EXPECT_TRUE(stats_mgr.getObservation("subnet[123].total-PDs")); + EXPECT_TRUE(stats_mgr.getObservation("subnet[123].assigned-PDs")); + + // Let's remove all configurations + cfg_mgr.clear(); + + // The stats should not be there anymore. + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].total-NAs")); + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].assigned-NAs")); + + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].total-PDs")); + EXPECT_FALSE(stats_mgr.getObservation("subnet[123].assigned-PDs")); +} + /// @todo Add unit-tests for testing: /// - addActiveIface() with invalid interface name /// - addActiveIface() with the same interface twice