Commit 2a599377 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[3793] StatContext implemented.

parent 83b9b8a8
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <stats/context.h>
#include <map>
namespace isc {
namespace stats {
ObservationPtr StatContext::get(const std::string& name) {
std::map<std::string, ObservationPtr>::iterator obs = stats_.find(name);
if (obs == stats_.end()) {
return (ObservationPtr());
} else {
return (obs->second);
}
}
void StatContext::add(const ObservationPtr& obs) {
std::map<std::string, ObservationPtr>::iterator obs = stats_.find(name);
if (obs == stats_.end()) {
stats_.insert(make_pair(obs->getName() ,obs));
} else {
isc_throw(InvalidStatType, "Statistic named " << obs->getName()
<< " already exists.");
}
}
bool StatContext::del(const std::string& name) {
std::map<std::string, ObservationPtr>::iterator obs = stats_.find(name);
if (obs == stats_.end()) {
return (false);
} else {
stats_.erase(obs);
return (true);
}
}
};
};
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef CONTEXT_H
#define CONTEXT_H
#include <stats/observation.h>
#include <boost/shared_ptr.hpp>
#include <string>
namespace isc {
namespace stats {
/// @brief Exception indicating that a given statistic is duplicated.
class DuplicateStat : public Exception {
public:
DuplicateStat(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Statistics context
///
/// Statistics context is essentially a container used to group statistics
/// related to a given context together. Two examples of such contexts are
/// all statistics related to a given subnet or all statistics related to a
/// given network interface.
class StatContext {
public:
std::map<std::string, ObservationPtr> stats;
/// @brief attempts to get an observation
/// @param name name of the statistic
/// @return appropriate Observation object (or NULL)
ObservationPtr get(const std::string& name);
/// @brief Adds a new observation
/// @param obs observation to be added
/// @throw DuplicateStat if an observation with the same name exists already
void add(const ObservationPtr& obs);
/// @brief Attempts to delete an observation
/// @param name name of the observation to be deleted
/// @return true if successful, false if no such statistic was found
bool del(const std::string& name);
/// @brief Statistics container
///
/// It is public to allow various operations that require iterating over
/// all elements. In particular, two operations (setting all stats to 0;
/// reporting all stats) will take advantage of this. Alternatively, we
/// could make it protected and then return a pointer to it, but that
/// would defeat the purpose of the hermetization in the first place.
std::map<std::string, ObservationPtr> stats_;
};
typedef boost::shared_ptr<StatContext> StatContextPtr;
typedef boost::shared_ptr<StatContext> StatContextPtr;
};
};
......
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <stats/context.h>
#include <gtest/gtest.h>
using namespace isc::stats;
// Basic test that checks get, add, del methods
TEST(ContextTest, basic) {
// Let's create a couple observations. Using floating point,
// as they're easiest to initialize.
ObservationPtr a(new Observation("alpha", 1.11));
ObservationPtr b(new Observation("beta", 2.22));
ObservationPtr c(new Observation("gamma", 3.33));
// Context where we will store the observations.
StatContext ctx;
// By default the context does not hold any statistics.
EXPECT_EQ(0, ctx.stats_.size());
EXPECT_TRUE(ctx.stats_.empty());
// It should be possible to add 'a' statistic
EXPECT_NO_THROW(ctx.add(a));
// We can't add a duplicate.
EXPECT_THROW(ctx.add(a), DuplicateStat);
// It should be ok to add other statistics
EXPECT_NO_THROW(ctx.add(b));
EXPECT_NO_THROW(ctx.add(c));
// By now we should have 3 statistics recorded
EXPECT_EQ(3, ctx.stats_.size());
EXPECT_FALSE(ctx.stats_.empty());
// Let's try to retrieve them
ObservationPtr from_ctx;
EXPECT_NO_THROW(from_ctx = ctx.get("alpha"));
ASSERT_TRUE(from_ctx);
EXPECT_EQ(a->getJSON()->str(), from_ctx->getJSON()->str());
EXPECT_NO_THROW(from_ctx = ctx.get("beta"));
ASSERT_TRUE(from_ctx);
EXPECT_EQ(b->getJSON()->str(), from_ctx->getJSON()->str());
EXPECT_NO_THROW(from_ctx = ctx.get("gamma"));
ASSERT_TRUE(from_ctx);
EXPECT_EQ(c->getJSON()->str(), from_ctx->getJSON()->str());
// Let's try to retrieve non-existing stat
EXPECT_NO_THROW(from_ctx = ctx.get("delta"));
EXPECT_FALSE(from_ctx);
// Now delete one of the stats...
EXPECT_TRUE(ctx.del("beta"));
// ... and check that it's really gone.
EXPECT_FALSE(ctx.get("beta"));
// Attempt to delete non-existing stat should fail.
EXPECT_FALSE(ctx.del("beta"));
}
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