]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
new statistics commands
authorFranciszek Gorski <fagorski9@gmail.com>
Mon, 15 Jul 2019 10:19:12 +0000 (12:19 +0200)
committerRazvan Becheriu <razvan@isc.org>
Mon, 5 Aug 2019 17:34:27 +0000 (20:34 +0300)
src/lib/stats/observation.cc
src/lib/stats/observation.h
src/lib/stats/stats_mgr.cc
src/lib/stats/stats_mgr.h
src/lib/stats/tests/observation_unittest.cc
src/lib/stats/tests/stats_mgr_unittest.cc

index b790e8eb5b7973c4a5a9df4ca8d837eb873ab095..33661ffa9d92227e3ac7522e9f159bb57f2abc09 100644 (file)
@@ -150,6 +150,14 @@ size_t Observation::getSize() const {
     return (size);
 }
 
+std::pair<bool, StatsDuration> Observation::getMaxSampleAge() const {
+    return (max_sample_age_);
+}
+
+std::pair<bool, uint32_t> Observation::getMaxSampleCount() const {
+    return (max_sample_count_);
+}
+
 template<typename StorageType>
 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) {
index 23fd7ef23e04e497344c544fb4dc857fde5661bb..28cf9a8bdc2fe81d092da6a1f2af42ea5f62d48e 100644 (file)
@@ -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<bool, StatsDuration> getMaxSampleAge() const;
+
+    /// @brief Returns both value of max_sample_count_ of statistic.
+    ///
+    /// @return max_sample_count_.
+    std::pair<bool, uint32_t> getMaxSampleCount() const;
+
     /// @brief Resets statistic.
     ///
     /// Sets statistic to a neutral (0, 0.0 or "") value and
index eb2500ce345e4bc86e33ae0af57a5be690fdb844..444b5e49b863ebba0233aadae0c4bc3739cf5197 100644 (file)
@@ -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<std::string, ObservationPtr>::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<std::string, ObservationPtr>::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);
+}
+
 };
 };
index 085ab3cb5b60ebe5264c1cbc21ef330a24c4eca8..3ba00ad0722dd6fa62cfd709627784860cc88eff 100644 (file)
@@ -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_;
 };
index 2cab680da8956dd16848779fd41513f3d25deb37..e12d406626d24c55925ee705db1183565d4f4efc 100644 (file)
@@ -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();
index c61636f70bc7d58e4ec83da845316d73478103bf..7c9ab0b5cd837076466f0c221b08ac172097b9a9 100644 (file)
@@ -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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(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);
+}
+
 };