Commit 83b9b8a8 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3793] Unit-tests for StatsMgr implemented.

parent e76178c1
......@@ -32,17 +32,14 @@ class StatsMgr : public boost::noncopyable {
static StatsMgr& instance();
// methods used data producers
void addValue(const std::string& name, uint64_t value = 1);
void addValue(const std::string& name, double value = 1.0f);
void addValue(const std::string& name, uint64_t value);
void addValue(const std::string& name, double value);
void addValue(const std::string& name, StatsDuration time);
void addValue(const std::string& name, const std::string& value);
void setValue(const std::string& name, uint64_t value = 1);
void setValue(const std::string& name, double value = 1.0f);
void setValue(const std::string& name, StatsDuration time);
// resets statistic
// this is a convenience function and is equivalent to
// setValue(0) or setValue(0.0f)
void reset(const std::string& name);
void setValue(const std::string& name, const std::string& value);
/// @brief determines whether a given statistic is kept as a single value
/// or as a number of values
......@@ -50,14 +47,17 @@ class StatsMgr : public boost::noncopyable {
/// Specifies that statistic name should be stored not as a single value,
/// but rather as a set of values. duration determines the timespan.
/// Samples older than duration will be discarded. This is time-constrained
/// approach. For sample count constrained approach, see setStorage() below.
/// approach. For sample count constrained approach, see @ref
/// setMaxSampleCount() below.
///
/// @todo: Not implemented.
///
/// Example: to set a statistic to keep observations for the last 5 minutes,
/// call setStorage("incoming-packets", time_duration(0,5,0,0));
/// call setMaxSampleAge("incoming-packets", time_duration(0,5,0,0));
/// to revert statistic to a single value, call:
/// setStorage("incoming-packets" time_duration(0,0,0,0))
void setStorage(const std::string& name,
boost::posix_time::time_duration duration);
/// setMaxSampleAge("incoming-packets" time_duration(0,0,0,0))
void setMaxSampleAge(const std::string& name,
boost::posix_time::time_duration duration);
/// @brief determines how many samples of a given statistic should be kept.
///
......@@ -65,16 +65,50 @@ class StatsMgr : public boost::noncopyable {
/// rather as a set of values. In this form, at most max_samples will be kept.
/// When adding max_samples+1 sample, the oldest sample will be discarded.
///
/// @todo: Not implemented.
///
/// Example:
/// To set a statistic to keep the last 100 observations, call:
/// setStorage("incoming-packets", 100);
void setStorage(const std::string& name, uint32_t max_samples);
/// setMaxSampleCount("incoming-packets", 100);
void setMaxSampleCount(const std::string& name, uint32_t max_samples);
/// @brief Resets specified statistic.
///
/// This is a convenience function and is equivalent to setValue(name,
/// neutral_value), where neutral_value is 0, 0.0 or "".
/// @param name name of the statistic to be reset.
/// @return true if successful, false if there's no such statistic
bool reset(const std::string& name);
/// @brief Removes specified statistic.
/// @param name name of the statistic to be removed.
/// @return true if successful, false if there's no such statistic
bool remove(const std::string& name);
// methods used by data consumers
const ObservationPtr& getValue(const std::string& name);
/// @brief Resets all collected statistics back to zero.
void resetAll();
// returns all statistics
const std::map<std::string, ObservationPtr> getValues();
/// @brief Removes all collected statistics.
void removeAll();
/// @brief Returns number of available statistics.
/// @return number of recorded statistics.
size_t count();
/// @brief Returns a single statistic as a JSON structure
/// @return JSON structures representing a single statistic
isc::data::ConstElementPtr get(const std::string& name);
/// @brief Returns all statistics as a JSON structure
/// @return JSON structures representing all statistics
isc::data::ConstElementPtr getAll();
/// @brief Returns an observation
///
/// Used in testing only. Production code should use @ref get() method.
/// @param name name of the statistic
/// @return Pointer to the Observation object
ObservationPtr getObservation(const std::string& name);
private:
/// @brief returns a context for specified name
......@@ -82,8 +116,6 @@ class StatsMgr : public boost::noncopyable {
// This is a global context. All stats will initially be stored here.
StatContextPtr global_;
std::map<std::string, StatContextPtr> contexts_;
};
};
......
......@@ -16,28 +16,264 @@
#include <stats/stats_mgr.h>
#include <exceptions/exceptions.h>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/shared_ptr.hpp>
#include <cc/data.h>
#include <gtest/gtest.h>
#include <iostream>
#include <sstream>
using namespace isc;
using namespace isc::data;
using namespace isc::stats;
using namespace boost::posix_time;
namespace {
class StatsMgrTest : public ::testing::Test {
public:
StatsMgrTest() {
StatsMgr::instance();
}
~StatsMgrTest() {
StatsMgr::instance().removeAll();
}
};
// Basic tests for V4 functionality
// Basic test for statistics manager interface.
TEST_F(StatsMgrTest, basic) {
// EXPECT_NO_THROW(StatsMgr::instance());
// Getting an instance
EXPECT_NO_THROW(StatsMgr::instance());
// Check that there are no statistics recorded by default.
EXPECT_EQ(0, StatsMgr::instance().count());
}
// Test checks whether it's possible to record and later report
// an integer statistic.
TEST_F(StatsMgrTest, integerStat) {
EXPECT_NO_THROW(StatsMgr::instance().setValue("alpha",
static_cast<uint64_t>(1234)));
ObservationPtr alpha;
EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
EXPECT_TRUE(alpha);
std::string exp = "\"alpha\": [ [ 1234, \""
+ Observation::ptimeToText(alpha->getInteger().second) + "\" ] ]";
EXPECT_EQ(exp, StatsMgr::instance().get("alpha")->str());
}
// Test checks whether it's possible to record and later report
// a floating point statistic.
TEST_F(StatsMgrTest, floatStat) {
EXPECT_NO_THROW(StatsMgr::instance().setValue("beta", 12.34));
ObservationPtr beta;
EXPECT_NO_THROW(beta = StatsMgr::instance().getObservation("beta"));
EXPECT_TRUE(beta);
std::string exp = "\"beta\": [ [ 12.34, \""
+ Observation::ptimeToText(beta->getFloat().second) + "\" ] ]";
EXPECT_EQ(exp, StatsMgr::instance().get("beta")->str());
}
// Test checks whether it's possible to record and later report
// a duration statistic.
TEST_F(StatsMgrTest, durationStat) {
EXPECT_NO_THROW(StatsMgr::instance().setValue("gamma",
microsec::time_duration(1,2,3,4)));
ObservationPtr gamma;
EXPECT_NO_THROW(gamma = StatsMgr::instance().getObservation("beta"));
EXPECT_TRUE(gamma);
std::string exp = "\"gamma\": [ [ \"01:02:03.000004\", \""
+ Observation::ptimeToText(gamma->getDuration().second) + "\" ] ]";
EXPECT_EQ(exp, StatsMgr::instance().get("gamma")->str());
}
// Test checks whether it's possible to record and later report
// a string statistic.
TEST_F(StatsMgrTest, stringStat) {
EXPECT_NO_THROW(StatsMgr::instance().setValue("delta",
"Lorem ipsum"));
ObservationPtr delta;
EXPECT_NO_THROW(delta = StatsMgr::instance().getObservation("delta"));
EXPECT_TRUE(delta);
std::string exp = "\"delta\": [ [ \"Lorem impsum\", \""
+ Observation::ptimeToText(delta->getString().second) + "\" ] ]";
EXPECT_EQ(exp, StatsMgr::instance().get("delta")->str());
}
// Setting limits is currently not implemented, so those methods should
// throw.
TEST_F(StatsMgrTest, setLimits) {
EXPECT_THROW(StatsMgr::instance().setMaxSampleAge("foo",
time_duration(1,0,0,0)),
NotImplemented);
EXPECT_THROW(StatsMgr::instance().setMaxSampleCount("foo", 100),
NotImplemented);
}
// This test checks whether a single (get("foo")) and all (getAll())
// statistics are reported properly.
TEST_F(StatsMgrTest, getGetAll) {
// Set a couple of statistics
StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
StatsMgr::instance().setValue("beta", 12.34);
StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
StatsMgr::instance().setValue("delta", "Lorem");
// Now add some values to them
StatsMgr::instance().addValue("alpha", static_cast<uint64_t>(5678));
StatsMgr::instance().addValue("beta", 56.78);
StatsMgr::instance().addValue("gamma", time_duration(5,6,7,8));
StatsMgr::instance().addValue("delta", " ipsum");
// There should be 4 statistics reported
EXPECT_EQ(4, StatsMgr::instance().count());
// Now check whether they can be reported back
ConstElementPtr rep_alpha = StatsMgr::instance().get("alpha");
ConstElementPtr rep_beta = StatsMgr::instance().get("beta");
ConstElementPtr rep_gamma = StatsMgr::instance().get("gamma");
ConstElementPtr rep_delta = StatsMgr::instance().get("delta");
ASSERT_TRUE(rep_alpha);
ASSERT_TRUE(rep_beta);
ASSERT_TRUE(rep_gamma);
ASSERT_TRUE(rep_delta);
std::string exp_str_alpha = "\"alpha\": [ [ 1234, \""
+ Observation::ptimeToText(StatsMgr::instance().getObservation("alpha")
->getInteger().second) + "\" ] ]";
std::string exp_str_beta = "\"beta\": [ [ 12.34, \""
+ Observation::ptimeToText(StatsMgr::instance().getObservation("beta")
->getFloat().second) + "\" ] ]";
std::string exp_str_gamma = "\"gamma\": [ [ \"01:02:03.000004\", \""
+ Observation::ptimeToText(StatsMgr::instance().getObservation("gamma")
->getDuration().second) + "\" ] ]";
std::string exp_str_delta = "\"delta\": [ [ \"Lorem impsum\", \""
+ Observation::ptimeToText(StatsMgr::instance().getObservation("delta")
->getString().second) + "\" ] ]";
// Check that individual stats are reported properly
EXPECT_EQ(exp_str_alpha, rep_alpha->str());
EXPECT_EQ(exp_str_beta, rep_beta->str());
EXPECT_EQ(exp_str_gamma, rep_gamma->str());
EXPECT_EQ(exp_str_delta, rep_delta->str());
// Check that non-existent metric is not reported.
EXPECT_FALSE(StatsMgr::instance().get("epsilon"));
// Check that all of them can be reported at once
ConstElementPtr rep_all = StatsMgr::instance().getAll();
ASSERT_TRUE(rep_all);
// This may not be the best verification. There's no guarantee that the
// statistics will be reported in this specific order.
std::string exp_all = exp_str_alpha + ", " + exp_str_beta + ", "
+ exp_str_gamma + ", " + exp_str_delta;
EXPECT_EQ(exp_all, rep_all->str());
}
// This test checks whether existing statistics can be reset.
TEST_F(StatsMgrTest, reset) {
// Set a couple of statistics
StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
StatsMgr::instance().setValue("beta", 12.34);
StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
StatsMgr::instance().setValue("delta", "Lorem ipsum");
// This should reset alpha to 0
EXPECT_NO_THROW(StatsMgr::instance().reset("alpha"));
EXPECT_EQ(0, StatsMgr::instance().getObservation("alpha")->getInteger().first);
// The other stats should remain untouched
EXPECT_EQ(12.34,
StatsMgr::instance().getObservation("beta")->getFloat().first);
EXPECT_EQ(time_duration(1,2,3,4),
StatsMgr::instance().getObservation("gamma")->getDuration().first);
EXPECT_EQ("Lorem ipsum",
StatsMgr::instance().getObservation("delta")->getString().first);
// Now let's wipe them, too.
EXPECT_NO_THROW(StatsMgr::instance().reset("beta"));
EXPECT_NO_THROW(StatsMgr::instance().reset("gamma"));
EXPECT_NO_THROW(StatsMgr::instance().reset("delta"));
EXPECT_EQ(0.0,
StatsMgr::instance().getObservation("beta")->getFloat().first);
EXPECT_EQ(time_duration(0,0,0,0),
StatsMgr::instance().getObservation("gamma")->getDuration().first);
EXPECT_EQ("",
StatsMgr::instance().getObservation("delta")->getString().first);
// Resetting statistics should not remove them
EXPECT_EQ(4, StatsMgr::instance().count());
}
// This test checks whether existing statistics can be reset.
TEST_F(StatsMgrTest, resetAll) {
// Set a couple of statistics
StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
StatsMgr::instance().setValue("beta", 12.34);
StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
StatsMgr::instance().setValue("delta", "Lorem ipsum");
// This should reset alpha to 0
EXPECT_NO_THROW(StatsMgr::instance().resetAll());
EXPECT_EQ(0, StatsMgr::instance().getObservation("alpha")->getInteger().first);
EXPECT_EQ(0.0,
StatsMgr::instance().getObservation("beta")->getFloat().first);
EXPECT_EQ(time_duration(0,0,0,0),
StatsMgr::instance().getObservation("gamma")->getDuration().first);
EXPECT_EQ("",
StatsMgr::instance().getObservation("delta")->getString().first);
// Resetting all statistics should not remove them
EXPECT_EQ(4, StatsMgr::instance().count());
}
// This test checks whether statistics can be removed.
TEST_F(StatsMgrTest, removeAll) {
// Set a couple of statistics
StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
StatsMgr::instance().setValue("beta", 12.34);
StatsMgr::instance().setValue("gamma", time_duration(1,2,3,4));
StatsMgr::instance().setValue("delta", "Lorem ipsum");
// This should reset alpha to 0
EXPECT_NO_THROW(StatsMgr::instance().removeAll());
// Resetting all statistics should not remove them
EXPECT_EQ(0, StatsMgr::instance().count());
// There should be no such statistics anymore
EXPECT_FALSE(StatsMgr::instance().get("alpha"));
EXPECT_FALSE(StatsMgr::instance().get("beta"));
EXPECT_FALSE(StatsMgr::instance().get("gamma"));
EXPECT_FALSE(StatsMgr::instance().get("delta"));
// There should be no such statistics anymore
EXPECT_FALSE(StatsMgr::instance().getObservation("alpha"));
EXPECT_FALSE(StatsMgr::instance().getObservation("beta"));
EXPECT_FALSE(StatsMgr::instance().getObservation("gamma"));
EXPECT_FALSE(StatsMgr::instance().getObservation("delta"));
}
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment