From: Franciszek Gorski Date: Mon, 15 Jul 2019 10:19:12 +0000 (+0200) Subject: new statistics commands X-Git-Tag: Kea-1.6.1~10^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cdf12c66122fee9875e0f31cf987cce4ebc0268d;p=thirdparty%2Fkea.git new statistics commands --- diff --git a/src/lib/stats/observation.cc b/src/lib/stats/observation.cc index b790e8eb5b..33661ffa9d 100644 --- a/src/lib/stats/observation.cc +++ b/src/lib/stats/observation.cc @@ -150,6 +150,14 @@ size_t Observation::getSize() const { return (size); } +std::pair Observation::getMaxSampleAge() const { + return (max_sample_age_); +} + +std::pair Observation::getMaxSampleCount() const { + return (max_sample_count_); +} + template size_t Observation::getSizeInternal(StorageType& storage, Type exp_type) const { if (type_ != exp_type) { @@ -178,8 +186,8 @@ void Observation::setValueInternal(SampleType value, StorageType& storage, storage.push_front(make_pair(value, microsec_clock::local_time())); if (max_sample_count_.first) { - // if max_sample_count is set to true - // and size of storage is equal to max_sample_count + // if max_sample_count_ is set to true + // and size of storage is equal to max_sample_count_ if (storage.size() > max_sample_count_.second) { storage.pop_back(); // removing the last element } @@ -273,10 +281,10 @@ void Observation::setMaxSampleAgeInternal(StorageType& storage, << typeToText(exp_type) << ", but the actual type is " << typeToText(type_)); } - // setting new value of max_sample_age + // setting new value of max_sample_age_ max_sample_age_.first = true; max_sample_age_.second = duration; - // deactivating the max_sample_count limit + // deactivating the max_sample_count_ limit max_sample_count_.first = false; StatsDuration range_of_storage = @@ -298,10 +306,10 @@ void Observation::setMaxSampleCountInternal(StorageType& storage, << typeToText(exp_type) << ", but the actual type is " << typeToText(type_)); } - // setting new value of max_sample_count + // setting new value of max_sample_count_ max_sample_count_.first = true; max_sample_count_.second = max_samples; - // deactivating the max_sample_age limit + // deactivating the max_sample_age_ limit max_sample_age_.first = false; while (storage.size() > max_samples) { diff --git a/src/lib/stats/observation.h b/src/lib/stats/observation.h index 23fd7ef23e..28cf9a8bdc 100644 --- a/src/lib/stats/observation.h +++ b/src/lib/stats/observation.h @@ -194,6 +194,16 @@ class Observation { /// @return size of storage size_t getSize() const; + /// @brief Returns both value of max_sample_age_ of statistic. + /// + /// @return max_sample_age_. + std::pair getMaxSampleAge() const; + + /// @brief Returns both value of max_sample_count_ of statistic. + /// + /// @return max_sample_count_. + std::pair getMaxSampleCount() const; + /// @brief Resets statistic. /// /// Sets statistic to a neutral (0, 0.0 or "") value and diff --git a/src/lib/stats/stats_mgr.cc b/src/lib/stats/stats_mgr.cc index eb2500ce34..444b5e49b8 100644 --- a/src/lib/stats/stats_mgr.cc +++ b/src/lib/stats/stats_mgr.cc @@ -101,6 +101,26 @@ bool StatsMgr::setMaxSampleCount(const std::string& name, } } +void StatsMgr::setMaxSampleAgeAll(const StatsDuration& duration) { + // Let's iterate over all stored statistics... + for (std::map::iterator s = global_->stats_.begin(); + s != global_->stats_.end(); ++s) { + + // ... and set duration limit for each statistic. + s->second->setMaxSampleAge(duration); + } +} + +void StatsMgr::setMaxSampleCountAll(uint32_t max_samples) { + // Let's iterate over all stored statistics... + for (std::map::iterator s = global_->stats_.begin(); + s != global_->stats_.end(); ++s) { + + // ... and set count limit for each statistic. + s->second->setMaxSampleCount(max_samples); + } +} + bool StatsMgr::reset(const std::string& name) { ObservationPtr obs = getObservation(name); if (obs) { @@ -164,6 +184,46 @@ size_t StatsMgr::count() const { return (global_->stats_.size()); } +isc::data::ConstElementPtr +StatsMgr::statisticSetMaxSampleAgeHandler(const std::string& /*name*/, + const isc::data::ConstElementPtr& params) { + std::string name, error; + StatsDuration duration; + if (!getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (!getStatDuration(params, duration, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (instance().setMaxSampleAge(name, duration)) { + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Statistic '" + name + "' duration limit is set.")); + } else { + return (createAnswer(CONTROL_RESULT_ERROR, + "No '" + name + "' statistic found")); + } +} + +isc::data::ConstElementPtr +StatsMgr::statisticSetMaxSampleCountHandler(const std::string& /*name*/, + const isc::data::ConstElementPtr& params) { + std::string name, error; + uint32_t max_samples; + if (!getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (!getStatMaxSamples(params, max_samples, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (instance().setMaxSampleCount(name, max_samples)) { + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Statistic '" + name + "' count limit is set.")); + } else { + return (createAnswer(CONTROL_RESULT_ERROR, + "No '" + name + "' statistic found")); + } +} + isc::data::ConstElementPtr StatsMgr::statisticGetHandler(const std::string& /*name*/, const isc::data::ConstElementPtr& params) { @@ -232,6 +292,32 @@ StatsMgr::statisticResetAllHandler(const std::string& /*name*/, "All statistics reset to neutral values.")); } +isc::data::ConstElementPtr +StatsMgr::statisticSetMaxSampleAgeAllHandler(const std::string& /*name*/, + const isc::data::ConstElementPtr& params) { + std::string error; + StatsDuration duration; + if (!getStatDuration(params, duration, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + instance().setMaxSampleAgeAll(duration); + return (createAnswer(CONTROL_RESULT_SUCCESS, + "All statistics duration limit are set.")); +} + +isc::data::ConstElementPtr +StatsMgr::statisticSetMaxSampleCountAllHandler(const std::string& /*name*/, + const isc::data::ConstElementPtr& params) { + std::string error; + uint32_t max_samples; + if (!getStatMaxSamples(params, max_samples, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + instance().setMaxSampleCountAll(max_samples); + return (createAnswer(CONTROL_RESULT_SUCCESS, + "All statistics count limit are set.")); +} + bool StatsMgr::getStatName(const isc::data::ConstElementPtr& params, std::string& name, @@ -254,5 +340,54 @@ StatsMgr::getStatName(const isc::data::ConstElementPtr& params, return (true); } +bool +StatsMgr::getStatDuration(const isc::data::ConstElementPtr& params, + StatsDuration& duration, + std::string& reason) { + if (!params) { + reason = "Missing mandatory 'duration' parameter."; + return (false); + } + ConstElementPtr stat_duration = params->get("duration"); + if (!stat_duration) { + reason = "Missing mandatory 'duration' parameter."; + return (false); + } + + int64_t dur = stat_duration->intValue(); + + int64_t hours = dur/3600; + dur = dur - hours*3600; + + int64_t minutes = dur/60; + dur = dur - minutes*60; + + int64_t seconds = dur; + duration = boost::posix_time::time_duration(hours,minutes,seconds,0); + return (true); +} + +bool +StatsMgr::getStatMaxSamples(const isc::data::ConstElementPtr& params, + uint32_t& max_samples, + std::string& reason) { + if (!params) { + reason = "Missing mandatory 'max-samples' parameter."; + return (false); + } + ConstElementPtr stat_max_samples = params->get("max-samples"); + if (!stat_max_samples) { + reason = "Missing mandatory 'max-samples' parameter."; + return (false); + } + if (stat_max_samples->getType() != Element::integer) { + reason = "'max-samples' parameter expected to be an integer."; + return (false); + } + + max_samples = stat_max_samples->intValue(); + return (true); +} + }; }; diff --git a/src/lib/stats/stats_mgr.h b/src/lib/stats/stats_mgr.h index 085ab3cb5b..3ba00ad072 100644 --- a/src/lib/stats/stats_mgr.h +++ b/src/lib/stats/stats_mgr.h @@ -160,6 +160,12 @@ class StatsMgr : public boost::noncopyable { /// setMaxSampleCount("incoming-packets", 100); bool setMaxSampleCount(const std::string& name, uint32_t max_samples); + /// @brief Set duration limit for all collected statistics. + void setMaxSampleAgeAll(const StatsDuration& duration); + + /// @brief Set count limit for all collected statistics. + void setMaxSampleCountAll(uint32_t max_samples); + /// @} /// @defgroup consumer_methods Methods are used by data consumers. @@ -191,7 +197,7 @@ class StatsMgr : public boost::noncopyable { /// @brief Returns size of specified statistic. /// /// @param name name of the statistic which size should be return. - /// @return size of specified statistic. + /// @return size of specified statistic, 0 means lack of given statistic. size_t getSize(const std::string& name) const; /// @brief Returns number of available statistics. @@ -300,6 +306,50 @@ class StatsMgr : public boost::noncopyable { statisticRemoveHandler(const std::string& name, const isc::data::ConstElementPtr& params); + /// @brief Handles statistic-set-max-sample-age command + /// + /// This method handles statistic-set-max-sample-age command, + /// which set max_sample_age_ limit of a given statistic + /// and leaves max_sample_count_ disabled. + /// It expects two parameters stored in params map: + /// name: name-of-the-statistic + /// duration: time limit expressed as a number of seconds + /// + /// Example params structure: + /// { + /// "name": "packets-received", + /// "duration": 1245 + /// } + /// + /// @param name name of the command (ignored, should be "statistic-set-max-sample-age") + /// @param params structure containing a map that contains "name" and "duration" + /// @return answer containing information about successfully setup limit of statistic + static isc::data::ConstElementPtr + statisticSetMaxSampleAgeHandler(const std::string& name, + const isc::data::ConstElementPtr& params); + + /// @brief Handles statistic-set-max-sample-count command + /// + /// This method handles statistic-set-max-sample-count command, + /// which set max_sample_count_ limit of a given statistic + /// and leaves max_sample_age_ disabled. + /// It expects two parameters stored in params map: + /// name: name-of-the-statistic + /// max-samples: value of max_sample_count_ + /// + /// Example params structure: + /// { + /// "name": "packets-received", + /// "max-samples": 15 + /// } + /// + /// @param name name of the command (ignored, should be "statistic-set-max-sample-count") + /// @param params structure containing a map that contains "name" and "max-samples" + /// @return answer containing information about successfully setup limit of statistic + static isc::data::ConstElementPtr + statisticSetMaxSampleCountHandler(const std::string& name, + const isc::data::ConstElementPtr& params); + /// @brief Handles statistic-get-all command /// /// This method handles statistic-get-all command, which returns values @@ -336,6 +386,45 @@ class StatsMgr : public boost::noncopyable { statisticRemoveAllHandler(const std::string& name, const isc::data::ConstElementPtr& params); + /// @brief Handles statistic-set-max-sample-age-all command + /// + /// This method handles statistic-set-max-sample-age-all command, + /// which set max_sample_age_ limit to all statistics. + /// It expects one parameter stored in params map: + /// duration: limit expressed as a number of seconds + /// + /// Example params structure: + /// { + /// "duration": 1245 + /// } + /// + /// @param name name of the command (ignored, should be "statistic-set-max-sample-age-all") + /// @param params structure containing a map that contains "duration" + /// @return answer confirming success of this operation + static isc::data::ConstElementPtr + statisticSetMaxSampleAgeAllHandler(const std::string& name, + const isc::data::ConstElementPtr& params); + + /// @brief Handles statistic-set-max-sample-count command + /// + /// This method handles statistic-set-max-sample-count command, + /// which set max_sample_count_ limit of a given statistic + /// and leaves max_sample_age_ disabled. + /// It expects one parameter stored in params map: + /// max-samples: value of max_sample_count_ + /// + /// Example params structure: + /// { + /// "max-samples": 15 + /// } + /// + /// @param name name of the command (ignored, should be "statistic-set-max-sample-count") + /// @param params structure containing a map that contains "max-samples" + /// @return answer confirming success of this operation + static isc::data::ConstElementPtr + statisticSetMaxSampleCountAllHandler(const std::string& name, + const isc::data::ConstElementPtr& params); + /// @} private: @@ -433,6 +522,45 @@ private: std::string& name, std::string& reason); + /// @brief Utility method that attempts to extract duration limit for + /// a given statistic + /// + /// This method attempts to extract duration limit for a given statistic + /// from the params structure. + /// It is expected to be a map that contains four 'duration' elements: 'hours', + /// 'minutes', 'seconds' and 'milliseconds' + /// all are of type int. If present as expected, statistic duration + /// limit is set and true is returned. + /// If any of these four parameters is missing or is of incorrect type, + /// the reason is specified in reason parameter and false is returned. + /// + /// @param params parameters structure received in command + /// @param duration [out] duration limit for the statistic (if no error detected) + /// @param reason [out] failure reason (if error is detected) + /// @return true (if everything is ok), false otherwise + static bool getStatDuration(const isc::data::ConstElementPtr& params, + StatsDuration& duration, + std::string& reason); + + /// @brief Utility method that attempts to extract count limit for + /// a given statistic + /// + /// This method attempts to extract count limit for a given statistic + /// from the params structure. + /// It is expected to be a map that contains 'max_samples' element, + /// that is of type int. If present as expected, statistic count + /// limit (max_samples) is set and true is returned. + /// If missing or is of incorrect type, the reason is specified in reason + /// parameter and false is returned. + /// + /// @param params parameters structure received in command + /// @param max_samples [out] count limit for the statistic (if no error detected) + /// @param reason [out] failure reason (if error is detected) + /// @return true (if everything is ok), false otherwise + static bool getStatMaxSamples(const isc::data::ConstElementPtr& params, + uint32_t& max_samples, + std::string& reason); + // This is a global context. All statistics will initially be stored here. StatContextPtr global_; }; diff --git a/src/lib/stats/tests/observation_unittest.cc b/src/lib/stats/tests/observation_unittest.cc index 2cab680da8..e12d406626 100644 --- a/src/lib/stats/tests/observation_unittest.cc +++ b/src/lib/stats/tests/observation_unittest.cc @@ -430,6 +430,35 @@ TEST_F(ObservationTest, setAgeLimit) { } } +// Test checks whether we can get max_sample_age_ and max_sample_count_ +// properly. +TEST_F(ObservationTest, getLimits) { + // First checks whether getting default values works properly + EXPECT_EQ(a.getMaxSampleAge().first, false); + EXPECT_EQ(b.getMaxSampleAge().first, false); + EXPECT_EQ(c.getMaxSampleAge().first, false); + EXPECT_EQ(d.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(a.getMaxSampleCount().second, 20); + EXPECT_EQ(b.getMaxSampleCount().second, 20); + EXPECT_EQ(c.getMaxSampleCount().second, 20); + EXPECT_EQ(d.getMaxSampleCount().second, 20); + + // Change limit to max_sample_age_ + a.setMaxSampleAge(millisec::time_duration(0, 4, 5, 3)); + EXPECT_EQ(a.getMaxSampleAge().first, true); + EXPECT_EQ(a.getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3)); + + EXPECT_EQ(a.getMaxSampleCount().first, false); + EXPECT_EQ(a.getMaxSampleCount().second, 20); + +} + // Test checks whether timing is reported properly. TEST_F(ObservationTest, timers) { ptime before = microsec_clock::local_time(); diff --git a/src/lib/stats/tests/stats_mgr_unittest.cc b/src/lib/stats/tests/stats_mgr_unittest.cc index c61636f70b..7c9ab0b5cd 100644 --- a/src/lib/stats/tests/stats_mgr_unittest.cc +++ b/src/lib/stats/tests/stats_mgr_unittest.cc @@ -136,7 +136,7 @@ TEST_F(StatsMgrTest, getSize) { EXPECT_EQ(StatsMgr::instance().getSize("delta"), 1); } -// Test checks whether setting age limit and count limit works properly +// Test checks whether setting age limit and count limit works properly. TEST_F(StatsMgrTest, setLimits) { // Initializing of an integer type observation StatsMgr::instance().setValue("foo", static_cast(1)); @@ -161,6 +161,66 @@ TEST_F(StatsMgrTest, setLimits) { EXPECT_EQ(StatsMgr::instance().getSize("foo"), 100); } +// Test checks whether setting age limit and count limit to existing +// statistics works properly. +TEST_F(StatsMgrTest, setLimitsAll) { + // Set a couple of statistics + StatsMgr::instance().setValue("alpha", static_cast(1234)); + StatsMgr::instance().setValue("beta", 12.34); + StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4)); + StatsMgr::instance().setValue("delta", "Lorem ipsum"); + + //First, check the setting of time limit to existing statistics + EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAgeAll(time_duration(0, 0, 1, 0))); + // Now check if time limit was set properly + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, + time_duration(0, 0, 1, 0)); + // and whether count limit is disabled + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, + time_duration(0, 0, 1, 0)); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, + time_duration(0, 0, 1, 0)); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, + time_duration(0, 0, 1, 0)); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false); + + //then, check the setting of count limit to existing statistics + EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleCountAll(1200)); + // Now check if count limit was set properly + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 1200); + // and whether count limit is disabled + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 1200); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 1200); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 1200); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false); +} + // This test checks whether a single (get("foo")) and all (getAll()) // statistics are reported properly. TEST_F(StatsMgrTest, getGetAll) { @@ -718,4 +778,199 @@ TEST_F(StatsMgrTest, commandRemoveAll) { EXPECT_EQ(0, StatsMgr::instance().count()); } +// This test checks whether statistic-set-max-sample-age command really set +// max_sample_age_ limit correctly. +TEST_F(StatsMgrTest, commandSetMaxSampleAge) { + StatsMgr::instance().setValue("alpha", static_cast(1234)); + + ElementPtr params = Element::createMap(); + params->set("name", Element::create("alpha")); + params->set("duration", Element::create(1245)); // time_duration(0, 20, 45, 0) + + ConstElementPtr rsp = + StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-set-max-sample-age", params); + int status_code; + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code); + + // Now check if time limit was set properly + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, + time_duration(0, 20, 45, 0)); + // and whether count limit is disabled + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false); +} + +// Test checks if statistic-set-max-sample-age is able to handle: +// - a request without parameters +// - a request without duration parameter +// - a request with missing statistic name +// - a request for non-existing statistic. +TEST_F(StatsMgrTest, commandSetMaxSampleAgeNegative) { + + // Case 1: a request without parameters + ConstElementPtr rsp = + StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-set-max-sample-age", ElementPtr()); + int status_code; + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(status_code, CONTROL_RESULT_ERROR); + + // Case 2: a request without duration parameter + ElementPtr params = Element::createMap(); + params->set("name", Element::create("alpha")); + rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-set-max-sample-age", params); + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(status_code, CONTROL_RESULT_ERROR); + + // Case 3: a request with missing statistic name + params = Element::createMap(); + params->set("duration", Element::create(100)); + rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-set-max-sample-age", params); + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(status_code, CONTROL_RESULT_ERROR); + + // Case 4: a request for non-existing statistic + params->set("name", Element::create("alpha")); + rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-set-max-sample-age", params); + EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }", + rsp->str()); +} + +TEST_F(StatsMgrTest, commandSetMaxSampleAgeAll) { + // Set a couple of statistics + StatsMgr::instance().setValue("alpha", static_cast(1234)); + StatsMgr::instance().setValue("beta", 12.34); + StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4)); + StatsMgr::instance().setValue("delta", "Lorem ipsum"); + + ElementPtr params = Element::createMap(); + params->set("duration", Element::create(3765)); // time_duration(1, 2, 45, 0) + + ConstElementPtr rsp = + StatsMgr::instance().statisticSetMaxSampleAgeAllHandler("statistic-set-max-sample-age-all", params); + int status_code; + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code); + + // Now check if time limit was set properly + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, + time_duration(1, 2, 45, 0)); + // and whether count limit is disabled + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, + time_duration(1, 2, 45, 0)); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, + time_duration(1, 2, 45, 0)); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, + time_duration(1, 2, 45, 0)); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false); +} + +// This test checks whether statistic-set-max-sample-count command really set +// max_sample_count_ limit correctly. +TEST_F(StatsMgrTest, commandSetMaxSampleCount) { + StatsMgr::instance().setValue("alpha", static_cast(1234)); + + ElementPtr params = Element::createMap(); + params->set("name", Element::create("alpha")); + params->set("max-samples", Element::create(15)); + + ConstElementPtr rsp = + StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-set-max-sample-count", params); + int status_code; + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code); + + // Now check if time limit was set properly + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 15); + + // and whether duration limit is disabled + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false); +} + +// Test checks if statistic-set-max-sample-age is able to handle: +// - a request without parameters +// - a request without max-samples parameter +// - a request with missing statistic name +// - a request for non-existing statistic. +TEST_F(StatsMgrTest, commandSetMaxSampleCountNegative) { + + // Case 1: a request without parameters + ConstElementPtr rsp = + StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-set-max-sample-count", ElementPtr()); + int status_code; + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(status_code, CONTROL_RESULT_ERROR); + + // Case 2: a request without max-samples parameter + ElementPtr params = Element::createMap(); + params->set("name", Element::create("alpha")); + rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-set-max-sample-count", params); + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(status_code, CONTROL_RESULT_ERROR); + + // Case 3: a request with missing statistic name + params = Element::createMap(); + params->set("max-samples", Element::create(10)); + rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-set-max-sample-count", params); + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(status_code, CONTROL_RESULT_ERROR); + + // Case 4: a request for non-existing statistic + params->set("name", Element::create("alpha")); + rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-set-max-sample-count", params); + EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }", + rsp->str()); +} + +TEST_F(StatsMgrTest, commandSetMaxSampleCountAll) { + // Set a couple of statistics + StatsMgr::instance().setValue("alpha", static_cast(1234)); + StatsMgr::instance().setValue("beta", 12.34); + StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4)); + StatsMgr::instance().setValue("delta", "Lorem ipsum"); + + ElementPtr params = Element::createMap(); + params->set("max-samples", Element::create(200)); + + ConstElementPtr rsp = + StatsMgr::instance().statisticSetMaxSampleCountAllHandler("statistic-set-max-sample-count-all", params); + int status_code; + ASSERT_NO_THROW(parseAnswer(status_code, rsp)); + EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code); + // Now check if count limit was set properly + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 200); + // and whether count limit is disabled + EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 200); + + EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 200); + + EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true); + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 200); + + EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false); +} + };