2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 05:55:28 +00:00

Revert "Merge branch 'master' into trac510"

This reverts commit 662233a148, reversing
changes made to b41b7dc34a.
This commit is contained in:
Yoshitaka Aharen
2011-12-08 21:04:34 +09:00
parent 777d6f3037
commit e82cf73f21
21 changed files with 62 additions and 974 deletions

View File

@@ -1,9 +1,3 @@
339. [func] y-aharen
src/lib/statistics: Added statistics counter library for entire server
items and per zone items. Also, modified b10-auth to use it. It is
also intended to use in the other modules such as b10-resolver.
(Trac #510, git TBD)
338. [bug] jinmei
b10-xfrin didn't check SOA serials of SOA and IXFR responses,
which resulted in unnecessary transfer or unexpected IXFR

View File

@@ -933,8 +933,6 @@ AC_CONFIG_FILES([Makefile
src/lib/util/tests/Makefile
src/lib/acl/Makefile
src/lib/acl/tests/Makefile
src/lib/statistics/Makefile
src/lib/statistics/tests/Makefile
tests/Makefile
tests/system/Makefile
tests/tools/Makefile

View File

@@ -71,7 +71,6 @@ b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/log/liblog.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
b10_auth_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
b10_auth_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la
b10_auth_LDADD += $(SQLITE_LIBS)
# TODO: config.h.in is wrong because doesn't honor pkgdatadir

View File

@@ -671,9 +671,9 @@ void
AuthSrvImpl::incCounter(const int protocol) {
// Increment query counter.
if (protocol == IPPROTO_UDP) {
counters_.inc(AuthCounters::SERVER_UDP_QUERY);
counters_.inc(AuthCounters::COUNTER_UDP_QUERY);
} else if (protocol == IPPROTO_TCP) {
counters_.inc(AuthCounters::SERVER_TCP_QUERY);
counters_.inc(AuthCounters::COUNTER_TCP_QUERY);
} else {
// unknown protocol
isc_throw(Unexpected, "Unknown protocol: " << protocol);
@@ -766,7 +766,7 @@ bool AuthSrv::submitStatistics() const {
}
uint64_t
AuthSrv::getCounter(const AuthCounters::ServerCounterType type) const {
AuthSrv::getCounter(const AuthCounters::CounterType type) const {
return (impl_->counters_.getCounter(type));
}

View File

@@ -343,7 +343,7 @@ public:
/// \param type Type of a counter to get the value of
///
/// \return the value of the counter.
uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
uint64_t getCounter(const AuthCounters::CounterType type) const;
/**
* \brief Set and get the addresses we listen on.

View File

@@ -35,6 +35,5 @@ query_bench_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
query_bench_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
query_bench_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la
query_bench_LDADD += $(SQLITE_LIBS)

View File

@@ -18,67 +18,48 @@
#include <cc/data.h>
#include <cc/session.h>
#include <statistics/counter.h>
#include <statistics/counter_dict.h>
#include <sstream>
#include <iostream>
#include <boost/noncopyable.hpp>
using namespace isc::auth;
using namespace isc::statistics;
// TODO: We need a namespace ("auth_server"?) to hold
// AuthSrv and AuthCounters.
// AuthSrv and AuthCounters.
// TODO: Make use of wrappers like isc::dns::Opcode
// for counter item type.
class AuthCountersImpl : boost::noncopyable {
class AuthCountersImpl {
private:
// prohibit copy
AuthCountersImpl(const AuthCountersImpl& source);
AuthCountersImpl& operator=(const AuthCountersImpl& source);
public:
AuthCountersImpl();
~AuthCountersImpl();
void inc(const AuthCounters::ServerCounterType type);
void inc(const std::string& zone,
const AuthCounters::PerZoneCounterType type);
void inc(const AuthCounters::CounterType type);
bool submitStatistics() const;
void setStatisticsSession(isc::cc::AbstractSession* statistics_session);
void registerStatisticsValidator
(AuthCounters::validator_type validator);
// Currently for testing purpose only
uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
uint64_t getCounter(const AuthCounters::CounterType type) const;
private:
Counter server_counter_;
CounterDictionary per_zone_counter_;
std::vector<uint64_t> counters_;
isc::cc::AbstractSession* statistics_session_;
AuthCounters::validator_type validator_;
};
AuthCountersImpl::AuthCountersImpl() :
// initialize counter
// size of server_counter_: AuthCounters::SERVER_COUNTER_TYPES
// size of per_zone_counter_: AuthCounters::PER_ZONE_COUNTER_TYPES
server_counter_(AuthCounters::SERVER_COUNTER_TYPES),
per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES),
// size: AuthCounters::COUNTER_TYPES, initial value: 0
counters_(AuthCounters::COUNTER_TYPES, 0),
statistics_session_(NULL)
{
per_zone_counter_.addElement("_SERVER_");
}
{}
AuthCountersImpl::~AuthCountersImpl()
{}
void
AuthCountersImpl::inc(const AuthCounters::ServerCounterType type) {
server_counter_.inc(type);
}
void
AuthCountersImpl::inc(const std::string& zone,
const AuthCounters::PerZoneCounterType type)
{
per_zone_counter_[zone].inc(type);
AuthCountersImpl::inc(const AuthCounters::CounterType type) {
++counters_.at(type);
}
bool
@@ -92,9 +73,9 @@ AuthCountersImpl::submitStatistics() const {
<< "{ \"owner\": \"Auth\","
<< " \"data\":"
<< "{ \"queries.udp\": "
<< server_counter_.get(AuthCounters::SERVER_UDP_QUERY)
<< counters_.at(AuthCounters::COUNTER_UDP_QUERY)
<< ", \"queries.tcp\": "
<< server_counter_.get(AuthCounters::SERVER_TCP_QUERY)
<< counters_.at(AuthCounters::COUNTER_TCP_QUERY)
<< " }"
<< "}"
<< "]}";
@@ -145,17 +126,19 @@ AuthCountersImpl::registerStatisticsValidator
// Currently for testing purpose only
uint64_t
AuthCountersImpl::getCounter(const AuthCounters::ServerCounterType type) const {
return (server_counter_.get(type));
AuthCountersImpl::getCounter(const AuthCounters::CounterType type) const {
return (counters_.at(type));
}
AuthCounters::AuthCounters() : impl_(new AuthCountersImpl())
{}
AuthCounters::~AuthCounters() {}
AuthCounters::~AuthCounters() {
delete impl_;
}
void
AuthCounters::inc(const AuthCounters::ServerCounterType type) {
AuthCounters::inc(const AuthCounters::CounterType type) {
impl_->inc(type);
}
@@ -172,7 +155,7 @@ AuthCounters::setStatisticsSession
}
uint64_t
AuthCounters::getCounter(const AuthCounters::ServerCounterType type) const {
AuthCounters::getCounter(const AuthCounters::CounterType type) const {
return (impl_->getCounter(type));
}

View File

@@ -17,7 +17,6 @@
#include <cc/session.h>
#include <stdint.h>
#include <boost/scoped_ptr.hpp>
class AuthCountersImpl;
@@ -52,18 +51,13 @@ class AuthCountersImpl;
/// \todo Consider overhead of \c AuthCounters::inc()
class AuthCounters {
private:
boost::scoped_ptr<AuthCountersImpl> impl_;
AuthCountersImpl* impl_;
public:
// Enum for the type of counter
enum ServerCounterType {
SERVER_UDP_QUERY, ///< SERVER_UDP_QUERY: counter for UDP queries
SERVER_TCP_QUERY, ///< SERVER_TCP_QUERY: counter for TCP queries
SERVER_COUNTER_TYPES ///< The number of defined counters
};
enum PerZoneCounterType {
ZONE_UDP_QUERY, ///< ZONE_UDP_QUERY: counter for UDP queries
ZONE_TCP_QUERY, ///< ZONE_TCP_QUERY: counter for TCP queries
PER_ZONE_COUNTER_TYPES ///< The number of defined counters
enum CounterType {
COUNTER_UDP_QUERY = 0, ///< COUNTER_UDP_QUERY: counter for UDP queries
COUNTER_TCP_QUERY = 1, ///< COUNTER_TCP_QUERY: counter for TCP queries
COUNTER_TYPES = 2 ///< The number of defined counters
};
/// The constructor.
///
@@ -83,9 +77,9 @@ public:
///
/// \throw std::out_of_range \a type is unknown.
///
/// usage: counter.inc(AuthCounters::SERVER_UDP_QUERY);
/// usage: counter.inc(CounterType::COUNTER_UDP_QUERY);
///
void inc(const ServerCounterType type);
void inc(const CounterType type);
/// \brief Submit statistics counters to statistics module.
///
@@ -136,7 +130,7 @@ public:
///
/// \return the value of the counter specified by \a type.
///
uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
uint64_t getCounter(const AuthCounters::CounterType type) const;
/// \brief A type of validation function for the specification in
/// isc::config::ModuleSpec.

View File

@@ -64,7 +64,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
endif

View File

@@ -779,7 +779,7 @@ TEST_F(AuthSrvTest, cacheSlots) {
// Submit UDP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterUDPNormal) {
// The counter should be initialized to 0.
EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_UDP_QUERY));
// Create UDP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -788,13 +788,13 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) {
server.processMessage(*io_message, parse_message, response_obuffer,
&dnsserv);
// After processing UDP query, the counter should be 1.
EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_UDP_QUERY));
}
// Submit TCP normal query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPNormal) {
// The counter should be initialized to 0.
EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
// Create TCP message and process.
UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
default_qid, Name("example.com"),
@@ -803,13 +803,13 @@ TEST_F(AuthSrvTest, queryCounterTCPNormal) {
server.processMessage(*io_message, parse_message, response_obuffer,
&dnsserv);
// After processing TCP query, the counter should be 1.
EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
}
// Submit TCP AXFR query and check query counter
TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
// The counter should be initialized to 0.
EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(0, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
Name("example.com"), RRClass::IN(), RRType::AXFR());
createRequestPacket(request_message, IPPROTO_TCP);
@@ -818,7 +818,7 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(dnsserv.hasAnswer());
// After processing TCP AXFR query, the counter should be 1.
EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP_QUERY));
}
// Submit TCP IXFR query and check query counter

View File

@@ -150,24 +150,25 @@ AuthCountersTest::MockSession::setThrowSessionTimeout(bool flag) {
TEST_F(AuthCountersTest, incrementUDPCounter) {
// The counter should be initialized to 0.
EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_UDP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY));
EXPECT_NO_THROW(counters.inc(AuthCounters::COUNTER_UDP_QUERY));
// After increment, the counter should be 1.
EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
EXPECT_EQ(1, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY));
}
TEST_F(AuthCountersTest, incrementTCPCounter) {
// The counter should be initialized to 0.
EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY));
EXPECT_NO_THROW(counters.inc(AuthCounters::COUNTER_TCP_QUERY));
// After increment, the counter should be 1.
EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(1, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY));
}
TEST_F(AuthCountersTest, incrementInvalidCounter) {
// Expect to throw an isc::OutOfRange
EXPECT_THROW(counters.inc(AuthCounters::SERVER_COUNTER_TYPES),
isc::OutOfRange);
// Expect to throw isc::InvalidParameter if the type of the counter is
// invalid.
EXPECT_THROW(counters.inc(AuthCounters::COUNTER_TYPES),
std::out_of_range);
}
TEST_F(AuthCountersTest, submitStatisticsWithoutSession) {
@@ -194,14 +195,14 @@ TEST_F(AuthCountersTest, submitStatisticsWithoutValidator) {
// Validate if it submits correct data.
// Counters should be initialized to 0.
EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY));
// UDP query counter is set to 2.
counters.inc(AuthCounters::SERVER_UDP_QUERY);
counters.inc(AuthCounters::SERVER_UDP_QUERY);
counters.inc(AuthCounters::COUNTER_UDP_QUERY);
counters.inc(AuthCounters::COUNTER_UDP_QUERY);
// TCP query counter is set to 1.
counters.inc(AuthCounters::SERVER_TCP_QUERY);
counters.inc(AuthCounters::COUNTER_TCP_QUERY);
counters.submitStatistics();
// Destination is "Stats".
@@ -236,14 +237,14 @@ TEST_F(AuthCountersTest, submitStatisticsWithValidator) {
counters.registerStatisticsValidator(validator);
// Counters should be initialized to 0.
EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP_QUERY));
EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP_QUERY));
// UDP query counter is set to 2.
counters.inc(AuthCounters::SERVER_UDP_QUERY);
counters.inc(AuthCounters::SERVER_UDP_QUERY);
counters.inc(AuthCounters::COUNTER_UDP_QUERY);
counters.inc(AuthCounters::COUNTER_UDP_QUERY);
// TCP query counter is set to 1.
counters.inc(AuthCounters::SERVER_TCP_QUERY);
counters.inc(AuthCounters::COUNTER_TCP_QUERY);
// checks the value returned by submitStatistics
EXPECT_TRUE(counters.submitStatistics());

View File

@@ -1,3 +1,3 @@
SUBDIRS = exceptions util log cryptolink dns cc config acl xfr bench \
asiolink asiodns nsas cache resolve testutils datasrc \
server_common python dhcp statistics
server_common python dhcp

View File

@@ -1,24 +0,0 @@
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/statistics -I$(top_builddir)/src/lib/statistics
AM_CXXFLAGS = $(B10_CXXFLAGS)
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
# https://svn.boost.org/trac/boost/ticket/3477
# But older GCC compilers don't have the flag.
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
if USE_CLANGPP
# clang++ complains about unused function parameters in some boost header
# files.
AM_CXXFLAGS += -Wno-unused-parameter
endif
lib_LTLIBRARIES = libstatistics.la
libstatistics_la_SOURCES = counter.h counter.cc
libstatistics_la_SOURCES += counter_dict.h counter_dict.cc
CLEANFILES = *.gcno *.gcda

View File

@@ -1,68 +0,0 @@
#include <vector>
#include <boost/noncopyable.hpp>
#include <statistics/counter.h>
namespace {
const unsigned int InitialValue = 0;
} // namespace
namespace isc {
namespace statistics {
class CounterImpl : boost::noncopyable {
private:
std::vector<Counter::Value> counters_;
public:
CounterImpl(const size_t nelements);
~CounterImpl();
void inc(const Counter::Type&);
const Counter::Value& get(const Counter::Type&) const;
};
CounterImpl::CounterImpl(const size_t items) :
counters_(items, InitialValue)
{
if (items == 0) {
isc_throw(isc::InvalidParameter, "Items must not be 0");
}
}
CounterImpl::~CounterImpl() {}
void
CounterImpl::inc(const Counter::Type& type) {
if(type >= counters_.size()) {
isc_throw(isc::OutOfRange, "Counter type is out of range");
}
++counters_.at(type);
return;
}
const Counter::Value&
CounterImpl::get(const Counter::Type& type) const {
if(type >= counters_.size()) {
isc_throw(isc::OutOfRange, "Counter type is out of range");
}
return (counters_.at(type));
}
Counter::Counter(const size_t items) : impl_(new CounterImpl(items))
{}
Counter::~Counter() {}
void
Counter::inc(const Type& type) {
impl_->inc(type);
return;
}
const Counter::Value&
Counter::get(const Type& type) const {
return (impl_->get(type));
}
} // namespace statistics
} // namespace isc

View File

@@ -1,55 +0,0 @@
#ifndef __COUNTER_H
#define __COUNTER_H 1
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <exceptions/exceptions.h>
namespace isc {
namespace statistics {
// forward declaration for pImpl idiom
class CounterImpl;
class Counter : boost::noncopyable {
private:
boost::scoped_ptr<CounterImpl> impl_;
public:
typedef unsigned int Type;
typedef unsigned int Value;
/// The constructor.
///
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
/// \param items A number of counter items to hold (greater than 0)
///
/// \throw isc::InvalidParameter \a items is 0
Counter(const size_t items);
/// The destructor.
///
/// This method never throws an exception.
~Counter();
/// \brief Increment a counter item specified with \a type.
///
/// \param type %Counter item to increment
///
/// \throw isc::OutOfRange \a type is invalid
void inc(const Type& type);
/// \brief Get the value of a counter item specified with \a type.
///
/// \param type %Counter item to get the value of
///
/// \throw isc::OutOfRange \a type is invalid
const Value& get(const Type& type) const;
};
} // namespace statistics
} // namespace isc
#endif

View File

@@ -1,249 +0,0 @@
#include <cassert>
#include <stdexcept>
#include <iterator>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp>
#include <statistics/counter_dict.h>
namespace {
typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
typedef boost::unordered_map<std::string, CounterPtr> DictionaryMap;
}
namespace isc {
namespace statistics {
// Implementation detail class for CounterDictionary::ConstIterator
class CounterDictionaryConstIteratorImpl;
class CounterDictionaryImpl : boost::noncopyable {
private:
DictionaryMap dictionary_;
std::vector<std::string> elements_;
const size_t items_;
// Default constructor is forbidden; number of counter items must be
// specified at the construction of this class.
CounterDictionaryImpl();
public:
CounterDictionaryImpl(const size_t items);
~CounterDictionaryImpl();
void addElement(const std::string& name);
void deleteElement(const std::string& name);
Counter& getElement(const std::string& name);
public:
CounterDictionaryConstIteratorImpl begin() const;
CounterDictionaryConstIteratorImpl end() const;
};
// Constructor with number of items
CounterDictionaryImpl::CounterDictionaryImpl(const size_t items) :
items_(items)
{
// The number of items must not be 0
if (items == 0) {
isc_throw(isc::InvalidParameter, "Items must not be 0");
}
}
// Destructor
CounterDictionaryImpl::~CounterDictionaryImpl() {}
void
CounterDictionaryImpl::addElement(const std::string& name) {
// throw if the element already exists
if (dictionary_.count(name) != 0) {
isc_throw(isc::InvalidParameter,
"Element " << name << " already exists");
}
assert(items_ != 0);
// Create a new Counter and add to the map
dictionary_.insert(
DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
}
void
CounterDictionaryImpl::deleteElement(const std::string& name) {
size_t result = dictionary_.erase(name);
if (result != 1) {
// If an element with specified name does not exist, throw
// isc::OutOfRange.
isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
}
}
Counter&
CounterDictionaryImpl::getElement(const std::string& name) {
try {
return (*(dictionary_.at(name)));
} catch (const std::out_of_range &e) {
// If an element with specified name does not exist, throw
// isc::OutOfRange.
isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
}
}
// Constructor
// Initialize impl_
CounterDictionary::CounterDictionary(const size_t items) :
impl_(new CounterDictionaryImpl(items))
{}
// Destructor
// impl_ will be freed automatically with scoped_ptr
CounterDictionary::~CounterDictionary() {}
void
CounterDictionary::addElement(const std::string& name) {
impl_->addElement(name);
}
void
CounterDictionary::deleteElement(const std::string& name) {
impl_->deleteElement(name);
}
Counter&
CounterDictionary::getElement(const std::string& name) const {
return (impl_->getElement(name));
}
Counter&
CounterDictionary::operator[](const std::string& name) const {
return (impl_->getElement(name));
}
// Implementation detail class for CounterDictionary::ConstIterator
class CounterDictionaryConstIteratorImpl {
public:
CounterDictionaryConstIteratorImpl();
~CounterDictionaryConstIteratorImpl();
CounterDictionaryConstIteratorImpl(
const CounterDictionaryConstIteratorImpl &other);
CounterDictionaryConstIteratorImpl &operator=(
const CounterDictionaryConstIteratorImpl &source);
CounterDictionaryConstIteratorImpl(
DictionaryMap::const_iterator iterator);
public:
void increment();
CounterDictionary::ValueType dereference() const;
bool equal(const CounterDictionaryConstIteratorImpl& other) const;
private:
DictionaryMap::const_iterator iterator_;
};
CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl() {}
CounterDictionaryConstIteratorImpl::~CounterDictionaryConstIteratorImpl() {}
// Copy constructor: deep copy of iterator_
CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
const CounterDictionaryConstIteratorImpl &other) :
iterator_(other.iterator_)
{}
// Assignment operator: deep copy of iterator_
CounterDictionaryConstIteratorImpl &
CounterDictionaryConstIteratorImpl::operator=(
const CounterDictionaryConstIteratorImpl &source)
{
iterator_ = source.iterator_;
return (*this);
}
// Constructor from implementation detail DictionaryMap::const_iterator
CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
DictionaryMap::const_iterator iterator) :
iterator_(iterator)
{}
CounterDictionaryConstIteratorImpl
CounterDictionaryImpl::begin() const {
return (CounterDictionaryConstIteratorImpl(dictionary_.begin()));
}
CounterDictionaryConstIteratorImpl
CounterDictionaryImpl::end() const {
return (CounterDictionaryConstIteratorImpl(dictionary_.end()));
}
void
CounterDictionaryConstIteratorImpl::increment() {
++iterator_;
return;
}
CounterDictionary::ValueType
CounterDictionaryConstIteratorImpl::dereference() const {
return (CounterDictionary::ValueType(iterator_->first,
*(iterator_->second)));
}
bool
CounterDictionaryConstIteratorImpl::equal(
const CounterDictionaryConstIteratorImpl& other) const
{
return (iterator_ == other.iterator_);
}
CounterDictionary::ConstIterator
CounterDictionary::begin() const {
return (CounterDictionary::ConstIterator(
CounterDictionaryConstIteratorImpl(impl_->begin())));
}
CounterDictionary::ConstIterator
CounterDictionary::end() const {
return (CounterDictionary::ConstIterator(
CounterDictionaryConstIteratorImpl(impl_->end())));
}
CounterDictionary::ConstIterator::ConstIterator() :
impl_(new CounterDictionaryConstIteratorImpl())
{}
CounterDictionary::ConstIterator::~ConstIterator() {}
// Copy constructor: deep copy of impl_
CounterDictionary::ConstIterator::ConstIterator(
const CounterDictionary::ConstIterator& source) :
impl_(new CounterDictionaryConstIteratorImpl(*(source.impl_)))
{}
// Assignment operator: deep copy of impl_
CounterDictionary::ConstIterator &
CounterDictionary::ConstIterator::operator=(
const CounterDictionary::ConstIterator &source)
{
*impl_ = *source.impl_;
return (*this);
}
// The constructor from implementation detail
CounterDictionary::ConstIterator::ConstIterator(
const CounterDictionaryConstIteratorImpl& source) :
impl_(new CounterDictionaryConstIteratorImpl(source))
{}
const CounterDictionary::ValueType
CounterDictionary::ConstIterator::dereference() const
{
return (impl_->dereference());
}
bool
CounterDictionary::ConstIterator::equal(
CounterDictionary::ConstIterator const& other) const
{
return (impl_->equal(*(other.impl_)));
}
void
CounterDictionary::ConstIterator::increment() {
impl_->increment();
return;
}
} // namespace statistics
} // namespace isc

View File

@@ -1,156 +0,0 @@
#ifndef __COUNTER_DICT_H
#define __COUNTER_DICT_H 1
#include <string>
#include <vector>
#include <utility>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <exceptions/exceptions.h>
#include <statistics/counter.h>
namespace isc {
namespace statistics {
class CounterDictionaryImpl;
class CounterDictionaryConstIteratorImpl;
class CounterDictionary : boost::noncopyable {
private:
boost::scoped_ptr<CounterDictionaryImpl> impl_;
// Default constructor is forbidden; number of counter items must be
// specified at the construction of this class.
CounterDictionary();
public:
/// The constructor.
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
/// \param items A number of counter items to hold (greater than 0)
///
/// \throw isc::InvalidParameter \a items is 0
CounterDictionary(const size_t items);
/// The destructor.
///
/// This method never throws an exception.
~CounterDictionary();
/// \brief Add an element
///
/// \throw isc::InvalidParameter \a element already exists.
///
/// \param name A name of the element to append
void addElement(const std::string& name);
/// \brief Delete
///
/// \throw isc::OutOfRange \a element does not exist.
///
/// \param name A name of the element to delete
void deleteElement(const std::string& name);
/// \brief Lookup
///
/// \throw isc::OutOfRange \a element does not exist.
///
/// \param name A name of the element to get the counters
Counter& getElement(const std::string &name) const;
/// Same as getElement()
Counter& operator[](const std::string &name) const;
/// \brief A helper structure to represent an element of
/// CounterDictionary. This type is used for the iterator.
struct ValueType {
public:
const std::string& name;
const Counter& element;
ValueType(const std::string& name_, const Counter& element_) :
name(name_), element(element_)
{}
};
/// \brief \c ConstIterator is a constant iterator that provides an
/// interface for accessing elements stored in CounterDictionary.
///
/// This class is derived from boost::iterator_facade and uses pImpl
/// idiom not to expose implementation detail of
/// CounterDictionary::iterator.
///
/// It is intended to walk through the elements when sending the
/// counters to statistics module.
class ConstIterator :
public boost::iterator_facade<ConstIterator,
const ValueType,
boost::forward_traversal_tag>
{
private:
boost::scoped_ptr<CounterDictionaryConstIteratorImpl> impl_;
public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
ConstIterator();
/// The destructor.
///
/// This method never throws an exception.
~ConstIterator();
/// The assignment operator.
///
/// This method is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
ConstIterator& operator=(const ConstIterator &source);
/// The copy constructor.
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
ConstIterator(const ConstIterator& source);
/// The constructor from implementation detail.
///
/// This method is used to create an instance of ConstIterator
/// by CounterDict::begin() and CounterDict::end().
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
ConstIterator(
const CounterDictionaryConstIteratorImpl& source);
private:
/// \brief An internal method to increment this iterator.
void increment();
/// \brief An internal method to check equality.
bool equal(const ConstIterator& other) const;
/// \brief An internal method to dereference this iterator.
const value_type dereference() const;
private:
friend class boost::iterator_core_access;
};
typedef ConstIterator const_iterator;
/// \brief Return an iterator corresponding to the beginning of the
/// elements stored in CounterDictionary.
///
/// This method is mostly exception free. But it may still throw a
/// standard exception if memory allocation fails inside the method.
const_iterator begin() const;
/// \brief Return an iterator corresponding to the end of the elements
/// stored in CounterDictionary.
///
/// This method is mostly exception free. But it may still throw a
/// standard exception if memory allocation fails inside the method.
const_iterator end() const;
};
} // namespace statistics
} // namespace isc
#endif

View File

@@ -1,47 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
# https://svn.boost.org/trac/boost/ticket/3477
# But older GCC compilers don't have the flag.
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
CLEANFILES = *.gcno *.gcda
TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = run_unittests.cc
run_unittests_SOURCES += counter_unittest.cc
run_unittests_SOURCES += counter_dict_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
run_unittests_CXXFLAGS = $(AM_CXXFLAGS)
if USE_GXX
run_unittests_CXXFLAGS += -Wno-unused-parameter
endif
if USE_CLANGPP
# Same for clang++, but we need to turn off -Werror completely.
run_unittests_CXXFLAGS += -Wno-error
endif
endif
noinst_PROGRAMS = $(TESTS)

View File

@@ -1,170 +0,0 @@
// Copyright (C) 2011 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 <gtest/gtest.h>
#include <set>
#include <boost/foreach.hpp>
#include <statistics/counter_dict.h>
enum CounterItems {
ITEM1 = 0,
ITEM2 = 1,
ITEM3 = 2,
NUMBER_OF_ITEMS = 3
};
using namespace isc::statistics;
TEST(CounterDictionaryCreateTest, invalidCounterSize) {
// Creating counter with 0 elements will cause an isc::InvalidParameter
// exception
EXPECT_THROW(CounterDictionary counters(0), isc::InvalidParameter);
}
// This fixture is for testing CounterDictionary.
class CounterDictionaryTest : public ::testing::Test {
protected:
CounterDictionaryTest() : counters(NUMBER_OF_ITEMS) {
counters.addElement("test");
counters.addElement("sub.test");
}
~CounterDictionaryTest() {}
CounterDictionary counters;
};
TEST_F(CounterDictionaryTest, initializeCheck) {
// Check if the all counters are initialized with 0
EXPECT_EQ(counters["test"].get(ITEM1), 0);
EXPECT_EQ(counters["test"].get(ITEM2), 0);
EXPECT_EQ(counters["test"].get(ITEM3), 0);
}
TEST_F(CounterDictionaryTest, getElement) {
// Another member function to get counters for the element
EXPECT_EQ(counters.getElement("test").get(ITEM1), 0);
EXPECT_EQ(counters.getElement("test").get(ITEM2), 0);
EXPECT_EQ(counters.getElement("test").get(ITEM3), 0);
}
TEST_F(CounterDictionaryTest, incrementCounterItem) {
// Increment counters
counters["test"].inc(ITEM1);
counters["test"].inc(ITEM2);
counters["test"].inc(ITEM2);
counters["test"].inc(ITEM3);
counters["test"].inc(ITEM3);
counters["test"].inc(ITEM3);
// Check if the counters have expected values
EXPECT_EQ(counters["test"].get(ITEM1), 1);
EXPECT_EQ(counters["test"].get(ITEM2), 2);
EXPECT_EQ(counters["test"].get(ITEM3), 3);
EXPECT_EQ(counters["sub.test"].get(ITEM1), 0);
EXPECT_EQ(counters["sub.test"].get(ITEM2), 0);
EXPECT_EQ(counters["sub.test"].get(ITEM3), 0);
}
TEST_F(CounterDictionaryTest, deleteElement) {
// Ensure the element is accessible
EXPECT_EQ(counters["test"].get(ITEM1), 0);
EXPECT_EQ(counters["test"].get(ITEM2), 0);
EXPECT_EQ(counters["test"].get(ITEM3), 0);
// Delete the element
counters.deleteElement("test");
// Accessing to the deleted element will cause an isc::OutOfRange exception
EXPECT_THROW(counters["test"].get(ITEM1), isc::OutOfRange);
// Deleting an element which does not exist will cause an isc::OutOfRange
// exception
EXPECT_THROW(counters.deleteElement("test"), isc::OutOfRange);
}
TEST_F(CounterDictionaryTest, invalidCounterItem) {
// Incrementing out-of-bound counter will cause an isc::OutOfRange
// exception
EXPECT_THROW(counters["test"].inc(NUMBER_OF_ITEMS), isc::OutOfRange);
}
TEST_F(CounterDictionaryTest, uniquenessCheck) {
// Adding an element which already exists will cause an isc::OutOfRange
// exception
EXPECT_THROW(counters.addElement("test"), isc::InvalidParameter);
}
TEST_F(CounterDictionaryTest, iteratorTest) {
// Increment counters
counters["test"].inc(ITEM1);
counters["sub.test"].inc(ITEM2);
counters["sub.test"].inc(ITEM2);
// boolean values to check all of the elements can be accessed through
// the iterator
bool element_test_visited = false;
bool element_sub_test_visited = false;
// Walk through the elements with iterator
// Check if the elements "test" and "sub.test" appears only once
// and the counters have expected value
BOOST_FOREACH(CounterDictionary::ValueType i,
static_cast<const CounterDictionary &>(counters))
{
if (i.name == "test" && element_test_visited == false) {
element_test_visited = true;
// Check if the counters have expected value
EXPECT_EQ(i.element.get(ITEM1), 1);
EXPECT_EQ(i.element.get(ITEM2), 0);
} else if (i.name == "sub.test" &&
element_sub_test_visited == false) {
element_sub_test_visited = true;
// Check if the counters have expected value
EXPECT_EQ(i.element.get(ITEM1), 0);
EXPECT_EQ(i.element.get(ITEM2), 2);
} else {
// Test fails when reaches here: the element is not expected or
// the element appeared twice
FAIL() << "Unexpected iterator value";
}
}
// Check if the "test" and "sub.test" is accessible
EXPECT_TRUE(element_test_visited);
EXPECT_TRUE(element_sub_test_visited);
}
TEST_F(CounterDictionaryTest, iteratorCopyTest) {
// Increment counters
counters["test"].inc(ITEM1);
counters["sub.test"].inc(ITEM2);
counters["sub.test"].inc(ITEM2);
CounterDictionary::ConstIterator i1 = counters.begin();
CounterDictionary::ConstIterator i2(i1);
CounterDictionary::ConstIterator i3;
i3 = i1;
EXPECT_TRUE(i1 == i2);
EXPECT_TRUE(i1 == i3);
EXPECT_TRUE(i2 == i3);
++i2;
EXPECT_TRUE(i1 != i2);
EXPECT_TRUE(i1 == i3);
EXPECT_TRUE(i2 != i3);
++i3;
EXPECT_TRUE(i1 != i2);
EXPECT_TRUE(i1 != i3);
EXPECT_TRUE(i2 == i3);
}

View File

@@ -1,85 +0,0 @@
// Copyright (C) 2011 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 <gtest/gtest.h>
#include <statistics/counter.h>
namespace {
enum CounterItems {
ITEM1 = 0,
ITEM2 = 1,
ITEM3 = 2,
NUMBER_OF_ITEMS = 3
};
}
using namespace isc::statistics;
TEST(CounterCreateTest, invalidCounterSize) {
// Creating counter with 0 elements will cause an isc::InvalidParameter
// exception
EXPECT_THROW(Counter counter(0), isc::InvalidParameter);
}
// This fixture is for testing Counter.
class CounterTest : public ::testing::Test {
protected:
CounterTest() : counter(NUMBER_OF_ITEMS) {}
~CounterTest() {}
Counter counter;
};
TEST_F(CounterTest, createCounter) {
// Check if the all counters are initialized with 0
EXPECT_EQ(counter.get(ITEM1), 0);
EXPECT_EQ(counter.get(ITEM2), 0);
EXPECT_EQ(counter.get(ITEM3), 0);
}
TEST_F(CounterTest, incrementCounterItem) {
// Increment counters
counter.inc(ITEM1);
counter.inc(ITEM2);
counter.inc(ITEM2);
counter.inc(ITEM3);
counter.inc(ITEM3);
counter.inc(ITEM3);
// Check if the counters have expected values
EXPECT_EQ(counter.get(ITEM1), 1);
EXPECT_EQ(counter.get(ITEM2), 2);
EXPECT_EQ(counter.get(ITEM3), 3);
// Increment counters once more
counter.inc(ITEM1);
counter.inc(ITEM2);
counter.inc(ITEM2);
counter.inc(ITEM3);
counter.inc(ITEM3);
counter.inc(ITEM3);
// Check if the counters have expected values
EXPECT_EQ(counter.get(ITEM1), 2);
EXPECT_EQ(counter.get(ITEM2), 4);
EXPECT_EQ(counter.get(ITEM3), 6);
}
TEST_F(CounterTest, invalidCounterItem) {
// Incrementing out-of-bound counter will cause an isc::OutOfRange
// exception
EXPECT_THROW(counter.inc(NUMBER_OF_ITEMS), isc::OutOfRange);
// Trying to get out-of-bound counter will cause an isc::OutOfRange
// exception
EXPECT_THROW(counter.get(NUMBER_OF_ITEMS), isc::OutOfRange);
}

View File

@@ -1,25 +0,0 @@
// Copyright (C) 2009 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 <gtest/gtest.h>
#include <util/unittests/run_all.h>
#include <log/logger_support.h>
int
main(int argc, char* argv[])
{
::testing::InitGoogleTest(&argc, argv); // Initialize Google test
isc::log::initLogger();
return (isc::util::unittests::run_all());
}