Browse Source

[3798] Changes after review:

 - packet names updated in User's Guide
 - StatsMgr now uses int64_t, not uint64_t
 - StatsMgr::generateName() added
 - DISCOVER => DHCPDISCOVER
Tomek Mrugalski 10 years ago
parent
commit
0e3de871a8

+ 7 - 6
doc/guide/dhcp4-srv.xml

@@ -1809,11 +1809,11 @@ temporarily override a list of interface names and listen on all interfaces.
       The rules for determining the FQDN option are as follows:
       The rules for determining the FQDN option are as follows:
       <orderedlist>
       <orderedlist>
       <listitem><para>
       <listitem><para>
-      If configured to do, so ignore the REQUEST contents and generate a
+      If configured to do, so ignore the DHCPREQUEST contents and generate a
       FQDN using a configurable prefix and suffix.
       FQDN using a configurable prefix and suffix.
       </para></listitem>
       </para></listitem>
       <listitem><para>
       <listitem><para>
-      If the REQUEST contains the client FQDN option, the candidate
+      If the DHCPREQUEST contains the client FQDN option, the candidate
       name is taken from there, otherwise it is taken from the Host Name option.
       name is taken from there, otherwise it is taken from the Host Name option.
       The candidate name may then be modified:
       The candidate name may then be modified:
       <orderedlist>
       <orderedlist>
@@ -2606,8 +2606,8 @@ appropiately -->
         <simpara><emphasis>subnet[id].assigned-addresses</emphasis> (integer) -
         <simpara><emphasis>subnet[id].assigned-addresses</emphasis> (integer) -
         this statistic shows the number of assigned addresses in a given subnet.
         this statistic shows the number of assigned addresses in a given subnet.
         This statistic increases every time a new lease is allocated (as a result
         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 proper lease expiration
+        of receiving a DHCPREQUEST message) and is decreased every time a lease is
+        released (a DHCPRELEASE message is received). When lease expiration
         is implemented (planned for Kea 1.0), it will also decrease when a lease
         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
         is expired. The <emphasis>id</emphasis> is the subnet-id of a given
         subnet. This statistic is exposed for each subnet separately. This
         subnet. This statistic is exposed for each subnet separately. This
@@ -2625,8 +2625,9 @@ appropiately -->
           <listitem>
           <listitem>
             <simpara><emphasis>Dynamic Host Configuration Protocol</emphasis>,
             <simpara><emphasis>Dynamic Host Configuration Protocol</emphasis>,
             <ulink url="http://tools.ietf.org/html/rfc2131">RFC 2131</ulink>:
             <ulink url="http://tools.ietf.org/html/rfc2131">RFC 2131</ulink>:
-            Supported messages are DISCOVER (1), OFFER (2),
-            REQUEST (3), RELEASE (7), INFORM (8), ACK (5), and NAK(6).</simpara>
+            Supported messages are DHCPDISCOVER (1), DHCPOFFER (2),
+            DHCPREQUEST (3), DHCPRELEASE (7), DHCPINFORM (8), DHCPACK (5), and
+            DHCPNAK(6).</simpara>
           </listitem>
           </listitem>
           <listitem>
           <listitem>
             <simpara><emphasis>DHCP Options and BOOTP Vendor Extensions</emphasis>,
             <simpara><emphasis>DHCP Options and BOOTP Vendor Extensions</emphasis>,

+ 4 - 4
src/bin/dhcp4/dhcp4_srv.cc

@@ -56,6 +56,7 @@ using namespace isc::dhcp;
 using namespace isc::dhcp_ddns;
 using namespace isc::dhcp_ddns;
 using namespace isc::hooks;
 using namespace isc::hooks;
 using namespace isc::log;
 using namespace isc::log;
+using namespace isc::stats;
 using namespace std;
 using namespace std;
 
 
 /// Structure that holds registered hook indexes
 /// Structure that holds registered hook indexes
@@ -1747,10 +1748,9 @@ Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
                     .arg(lease->addr_.toText());
                     .arg(lease->addr_.toText());
 
 
                 // Need to decrease statistic for assigned addresses.
                 // Need to decrease statistic for assigned addresses.
