]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3799] Add v6 subnet statistics
authorShawn Routhier <sar@isc.org>
Wed, 17 Jun 2015 08:50:41 +0000 (01:50 -0700)
committerShawn Routhier <sar@isc.org>
Wed, 17 Jun 2015 08:50:41 +0000 (01:50 -0700)
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.

doc/guide/dhcp6-srv.xml
src/bin/dhcp6/Makefile.am
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/tests/Makefile.am
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/cfg_subnets6.cc
src/lib/dhcpsrv/cfg_subnets6.h
src/lib/dhcpsrv/srv_config.cc
src/lib/dhcpsrv/srv_config.h
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc

index c0472a69ff65d54b924d2c7eab6b09346b3ad19e..466a2ccbf9c71f0cfc8d227362eb28f9bb582ace 100644 (file)
@@ -2579,6 +2579,94 @@ should include options from the isc option space:
     </para>
     </section>
 
+    <section id="dhcp6-stats">
+      <title>Statistics in DHCPv6 server</title>
+      <note>
+        <para>This section describes DHCPv6-specific statistics. For a general
+        overview and usage of statistics, see <xref linkend="stats" />.</para>
+      </note>
+
+      <para>
+        The DHCPv6 server supports the following statistics:
+      </para>
+        <table frame="all" id="dhcp4-statistics">
+          <title>DHCPv6 Statistics</title>
+          <tgroup cols='3'>
+          <colspec colname='statistic' align='center'/>
+          <colspec colname='type' align='center'/>
+          <colspec colname='description' align='left'/>
+          <thead>
+            <row>
+              <entry>Statistic</entry>
+              <entry>Data Type</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+
+            <row>
+            <entry>subnet[id].total-NAs</entry>
+            <entry>integer</entry>
+            <entry>
+            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 <emphasis>id</emphasis> is the
+            subnet-id of a given subnet. This statistic is exposed for each subnet
+           separately. This statistic is reset during reconfiguration event.
+            </entry>
+            </row>
+
+            <row>
+            <entry>subnet[id].assigned-NAs</entry>
+            <entry>integer</entry>
+            <entry>
+            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 <emphasis>id</emphasis> is the subnet-id of a given
+            subnet. This statistic is exposed for each subnet separately. This
+            statistic is reset during reconfiguration event.
+            </entry>
+            </row>
+
+            <row>
+            <entry>subnet[id].total-PDs</entry>
+            <entry>integer</entry>
+            <entry>
+            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 <emphasis>id</emphasis> is the
+            subnet-id of a given subnet. This statistic is exposed for each subnet
+           separately. This statistic is reset during reconfiguration event.
+            </entry>
+            </row>
+
+            <row>
+            <entry>subnet[id].assigned-NAs</entry>
+            <entry>integer</entry>
+            <entry>
+            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 <emphasis>id</emphasis> is the subnet-id of a given
+            subnet. This statistic is exposed for each subnet separately. This
+            statistic is reset during reconfiguration event.
+            </entry>
+            </row>
+
+        </tbody>
+        </tgroup>
+        </table>
+    </section>
+
     <section id="dhcp6-std">
       <title>Supported DHCPv6 Standards</title>
       <para>The following standards are currently
index a899787db76646846f01ad099f4a47d38619b080..af5b558f24854dc45e54747ac6c5f87dfe7819d7 100644 (file)
@@ -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
 
index 24bdfce8004f53183211dd61467b9c192652e2f9..7a853b91cff765bcc7ca82e6c2b9365b5d55da7f 100644 (file)
@@ -45,6 +45,7 @@
 #include <hooks/callout_handle.h>
 #include <hooks/hooks_log.h>
 #include <hooks/hooks_manager.h>
+#include <stats/stats_mgr.h>
 
 #include <util/encode/hex.h>
 #include <util/io_utilities.h>
@@ -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<int64_t>(-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<int64_t>(-1));
     }
 
     return (ia_rsp);
index ed16e00a602763c8e7d709e42755587e87986e9f..396c298e31a861a592593fe9e7420c642b5d642e 100644 (file)
@@ -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
index f52a67992411b0bccb59415df833beb7ed5bbc26..d441a2c4ba8fa0de6bb530b859d58bd7500af212 100644 (file)
@@ -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<int64_t>(-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<int64_t>(-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<int64_t>(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<int64_t>(-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<int64_t>(1));
 
index 8031f3f653b7037ff4c4fa40fe656210e8a83278..cc9c439263995c1d4a58b00b03526a72f2138b6c 100644 (file)
@@ -16,6 +16,7 @@
 #include <dhcpsrv/cfg_subnets6.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/subnet_id.h>
+#include <stats/stats_mgr.h>
 
 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<int64_t>((*subnet)->getPoolCapacity(Lease::TYPE_NA)));
+
+        StatsMgr::instance().setValue(
+            StatsMgr::generateName("subnet", (*subnet)->getID(), "total-PDs"),
+            static_cast<int64_t>((*subnet)->getPoolCapacity(Lease::TYPE_PD)));
+    }
+}
+
 } // end of namespace isc::dhcp
 } // end of namespace isc
index 6f631849f8e136ca03b74c0a2db83a83bc10fdfa..67db975ba7f9e8d1eaba3f09b059e7d85768f140 100644 (file)
@@ -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.
index 577deca404c59f185834163cab0e9a4cf55a4a37..823c6708b4d4d4c1d99e72269c6e0d9dbccbacde 100644 (file)
@@ -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();
 }
 
 }
index d13c48add0c1ce149e170b4c9061e37d822a9665..770371b00b7e1181815028a7a9538461cca76256 100644 (file)
@@ -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:
index f6ca2c485cc2cdaff0bb4e917c8440131441d731..c0c8fb64e228d254ee74fde7db2510e3f39eee64 100644 (file)
 #include <dhcp/pkt6.h>
 #include <dhcpsrv/tests/alloc_engine_utils.h>
 #include <dhcpsrv/tests/test_utils.h>
+#include <stats/stats_mgr.h>
 
 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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(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<AllocEngine> 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<int64_t>(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
index 38328a27af6ab0aa1b51a0bac2155327e44303d4..c43ea6cf7123fe1c566d16ddb3766495e5450700 100644 (file)
@@ -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<int64_t>(256));
+    stats_mgr.setValue("subnet[123].assigned-NAs", static_cast<int64_t>(150));
+
+    stats_mgr.addValue("subnet[123].total-PDs", static_cast<int64_t>(256));
+    stats_mgr.setValue("subnet[123].assigned-PDs", static_cast<int64_t>(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<int64_t>(256));
+    stats_mgr.setValue("subnet[123].assigned-NAs", static_cast<int64_t>(150));
+
+    stats_mgr.addValue("subnet[123].total-PDs", static_cast<int64_t>(256));
+    stats_mgr.setValue("subnet[123].assigned-PDs", static_cast<int64_t>(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