#include <exceptions/exceptions.h>
#include <stats/stats_mgr.h>
+#include <cc/data.h>
+#include <config/command_interpreter.h>
using namespace std;
+using namespace isc::data;
+using namespace isc::config;
namespace isc {
namespace stats {
return (global_->stats_.size());
}
+isc::data::ConstElementPtr
+StatsMgr::statisticGetHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& params) {
+ if (!params) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "Missing mandatory 'name' parameter."));
+ }
+ ConstElementPtr stat_name = params->get("name");
+ if (!stat_name) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "Missing mandatory 'name' parameter."));
+ }
+ if (stat_name->getType() != Element::string) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "'name' parameter expected to be a string."));
+ }
+ return (createAnswer(CONTROL_RESULT_SUCCESS, get(stat_name->stringValue())));
+}
+
+isc::data::ConstElementPtr
+StatsMgr::statisticResetHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& params) {
+ if (!params) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "Missing mandatory 'name' parameter."));
+ }
+ ConstElementPtr stat_name = params->get("name");
+ if (!stat_name) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "Missing mandatory 'name' parameter."));
+ }
+ if (stat_name->getType() != Element::string) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "'name' parameter expected to be a string."));
+ }
+
+ if (reset(stat_name->stringValue())) {
+ return (createAnswer(CONTROL_RESULT_SUCCESS,
+ "Statistic '" + stat_name->stringValue() + "' reset."));
+ } else {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "No '" + stat_name->stringValue() + "' statistic found"));
+ }
+}
+
+isc::data::ConstElementPtr
+StatsMgr::statisticRemoveHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& params) {
+ if (!params) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "Missing mandatory 'name' parameter."));
+ }
+ ConstElementPtr stat_name = params->get("name");
+ if (!stat_name) {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "Missing mandatory 'name' parameter."));
+ }
+ if (del(stat_name->stringValue())) {
+ return (createAnswer(CONTROL_RESULT_SUCCESS,
+ "Statistic '" + stat_name->stringValue() + "' removed."));
+ } else {
+ return (createAnswer(CONTROL_RESULT_ERROR,
+ "No '" + stat_name->stringValue() + "' statistic found"));
+ }
+
+}
+
+isc::data::ConstElementPtr
+StatsMgr::statisticRemoveAllHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& /*params*/) {
+ removeAll();
+ return (createAnswer(CONTROL_RESULT_SUCCESS,
+ "All statistics removed."));
+}
+
+isc::data::ConstElementPtr
+StatsMgr::statisticGetAllHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& /*params*/) {
+ ConstElementPtr all_stats = getAll();
+ return (createAnswer(CONTROL_RESULT_SUCCESS, all_stats));
+}
+
+isc::data::ConstElementPtr
+StatsMgr::statisticResetAllHandler(const std::string& /*name*/,
+ const isc::data::ConstElementPtr& /*params*/) {
+ resetAll();
+ return (createAnswer(CONTROL_RESULT_SUCCESS,
+ "All statistics reset to neutral values."));
+}
};
/// @return Pointer to the Observation object
ObservationPtr getObservation(const std::string& name) const;
+ /// @defgroup command_methods Methods are used to handle commands.
+ ///
+ /// @brief The following methods are used to handle commands:
+ ///
+ /// @{
+
+ /// @brief Handles statistic-get command
+ ///
+ /// This method handles statistic-get command, which returns value
+ /// of a given statistic). It expects one parameter stored in params map:
+ /// name: name-of-the-statistic
+ ///
+ /// Example params structure:
+ /// {
+ /// "name": "packets-received"
+ /// }
+ ///
+ /// @param name name of the command (ignored, should be "statistic-get")
+ /// @param params structure containing a map that contains "name"
+ /// @param return answer containing details of specified statistic
+ isc::data::ConstElementPtr
+ statisticGetHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
+ /// @param Handles statistic-reset command
+ ///
+ /// This method handles statistic-reset command, which resets value
+ /// of a given statistic. It expects one parameter stored in params map:
+ /// name: name-of-the-statistic
+ ///
+ /// Example params structure:
+ /// {
+ /// "name": "packets-received"
+ /// }
+ ///
+ /// @param name name of the command (ignored, should be "statistic-reset")
+ /// @param params structure containing a map that contains "name"
+ /// @param return answer containing confirmation
+ isc::data::ConstElementPtr
+ statisticResetHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
+ /// @param Handles statistic-remove command
+ ///
+ /// This method handles statistic-reset command, which removes a given
+ /// statistic completely. It expects one parameter stored in params map:
+ /// name: name-of-the-statistic
+ ///
+ /// Example params structure:
+ /// {
+ /// "name": "packets-received"
+ /// }
+ ///
+ /// @param name name of the command (ignored, should be "statistic-remove")
+ /// @param params structure containing a map that contains "name" element
+ /// @param return answer containing confirmation
+ isc::data::ConstElementPtr
+ statisticRemoveHandler(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
+ /// of all statistics. Params parameter is ignored.
+ ///
+ /// @param name name of the command (ignored, should be "statistic-get-all")
+ /// @param params ignored
+ /// @param return answer containing values of all statistic
+ isc::data::ConstElementPtr
+ statisticGetAllHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
+ /// @brief Handles statistic-reset-all command
+ ///
+ /// This method handles statistic-reset-all command, which sets values of
+ /// all statistics back to zero. Params parameter is ignored.
+ ///
+ /// @param name name of the command (ignored, should be "statistic-reset-all")
+ /// @param params ignored
+ /// @param return answer confirming success of this operation
+ isc::data::ConstElementPtr
+ statisticResetAllHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
+ /// @brief Handles statistic-remove-all command
+ ///
+ /// This method handles statistic-remove-all command, which removes all
+ /// statistics. Params parameter is ignored.
+ ///
+ /// @param name name of the command (ignored, should be "statistic-remove-all")
+ /// @param params ignored
+ /// @param return answer confirming success of this operation
+ isc::data::ConstElementPtr
+ statisticRemoveAllHandler(const std::string& name,
+ const isc::data::ConstElementPtr& params);
+
+ /// @}
+
private:
/// @brief Sets a given statistic to specified value (internal version).
#include <stats/stats_mgr.h>
#include <exceptions/exceptions.h>
#include <cc/data.h>
+#include <config/command_interpreter.h>
#include <util/boost_time_utils.h>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/shared_ptr.hpp>
using namespace isc;
using namespace isc::data;
using namespace isc::stats;
+using namespace isc::config;
using namespace boost::posix_time;
namespace {
/// Makes sure that the Statistics Manager is instantiated.
StatsMgrTest() {
StatsMgr::instance();
+ StatsMgr::instance().removeAll();
}
/// @brief Destructor
<< " times took: " << isc::util::durationToText(dur) << std::endl;
}
+// Test checks if statistic-get handler is able to return specified statistic.
+TEST_F(StatsMgrTest, commandStatisticGet) {
+ StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+
+ ElementPtr params = Element::createMap();
+ params->set("name", Element::create("alpha"));
+
+ ConstElementPtr rsp = StatsMgr::instance().statisticGetHandler("statistic-get",
+ params);
+
+ ObservationPtr alpha;
+ EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
+ ASSERT_TRUE(alpha);
+
+ std::string exp = "{ \"alpha\": [ [ 1234, \""
+ + isc::util::ptimeToText(alpha->getInteger().second) + "\" ] ] }";
+
+ EXPECT_EQ("{ \"arguments\": " + exp + ", \"result\": 0 }", rsp->str());
+}
+
+// Test checks if statistic-get is able to handle:
+// - a request without parameters
+// - a request with missing statistic name
+// - a request for non-existing statistic.
+TEST_F(StatsMgrTest, commandStatisticGetNegative) {
+
+ // Case 1: a request without parameters
+ ConstElementPtr rsp = StatsMgr::instance().statisticGetHandler("statistic-get",
+ ElementPtr());
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 2: a request with missing statistic name
+ ElementPtr params = Element::createMap();
+ rsp = StatsMgr::instance().statisticGetHandler("statistic-get", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 3: a request for non-existing statistic
+ params->set("name", Element::create("alpha"));
+ rsp = StatsMgr::instance().statisticGetHandler("statistic-get", params);
+ EXPECT_EQ("{ \"arguments\": { }, \"result\": 0 }", rsp->str());
+}
+
+// This test checks whether statistc-get-all command returns all statistics
+// correctly.
+TEST_F(StatsMgrTest, commandGetAll) {
+
+ // 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");
+
+ // Now get them. They're used to generate expected output
+ 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 = "[ [ 1234, \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("alpha")
+ ->getInteger().second) + "\" ] ]";
+ std::string exp_str_beta = "[ [ 12.34, \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("beta")
+ ->getFloat().second) + "\" ] ]";
+ std::string exp_str_gamma = "[ [ \"01:02:03.000004\", \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("gamma")
+ ->getDuration().second) + "\" ] ]";
+ std::string exp_str_delta = "[ [ \"Lorem ipsum\", \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("delta")
+ ->getString().second) + "\" ] ]";
+
+ // Check that all of them can be reported at once
+ ConstElementPtr rsp = StatsMgr::instance().statisticGetAllHandler(
+ "statistic-get-all", ElementPtr());
+ ASSERT_TRUE(rsp);
+ int status_code;
+ ConstElementPtr rep_all = parseAnswer(status_code, rsp);
+ ASSERT_EQ(0, status_code);
+ ASSERT_TRUE(rep_all);
+
+ // Verifying this is a bit more involved, as we don't know whether the
+ // order would be preserved or not.
+ EXPECT_EQ(4, rep_all->size());
+ ASSERT_TRUE(rep_all->get("alpha"));
+ ASSERT_TRUE(rep_all->get("beta"));
+ ASSERT_TRUE(rep_all->get("delta"));
+ ASSERT_TRUE(rep_all->get("gamma"));
+ EXPECT_FALSE(rep_all->get("epsilon"));
+
+ EXPECT_EQ(exp_str_alpha, rep_all->get("alpha")->str());
+ EXPECT_EQ(exp_str_beta, rep_all->get("beta")->str());
+ EXPECT_EQ(exp_str_gamma, rep_all->get("gamma")->str());
+ EXPECT_EQ(exp_str_delta, rep_all->get("delta")->str());
+}
+
+// Test checks if statistic-reset handler is able to reset specified statistic.
+TEST_F(StatsMgrTest, commandStatisticReset) {
+ StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+
+ ElementPtr params = Element::createMap();
+ params->set("name", Element::create("alpha"));
+
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticResetHandler("statistic-reset", params);
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
+
+ ObservationPtr alpha;
+ EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
+ ASSERT_TRUE(alpha);
+
+ // Check that it was indeed reset
+ EXPECT_EQ(0, alpha->getInteger().first);
+}
+
+// Test checks if statistic-reset is able to handle:
+// - a request without parameters
+// - a request with missing statistic name
+// - a request for non-existing statistic.
+TEST_F(StatsMgrTest, commandStatisticResetNegative) {
+
+ // Case 1: a request without parameters
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticResetHandler("statistic-reset", ElementPtr());
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 2: a request with missing statistic name
+ ElementPtr params = Element::createMap();
+ rsp = StatsMgr::instance().statisticResetHandler("statistic-reset", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 3: a request for non-existing statistic
+ params->set("name", Element::create("alpha"));
+ rsp = StatsMgr::instance().statisticResetHandler("statistic-reset", params);
+ EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
+ rsp->str());
+}
+
+// This test checks whether statistic-reset-all command really resets all
+// statistics correctly.
+TEST_F(StatsMgrTest, commandResetAll) {
+
+ // 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");
+
+ // Now get them. They're used to generate expected output
+ 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 = "[ [ 1234, \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("alpha")
+ ->getInteger().second) + "\" ] ]";
+ std::string exp_str_beta = "[ [ 12.34, \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("beta")
+ ->getFloat().second) + "\" ] ]";
+ std::string exp_str_gamma = "[ [ \"01:02:03.000004\", \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("gamma")
+ ->getDuration().second) + "\" ] ]";
+ std::string exp_str_delta = "[ [ \"Lorem ipsum\", \""
+ + isc::util::ptimeToText(StatsMgr::instance().getObservation("delta")
+ ->getString().second) + "\" ] ]";
+
+ // Check that all of them can be reset at once
+ ConstElementPtr rsp = StatsMgr::instance().statisticResetAllHandler(
+ "statistic-reset-all", ElementPtr());
+ ASSERT_TRUE(rsp);
+ int status_code;
+ ConstElementPtr rep_all = parseAnswer(status_code, rsp);
+ ASSERT_EQ(0, status_code);
+ ASSERT_TRUE(rep_all);
+
+ // Check that they're indeed reset
+ EXPECT_EQ(0, StatsMgr::instance().getObservation("alpha")->getInteger().first);
+ EXPECT_EQ(0.0f,
+ 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);
+}
+
+// Test checks if statistic-remove handler is able to remove a statistic.
+TEST_F(StatsMgrTest, commandStatisticRemove) {
+ StatsMgr::instance().setValue("alpha", static_cast<uint64_t>(1234));
+
+ ElementPtr params = Element::createMap();
+ params->set("name", Element::create("alpha"));
+
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticRemoveHandler("statistic-remove", params);
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
+
+ // It should be gone.
+ EXPECT_FALSE(StatsMgr::instance().getObservation("alpha"));
+}
+
+// Test checks if statistic-remove is able to handle:
+// - a request without parameters
+// - a request with missing statistic name
+// - a request for non-existing statistic.
+TEST_F(StatsMgrTest, commandStatisticRemoveNegative) {
+
+ // Case 1: a request without parameters
+ ConstElementPtr rsp =
+ StatsMgr::instance().statisticRemoveHandler("statistic-remove", ElementPtr());
+ int status_code;
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 2: a request with missing statistic name
+ ElementPtr params = Element::createMap();
+ rsp = StatsMgr::instance().statisticRemoveHandler("statistic-remove", params);
+ ASSERT_NO_THROW(parseAnswer(status_code, rsp));
+ EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
+
+ // Case 3: a request for non-existing statistic
+ params->set("name", Element::create("alpha"));
+ rsp = StatsMgr::instance().statisticRemoveHandler("statistic-remove", params);
+ EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
+ rsp->str());
+}
+
+// This test checks whether statistic-remove-all command really resets all
+// statistics correctly.
+TEST_F(StatsMgrTest, commandRemoveAll) {
+
+ // 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");
+
+ // Check that all of them can be reset at once
+ ConstElementPtr rsp = StatsMgr::instance().statisticRemoveAllHandler(
+ "statistic-remove-all", ElementPtr());
+ ASSERT_TRUE(rsp);
+ int status_code;
+ ConstElementPtr rep_all = parseAnswer(status_code, rsp);
+ ASSERT_EQ(0, status_code);
+
+ EXPECT_FALSE(StatsMgr::instance().getObservation("alpha"));
+ EXPECT_FALSE(StatsMgr::instance().getObservation("beta"));
+ EXPECT_FALSE(StatsMgr::instance().getObservation("gamma"));
+ EXPECT_FALSE(StatsMgr::instance().getObservation("delta"));
+}
+
};