-                std::stringstream name;
-                name << "subnet[" << lease->subnet_id_ << "].assigned-addresses";
-                isc::stats::StatsMgr::instance().addValue(name.str(),
-                                                          static_cast<uint64_t>(-1));
+                StatsMgr::instance().addValue(
+                    StatsMgr::generateName("subnet", lease->subnet_id_, "assigned-addresses"),
+                    static_cast<int64_t>(-1));
 
 
                 if (CfgMgr::instance().ddnsEnabled()) {
                 if (CfgMgr::instance().ddnsEnabled()) {
                     // Remove existing DNS entries for the lease, if any.
                     // Remove existing DNS entries for the lease, if any.

+ 7 - 8
src/lib/dhcpsrv/alloc_engine.cc

@@ -34,6 +34,7 @@
 using namespace isc::asiolink;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace isc::dhcp;
 using namespace isc::hooks;
 using namespace isc::hooks;
+using namespace isc::stats;
 
 
 namespace {
 namespace {
 
 
@@ -1549,10 +1550,9 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
         lease_mgr.deleteLease(client_lease->addr_);
         lease_mgr.deleteLease(client_lease->addr_);
 
 
         // Need to decrease statistic for assigned addresses.
         // Need to decrease statistic for assigned addresses.
-        std::stringstream name;
-        name << "subnet[" << ctx.subnet_->getID() << "].assigned-addresses";
-        isc::stats::StatsMgr::instance().addValue(name.str(),
-                                                  static_cast<uint64_t>(-1));
+        StatsMgr::instance().addValue(
+            StatsMgr::generateName("subnet", ctx.subnet_->getID(), "assigned-addresses"),
+            static_cast<int64_t>(-1));
     }
     }
 
 
     // Return the allocated lease or NULL pointer if allocation was
     // Return the allocated lease or NULL pointer if allocation was
@@ -1631,10 +1631,9 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr) {
         if (status) {
         if (status) {
 
 
             // The lease insertion succeeded, let's bump up the statistic.
             // The lease insertion succeeded, let's bump up the statistic.
-            std::stringstream name;
-            name << "subnet[" << ctx.subnet_->getID() << "].assigned-addresses";
-            isc::stats::StatsMgr::instance().addValue(name.str(),
-                                                      static_cast<uint64_t>(1));
+            isc::stats::StatsMgr::instance().addValue(
+                StatsMgr::generateName("subnet", ctx.subnet_->getID(), "assigned-addresses"),
+                static_cast<int64_t>(1));
 
 
             return (lease);
             return (lease);
         } else {
         } else {

+ 1 - 1
src/lib/dhcpsrv/cfgmgr.cc

@@ -228,7 +228,7 @@ CfgMgr::updateStatistics() {
         name << "subnet[" << (*subnet)->getID() << "].total-addresses";
         name << "subnet[" << (*subnet)->getID() << "].total-addresses";
 
 
         StatsMgr::instance().setValue(name.str(),
         StatsMgr::instance().setValue(name.str(),
-                                      (*subnet)->getPoolCapacity(Lease::TYPE_V4));
+            static_cast<int64_t>((*subnet)->getPoolCapacity(Lease::TYPE_V4)));
     }
     }
 }
 }
 
 

+ 7 - 6
src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc

@@ -80,7 +80,7 @@ TEST_F(AllocEngine4Test, simpleAlloc4) {
     detailCompareLease(lease, from_mgr);
     detailCompareLease(lease, from_mgr);
 }
 }
 
 
