summaryrefslogtreecommitdiffstats
path: root/src/lib/stats
diff options
context:
space:
mode:
authorAndrei Pavel <andrei@isc.org>2023-04-26 14:45:29 +0200
committerAndrei Pavel <andrei@isc.org>2023-05-17 18:09:38 +0200
commit4a06d2baf0dff1d21948bd9a39f100c94a159fe0 (patch)
tree83c4bce0b946e63e204521806ad0341f747e5f46 /src/lib/stats
parent[#2658] add BigIntElement (diff)
downloadkea-4a06d2baf0dff1d21948bd9a39f100c94a159fe0.tar.xz
kea-4a06d2baf0dff1d21948bd9a39f100c94a159fe0.zip
[#2658] add big integer support to statistics
Pool capacities have been promoted in code from uint64_t to uint128_t. Bigint is modelled as an int128_t in statistics, following the precedent of signed integer of int64_t from statistics. - "total-nas" is extended to 128 bits as requested in the issue. - "total-pds" has the same risk of overflowing so it has been extended as well. - "total-addresses" always fits in 64 bits, but certain code forces a 128 bit value on it. See Pool::getCapacity(), Subnet::getPoolCapacity(), Subnet::sumPoolCapacity(). It could have been truncated to a 64 bit value, but that seems like an unnecessary complication. Because of the disparity in signedness there is some truncation that can happen when pool capacity values are passed on to statistics. That only happens for the last half of the value range, so for prefix ranges larger than /1.
Diffstat (limited to 'src/lib/stats')
-rw-r--r--src/lib/stats/observation.cc63
-rw-r--r--src/lib/stats/observation.h47
-rw-r--r--src/lib/stats/stats_mgr.cc256
-rw-r--r--src/lib/stats/stats_mgr.h16
-rw-r--r--src/lib/stats/tests/observation_unittest.cc122
-rw-r--r--src/lib/stats/testutils/stats_test_utils.h21
6 files changed, 323 insertions, 202 deletions
diff --git a/src/lib/stats/observation.cc b/src/lib/stats/observation.cc
index c8e7b0f5fd..034f2b9745 100644
--- a/src/lib/stats/observation.cc
+++ b/src/lib/stats/observation.cc
@@ -9,12 +9,14 @@
#include <stats/observation.h>
#include <util/chrono_time_utils.h>
#include <cc/data.h>
+
#include <chrono>
#include <utility>
using namespace std;
using namespace std::chrono;
using namespace isc::data;
+using namespace isc::util;
namespace isc {
namespace stats {
@@ -33,6 +35,13 @@ Observation::Observation(const std::string& name, const int64_t value) :
setValue(value);
}
+Observation::Observation(const std::string& name, const int128_t& value) :
+ name_(name), type_(STAT_BIG_INTEGER),
+ max_sample_count_(default_max_sample_count_),
+ max_sample_age_(default_max_sample_age_) {
+ setValue(value);
+}
+
Observation::Observation(const std::string& name, const double value) :
name_(name), type_(STAT_FLOAT),
max_sample_count_(default_max_sample_count_),
@@ -60,6 +69,10 @@ void Observation::setMaxSampleAge(const StatsDuration& duration) {
setMaxSampleAgeInternal(integer_samples_, duration, STAT_INTEGER);
return;
}
+ case STAT_BIG_INTEGER: {
+ setMaxSampleAgeInternal(big_integer_samples_, duration, STAT_BIG_INTEGER);
+ return;
+ }
case STAT_FLOAT: {
setMaxSampleAgeInternal(float_samples_, duration, STAT_FLOAT);
return;
@@ -84,6 +97,10 @@ void Observation::setMaxSampleCount(uint32_t max_samples) {
setMaxSampleCountInternal(integer_samples_, max_samples, STAT_INTEGER);
return;
}
+ case STAT_BIG_INTEGER: {
+ setMaxSampleCountInternal(big_integer_samples_, max_samples, STAT_BIG_INTEGER);
+ return;
+ }
case STAT_FLOAT: {
setMaxSampleCountInternal(float_samples_, max_samples, STAT_FLOAT);
return;
@@ -107,6 +124,11 @@ void Observation::addValue(const int64_t value) {
setValue(current.first + value);
}
+void Observation::addValue(const int128_t& value) {
+ BigIntegerSample current = getBigInteger();
+ setValue(current.first + value);
+}
+
void Observation::addValue(const double value) {
FloatSample current = getFloat();
setValue(current.first + value);
@@ -126,6 +148,10 @@ void Observation::setValue(const int64_t value) {
setValueInternal(value, integer_samples_, STAT_INTEGER);
}
+void Observation::setValue(const int128_t& value) {
+ setValueInternal(value, big_integer_samples_, STAT_BIG_INTEGER);
+}
+
void Observation::setValue(const double value) {
setValueInternal(value, float_samples_, STAT_FLOAT);
}
@@ -145,6 +171,10 @@ size_t Observation::getSize() const {
size = getSizeInternal(integer_samples_, STAT_INTEGER);
return (size);
}
+ case STAT_BIG_INTEGER: {
+ size = getSizeInternal(big_integer_samples_, STAT_BIG_INTEGER);
+ return (size);
+ }
case STAT_FLOAT: {
size = getSizeInternal(float_samples_, STAT_FLOAT);
return (size);
@@ -223,6 +253,10 @@ IntegerSample Observation::getInteger() const {
return (getValueInternal<IntegerSample>(integer_samples_, STAT_INTEGER));
}
+BigIntegerSample Observation::getBigInteger() const {
+ return (getValueInternal<BigIntegerSample>(big_integer_samples_, STAT_BIG_INTEGER));
+}
+
FloatSample Observation::getFloat() const {
return (getValueInternal<FloatSample>(float_samples_, STAT_FLOAT));
}
@@ -256,6 +290,10 @@ std::list<IntegerSample> Observation::getIntegers() const {
return (getValuesInternal<IntegerSample>(integer_samples_, STAT_INTEGER));
}
+std::list<BigIntegerSample> Observation::getBigIntegers() const {
+ return (getValuesInternal<BigIntegerSample>(big_integer_samples_, STAT_BIG_INTEGER));
+}
+
std::list<FloatSample> Observation::getFloats() const {
return (getValuesInternal<FloatSample>(float_samples_, STAT_FLOAT));
}
@@ -370,6 +408,9 @@ std::string Observation::typeToText(Type type) {
case STAT_INTEGER:
tmp << "integer";
break;
+ case STAT_BIG_INTEGER:
+ tmp << "big integer";
+ break;
case STAT_FLOAT:
tmp << "float";
break;
@@ -414,6 +455,23 @@ Observation::getJSON() const {
}
break;
}
+ case STAT_BIG_INTEGER: {
+ std::list<BigIntegerSample> const& samples(getBigIntegers());
+
+ // Iterate over all elements in the list and alternately add
+ // value and timestamp to the entry.
+ for (BigIntegerSample const& i : samples) {
+ entry = isc::data::Element::createList();
+ value = isc::data::Element::create(i.first);
+ timestamp = isc::data::Element::create(isc::util::clockToText(i.second));
+
+ entry->add(value);
+ entry->add(timestamp);
+
+ list->add(entry);
+ }
+ break;
+ }
case STAT_FLOAT: {
std::list<FloatSample> s = getFloats();
@@ -480,6 +538,11 @@ void Observation::reset() {
setValue(static_cast<int64_t>(0));
return;
}
+ case STAT_BIG_INTEGER: {
+ big_integer_samples_.clear();
+ setValue(int128_t(0));
+ return;
+ }
case STAT_FLOAT: {
float_samples_.clear();
setValue(0.0);
diff --git a/src/lib/stats/observation.h b/src/lib/stats/observation.h
index f1e0117ef4..883d7e7d1d 100644
--- a/src/lib/stats/observation.h
+++ b/src/lib/stats/observation.h
@@ -9,9 +9,13 @@
#include <cc/data.h>
#include <exceptions/exceptions.h>
+#include <util/bigints.h>
+
#include <boost/shared_ptr.hpp>
+
#include <chrono>
#include <list>
+
#include <stdint.h>
namespace isc {
@@ -55,6 +59,9 @@ inline long toSeconds(const StatsDuration& dur) {
/// @brief Integer (implemented as signed 64-bit integer)
typedef std::pair<int64_t, SampleClock::time_point> IntegerSample;
+/// @brief BigInteger (implemented as signed 128-bit integer)
+typedef std::pair<isc::util::int128_t, SampleClock::time_point> BigIntegerSample;
+
/// @brief Float (implemented as double precision)
typedef std::pair<double, SampleClock::time_point> FloatSample;
@@ -93,10 +100,11 @@ public:
/// int64_t and double. If convincing use cases appear to change them
/// to something else, we may change the underlying type.
enum Type {
- STAT_INTEGER, ///< this statistic is unsigned 64-bit integer value
- STAT_FLOAT, ///< this statistic is a floating point value
- STAT_DURATION,///< this statistic represents time duration
- STAT_STRING ///< this statistic represents a string
+ STAT_INTEGER, ///< this statistic is signed 64-bit integer value
+ STAT_BIG_INTEGER, ///< this statistic is signed 128-bit integer value
+ STAT_FLOAT, ///< this statistic is a floating point value
+ STAT_DURATION, ///< this statistic represents time duration
+ STAT_STRING ///< this statistic represents a string
};
/// @brief Constructor for integer observations
@@ -105,6 +113,12 @@ public:
/// @param value integer value observed.
Observation(const std::string& name, const int64_t value);
+ /// @brief Constructor for big integer observations
+ ///
+ /// @param name observation name
+ /// @param value integer value observed.
+ Observation(const std::string& name, const isc::util::int128_t& value);
+
/// @brief Constructor for floating point observations
///
/// @param name observation name
@@ -184,6 +198,12 @@ public:
/// @throw InvalidStatType if statistic is not integer
void setValue(const int64_t value);
+ /// @brief Records big integer observation
+ ///
+ /// @param value integer value observed
+ /// @throw InvalidStatType if statistic is not integer
+ void setValue(const isc::util::int128_t& value);
+
/// @brief Records absolute floating point observation
///
/// @param value floating point value observed
@@ -208,6 +228,12 @@ public:
/// @throw InvalidStatType if statistic is not integer
void addValue(const int64_t value);
+ /// @brief Records incremental integer observation
+ ///
+ /// @param value integer value observed
+ /// @throw InvalidStatType if statistic is not integer
+ void addValue(const isc::util::int128_t& value);
+
/// @brief Records incremental floating point observation
///
/// @param value floating point value observed
@@ -258,6 +284,11 @@ public:
/// @throw InvalidStatType if statistic is not integer
IntegerSample getInteger() const;
+ /// @brief Returns observed integer sample
+ /// @return observed sample (value + timestamp)
+ /// @throw InvalidStatType if statistic is not integer
+ BigIntegerSample getBigInteger() const;
+
/// @brief Returns observed float sample
/// @return observed sample (value + timestamp)
/// @throw InvalidStatType if statistic is not fp
@@ -278,6 +309,11 @@ public:
/// @throw InvalidStatType if statistic is not integer
std::list<IntegerSample> getIntegers() const;
+ /// @brief Returns observed big-integer samples
+ /// @return list of observed samples (value + timestamp)
+ /// @throw InvalidStatType if statistic is not integer
+ std::list<BigIntegerSample> getBigIntegers() const;
+
/// @brief Returns observed float samples
/// @return list of observed samples (value + timestamp)
/// @throw InvalidStatType if statistic is not fp
@@ -425,6 +461,9 @@ private:
/// @brief Storage for integer samples
std::list<IntegerSample> integer_samples_;
+ /// @brief Storage for big integer samples
+ std::list<BigIntegerSample> big_integer_samples_;
+
/// @brief Storage for floating point samples
std::list<FloatSample> float_samples_;
diff --git a/src/lib/stats/stats_mgr.cc b/src/lib/stats/stats_mgr.cc
index 58b36abeed..37536d31d0 100644
--- a/src/lib/stats/stats_mgr.cc
+++ b/src/lib/stats/stats_mgr.cc
@@ -11,7 +11,10 @@
#include <cc/data.h>
#include <cc/command_interpreter.h>
#include <util/multi_threading_mgr.h>
+#include <util/bigints.h>
+
#include <boost/make_shared.hpp>
+
#include <chrono>
using namespace std;
@@ -35,92 +38,68 @@ StatsMgr::StatsMgr() :
void
StatsMgr::setValue(const string& name, const int64_t value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setValueInternal(name, value);
- } else {
- setValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ setValueInternal(name, value);
+}
+
+void
+StatsMgr::setValue(const string& name, const int128_t& value) {
+ MultiThreadingLock lock(*mutex_);
+ setValueInternal(name, value);
}
void
StatsMgr::setValue(const string& name, const double value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setValueInternal(name, value);
- } else {
- setValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ setValueInternal(name, value);
}
void
StatsMgr::setValue(const string& name, const StatsDuration& value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setValueInternal(name, value);
- } else {
- setValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ setValueInternal(name, value);
}
void
StatsMgr::setValue(const string& name, const string& value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setValueInternal(name, value);
- } else {
- setValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ setValueInternal(name, value);
}
void
StatsMgr::addValue(const string& name, const int64_t value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- addValueInternal(name, value);
- } else {
- addValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ addValueInternal(name, value);
+}
+
+void
+StatsMgr::addValue(const string& name, const int128_t& value) {
+ MultiThreadingLock lock(*mutex_);
+ addValueInternal(name, value);
}
void
StatsMgr::addValue(const string& name, const double value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- addValueInternal(name, value);
- } else {
- addValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ addValueInternal(name, value);
}
void
StatsMgr::addValue(const string& name, const StatsDuration& value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- addValueInternal(name, value);
- } else {
- addValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ addValueInternal(name, value);
}
void
StatsMgr::addValue(const string& name, const string& value) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- addValueInternal(name, value);
- } else {
- addValueInternal(name, value);
- }
+ MultiThreadingLock lock(*mutex_);
+ addValueInternal(name, value);
}
ObservationPtr
StatsMgr::getObservation(const string& name) const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (getObservationInternal(name));
- } else {
- return (getObservationInternal(name));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (getObservationInternal(name));
}
ObservationPtr
@@ -132,12 +111,8 @@ StatsMgr::getObservationInternal(const string& name) const {
void
StatsMgr::addObservation(const ObservationPtr& stat) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- addObservationInternal(stat);
- } else {
- addObservationInternal(stat);
- }
+ MultiThreadingLock lock(*mutex_);
+ addObservationInternal(stat);
}
void
@@ -149,12 +124,8 @@ StatsMgr::addObservationInternal(const ObservationPtr& stat) {
bool
StatsMgr::deleteObservation(const string& name) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (deleteObservationInternal(name));
- } else {
- return (deleteObservationInternal(name));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (deleteObservationInternal(name));
}
bool
@@ -166,12 +137,8 @@ StatsMgr::deleteObservationInternal(const string& name) {
bool
StatsMgr::setMaxSampleAge(const string& name, const StatsDuration& duration) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (setMaxSampleAgeInternal(name, duration));
- } else {
- return (setMaxSampleAgeInternal(name, duration));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (setMaxSampleAgeInternal(name, duration));
}
bool
@@ -187,12 +154,8 @@ StatsMgr::setMaxSampleAgeInternal(const string& name,
bool
StatsMgr::setMaxSampleCount(const string& name, uint32_t max_samples) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (setMaxSampleCountInternal(name, max_samples));
- } else {
- return (setMaxSampleCountInternal(name, max_samples));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (setMaxSampleCountInternal(name, max_samples));
}
bool
@@ -208,12 +171,8 @@ StatsMgr::setMaxSampleCountInternal(const string& name,
void
StatsMgr::setMaxSampleAgeAll(const StatsDuration& duration) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setMaxSampleAgeAllInternal(duration);
- } else {
- setMaxSampleAgeAllInternal(duration);
- }
+ MultiThreadingLock lock(*mutex_);
+ setMaxSampleAgeAllInternal(duration);
}
void
@@ -223,12 +182,8 @@ StatsMgr::setMaxSampleAgeAllInternal(const StatsDuration& duration) {
void
StatsMgr::setMaxSampleCountAll(uint32_t max_samples) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setMaxSampleCountAllInternal(max_samples);
- } else {
- setMaxSampleCountAllInternal(max_samples);
- }
+ MultiThreadingLock lock(*mutex_);
+ setMaxSampleCountAllInternal(max_samples);
}
void
@@ -238,12 +193,8 @@ StatsMgr::setMaxSampleCountAllInternal(uint32_t max_samples) {
void
StatsMgr::setMaxSampleAgeDefault(const StatsDuration& duration) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setMaxSampleAgeDefaultInternal(duration);
- } else {
- setMaxSampleAgeDefaultInternal(duration);
- }
+ MultiThreadingLock lock(*mutex_);
+ setMaxSampleAgeDefaultInternal(duration);
}
void
@@ -253,12 +204,8 @@ StatsMgr::setMaxSampleAgeDefaultInternal(const StatsDuration& duration) {
void
StatsMgr::setMaxSampleCountDefault(uint32_t max_samples) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- setMaxSampleCountDefaultInternal(max_samples);
- } else {
- setMaxSampleCountDefaultInternal(max_samples);
- }
+ MultiThreadingLock lock(*mutex_);
+ setMaxSampleCountDefaultInternal(max_samples);
}
void
@@ -268,12 +215,8 @@ StatsMgr::setMaxSampleCountDefaultInternal(uint32_t max_samples) {
const StatsDuration&
StatsMgr::getMaxSampleAgeDefault() const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (getMaxSampleAgeDefaultInternal());
- } else {
- return (getMaxSampleAgeDefaultInternal());
- }
+ MultiThreadingLock lock(*mutex_);
+ return (getMaxSampleAgeDefaultInternal());
}
const StatsDuration&
@@ -283,12 +226,8 @@ StatsMgr::getMaxSampleAgeDefaultInternal() const {
uint32_t
StatsMgr::getMaxSampleCountDefault() const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (getMaxSampleCountDefaultInternal());
- } else {
- return (getMaxSampleCountDefaultInternal());
- }
+ MultiThreadingLock lock(*mutex_);
+ return (getMaxSampleCountDefaultInternal());
}
uint32_t
@@ -298,12 +237,8 @@ StatsMgr::getMaxSampleCountDefaultInternal() const {
bool
StatsMgr::reset(const string& name) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (resetInternal(name));
- } else {
- return (resetInternal(name));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (resetInternal(name));
}
bool
@@ -318,12 +253,8 @@ StatsMgr::resetInternal(const string& name) {
bool
StatsMgr::del(const string& name) {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (delInternal(name));
- } else {
- return (delInternal(name));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (delInternal(name));
}
bool
@@ -333,12 +264,8 @@ StatsMgr::delInternal(const string& name) {
void
StatsMgr::removeAll() {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- removeAllInternal();
- } else {
- removeAllInternal();
- }
+ MultiThreadingLock lock(*mutex_);
+ removeAllInternal();
}
void
@@ -348,12 +275,8 @@ StatsMgr::removeAllInternal() {
ConstElementPtr
StatsMgr::get(const string& name) const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (getInternal(name));
- } else {
- return (getInternal(name));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (getInternal(name));
}
ConstElementPtr
@@ -368,12 +291,8 @@ StatsMgr::getInternal(const string& name) const {
ConstElementPtr
StatsMgr::getAll() const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (getAllInternal());
- } else {
- return (getAllInternal());
- }
+ MultiThreadingLock lock(*mutex_);
+ return (getAllInternal());
}
ConstElementPtr
@@ -383,12 +302,8 @@ StatsMgr::getAllInternal() const {
void
StatsMgr::resetAll() {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- resetAllInternal();
- } else {
- resetAllInternal();
- }
+ MultiThreadingLock lock(*mutex_);
+ resetAllInternal();
}
void
@@ -398,12 +313,8 @@ StatsMgr::resetAllInternal() {
size_t
StatsMgr::getSize(const string& name) const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (getSizeInternal(name));
- } else {
- return (getSizeInternal(name));
- }
+ MultiThreadingLock lock(*mutex_);
+ return (getSizeInternal(name));
}
size_t
@@ -417,12 +328,8 @@ StatsMgr::getSizeInternal(const string& name) const {
size_t
StatsMgr::count() const {
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- return (countInternal());
- } else {
- return (countInternal());
- }
+ MultiThreadingLock lock(*mutex_);
+ return (countInternal());
}
size_t
@@ -545,16 +452,10 @@ StatsMgr::statisticSetMaxSampleAgeAllHandler(const ConstElementPtr& params) {
if (!StatsMgr::getStatDuration(params, duration, error)) {
return (createAnswer(CONTROL_RESULT_ERROR, error));
}
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- StatsMgr::instance().setMaxSampleCountDefaultInternal(0);
- StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration);
- StatsMgr::instance().setMaxSampleAgeAllInternal(duration);
- } else {
- StatsMgr::instance().setMaxSampleCountDefaultInternal(0);
- StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration);
- StatsMgr::instance().setMaxSampleAgeAllInternal(duration);
- }
+ MultiThreadingLock lock(*mutex_);
+ StatsMgr::instance().setMaxSampleCountDefaultInternal(0);
+ StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration);
+ StatsMgr::instance().setMaxSampleAgeAllInternal(duration);
return (createAnswer(CONTROL_RESULT_SUCCESS,
"All statistics duration limit are set."));
}
@@ -570,14 +471,9 @@ StatsMgr::statisticSetMaxSampleCountAllHandler(const ConstElementPtr& params) {
error = "'max-samples' parameter must not be zero";
return (createAnswer(CONTROL_RESULT_ERROR, error));
}
- if (MultiThreadingMgr::instance().getMode()) {
- lock_guard<mutex> lock(*mutex_);
- StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples);
- StatsMgr::instance().setMaxSampleCountAllInternal(max_samples);
- } else {
- StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples);
- StatsMgr::instance().setMaxSampleCountAllInternal(max_samples);
- }
+ MultiThreadingLock lock(*mutex_);
+ StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples);
+ StatsMgr::instance().setMaxSampleCountAllInternal(max_samples);
return (createAnswer(CONTROL_RESULT_SUCCESS,
"All statistics count limit are set."));
}
diff --git a/src/lib/stats/stats_mgr.h b/src/lib/stats/stats_mgr.h
index 564df43976..c1e688d290 100644
--- a/src/lib/stats/stats_mgr.h
+++ b/src/lib/stats/stats_mgr.h
@@ -9,6 +9,8 @@
#include <stats/observation.h>
#include <stats/context.h>
+#include <util/bigints.h>
+
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
@@ -79,6 +81,13 @@ public:
/// @throw InvalidStatType if statistic is not integer
void setValue(const std::string& name, const int64_t value);
+ /// @brief Records an absolute big integer observation.
+ ///
+ /// @param name name of the observation
+ /// @param value integer value observed
+ /// @throw InvalidStatType if statistic is not integer
+ void setValue(const std::string& name, const isc::util::int128_t& value);
+
/// @brief Records absolute floating point observation.
///
/// @param name name of the observation
@@ -107,6 +116,13 @@ public:
/// @throw InvalidStatType if statistic is not integer
void addValue(const std::string& name, const int64_t value);
+ /// @brief Records an incremental big integer observation.
+ ///
+ /// @param name name of the observation
+ /// @param value integer value observed
+ /// @throw InvalidStatType if statistic is not integer
+ void addValue(const std::string& name, const isc::util::int128_t& value);
+
/// @brief Records incremental floating point observation.
///
/// @param name name of the observation
diff --git a/src/lib/stats/tests/observation_unittest.cc b/src/lib/stats/tests/observation_unittest.cc
index ad1036809c..dc0a4d9826 100644
--- a/src/lib/stats/tests/observation_unittest.cc
+++ b/src/lib/stats/tests/observation_unittest.cc
@@ -6,10 +6,13 @@
#include <config.h>
-#include <stats/observation.h>
#include <exceptions/exceptions.h>
+#include <stats/observation.h>
#include <util/chrono_time_utils.h>
+#include <util/bigints.h>
+
#include <boost/shared_ptr.hpp>
+
#include <gtest/gtest.h>
#include <iostream>
@@ -19,6 +22,7 @@
using namespace isc;
using namespace isc::stats;
+using namespace isc::util;
using namespace std::chrono;
namespace {
@@ -51,13 +55,15 @@ public:
a("alpha", static_cast<int64_t>(1234)), // integer
b("beta", 12.34), // float
c("gamma", dur1234), // duration
- d("delta", "1234") { // string
+ d("delta", "1234"), // string
+ e("epsilon", int128_t(12e34)) { // big integer
}
Observation a;
Observation b;
Observation c;
Observation d;
+ Observation e;
};
// Basic tests for the Observation constructors. This test checks whether
@@ -67,29 +73,40 @@ TEST_F(ObservationTest, constructor) {
EXPECT_EQ(Observation::STAT_FLOAT, b.getType());
EXPECT_EQ(Observation::STAT_DURATION, c.getType());
EXPECT_EQ(Observation::STAT_STRING, d.getType());
+ EXPECT_EQ(Observation::STAT_BIG_INTEGER, e.getType());
EXPECT_EQ(1234, a.getInteger().first);
EXPECT_EQ(12.34, b.getFloat().first);
EXPECT_EQ(dur1234, c.getDuration().first);
EXPECT_EQ("1234", d.getString().first);
+ EXPECT_EQ(int128_t(12e34), e.getBigInteger().first);
// Let's check that attempting to get a different type
// than used will cause an exception.
EXPECT_THROW(a.getFloat(), InvalidStatType);
EXPECT_THROW(a.getDuration(), InvalidStatType);
EXPECT_THROW(a.getString(), InvalidStatType);
+ EXPECT_THROW(a.getBigInteger(), InvalidStatType);
EXPECT_THROW(b.getInteger(), InvalidStatType);
EXPECT_THROW(b.getDuration(), InvalidStatType);
EXPECT_THROW(b.getString(), InvalidStatType);
+ EXPECT_THROW(b.getBigInteger(), InvalidStatType);
EXPECT_THROW(c.getInteger(), InvalidStatType);
EXPECT_THROW(c.getFloat(), InvalidStatType);
EXPECT_THROW(c.getString(), InvalidStatType);
+ EXPECT_THROW(c.getBigInteger(), InvalidStatType);
EXPECT_THROW(d.getInteger(), InvalidStatType);
EXPECT_THROW(d.getFloat(), InvalidStatType);
EXPECT_THROW(d.getDuration(), InvalidStatType);
+ EXPECT_THROW(d.getBigInteger(), InvalidStatType);
+
+ EXPECT_THROW(e.getInteger(), InvalidStatType);
+ EXPECT_THROW(e.getFloat(), InvalidStatType);
+ EXPECT_THROW(e.getDuration(), InvalidStatType);
+ EXPECT_THROW(e.getString(), InvalidStatType);
}
// This test checks whether it is possible to set to an absolute value for all
@@ -99,30 +116,40 @@ TEST_F(ObservationTest, setValue) {
EXPECT_NO_THROW(b.setValue(56e+78));
EXPECT_NO_THROW(c.setValue(dur5678));
EXPECT_NO_THROW(d.setValue("fiveSixSevenEight"));
-
+ EXPECT_NO_THROW(e.setValue(int128_t(43e21)));
EXPECT_EQ(5678, a.getInteger().first);
EXPECT_EQ(56e+78, b.getFloat().first);
EXPECT_EQ(dur5678, c.getDuration().first);
EXPECT_EQ("fiveSixSevenEight", d.getString().first);
+ EXPECT_EQ(int128_t(43e21), e.getBigInteger().first);
// Now check whether setting value to a different type does
// throw an exception
EXPECT_THROW(a.setValue(56e+78), InvalidStatType);
EXPECT_THROW(a.setValue(dur5678), InvalidStatType);
EXPECT_THROW(a.setValue("fiveSixSevenEight"), InvalidStatType);
+ EXPECT_THROW(a.setValue(int128_t(43e21)), InvalidStatType);
EXPECT_THROW(b.setValue(static_cast<int64_t>(5678)), InvalidStatType);
EXPECT_THROW(b.setValue(dur5678), InvalidStatType);
EXPECT_THROW(b.setValue("fiveSixSevenEight"), InvalidStatType);
+ EXPECT_THROW(b.setValue(int128_t(43e21)), InvalidStatType);
EXPECT_THROW(c.setValue(static_cast<int64_t>(5678)), InvalidStatType);
EXPECT_THROW(c.setValue(56e+78), InvalidStatType);
EXPECT_THROW(c.setValue("fiveSixSevenEight"), InvalidStatType);
+ EXPECT_THROW(c.setValue(int128_t(43e21)), InvalidStatType);
EXPECT_THROW(d.setValue(static_cast<int64_t>(5678)), InvalidStatType);
EXPECT_THROW(d.setValue(56e+78), InvalidStatType);
EXPECT_THROW(d.setValue(dur5678), InvalidStatType);
+ EXPECT_THROW(d.setValue(int128_t(43e21)), InvalidStatType);
+
+ EXPECT_THROW(e.setValue(int64_t(5678)), InvalidStatType);
+ EXPECT_THROW(e.setValue(56e+78), InvalidStatType);
+ EXPECT_THROW(e.setValue(dur5678), InvalidStatType);
+ EXPECT_THROW(e.setValue("fiveSixSevenEight"), InvalidStatType);
}
// This test checks whether it is possible to add value to existing
@@ -135,16 +162,19 @@ TEST_F(ObservationTest, addValue) {
EXPECT_NO_THROW(b.addValue(56.78));
EXPECT_NO_THROW(c.addValue(dur5678));
EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
+ EXPECT_NO_THROW(e.addValue(int128_t(43e21)));
EXPECT_EQ(6912, a.getInteger().first);
EXPECT_EQ(69.12, b.getFloat().first);
EXPECT_EQ(dur681012, c.getDuration().first);
EXPECT_EQ("1234fiveSixSevenEight", d.getString().first);
+ EXPECT_EQ(int128_t(12e34) + int128_t(43e21), e.getBigInteger().first);
ASSERT_EQ(a.getSize(), 2);
ASSERT_EQ(b.getSize(), 2);
ASSERT_EQ(c.getSize(), 2);
ASSERT_EQ(d.getSize(), 2);
+ ASSERT_EQ(e.getSize(), 2);
}
// This test checks if collecting more than one sample
@@ -153,37 +183,42 @@ TEST_F(ObservationTest, moreThanOne) {
// Arrays of 4 types of samples
int64_t int_samples[3] = {1234, 6912, 5678};
double float_samples[3] = {12.34, 69.12, 56e+78};
- StatsDuration duration_samples[3] = {dur1234,
- dur681012, dur5678};
+ StatsDuration duration_samples[3] = {dur1234, dur681012, dur5678};
std::string string_samples[3] = {"1234", "1234fiveSixSevenEight", "fiveSixSevenEight"};
+ int128_t bigint_samples[3] = {int128_t(12e34), int128_t(12e34) + int128_t(43e21),
+ int128_t(43e21)};
EXPECT_NO_THROW(a.addValue(static_cast<int64_t>(5678)));
EXPECT_NO_THROW(b.addValue(56.78));
EXPECT_NO_THROW(c.addValue(dur5678));
EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
+ EXPECT_NO_THROW(e.addValue(int128_t(43e21)));
EXPECT_NO_THROW(a.setValue(static_cast<int64_t>(5678)));
EXPECT_NO_THROW(b.setValue(56e+78));
EXPECT_NO_THROW(c.setValue(dur5678));
EXPECT_NO_THROW(d.setValue("fiveSixSevenEight"));
+ EXPECT_NO_THROW(e.setValue(int128_t(43e21)));
ASSERT_EQ(a.getSize(), 3);
ASSERT_EQ(b.getSize(), 3);
ASSERT_EQ(c.getSize(), 3);
ASSERT_EQ(d.getSize(), 3);
+ ASSERT_EQ(e.getSize(), 3);
ASSERT_NO_THROW(a.getIntegers());
ASSERT_NO_THROW(b.getFloats());
ASSERT_NO_THROW(c.getDurations());
ASSERT_NO_THROW(d.getStrings());
+ ASSERT_NO_THROW(e.getBigIntegers());
std::list<IntegerSample> samples_int = a.getIntegers(); // List of all integer samples
std::list<FloatSample> samples_float = b.getFloats(); // List of all float samples
std::list<DurationSample> samples_dur = c.getDurations(); // List of all duration samples
std::list<StringSample> samples_str = d.getStrings(); // List of all string samples
+ std::list<BigIntegerSample> samples_bigint = e.getBigIntegers(); // List of all big integer samples
uint32_t i = 2; // Index pointed to the end of array of samples
-
for (std::list<IntegerSample>::iterator it = samples_int.begin(); it != samples_int.end(); ++it) {
EXPECT_EQ(int_samples[i], static_cast<int64_t>((*it).first));
--i;
@@ -203,6 +238,11 @@ TEST_F(ObservationTest, moreThanOne) {
EXPECT_EQ(string_samples[i], (*it).first);
--i;
}
+ i = 2;
+ for (BigIntegerSample const& sample : samples_bigint) {
+ EXPECT_EQ(bigint_samples[i], sample.first);
+ --i;
+ }
}
// This test checks whether the size of storage
@@ -213,27 +253,32 @@ TEST_F(ObservationTest, getSize) {
ASSERT_EQ(b.getSize(), 1);
ASSERT_EQ(c.getSize(), 1);
ASSERT_EQ(d.getSize(), 1);
+ ASSERT_EQ(e.getSize(), 1);
a.addValue(static_cast<int64_t>(5678));
b.addValue(56.78);
c.addValue(dur5678);
d.addValue("fiveSixSevenEight");
+ e.addValue(int128_t(43e21));
EXPECT_NO_THROW(a.getSize());
EXPECT_NO_THROW(b.getSize());
EXPECT_NO_THROW(c.getSize());
EXPECT_NO_THROW(d.getSize());
+ EXPECT_NO_THROW(e.getSize());
// Check if size of storages is equal to 2
ASSERT_EQ(a.getSize(), 2);
ASSERT_EQ(b.getSize(), 2);
ASSERT_EQ(c.getSize(), 2);
ASSERT_EQ(d.getSize(), 2);
+ ASSERT_EQ(e.getSize(), 2);
a.setValue(static_cast<int64_t>(5678));
b.setValue(56e+78);
c.setValue(dur5678);
d.setValue("fiveSixSevenEight");
+ e.setValue(int128_t(43e21));
EXPECT_NO_THROW(a.getSize());
EXPECT_NO_THROW(b.getSize());
@@ -245,6 +290,7 @@ TEST_F(ObservationTest, getSize) {
ASSERT_EQ(b.getSize(), 3);
ASSERT_EQ(c.getSize(), 3);
ASSERT_EQ(d.getSize(), 3);
+ ASSERT_EQ(e.getSize(), 3);
}
// Checks whether setting amount limits works properly
@@ -279,18 +325,23 @@ TEST_F(ObservationTest, setCountLimit) {
for (uint32_t i = 0; i < 21; ++i) {
d.setValue(string_samples[i]);
}
+ for (uint32_t i = 0; i < 21; ++i) {
+ e.setValue(int128_t(int_samples[i]));
+ }
// Getting all 4 types of samples after inserting 21 values
std::list<IntegerSample> samples_int = a.getIntegers();
std::list<FloatSample> samples_float = b.getFloats();
std::list<DurationSample> samples_duration = c.getDurations();
std::list<StringSample> samples_string = d.getStrings();
+ std::list<BigIntegerSample> samples_bigint = e.getBigIntegers();
// Check if size of storages is equal to 20
ASSERT_EQ(a.getSize(), 20);
ASSERT_EQ(b.getSize(), 20);
ASSERT_EQ(c.getSize(), 20);
ASSERT_EQ(d.getSize(), 20);
+ ASSERT_EQ(e.getSize(), 20);
// And whether stored values are correct
uint32_t i = 20; // index of the last element in array of test's samples
@@ -313,23 +364,31 @@ TEST_F(ObservationTest, setCountLimit) {
EXPECT_EQ((*it).first, string_samples[i]);
--i;
}
+ i = 20; // index of last element in array of test's samples
+ for (BigIntegerSample const& sample : samples_bigint) {
+ EXPECT_EQ(sample.first, int_samples[i]);
+ --i;
+ }
// Change size of storage to smaller one
ASSERT_NO_THROW(a.setMaxSampleCount(10));
ASSERT_NO_THROW(b.setMaxSampleCount(10));
ASSERT_NO_THROW(c.setMaxSampleCount(10));
ASSERT_NO_THROW(d.setMaxSampleCount(10));
+ ASSERT_NO_THROW(e.setMaxSampleCount(10));
samples_int = a.getIntegers();
samples_float = b.getFloats();
samples_duration = c.getDurations();
samples_string = d.getStrings();
+ samples_bigint = e.getBigIntegers();
// Check if size of storages is equal to 10
ASSERT_EQ(a.getSize(), 10);
ASSERT_EQ(b.getSize(), 10);
ASSERT_EQ(c.getSize(), 10);
ASSERT_EQ(d.getSize(), 10);
+ ASSERT_EQ(e.getSize(), 10);
// And whether storages contain only the 10 newest values
i = 20; // index of last element in array of test's samples
@@ -352,34 +411,44 @@ TEST_F(ObservationTest, setCountLimit) {
EXPECT_EQ((*it).first, string_samples[i]);
--i;
}
+ i = 20; // index of last element in array of test's samples
+ for (BigIntegerSample const& sample : samples_bigint) {
+ EXPECT_EQ(sample.first, int_samples[i]);
+ --i;
+ }
// Resize max_sample_count to greater
ASSERT_NO_THROW(a.setMaxSampleCount(50));
ASSERT_NO_THROW(b.setMaxSampleCount(50));
ASSERT_NO_THROW(c.setMaxSampleCount(50));
ASSERT_NO_THROW(d.setMaxSampleCount(50));
+ ASSERT_NO_THROW(e.setMaxSampleCount(50));
// Check if size of storages did not change without adding new value
ASSERT_EQ(a.getSize(), 10);
ASSERT_EQ(b.getSize(), 10);
ASSERT_EQ(c.getSize(), 10);
ASSERT_EQ(d.getSize(), 10);
+ ASSERT_EQ(e.getSize(), 10);
// Add new values to each type of Observation
a.setValue(static_cast<int64_t>(21));
b.setValue(21.0);
c.setValue(milliseconds(21));
d.setValue("v");
+ e.setValue(int128_t(21));
samples_int = a.getIntegers();
samples_float = b.getFloats();
samples_duration = c.getDurations();
samples_string = d.getStrings();
+ samples_bigint = e.getBigIntegers();
ASSERT_EQ(a.getSize(), 11);
ASSERT_EQ(b.getSize(), 11);
ASSERT_EQ(c.getSize(), 11);
ASSERT_EQ(d.getSize(), 11);
+ ASSERT_EQ(e.getSize(), 11);
i = 21; // index of last element in array of test's samples
for (std::list<IntegerSample>::iterator it = samples_int.begin(); it != samples_int.end(); ++it) {
@@ -401,7 +470,11 @@ TEST_F(ObservationTest, setCountLimit) {
EXPECT_EQ((*it).first, string_samples[i]);
--i;
}
-
+ i = 21; // index of last element in array of test's samples
+ for (BigIntegerSample const& sample : samples_bigint) {
+ EXPECT_EQ(sample.first, int_samples[i]);
+ --i;
+ }
}
// Checks whether setting age limits works properly
@@ -451,42 +524,50 @@ TEST_F(ObservationTest, getLimits) {
EXPECT_EQ(b.getMaxSampleAge().first, false);
EXPECT_EQ(c.getMaxSampleAge().first, false);
EXPECT_EQ(d.getMaxSampleAge().first, false);
+ EXPECT_EQ(e.getMaxSampleAge().first, false);
EXPECT_EQ(a.getMaxSampleCount().first, true);
EXPECT_EQ(b.getMaxSampleCount().first, true);
EXPECT_EQ(c.getMaxSampleCount().first, true);
EXPECT_EQ(d.getMaxSampleCount().first, true);
+ EXPECT_EQ(e.getMaxSampleCount().first, true);
EXPECT_EQ(a.getMaxSampleCount().second, 20);
EXPECT_EQ(b.getMaxSampleCount().second, 20);
EXPECT_EQ(c.getMaxSampleCount().second, 20);
EXPECT_EQ(d.getMaxSampleCount().second, 20);
+ EXPECT_EQ(e.getMaxSampleCount().second, 20);
// change limit to time duration
ASSERT_NO_THROW(a.setMaxSampleAge(dur453));
ASSERT_NO_THROW(b.setMaxSampleAge(dur453));
ASSERT_NO_THROW(c.setMaxSampleAge(dur453));
ASSERT_NO_THROW(d.setMaxSampleAge(dur453));
+ ASSERT_NO_THROW(e.setMaxSampleAge(dur453));
EXPECT_EQ(a.getMaxSampleAge().first, true);
EXPECT_EQ(b.getMaxSampleAge().first, true);
EXPECT_EQ(c.getMaxSampleAge().first, true);
EXPECT_EQ(d.getMaxSampleAge().first, true);
+ EXPECT_EQ(e.getMaxSampleAge().first, true);
EXPECT_EQ(a.getMaxSampleAge().second, dur453);
EXPECT_EQ(b.getMaxSampleAge().second, dur453);
EXPECT_EQ(c.getMaxSampleAge().second, dur453);
EXPECT_EQ(d.getMaxSampleAge().second, dur453);
+ EXPECT_EQ(e.getMaxSampleAge().second, dur453);
EXPECT_EQ(a.getMaxSampleCount().first, false);
EXPECT_EQ(b.getMaxSampleCount().first, false);
EXPECT_EQ(c.getMaxSampleCount().first, false);
EXPECT_EQ(d.getMaxSampleCount().first, false);
+ EXPECT_EQ(e.getMaxSampleCount().first, false);
EXPECT_EQ(a.getMaxSampleCount().second, 20);
EXPECT_EQ(b.getMaxSampleCount().second, 20);
EXPECT_EQ(c.getMaxSampleCount().second, 20);
EXPECT_EQ(d.getMaxSampleCount().second, 20);
+ EXPECT_EQ(e.getMaxSampleCount().second, 20);
}
// limit defaults are tested with StatsMgr.
@@ -525,7 +606,6 @@ TEST_F(ObservationTest, integerToJSON) {
std::string exp = "[ [ 1234, \"" +
isc::util::clockToText(a.getInteger().second) + "\" ]" + first_sample;
- std::cout << a.getJSON()->str() << std::endl;
EXPECT_EQ(exp, a.getJSON()->str());
}
@@ -546,7 +626,6 @@ TEST_F(ObservationTest, floatToJSON) {
std::string exp = "[ [ 1234.5, \"" +
isc::util::clockToText(b.getFloat().second) + "\" ]" + first_sample;
- std::cout << b.getJSON()->str() << std::endl;
EXPECT_EQ(exp, b.getJSON()->str());
}
@@ -564,7 +643,6 @@ TEST_F(ObservationTest, durationToJSON) {
std::string exp = "[ [ \"01:02:03.004000\", \"" +
isc::util::clockToText(c.getDuration().second) + "\" ]" + first_sample;
- std::cout << c.getJSON()->str() << std::endl;
EXPECT_EQ(exp, c.getJSON()->str());
}
@@ -581,31 +659,50 @@ TEST_F(ObservationTest, stringToJSON) {
std::string exp = "[ [ \"Lorem ipsum dolor sit amet\", \"" +
isc::util::clockToText(d.getString().second) + "\" ]" + first_sample;
- std::cout << d.getJSON()->str() << std::endl;
EXPECT_EQ(exp, d.getJSON()->str());
}
+// Checks whether a big integer statistic can generate proper JSON structures.
+// See https://gitlab.isc.org/isc-projects/kea/wikis/designs/Stats-design
+// for details.
+TEST_F(ObservationTest, bigIntegerToJSON) {
+ // String which contains first added sample
+ std::string first_sample = ", [ 120000000000000007304085773727301632, \"" +
+ isc::util::clockToText(e.getBigInteger().second) + "\" ] ]";
+
+ e.setValue(int128_t(43e21));
+
+ std::string exp = "[ [ 43000000000000002097152, \"" +
+ isc::util::clockToText(e.getBigInteger().second) + "\" ]" + first_sample;
+
+ EXPECT_EQ(exp, e.getJSON()->str());
+}
+
// Checks whether reset() resets the statistics properly.
TEST_F(ObservationTest, reset) {
EXPECT_NO_THROW(a.addValue(static_cast<int64_t>(5678)));
EXPECT_NO_THROW(b.addValue(56.78));
EXPECT_NO_THROW(c.addValue(dur5678));
EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
+ EXPECT_NO_THROW(e.addValue(int128_t(43e21)));
a.reset(); // integer
b.reset(); // float
c.reset(); // duration
d.reset(); // string
+ e.reset(); // big integer
EXPECT_EQ(0, a.getInteger().first);
EXPECT_EQ(0.0, b.getFloat().first);
EXPECT_EQ(StatsDuration::zero(), c.getDuration().first);
EXPECT_EQ("", d.getString().first);
+ EXPECT_EQ(0, e.getBigInteger().first);
ASSERT_EQ(a.getSize(), 1);
ASSERT_EQ(b.getSize(), 1);
ASSERT_EQ(c.getSize(), 1);
ASSERT_EQ(d.getSize(), 1);
+ ASSERT_EQ(e.getSize(), 1);
}
// Checks whether an observation can keep its name.
@@ -614,6 +711,7 @@ TEST_F(ObservationTest, names) {
EXPECT_EQ("beta", b.getName());
EXPECT_EQ("gamma", c.getName());
EXPECT_EQ("delta", d.getName());
+ EXPECT_EQ("epsilon", e.getName());
}
-}
+} // namespace
diff --git a/src/lib/stats/testutils/stats_test_utils.h b/src/lib/stats/testutils/stats_test_utils.h
index 808dced39a..cad71a35d1 100644
--- a/src/lib/stats/testutils/stats_test_utils.h
+++ b/src/lib/stats/testutils/stats_test_utils.h
@@ -27,12 +27,21 @@ typedef std::map<std::string, int64_t> StatMap;
///
/// @param name StatsMgr name for the statistic to check.
/// @param expected_value expected value of the statistic.
-inline void checkStat(const std::string& name, const int64_t expected_value) {
- using namespace isc::stats;
- ObservationPtr obs = StatsMgr::instance().getObservation(name);
- ASSERT_TRUE(obs) << " stat: " << name << " not found ";
- ASSERT_EQ(expected_value, obs->getInteger().first)
- << " stat: " << name << " value wrong";
+inline void checkStat(const std::string& name,
+ const isc::util::int128_t expected_value) {
+ ObservationPtr const obs(isc::stats::StatsMgr::instance().getObservation(name));
+
+ ASSERT_TRUE(obs) << "stat " << name << " not found ";
+ if (obs->getType() == Observation::STAT_INTEGER) {
+ EXPECT_EQ(expected_value, obs->getInteger().first)
+ << " wrong value for stat " << name;
+ } else if (obs->getType() == Observation::STAT_BIG_INTEGER) {
+ EXPECT_EQ(expected_value, obs->getBigInteger().first)
+ << " wrong value for stat " << name;
+ } else {
+ GTEST_FAIL() << "unexpected statistic type: "
+ << Observation::typeToText(obs->getType());
+ }
}
/// @brief Check if a statistic does not exists.