-// This test checks if the fake allocation (for DISCOVER) can succeed
+// This test checks if the fake allocation (for DHCPDISCOVER) can succeed
 TEST_F(AllocEngine4Test, fakeAlloc4) {
 TEST_F(AllocEngine4Test, fakeAlloc4) {
     boost::scoped_ptr<AllocEngine> engine;
     boost::scoped_ptr<AllocEngine> engine;
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
@@ -422,7 +422,8 @@ TEST_F(AllocEngine4Test, outOfAddresses4) {
     EXPECT_FALSE(ctx.old_lease_);
     EXPECT_FALSE(ctx.old_lease_);
 }
 }
 
 
-// This test checks if an expired lease can be reused in DISCOVER (fake allocation)
+// This test checks if an expired lease can be reused in DHCPDISCOVER (fake
+// allocation)
 TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
 TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
     boost::scoped_ptr<AllocEngine> engine;
     boost::scoped_ptr<AllocEngine> engine;
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
     ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
@@ -1519,7 +1520,7 @@ TEST_F(AllocEngine4Test, simpleAlloc4Stats) {
     // Let's pretend 100 addresses were allocated already
     // Let's pretend 100 addresses were allocated already
     stringstream name;
     stringstream name;
     name << "subnet[" << subnet_->getID() << "].assigned-addresses";
     name << "subnet[" << subnet_->getID() << "].assigned-addresses";
-    StatsMgr::instance().addValue(name.str(), static_cast<uint64_t>(100));
+    StatsMgr::instance().addValue(name.str(), static_cast<int64_t>(100));
 
 
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
     // The new lease has been allocated, so the old lease should not exist.
     // The new lease has been allocated, so the old lease should not exist.
@@ -1534,7 +1535,7 @@ TEST_F(AllocEngine4Test, simpleAlloc4Stats) {
     EXPECT_EQ(101, stat->getInteger().first);
     EXPECT_EQ(101, stat->getInteger().first);
 }
 }
 
 
-// This test checks if the fake allocation (for DISCOVER) can succeed
+// This test checks if the fake allocation (for DHCPDISCOVER) can succeed
 // and that it doesn't increase allocated-addresses statistic.
 // and that it doesn't increase allocated-addresses statistic.
 TEST_F(AllocEngine4Test, fakeAlloc4Stat) {
 TEST_F(AllocEngine4Test, fakeAlloc4Stat) {
     boost::scoped_ptr<AllocEngine> engine;
     boost::scoped_ptr<AllocEngine> engine;
@@ -1549,7 +1550,7 @@ TEST_F(AllocEngine4Test, fakeAlloc4Stat) {
     // Let's pretend 100 addresses were allocated already
     // Let's pretend 100 addresses were allocated already
     stringstream name;
     stringstream name;
     name << "subnet[" << subnet_->getID() << "].assigned-addresses";
     name << "subnet[" << subnet_->getID() << "].assigned-addresses";
-    StatsMgr::instance().addValue(name.str(), static_cast<uint64_t>(100));
+    StatsMgr::instance().addValue(name.str(), static_cast<int64_t>(100));
 
 
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
 
 
@@ -1591,7 +1592,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseStat) {
     // Let's pretend 100 addresses were allocated already
     // Let's pretend 100 addresses were allocated already
     stringstream name;
     stringstream name;
     name << "subnet[" << subnet_->getID() << "].assigned-addresses";
     name << "subnet[" << subnet_->getID() << "].assigned-addresses";
-    StatsMgr::instance().addValue(name.str(), static_cast<uint64_t>(100));
+    StatsMgr::instance().addValue(name.str(), static_cast<int64_t>(100));
 
 
     // Request allocation of the reserved address.
     // Request allocation of the reserved address.
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,

+ 2 - 2
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc

@@ -588,8 +588,8 @@ TEST_F(CfgMgrTest, commitStats) {
     CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4();
     CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4();
     subnets->add(subnet1);
     subnets->add(subnet1);
     cfg_mgr.commit();
     cfg_mgr.commit();
-    stats_mgr.addValue("subnet[123].total-addresses", static_cast<uint64_t>(256));
-    stats_mgr.setValue("subnet[123].assigned-addresses", static_cast<uint64_t>(150));
+    stats_mgr.addValue("subnet[123].total-addresses", static_cast<int64_t>(256));
+    stats_mgr.setValue("subnet[123].assigned-addresses", static_cast<int64_t>(150));
 
 
     // Now, let's change the configuration to something new.
     // Now, let's change the configuration to something new.
 
 

+ 4 - 4
src/lib/stats/observation.cc

@@ -26,7 +26,7 @@ using namespace boost::posix_time;
 namespace isc {
 namespace isc {
 namespace stats {
 namespace stats {
 
 
-Observation::Observation(const std::string& name, const uint64_t value)
+Observation::Observation(const std::string& name, const int64_t value)
     :name_(name), type_(STAT_INTEGER) {
     :name_(name), type_(STAT_INTEGER) {
     setValue(value);
     setValue(value);
 }
 }
@@ -46,7 +46,7 @@ Observation::Observation(const std::string& name, const std::string& value)
     setValue(value);
     setValue(value);
 }
 }
 
 
-void Observation::addValue(const uint64_t value) {
+void Observation::addValue(const int64_t value) {
     IntegerSample current = getInteger();
     IntegerSample current = getInteger();
     setValue(current.first + value);
     setValue(current.first + value);
 }
 }
@@ -66,7 +66,7 @@ void Observation::addValue(const std::string& value) {
     setValue(current.first + value);
     setValue(current.first + value);
 }
 }
 
 
-void Observation::setValue(const uint64_t value) {
+void Observation::setValue(const int64_t value) {
     setValueInternal(value, integer_samples_, STAT_INTEGER);
     setValueInternal(value, integer_samples_, STAT_INTEGER);
 }
 }
 
 
@@ -208,7 +208,7 @@ Observation::getJSON() const {
 void Observation::reset() {
 void Observation::reset() {
     switch(type_) {
     switch(type_) {
     case STAT_INTEGER: {
     case STAT_INTEGER: {
-        setValue(static_cast<uint64_t>(0));
+        setValue(static_cast<int64_t>(0));
         return;
         return;
     }
     }
     case STAT_FLOAT: {
     case STAT_FLOAT: {

+ 7 - 7
src/lib/stats/observation.h

@@ -46,8 +46,8 @@ typedef boost::posix_time::time_duration StatsDuration;
 ///
 ///
 /// @{
 /// @{
 
 
-/// @brief Integer (implemented as unsigned 64-bit integer)
-typedef std::pair<uint64_t, boost::posix_time::ptime> IntegerSample;
+/// @brief Integer (implemented as signed 64-bit integer)
+typedef std::pair<int64_t, boost::posix_time::ptime> IntegerSample;
 
 
 /// @brief Float (implemented as double precision)
 /// @brief Float (implemented as double precision)
 typedef std::pair<double, boost::posix_time::ptime> FloatSample;
 typedef std::pair<double, boost::posix_time::ptime> FloatSample;
@@ -62,7 +62,7 @@ typedef std::pair<std::string, boost::posix_time::ptime> StringSample;
 
 
 /// @brief Represents a single observable characteristic (a 'statistic')
 /// @brief Represents a single observable characteristic (a 'statistic')
 ///
 ///
-/// Currently it supports one of four types: integer (implemented as unsigned 64
+/// Currently it supports one of four types: integer (implemented as signed 64
 /// bit integer), float (implemented as double), time duration (implemented with
 /// bit integer), float (implemented as double), time duration (implemented with
 /// millisecond precision) and string. Absolute (setValue) and
 /// millisecond precision) and string. Absolute (setValue) and
 /// incremental (addValue) modes are supported. Statistic type is determined
 /// incremental (addValue) modes are supported. Statistic type is determined
@@ -85,7 +85,7 @@ class Observation {
     /// an easy to understand names were chosen (integer instead of uint64).
     /// an easy to understand names were chosen (integer instead of uint64).
     /// To avoid confusion, we will support only one type of integer and only
     /// To avoid confusion, we will support only one type of integer and only
     /// one type of floating points. Initially, these are represented by
     /// one type of floating points. Initially, these are represented by
-    /// uint64_t and double. If convincing use cases appear to change them
+    /// int64_t and double. If convincing use cases appear to change them
     /// to something else, we may change the underlying type.
     /// to something else, we may change the underlying type.
     enum Type {
     enum Type {
         STAT_INTEGER, ///< this statistic is unsinged 64-bit integer value
         STAT_INTEGER, ///< this statistic is unsinged 64-bit integer value
@@ -98,7 +98,7 @@ class Observation {
     ///
     ///
     /// @param name observation name
     /// @param name observation name
     /// @param value integer value observed.
     /// @param value integer value observed.
-    Observation(const std::string& name, const uint64_t value);
+    Observation(const std::string& name, const int64_t value);
 
 
     /// @brief Constructor for floating point observations
     /// @brief Constructor for floating point observations
     ///
     ///
@@ -122,7 +122,7 @@ class Observation {
     ///
     ///
     /// @param value integer value observed
     /// @param value integer value observed
     /// @throw InvalidStatType if statistic is not integer
     /// @throw InvalidStatType if statistic is not integer
-    void setValue(const uint64_t value);
+    void setValue(const int64_t value);
 
 
     /// @brief Records absolute floating point observation
     /// @brief Records absolute floating point observation
     ///
     ///
@@ -146,7 +146,7 @@ class Observation {
     ///
     ///
     /// @param value integer value observed
     /// @param value integer value observed
     /// @throw InvalidStatType if statistic is not integer
     /// @throw InvalidStatType if statistic is not integer
-    void addValue(const uint64_t value);
+    void addValue(const int64_t value);
 
 
     /// @brief Records incremental floating point observation
     /// @brief Records incremental floating point observation
     ///
     ///

+ 2 - 2
src/lib/stats/stats_mgr.cc

@@ -30,7 +30,7 @@ StatsMgr::StatsMgr()
 
 
 }
 }
 
 
-void StatsMgr::setValue(const std::string& name, const uint64_t value) {
+void StatsMgr::setValue(const std::string& name, const int64_t value) {
     setValueInternal(name, value);
     setValueInternal(name, value);
 }
 }
 
 
@@ -45,7 +45,7 @@ void StatsMgr::setValue(const std::string& name, const std::string& value) {
     setValueInternal(name, value);
     setValueInternal(name, value);
 }
 }
 
 
-void StatsMgr::addValue(const std::string& name, const uint64_t value) {
+void StatsMgr::addValue(const std::string& name, const int64_t value) {
     addValueInternal(name, value);
     addValueInternal(name, value);
 }
 }
 
 

+ 24 - 4
src/lib/stats/stats_mgr.h

@@ -22,6 +22,7 @@
 #include <map>
 #include <map>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
+#include <sstream>
 
 
 namespace isc {
 namespace isc {
 namespace stats {
 namespace stats {
@@ -65,7 +66,7 @@ class StatsMgr : public boost::noncopyable {
     /// @param name name of the observation
     /// @param name name of the observation
     /// @param value integer value observed
     /// @param value integer value observed
     /// @throw InvalidStatType if statistic is not integer
     /// @throw InvalidStatType if statistic is not integer
-    void setValue(const std::string& name, const uint64_t value);
+    void setValue(const std::string& name, const int64_t value);
 
 
     /// @brief Records absolute floating point observation.
     /// @brief Records absolute floating point observation.
     ///
     ///
@@ -93,7 +94,7 @@ class StatsMgr : public boost::noncopyable {
     /// @param name name of the observation
     /// @param name name of the observation
     /// @param value integer value observed
     /// @param value integer value observed
     /// @throw InvalidStatType if statistic is not integer
     /// @throw InvalidStatType if statistic is not integer
-    void addValue(const std::string& name, const uint64_t value);
+    void addValue(const std::string& name, const int64_t value);
 
 
     /// @brief Records incremental floating point observation.
     /// @brief Records incremental floating point observation.
     ///
     ///
@@ -197,6 +198,25 @@ class StatsMgr : public boost::noncopyable {
     /// @return Pointer to the Observation object
     /// @return Pointer to the Observation object
     ObservationPtr getObservation(const std::string& name) const;
     ObservationPtr getObservation(const std::string& name) const;
 
 
+    /// @brief Generates statistic name in a given context
+    ///
+    /// example:
+    /// generateName("subnet", 123, "received-packets") will return
+    /// subnet[123].received-packets.
+    ///
+    /// @tparam Type any type that can be used to index contexts
+    /// @param context name of the context (e.g. 'subnet')
+    /// @param index value used for indexing contexts (e.g. subnet_id)
+    /// @param stat_name name of the statistic
+    /// @return returns full statistic name in form context[index].stat_name
+    template<typename Type>
+    static std::string generateName(const std::string& context, Type index,
+                             const std::string& stat_name) {
+        std::stringstream name;
+        name << context << "[" << index << "]." << stat_name;
+        return (name.str());
+    }
+
  private:
  private:
 
 
     /// @brief Sets a given statistic to specified value (internal version).
     /// @brief Sets a given statistic to specified value (internal version).
@@ -205,7 +225,7 @@ class StatsMgr : public boost::noncopyable {
     /// specified by value. This internal method is used by public @ref setValue
     /// specified by value. This internal method is used by public @ref setValue
     /// methods.
     /// methods.
     ///
     ///
-    /// @tparam DataType one of uint64_t, double, StatsDuration or string
+    /// @tparam DataType one of int64_t, double, StatsDuration or string
     /// @param name name of the statistic
     /// @param name name of the statistic
     /// @param value specified statistic will be set to this value
     /// @param value specified statistic will be set to this value
     /// @throw InvalidStatType is statistic exists and has a different type.
     /// @throw InvalidStatType is statistic exists and has a different type.
@@ -226,7 +246,7 @@ class StatsMgr : public boost::noncopyable {
     /// by name to a value). This internal method is used by public @ref setValue
     /// by name to a value). This internal method is used by public @ref setValue
     /// methods.
     /// methods.
     ///
     ///
-    /// @tparam DataType one of uint64_t, double, StatsDuration or string
+    /// @tparam DataType one of int64_t, double, StatsDuration or string
     /// @param name name of the statistic
     /// @param name name of the statistic
     /// @param value specified statistic will be set to this value
     /// @param value specified statistic will be set to this value
     /// @throw InvalidStatType is statistic exists and has a different type.
     /// @throw InvalidStatType is statistic exists and has a different type.

+ 7 - 7
src/lib/stats/tests/observation_unittest.cc

@@ -42,7 +42,7 @@ public:
     /// @brief Constructor
     /// @brief Constructor
     /// Initializes four observations.
     /// Initializes four observations.
     ObservationTest()
     ObservationTest()
-        :a("alpha", static_cast<uint64_t>(1234)), // integer
+        :a("alpha", static_cast<int64_t>(1234)), // integer
          b("beta", 12.34), // float
          b("beta", 12.34), // float
          c("gamma", millisec::time_duration(1,2,3,4)), // duration
          c("gamma", millisec::time_duration(1,2,3,4)), // duration
          d("delta", "1234") { // string
          d("delta", "1234") { // string
@@ -92,7 +92,7 @@ TEST_F(ObservationTest, constructor) {
 // given types.
 // given types.
 TEST_F(ObservationTest, setValue) {
 TEST_F(ObservationTest, setValue) {
 
 
-    EXPECT_NO_THROW(a.setValue(static_cast<uint64_t>(5678)));
+    EXPECT_NO_THROW(a.setValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.setValue(56e+78));
     EXPECT_NO_THROW(b.setValue(56e+78));
     EXPECT_NO_THROW(c.setValue(millisec::time_duration(5,6,7,8)));
     EXPECT_NO_THROW(c.setValue(millisec::time_duration(5,6,7,8)));
     EXPECT_NO_THROW(d.setValue("fiveSixSevenEight"));
     EXPECT_NO_THROW(d.setValue("fiveSixSevenEight"));
@@ -110,15 +110,15 @@ TEST_F(ObservationTest, setValue) {
     EXPECT_THROW(a.setValue(millisec::time_duration(5,6,7,8)), InvalidStatType);
     EXPECT_THROW(a.setValue(millisec::time_duration(5,6,7,8)), InvalidStatType);
     EXPECT_THROW(a.setValue("fiveSixSevenEight"), InvalidStatType);
     EXPECT_THROW(a.setValue("fiveSixSevenEight"), InvalidStatType);
 
 
-    EXPECT_THROW(b.setValue(static_cast<uint64_t>(5678)), InvalidStatType);
+    EXPECT_THROW(b.setValue(static_cast<int64_t>(5678)), InvalidStatType);
     EXPECT_THROW(b.setValue(millisec::time_duration(5,6,7,8)), InvalidStatType);
     EXPECT_THROW(b.setValue(millisec::time_duration(5,6,7,8)), InvalidStatType);
     EXPECT_THROW(b.setValue("fiveSixSevenEight"), InvalidStatType);
     EXPECT_THROW(b.setValue("fiveSixSevenEight"), InvalidStatType);
 
 
-    EXPECT_THROW(c.setValue(static_cast<uint64_t>(5678)), InvalidStatType);
+    EXPECT_THROW(c.setValue(static_cast<int64_t>(5678)), InvalidStatType);
     EXPECT_THROW(c.setValue(56e+78), InvalidStatType);
     EXPECT_THROW(c.setValue(56e+78), InvalidStatType);
     EXPECT_THROW(c.setValue("fiveSixSevenEight"), InvalidStatType);
     EXPECT_THROW(c.setValue("fiveSixSevenEight"), InvalidStatType);
 
 
-    EXPECT_THROW(d.setValue(static_cast<uint64_t>(5678)), InvalidStatType);
+    EXPECT_THROW(d.setValue(static_cast<int64_t>(5678)), InvalidStatType);
     EXPECT_THROW(d.setValue(56e+78), InvalidStatType);
     EXPECT_THROW(d.setValue(56e+78), InvalidStatType);
     EXPECT_THROW(d.setValue(millisec::time_duration(5,6,7,8)), InvalidStatType);
     EXPECT_THROW(d.setValue(millisec::time_duration(5,6,7,8)), InvalidStatType);
 }
 }
@@ -130,7 +130,7 @@ TEST_F(ObservationTest, addValue) {
     // Note: all Observations were set to 1234,12.34 or similar in
     // Note: all Observations were set to 1234,12.34 or similar in
     // ObservationTest constructor.
     // ObservationTest constructor.
 
 
-    EXPECT_NO_THROW(a.addValue(static_cast<uint64_t>(5678)));
+    EXPECT_NO_THROW(a.addValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.addValue(56.78));
     EXPECT_NO_THROW(b.addValue(56.78));
     EXPECT_NO_THROW(c.addValue(millisec::time_duration(5,6,7,8)));
     EXPECT_NO_THROW(c.addValue(millisec::time_duration(5,6,7,8)));
     EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
     EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
@@ -167,7 +167,7 @@ TEST_F(ObservationTest, timers) {
 // See http://kea.isc.org/wiki/StatsDesign for details.
 // See http://kea.isc.org/wiki/StatsDesign for details.
 TEST_F(ObservationTest, integerToJSON) {
 TEST_F(ObservationTest, integerToJSON) {
 
 
-    a.setValue(static_cast<uint64_t>(1234));
+    a.setValue(static_cast<int64_t>(1234));
 
 
     std::string exp = "[ [ 1234, \""
     std::string exp = "[ [ 1234, \""
         + isc::util::ptimeToText(a.getInteger().second) + "\" ] ]";
         + isc::util::ptimeToText(a.getInteger().second) + "\" ] ]";

+ 26 - 10
src/lib/stats/tests/stats_mgr_unittest.cc

@@ -65,7 +65,7 @@ TEST_F(StatsMgrTest, basic) {
 // an integer statistic.
 // an integer statistic.
 TEST_F(StatsMgrTest, integerStat) {
 TEST_F(StatsMgrTest, integerStat) {
     EXPECT_NO_THROW(StatsMgr::instance().setValue("alpha",
     EXPECT_NO_THROW(StatsMgr::instance().setValue("alpha",
-                                                  static_cast<uint64_t>(1234)));
+                                                  static_cast<int64_t>(1234)));
 
 
     ObservationPtr alpha;
     ObservationPtr alpha;
     EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
     EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
@@ -140,13 +140,13 @@ TEST_F(StatsMgrTest, setLimits) {
 TEST_F(StatsMgrTest, getGetAll) {
 TEST_F(StatsMgrTest, getGetAll) {
 
 
     // Set a couple of statistics
     // Set a couple of statistics
-    StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+    StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("delta", "Lorem");
     StatsMgr::instance().setValue("delta", "Lorem");
 
 
     // Now add some values to them
     // Now add some values to them
-    StatsMgr::instance().addValue("alpha", static_cast<uint64_t>(5678));
+    StatsMgr::instance().addValue("alpha", static_cast<int64_t>(5678));
     StatsMgr::instance().addValue("beta", 56.78);
     StatsMgr::instance().addValue("beta", 56.78);
     StatsMgr::instance().addValue("gamma", time_duration(5,6,7,8));
     StatsMgr::instance().addValue("gamma", time_duration(5,6,7,8));
     StatsMgr::instance().addValue("delta", " ipsum");
     StatsMgr::instance().addValue("delta", " ipsum");
@@ -210,7 +210,7 @@ TEST_F(StatsMgrTest, getGetAll) {
 TEST_F(StatsMgrTest, reset) {
 TEST_F(StatsMgrTest, reset) {
 
 
     // Set a couple of statistics
     // Set a couple of statistics
-    StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+    StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
@@ -246,7 +246,7 @@ TEST_F(StatsMgrTest, reset) {
 TEST_F(StatsMgrTest, resetAll) {
 TEST_F(StatsMgrTest, resetAll) {
 
 
     // Set a couple of statistics
     // Set a couple of statistics
-    StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+    StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
@@ -269,7 +269,7 @@ TEST_F(StatsMgrTest, resetAll) {
 TEST_F(StatsMgrTest, removeAll) {
 TEST_F(StatsMgrTest, removeAll) {
 
 
     // Set a couple of statistics
     // Set a couple of statistics
-    StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+    StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("beta", 12.34);
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
@@ -352,12 +352,12 @@ TEST_F(StatsMgrTest, DISABLED_performanceMultipleAdd) {
     for (uint32_t i = 0; i < stats; ++i) {
     for (uint32_t i = 0; i < stats; ++i) {
         std::stringstream tmp;
         std::stringstream tmp;
         tmp << "statistic" << i;
         tmp << "statistic" << i;
-        StatsMgr::instance().setValue(tmp.str(), static_cast<uint64_t>(i));
+        StatsMgr::instance().setValue(tmp.str(), static_cast<int64_t>(i));
     }
     }
 
 
     ptime before = microsec_clock::local_time();
     ptime before = microsec_clock::local_time();
     for (uint32_t i = 0; i < cycles; ++i) {
     for (uint32_t i = 0; i < cycles; ++i) {
-        StatsMgr::instance().addValue("metric1", static_cast<uint64_t>(i));
+        StatsMgr::instance().addValue("metric1", static_cast<int64_t>(i));
     }
     }
     ptime after = microsec_clock::local_time();
     ptime after = microsec_clock::local_time();
 
 
@@ -382,12 +382,12 @@ TEST_F(StatsMgrTest, DISABLED_performanceMultipleSet) {
     for (uint32_t i = 0; i < stats; ++i) {
     for (uint32_t i = 0; i < stats; ++i) {
         std::stringstream tmp;
         std::stringstream tmp;
         tmp << "statistic" << i;
         tmp << "statistic" << i;
-        StatsMgr::instance().setValue(tmp.str(), static_cast<uint64_t>(i));
+        StatsMgr::instance().setValue(tmp.str(), static_cast<int64_t>(i));
     }
     }
 
 
     ptime before = microsec_clock::local_time();
     ptime before = microsec_clock::local_time();
     for (uint32_t i = 0; i < cycles; ++i) {
     for (uint32_t i = 0; i < cycles; ++i) {
-        StatsMgr::instance().setValue("metric1", static_cast<uint64_t>(i));
+        StatsMgr::instance().setValue("metric1", static_cast<int64_t>(i));
     }
     }
     ptime after = microsec_clock::local_time();
     ptime after = microsec_clock::local_time();
 
 
@@ -397,4 +397,20 @@ TEST_F(StatsMgrTest, DISABLED_performanceMultipleSet) {
               << " times took: " << isc::util::durationToText(dur) << std::endl;
               << " times took: " << isc::util::durationToText(dur) << std::endl;
 }
 }
 
 
+// Test checks whether statistics name can be generated using various
+// indexes.
+TEST_F(StatsMgrTest, generateName) {
+    // generateName is a templated method, so in principle anything printable
+    // to stream can be used as index. However, in practice only integers
+    // and possibly strings will be used.
+
+    // Let's text integer as index.
+    EXPECT_EQ("subnet[123].pkt4-received",
+              StatsMgr::generateName("subnet", 123, "pkt4-received"));
+
+    // Lets' test string as index.
+    EXPECT_EQ("subnet[foo].pkt4-received",
+              StatsMgr::generateName("subnet", "foo", "pkt4-received"));
+}
+
 };
 };