[svn] commit: r3954 - in /branches/trac347: ./ src/bin/auth/ src/bin/auth/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Dec 22 13:05:42 UTC 2010
Author: y-aharen
Date: Wed Dec 22 13:05:42 2010
New Revision: 3954
Log:
Address review comments on ticket:347:12
- Documentation and comments were appended.
- Some classes and functions were renamed.
- Some test cases were appended.
- Removed unnecessary includes.
- Thrown exceptions were changed not to hide asio specific definitions.
- Query counter increment is moved from AuthSrv::processMessage() to
AuthSrvImpl::processNormalQuery() and AuthSrvImpl::processAxfrQuery().
Added:
branches/trac347/src/bin/auth/statistics.cc
branches/trac347/src/bin/auth/statistics.h
Modified:
branches/trac347/ChangeLog
branches/trac347/src/bin/auth/asio_link.cc
branches/trac347/src/bin/auth/asio_link.h
branches/trac347/src/bin/auth/auth_srv.cc
branches/trac347/src/bin/auth/auth_srv.h
branches/trac347/src/bin/auth/main.cc
branches/trac347/src/bin/auth/tests/asio_link_unittest.cc
branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac347/src/bin/auth/tests/statistics_unittest.cc
Modified: branches/trac347/ChangeLog
==============================================================================
--- branches/trac347/ChangeLog (original)
+++ branches/trac347/ChangeLog Wed Dec 22 13:05:42 2010
@@ -1,11 +1,13 @@
TBD. [func] y-aharen
- src/bin/auth: Added a feature to count query and send counter
+ src/bin/auth: Added a feature to count queries and send counter
values to statistics periodically. To support it, added wrapping
class of asio::deadline_timer to use as interval timer.
Added a command 'sendstats' to send counter values at once.
- The counter value can be seen with sending 'sendstats' command to
- statistics module via bindctl like:
+ The counters can be seen using the "Stats show" command from
+ bindctl. The result would look like:
... "auth.queries.tcp": 1, "auth.queries.udp": 1 ...
+ Using the "Auth sendstats" command you can make b10-auth send the
+ counters to b10-stats immediately.
(Trac #347, svn rxxxx)
122. [func] stephen
Modified: branches/trac347/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac347/src/bin/auth/asio_link.cc (original)
+++ branches/trac347/src/bin/auth/asio_link.cc Wed Dec 22 13:05:42 2010
@@ -719,8 +719,12 @@
void
IntervalTimerImpl::updateTimer() {
- // Update expire time to (current time + interval_).
- timer_.expires_from_now(boost::posix_time::seconds(interval_));
+ try {
+ // Update expire time to (current time + interval_).
+ timer_.expires_from_now(boost::posix_time::seconds(interval_));
+ } catch (asio::system_error& e) {
+ isc_throw(isc::Unexpected, "Failed to update timer");
+ }
// Reset timer.
timer_.async_wait(boost::bind(&IntervalTimerImpl::callback, this, _1));
}
Modified: branches/trac347/src/bin/auth/asio_link.h
==============================================================================
--- branches/trac347/src/bin/auth/asio_link.h (original)
+++ branches/trac347/src/bin/auth/asio_link.h Wed Dec 22 13:05:42 2010
@@ -462,9 +462,6 @@
/// and updates the timer to expire in (now + interval) seconds.
/// The type of call back function is \c void(void).
///
-/// This class is mainly designed to use for calling
-/// \c QueryCounters::submitStatistics() periodically.
-///
/// Note: Destruction of an instance of this class while call back
/// is pending causes throwing an exception from \c IOService.
///
@@ -516,22 +513,22 @@
~IntervalTimer();
//@}
- /// \brief Register timer callback function and interval
+ /// \brief Register timer callback function and interval.
///
/// This function sets call back function and interval in seconds.
/// Timer will actually start after calling \c IOService::run().
///
/// \param cbfunc A reference to a function \c void(void) to call back
- /// when the timer is expired
+ /// when the timer is expired (should not be an empty functor)
/// \param interval Interval in seconds (greater than 0)
///
- /// Note: IntervalTimer will not pass asio::error_code to
+ /// Note: IntervalTimer will not pass \c asio::error_code to
/// call back function. In case the timer is cancelled, the function
/// will not be called.
///
/// \throw isc::InvalidParameter cbfunc is empty
/// \throw isc::BadValue interval is 0
- /// \throw asio::system_error ASIO library error
+ /// \throw isc::Unexpected ASIO library error
///
void setupTimer(const Callback& cbfunc, const uint32_t interval);
private:
Modified: branches/trac347/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac347/src/bin/auth/auth_srv.cc (original)
+++ branches/trac347/src/bin/auth/auth_srv.cc Wed Dec 22 13:05:42 2010
@@ -102,7 +102,10 @@
isc::datasrc::HotCache cache_;
/// Query counters for statistics
- QueryCounters counters_;
+ AuthCounters counters_;
+private:
+ /// Increment query counter
+ void incCounter(int protocol);
};
AuthSrvImpl::AuthSrvImpl(const bool use_cache,
@@ -220,8 +223,8 @@
}
void
-AuthSrv::setStatsSession(AbstractSession* stats_session) {
- impl_->counters_.setStatsSession(stats_session);
+AuthSrv::setStatisticsSession(AbstractSession* statistics_session) {
+ impl_->counters_.setStatisticsSession(statistics_session);
}
ModuleCCSession*
@@ -274,17 +277,6 @@
if (impl_->verbose_mode_) {
cerr << "[b10-auth] received a message:\n" << message.toText() << endl;
- }
-
- // increment Query Counter
- if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
- impl_->counters_.inc(QueryCounters::COUNTER_UDP);
- } else if (io_message.getSocket().getProtocol() == IPPROTO_TCP) {
- impl_->counters_.inc(QueryCounters::COUNTER_TCP);
- } else {
- // unknown protocol
- isc_throw(Unexpected, "Unknown protocol: " <<
- io_message.getSocket().getProtocol());
}
// Perform further protocol-level validation.
@@ -334,6 +326,9 @@
message.setHeaderFlag(Message::HEADERFLAG_AA);
message.setRcode(Rcode::NOERROR());
+ // Increment query counter.
+ incCounter(io_message.getSocket().getProtocol());
+
if (remote_edns) {
EDNSPtr local_edns = EDNSPtr(new EDNS());
local_edns->setDNSSECAwareness(dnssec_ok);
@@ -371,6 +366,9 @@
AuthSrvImpl::processAxfrQuery(const IOMessage& io_message, Message& message,
MessageRenderer& response_renderer)
{
+ // Increment query counter.
+ incCounter(io_message.getSocket().getProtocol());
+
if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
if (verbose_mode_) {
cerr << "[b10-auth] AXFR query over UDP isn't allowed" << endl;
@@ -498,6 +496,19 @@
return (true);
}
+void
+AuthSrvImpl::incCounter(int protocol) {
+ // Increment query counter.
+ if (protocol == IPPROTO_UDP) {
+ counters_.inc(AuthCounters::COUNTER_UDP);
+ } else if (protocol == IPPROTO_TCP) {
+ counters_.inc(AuthCounters::COUNTER_TCP);
+ } else {
+ // unknown protocol
+ isc_throw(Unexpected, "Unknown protocol: " << protocol);
+ }
+}
+
ConstElementPtr
AuthSrvImpl::setDbFile(ConstElementPtr config) {
ConstElementPtr answer = isc::config::createAnswer();
@@ -565,11 +576,11 @@
}
}
-bool AuthSrv::submitStatistics() {
+bool AuthSrv::submitStatistics() const {
return (impl_->counters_.submitStatistics());
}
-const std::vector<uint64_t>&
-AuthSrv::getCounters() const {
- return (impl_->counters_.getCounters());
-}
+uint64_t
+AuthSrv::getCounter(const AuthCounters::QueryType type) const {
+ return (impl_->counters_.getCounter(type));
+}
Modified: branches/trac347/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac347/src/bin/auth/auth_srv.h (original)
+++ branches/trac347/src/bin/auth/auth_srv.h Wed Dec 22 13:05:42 2010
@@ -22,6 +22,8 @@
#include <cc/data.h>
#include <config/ccsession.h>
+#include <auth/statistics.h>
+
namespace isc {
namespace dns {
class InputBuffer;
@@ -62,6 +64,7 @@
///
/// The design of this class is still in flux. It's quite likely to change
/// in future versions.
+///
class AuthSrv {
///
/// \name Constructors, Assignment Operator and Destructor.
@@ -86,6 +89,8 @@
//@}
/// \return \c true if the \a message contains a response to be returned;
/// otherwise \c false.
+ ///
+ /// \throw isc::Unexpected Protocol type of \a message is unexpected
bool processMessage(const asio_link::IOMessage& io_message,
isc::dns::Message& message,
isc::dns::MessageRenderer& response_renderer);
@@ -203,13 +208,13 @@
/// \brief Set the communication session with Statistics.
///
/// This function never throws an exception as far as
- /// QueryCounters::setStatsSession() doesn't throw.
+ /// AuthCounters::setStatisticsSession() doesn't throw.
///
/// Note: this interface is tentative. We'll revisit the ASIO and
/// session frameworks, at which point the session will probably
/// be passed on construction of the server.
///
- /// \param stats_session A Session object over which statistics
+ /// \param statistics_session A Session object over which statistics
/// information is exchanged with statistics module.
/// The session must be established before setting in the server
/// object.
@@ -218,32 +223,33 @@
/// disconnecting the session and destroying the object when the server
/// is shutdown.
///
- void setStatsSession(isc::cc::AbstractSession* stats_session);
+ void setStatisticsSession(isc::cc::AbstractSession* statistics_session);
/// \brief Submit statistics counters to statistics module.
///
/// This function can throw an exception from
- /// QueryCounters::submitStatistics().
+ /// AuthCounters::submitStatistics().
///
/// \return true on success, false on failure (e.g. session timeout,
/// session error).
///
- bool submitStatistics();
-
- /// \brief Get counters in the QueryCounters.
+ bool submitStatistics() const;
+
+ /// \brief Get the value of counter in the AuthCounters.
///
- /// This function calls QueryCounters::getCounters() and
- /// returns its return velue, a reference to the counters.
+ /// This function calls AuthCounters::getCounter() and
+ /// returns its return value.
///
/// This function never throws an exception as far as
- /// QueryCounters::getCounters() doesn't throw.
+ /// AuthCounters::getCounter() doesn't throw.
///
/// Note: Currently this function is for testing purpose only.
- /// This function should not be called except from tests.
- ///
- /// \return a reference to the counters.
- ///
- const std::vector<uint64_t>& getCounters() const;
+ ///
+ /// \param type Type of a counter to get the value of
+ ///
+ /// \return the value of the counter.
+ ///
+ uint64_t getCounter(const AuthCounters::QueryType type) const;
private:
AuthSrvImpl* impl_;
};
Modified: branches/trac347/src/bin/auth/main.cc
==============================================================================
--- branches/trac347/src/bin/auth/main.cc (original)
+++ branches/trac347/src/bin/auth/main.cc Wed Dec 22 13:05:42 2010
@@ -61,7 +61,7 @@
// Note: this value must be greater than 0.
// TODO: make it configurable via command channel.
-const uint32_t STATS_SEND_INTERVAL_SEC = 60;
+const uint32_t STATISTICS_SEND_INTERVAL_SEC = 60;
/* need global var for config/command handlers.
* todo: turn this around, and put handlers in the authserver
@@ -170,10 +170,10 @@
// XXX: we should eventually pass io_service here.
Session* cc_session = NULL;
Session* xfrin_session = NULL;
- Session* stats_session = NULL;
+ Session* statistics_session = NULL;
asio_link::IntervalTimer* itimer = NULL;
bool xfrin_session_established = false; // XXX (see Trac #287)
- bool stats_session_established = false; // XXX (see Trac #287)
+ bool statistics_session_established = false; // XXX (see Trac #287)
ModuleCCSession* config_session = NULL;
string xfrout_socket_path;
if (getenv("B10_FROM_BUILD") != NULL) {
@@ -228,11 +228,11 @@
xfrin_session_established = true;
cout << "[b10-auth] Xfrin session channel established." << endl;
- stats_session = new Session(io_service->get_io_service());
- cout << "[b10-auth] Stats session channel created." << endl;
- stats_session->establish(NULL);
- stats_session_established = true;
- cout << "[b10-auth] Stats session channel established." << endl;
+ statistics_session = new Session(io_service->get_io_service());
+ cout << "[b10-auth] Statistics session channel created." << endl;
+ statistics_session->establish(NULL);
+ statistics_session_established = true;
+ cout << "[b10-auth] Statistics session channel established." << endl;
// XXX: with the current interface to asio_link we have to create
// auth_server before io_service while Session needs io_service.
@@ -240,7 +240,7 @@
// from auth_server, and create io_service, auth_server, and
// sessions in that order.
auth_server->setXfrinSession(xfrin_session);
- auth_server->setStatsSession(stats_session);
+ auth_server->setStatisticsSession(statistics_session);
auth_server->setConfigSession(config_session);
auth_server->updateConfig(ElementPtr());
@@ -249,8 +249,8 @@
// set up interval timer
// register function to send statistics with interval
itimer->setupTimer(boost::bind(statisticsTimerCallback, auth_server),
- STATS_SEND_INTERVAL_SEC);
- cout << "[b10-auth] Interval timer set to send stats." << endl;
+ STATISTICS_SEND_INTERVAL_SEC);
+ cout << "[b10-auth] Interval timer to send statistics set." << endl;
cout << "[b10-auth] Server started." << endl;
io_service->run();
@@ -259,8 +259,8 @@
ret = 1;
}
- if (stats_session_established) {
- stats_session->disconnect();
+ if (statistics_session_established) {
+ statistics_session->disconnect();
}
if (xfrin_session_established) {
@@ -268,7 +268,7 @@
}
delete itimer;
- delete stats_session;
+ delete statistics_session;
delete xfrin_session;
delete config_session;
delete cc_session;
Modified: branches/trac347/src/bin/auth/tests/asio_link_unittest.cc
==============================================================================
--- branches/trac347/src/bin/auth/tests/asio_link_unittest.cc (original)
+++ branches/trac347/src/bin/auth/tests/asio_link_unittest.cc Wed Dec 22 13:05:42 2010
@@ -257,20 +257,129 @@
callback_data_.size(),
expected_data, expected_datasize);
}
- class TimerCallBack : public std::unary_function<void, void> {
+private:
+ class ASIOCallBack : public std::unary_function<IOMessage, void> {
public:
- TimerCallBack(ASIOLinkTest* test_obj) : test_obj_(test_obj) {}
- void operator()() const {
- test_obj_->timer_called_ = true;
- test_obj_->io_service_->stop();
- return;
+ ASIOCallBack(ASIOLinkTest* test_obj) : test_obj_(test_obj) {}
+ void operator()(const IOMessage& io_message) const {
+ test_obj_->callBack(io_message);
}
private:
ASIOLinkTest* test_obj_;
};
+ void callBack(const IOMessage& io_message) {
+ callback_protocol_ = io_message.getSocket().getProtocol();
+ callback_native_ = io_message.getSocket().getNative();
+ callback_address_ =
+ io_message.getRemoteEndpoint().getAddress().toText();
+ callback_data_.assign(
+ static_cast<const uint8_t*>(io_message.getData()),
+ static_cast<const uint8_t*>(io_message.getData()) +
+ io_message.getDataSize());
+ io_service_->stop();
+ }
+protected:
+ IOService* io_service_;
+ int callback_protocol_;
+ int callback_native_;
+ string callback_address_;
+ vector<uint8_t> callback_data_;
+ int sock_;
+private:
+ struct addrinfo* res_;
+};
+
+ASIOLinkTest::ASIOLinkTest() :
+ io_service_(NULL), sock_(-1), res_(NULL)
+{
+ setIOService(true, true);
+}
+
+TEST_F(ASIOLinkTest, v6UDPSend) {
+ doTest(AF_INET6, IPPROTO_UDP);
+}
+
+TEST_F(ASIOLinkTest, v6TCPSend) {
+ doTest(AF_INET6, IPPROTO_TCP);
+}
+
+TEST_F(ASIOLinkTest, v4UDPSend) {
+ doTest(AF_INET, IPPROTO_UDP);
+}
+
+TEST_F(ASIOLinkTest, v4TCPSend) {
+ doTest(AF_INET, IPPROTO_TCP);
+}
+
+TEST_F(ASIOLinkTest, v6UDPSendSpecific) {
+ // Explicitly set a specific address to be bound to the socket.
+ // The subsequent test does not directly ensures the underlying socket
+ // is bound to the expected address, but the success of the tests should
+ // reasonably suggest it works as intended.
+ // Specifying an address also implicitly means the service runs in a
+ // single address-family mode. In tests using TCP we can confirm that
+ // by trying to make a connection and seeing a failure. In UDP, it'd be
+ // more complicated because we need to use a connected socket and catch
+ // an error on a subsequent read operation. We could do it, but for
+ // simplicity we only tests the easier cases for now.
+
+ setIOService(*TEST_IPV6_ADDR);
+ doTest(AF_INET6, IPPROTO_UDP);
+}
+
+TEST_F(ASIOLinkTest, v6TCPSendSpecific) {
+ setIOService(*TEST_IPV6_ADDR);
+ doTest(AF_INET6, IPPROTO_TCP);
+
+ EXPECT_THROW(sendTCP(AF_INET), IOError);
+}
+
+TEST_F(ASIOLinkTest, v4UDPSendSpecific) {
+ setIOService(*TEST_IPV4_ADDR);
+ doTest(AF_INET, IPPROTO_UDP);
+}
+
+TEST_F(ASIOLinkTest, v4TCPSendSpecific) {
+ setIOService(*TEST_IPV4_ADDR);
+ doTest(AF_INET, IPPROTO_TCP);
+
+ EXPECT_THROW(sendTCP(AF_INET6), IOError);
+}
+
+TEST_F(ASIOLinkTest, v6TCPOnly) {
+ // Open only IPv6 TCP socket. A subsequent attempt of establishing an
+ // IPv4/TCP connection should fail. See above for why we only test this
+ // for TCP.
+ setIOService(false, true);
+ EXPECT_THROW(sendTCP(AF_INET), IOError);
+}
+
+TEST_F(ASIOLinkTest, v4TCPOnly) {
+ setIOService(true, false);
+ EXPECT_THROW(sendTCP(AF_INET6), IOError);
+}
+
+// This fixture is for testing IntervalTimer. Some callback functors are
+// registered as callback function of the timer to test if they are called
+// or not.
+class IntervalTimerTest : public ::testing::Test {
+protected:
+ IntervalTimerTest() : io_service_(NULL, *TEST_PORT, false, false) {};
+ ~IntervalTimerTest() {}
+ class TimerCallBack : public std::unary_function<void, void> {
+ public:
+ TimerCallBack(IntervalTimerTest* test_obj) : test_obj_(test_obj) {}
+ void operator()() const {
+ test_obj_->timer_called_ = true;
+ test_obj_->io_service_.stop();
+ return;
+ }
+ private:
+ IntervalTimerTest* test_obj_;
+ };
class TimerCallBackCounter : public std::unary_function<void, void> {
public:
- TimerCallBackCounter(ASIOLinkTest* test_obj) : test_obj_(test_obj) {
+ TimerCallBackCounter(IntervalTimerTest* test_obj) : test_obj_(test_obj) {
counter_ = 0;
}
void operator()() {
@@ -279,11 +388,11 @@
}
int counter_;
private:
- ASIOLinkTest* test_obj_;
+ IntervalTimerTest* test_obj_;
};
class TimerCallBackCancelDeleter : public std::unary_function<void, void> {
public:
- TimerCallBackCancelDeleter(ASIOLinkTest* test_obj,
+ TimerCallBackCancelDeleter(IntervalTimerTest* test_obj,
IntervalTimer* timer,
TimerCallBackCounter& counter)
: test_obj_(test_obj), timer_(timer), counter_(counter), count_(0)
@@ -298,7 +407,7 @@
} else if (count_ == 2) {
// Second time of call back.
// Stop io_service to stop all timers.
- test_obj_->io_service_->stop();
+ test_obj_->io_service_.stop();
// Compare the value of counter_.counter_ with stored one.
// If TimerCallBackCounter was not called (expected behavior),
// they are same.
@@ -309,7 +418,7 @@
return;
}
private:
- ASIOLinkTest* test_obj_;
+ IntervalTimerTest* test_obj_;
IntervalTimer* timer_;
TimerCallBackCounter& counter_;
int count_;
@@ -317,7 +426,7 @@
};
class TimerCallBackOverwriter : public std::unary_function<void, void> {
public:
- TimerCallBackOverwriter(ASIOLinkTest* test_obj,
+ TimerCallBackOverwriter(IntervalTimerTest* test_obj,
IntervalTimer& timer)
: test_obj_(test_obj), timer_(timer), count_(0)
{}
@@ -328,153 +437,47 @@
// Call setupTimer() to update callback function
// to TimerCallBack.
test_obj_->timer_called_ = false;
- timer_.setupTimer(IntervalTimer::Callback(
- TimerCallBack(test_obj_)), 1);
+ timer_.setupTimer(TimerCallBack(test_obj_), 1);
} else if (count_ == 2) {
// Second time of call back.
// If it reaches here, re-setupTimer() is failed (unexpected).
// We should stop here.
- test_obj_->io_service_->stop();
+ test_obj_->io_service_.stop();
}
return;
}
private:
- ASIOLinkTest* test_obj_;
+ IntervalTimerTest* test_obj_;
IntervalTimer& timer_;
int count_;
};
-private:
- class ASIOCallBack : public std::unary_function<IOMessage, void> {
- public:
- ASIOCallBack(ASIOLinkTest* test_obj) : test_obj_(test_obj) {}
- void operator()(const IOMessage& io_message) const {
- test_obj_->callBack(io_message);
- }
- private:
- ASIOLinkTest* test_obj_;
- };
- void callBack(const IOMessage& io_message) {
- callback_protocol_ = io_message.getSocket().getProtocol();
- callback_native_ = io_message.getSocket().getNative();
- callback_address_ =
- io_message.getRemoteEndpoint().getAddress().toText();
- callback_data_.assign(
- static_cast<const uint8_t*>(io_message.getData()),
- static_cast<const uint8_t*>(io_message.getData()) +
- io_message.getDataSize());
- io_service_->stop();
- }
protected:
- IOService* io_service_;
- int callback_protocol_;
- int callback_native_;
- string callback_address_;
- vector<uint8_t> callback_data_;
+ IOService io_service_;
bool timer_called_;
bool timer_cancel_success_;
- int sock_;
-private:
- struct addrinfo* res_;
};
-ASIOLinkTest::ASIOLinkTest() :
- io_service_(NULL), sock_(-1), res_(NULL)
-{
- setIOService(true, true);
-}
-
-TEST_F(ASIOLinkTest, v6UDPSend) {
- doTest(AF_INET6, IPPROTO_UDP);
-}
-
-TEST_F(ASIOLinkTest, v6TCPSend) {
- doTest(AF_INET6, IPPROTO_TCP);
-}
-
-TEST_F(ASIOLinkTest, v4UDPSend) {
- doTest(AF_INET, IPPROTO_UDP);
-}
-
-TEST_F(ASIOLinkTest, v4TCPSend) {
- doTest(AF_INET, IPPROTO_TCP);
-}
-
-TEST_F(ASIOLinkTest, v6UDPSendSpecific) {
- // Explicitly set a specific address to be bound to the socket.
- // The subsequent test does not directly ensures the underlying socket
- // is bound to the expected address, but the success of the tests should
- // reasonably suggest it works as intended.
- // Specifying an address also implicitly means the service runs in a
- // single address-family mode. In tests using TCP we can confirm that
- // by trying to make a connection and seeing a failure. In UDP, it'd be
- // more complicated because we need to use a connected socket and catch
- // an error on a subsequent read operation. We could do it, but for
- // simplicity we only tests the easier cases for now.
-
- setIOService(*TEST_IPV6_ADDR);
- doTest(AF_INET6, IPPROTO_UDP);
-}
-
-TEST_F(ASIOLinkTest, v6TCPSendSpecific) {
- setIOService(*TEST_IPV6_ADDR);
- doTest(AF_INET6, IPPROTO_TCP);
-
- EXPECT_THROW(sendTCP(AF_INET), IOError);
-}
-
-TEST_F(ASIOLinkTest, v4UDPSendSpecific) {
- setIOService(*TEST_IPV4_ADDR);
- doTest(AF_INET, IPPROTO_UDP);
-}
-
-TEST_F(ASIOLinkTest, v4TCPSendSpecific) {
- setIOService(*TEST_IPV4_ADDR);
- doTest(AF_INET, IPPROTO_TCP);
-
- EXPECT_THROW(sendTCP(AF_INET6), IOError);
-}
-
-TEST_F(ASIOLinkTest, v6TCPOnly) {
- // Open only IPv6 TCP socket. A subsequent attempt of establishing an
- // IPv4/TCP connection should fail. See above for why we only test this
- // for TCP.
- setIOService(false, true);
- EXPECT_THROW(sendTCP(AF_INET), IOError);
-}
-
-TEST_F(ASIOLinkTest, v4TCPOnly) {
- setIOService(true, false);
- EXPECT_THROW(sendTCP(AF_INET6), IOError);
-}
-
-TEST_F(ASIOLinkTest, invalidArgumentToIntervalTimer) {
+TEST_F(IntervalTimerTest, invalidArgumentToIntervalTimer) {
// Create asio_link::IntervalTimer and setup.
- setIOService(false, false);
- IntervalTimer itimer(*io_service_);
+ IntervalTimer itimer(io_service_);
// expect throw if call back function is empty
- EXPECT_THROW(itimer.setupTimer(
- IntervalTimer::Callback(), 1),
+ EXPECT_THROW(itimer.setupTimer(IntervalTimer::Callback(), 1),
isc::InvalidParameter);
// expect throw if interval is 0
- EXPECT_THROW(itimer.setupTimer(
- IntervalTimer::Callback(TimerCallBack(this)), 0),
- isc::BadValue);
-}
-
-TEST_F(ASIOLinkTest, startIntervalTimer) {
+ EXPECT_THROW(itimer.setupTimer(TimerCallBack(this), 0), isc::BadValue);
+}
+
+TEST_F(IntervalTimerTest, startIntervalTimer) {
// Create asio_link::IntervalTimer and setup.
// Then run IOService and test if the callback function is called.
- setIOService(false, false);
- IntervalTimer itimer(*io_service_);
+ IntervalTimer itimer(io_service_);
timer_called_ = false;
// store start time
boost::posix_time::ptime start;
start = boost::posix_time::microsec_clock::universal_time();
// setup timer
- EXPECT_NO_THROW(itimer.setupTimer(
- IntervalTimer::Callback(TimerCallBack(this)),
- 1));
- io_service_->run();
+ itimer.setupTimer(TimerCallBack(this), 1);
+ io_service_.run();
// reaches here after timer expired
// delta: difference between elapsed time and 1 second
boost::posix_time::time_duration delta =
@@ -483,16 +486,40 @@
if (delta.is_negative()) {
delta.invert_sign();
}
- // expect call back is updated: TimerCallBack is called
+ // expect TimerCallBack is called; timer_called_ is true
EXPECT_TRUE(timer_called_);
// expect interval is 1 second +/- TIMER_MERGIN_MSEC.
EXPECT_TRUE(delta < TIMER_MERGIN_MSEC);
}
-TEST_F(ASIOLinkTest, destructIntervalTimer) {
- // The call back function will not be called
- // after the timer is destructed.
- setIOService(false, false);
+TEST_F(IntervalTimerTest, deleteIntervalTimerBeforeStart) {
+ // Note: This code isn't exception safe, but we'd rather keep the code
+ // simpler and more readable as this is only for tests and if it throws
+ // the program would immediately terminate anyway.
+
+ // Create asio_link::IntervalTimer and delete before starting timer.
+ // Test if the callback function is not called.
+ IntervalTimer* itimer = new IntervalTimer(io_service_);
+ timer_called_ = false;
+ // setup timer...
+ itimer->setupTimer(TimerCallBack(this), 1);
+ // and delete
+ delete itimer;
+ // expect the callback function is not called
+ EXPECT_FALSE(timer_called_);
+}
+
+TEST_F(IntervalTimerTest, destructIntervalTimer) {
+ // Note: This test currently takes 6 seconds. The timer should have
+ // finer granularity and timer periods in this test should be shorter
+ // in the future.
+ // This code isn't exception safe, but we'd rather keep the code
+ // simpler and more readable as this is only for tests and if it throws
+ // the program would immediately terminate anyway.
+
+ // The call back function will not be called after the timer is
+ // destructed.
+ //
// There are two timers:
// itimer_counter (A)
// (Calls TimerCallBackCounter)
@@ -513,35 +540,37 @@
// (B) i--------+--------s
// ^stop io_service
// and test itimer_counter have been stopped
-
- // itimer_counter will be deleted in
- // TimerCallBackCancelDeleter
- IntervalTimer* itimer_counter = NULL;
- ASSERT_NO_THROW(itimer_counter = new IntervalTimer(*io_service_));
- IntervalTimer itimer_canceller(*io_service_);
+ //
+
+ // itimer_counter will be deleted in TimerCallBackCancelDeleter
+ IntervalTimer* itimer_counter = new IntervalTimer(io_service_);
+ IntervalTimer itimer_canceller(io_service_);
timer_cancel_success_ = false;
TimerCallBackCounter callback_canceller(this);
- itimer_counter->setupTimer(IntervalTimer::Callback(callback_canceller), 2);
+ itimer_counter->setupTimer(callback_canceller, 2);
itimer_canceller.setupTimer(
- IntervalTimer::Callback(
- TimerCallBackCancelDeleter(this, itimer_counter,
- callback_canceller)),
+ TimerCallBackCancelDeleter(this, itimer_counter,
+ callback_canceller),
3);
- io_service_->run();
+ io_service_.run();
EXPECT_TRUE(timer_cancel_success_);
}
-TEST_F(ASIOLinkTest, overwriteIntervalTimer) {
- // Calling setupTimer() multiple times updates call back
- // function and interval.
- setIOService(false, false);
+TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
+ // Note: This test currently takes 4 seconds. The timer should have
+ // finer granularity and timer periods in this test should be shorter
+ // in the future.
+
+ // Calling setupTimer() multiple times updates call back function
+ // and interval.
+ //
// There are two timers:
// itimer (A)
// (Calls TimerCallBackCounter / TimerCallBack)
// - increments internal counter in callback function
// (TimerCallBackCounter)
// interval: 2 seconds
- // - io_service_->stop() (TimerCallBack)
+ // - io_service_.stop() (TimerCallBack)
// interval: 1 second
// itimer_overwriter (B)
// (Calls TimerCallBackOverwriter)
@@ -558,16 +587,16 @@
// |change call back function
// (B) i--------+--------S
// ^(stop io_service on fail)
-
- IntervalTimer itimer(*io_service_);
- IntervalTimer itimer_overwriter(*io_service_);
+ //
+
+ IntervalTimer itimer(io_service_);
+ IntervalTimer itimer_overwriter(io_service_);
// store start time
boost::posix_time::ptime start;
start = boost::posix_time::microsec_clock::universal_time();
- itimer.setupTimer(IntervalTimer::Callback(TimerCallBackCounter(this)), 2);
- itimer_overwriter.setupTimer(
- IntervalTimer::Callback(TimerCallBackOverwriter(this, itimer)), 3);
- io_service_->run();
+ itimer.setupTimer(TimerCallBackCounter(this), 2);
+ itimer_overwriter.setupTimer(TimerCallBackOverwriter(this, itimer), 3);
+ io_service_.run();
// reaches here after timer expired
// if interval is updated, it takes
// 3 seconds for TimerCallBackOverwriter
@@ -584,7 +613,7 @@
if (delta.is_negative()) {
delta.invert_sign();
}
- // expect call back is updated: TimerCallBack is called
+ // expect callback function is updated: TimerCallBack is called
EXPECT_TRUE(timer_called_);
// expect interval is updated
EXPECT_TRUE(delta < TIMER_MERGIN_MSEC);
Modified: branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac347/src/bin/auth/tests/auth_srv_unittest.cc Wed Dec 22 13:05:42 2010
@@ -124,14 +124,14 @@
response_obuffer(0), response_renderer(response_obuffer)
{
server.setXfrinSession(¬ify_session);
- server.setStatsSession(&stats_session);
+ server.setStatisticsSession(&statistics_session);
}
~AuthSrvTest() {
delete io_message;
delete endpoint;
}
MockSession notify_session;
- MockSession stats_session;
+ MockSession statistics_session;
MockXfroutClient xfrout;
AuthSrv server;
Message request_message;
@@ -771,21 +771,76 @@
EXPECT_EQ(00, server.getCacheSlots());
}
-TEST_F(AuthSrvTest, queryCounterUDP) {
- // submit UDP query and check query counter
+// 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::COUNTER_UDP));
createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
RRType::NS(), IPPROTO_UDP);
EXPECT_TRUE(server.processMessage(*io_message, parse_message,
response_renderer));
- EXPECT_EQ(1, server.getCounters().at(QueryCounters::COUNTER_UDP));
-}
-
-TEST_F(AuthSrvTest, queryCounterTCP) {
- // submit TCP query and check query counter
+ // After processing UDP query, the counter should be 1.
+ EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_UDP));
+}
+
+// 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::COUNTER_TCP));
createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
RRType::NS(), IPPROTO_TCP);
EXPECT_TRUE(server.processMessage(*io_message, parse_message,
response_renderer));
- EXPECT_EQ(1, server.getCounters().at(QueryCounters::COUNTER_TCP));
-}
-}
+ // After processing TCP query, the counter should be 1.
+ EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP));
+}
+
+// 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::COUNTER_TCP));
+ createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
+ RRType::AXFR(), IPPROTO_TCP);
+ // It returns false. see AXFRSuccess test.
+ EXPECT_FALSE(server.processMessage(*io_message, parse_message,
+ response_renderer));
+ // After processing TCP AXFR query, the counter should be 1.
+ EXPECT_EQ(1, server.getCounter(AuthCounters::COUNTER_TCP));
+}
+
+// class for queryCounterUnexpected test
+// getProtocol() returns IPPROTO_IP
+class DummyUnknownSocket : public IOSocket {
+public:
+ DummyUnknownSocket() {}
+ virtual int getNative() const { return (0); }
+ virtual int getProtocol() const { return (IPPROTO_IP); }
+};
+
+// function for queryCounterUnexpected test
+// returns a reference to a static object of DummyUnknownSocket
+IOSocket&
+getDummyUnknownSocket() {
+ static DummyUnknownSocket socket;
+ return (socket);
+}
+
+// Submit unexpected type of query and check it throws IPPROTO_IP
+TEST_F(AuthSrvTest, queryCounterUnexpected) {
+ // Create UDP query packet.
+ createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
+ RRType::NS(), IPPROTO_UDP);
+
+ // Modify the message
+ delete io_message;
+ endpoint = IOEndpoint::create(IPPROTO_UDP,
+ IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
+ io_message = new IOMessage(request_renderer.getData(),
+ request_renderer.getLength(),
+ getDummyUnknownSocket(), *endpoint);
+
+ EXPECT_THROW(server.processMessage(*io_message, parse_message,
+ response_renderer),
+ isc::Unexpected);
+}
+}
Modified: branches/trac347/src/bin/auth/tests/statistics_unittest.cc
==============================================================================
--- branches/trac347/src/bin/auth/tests/statistics_unittest.cc (original)
+++ branches/trac347/src/bin/auth/tests/statistics_unittest.cc Wed Dec 22 13:05:42 2010
@@ -33,7 +33,7 @@
namespace {
-class QueryCountersTest : public ::testing::Test {
+class AuthCountersTest : public ::testing::Test {
private:
class MockSession : public AbstractSession {
public:
@@ -71,46 +71,46 @@
};
protected:
- QueryCountersTest() : counters(verbose_mode_) {
- counters.setStatsSession(&stats_session_);
- }
- ~QueryCountersTest() {
- }
- MockSession stats_session_;
- QueryCounters counters;
+ AuthCountersTest() : verbose_mode_(false), counters(verbose_mode_) {
+ counters.setStatisticsSession(&statistics_session_);
+ }
+ ~AuthCountersTest() {
+ }
+ MockSession statistics_session_;
bool verbose_mode_;
+ AuthCounters counters;
};
void
-QueryCountersTest::MockSession::establish(const char*) {}
-
-void
-QueryCountersTest::MockSession::disconnect() {}
-
-void
-QueryCountersTest::MockSession::subscribe(string, string)
+AuthCountersTest::MockSession::establish(const char*) {}
+
+void
+AuthCountersTest::MockSession::disconnect() {}
+
+void
+AuthCountersTest::MockSession::subscribe(string, string)
{}
void
-QueryCountersTest::MockSession::unsubscribe(string, string)
+AuthCountersTest::MockSession::unsubscribe(string, string)
{}
void
-QueryCountersTest::MockSession::startRead(boost::function<void()>)
+AuthCountersTest::MockSession::startRead(boost::function<void()>)
{}
int
-QueryCountersTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
+AuthCountersTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
return (-1);
}
bool
-QueryCountersTest::MockSession::hasQueuedMsgs() const {
+AuthCountersTest::MockSession::hasQueuedMsgs() const {
return (false);
}
int
-QueryCountersTest::MockSession::group_sendmsg(ConstElementPtr msg,
+AuthCountersTest::MockSession::group_sendmsg(ConstElementPtr msg,
string group, string, string)
{
if (throw_session_error_) {
@@ -122,7 +122,7 @@
}
bool
-QueryCountersTest::MockSession::group_recvmsg(ConstElementPtr&,
+AuthCountersTest::MockSession::group_recvmsg(ConstElementPtr&,
ConstElementPtr& msg, bool, int)
{
if (throw_session_timeout_) {
@@ -133,68 +133,83 @@
}
void
-QueryCountersTest::MockSession::setThrowSessionError(bool flag) {
+AuthCountersTest::MockSession::setThrowSessionError(bool flag) {
throw_session_error_ = flag;
}
void
-QueryCountersTest::MockSession::setThrowSessionTimeout(bool flag) {
+AuthCountersTest::MockSession::setThrowSessionTimeout(bool flag) {
throw_session_timeout_ = flag;
}
-TEST_F(QueryCountersTest, incrementUDPCounter) {
- EXPECT_NO_THROW(counters.inc(QueryCounters::COUNTER_UDP));
-}
-
-TEST_F(QueryCountersTest, incrementTCPCounter) {
- EXPECT_NO_THROW(counters.inc(QueryCounters::COUNTER_TCP));
-}
-
-TEST_F(QueryCountersTest, incrementInvalidCounter) {
- EXPECT_THROW(counters.inc(QueryCounters::COUNTER_TYPES),
- isc::InvalidParameter);
-}
-
-TEST_F(QueryCountersTest, submitStatisticsWithoutSession) {
- // Set stats_session to NULL and call submitStatistics().
+TEST_F(AuthCountersTest, incrementUDPCounter) {
+ // The counter should be initialized to 0.
+ EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP));
+ EXPECT_NO_THROW(counters.inc(AuthCounters::COUNTER_UDP));
+ // After increment, the counter should be 1.
+ EXPECT_EQ(1, counters.getCounter(AuthCounters::COUNTER_UDP));
+}
+
+TEST_F(AuthCountersTest, incrementTCPCounter) {
+ // The counter should be initialized to 0.
+ EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP));
+ EXPECT_NO_THROW(counters.inc(AuthCounters::COUNTER_TCP));
+ // After increment, the counter should be 1.
+ EXPECT_EQ(1, counters.getCounter(AuthCounters::COUNTER_TCP));
+}
+
+TEST_F(AuthCountersTest, incrementInvalidCounter) {
+ // 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) {
+ // Set statistics_session to NULL and call submitStatistics().
// Expect to return false.
- counters.setStatsSession(NULL);
+ counters.setStatisticsSession(NULL);
EXPECT_FALSE(counters.submitStatistics());
}
-TEST_F(QueryCountersTest, submitStatisticsWithException) {
+TEST_F(AuthCountersTest, submitStatisticsWithException) {
// Exception SessionError and SessionTimeout will be thrown
// while sending statistics data.
// Both expect to return false.
- stats_session_.setThrowSessionError(true);
+ statistics_session_.setThrowSessionError(true);
EXPECT_FALSE(counters.submitStatistics());
- stats_session_.setThrowSessionError(false);
- stats_session_.setThrowSessionTimeout(true);
+ statistics_session_.setThrowSessionError(false);
+ statistics_session_.setThrowSessionTimeout(true);
EXPECT_FALSE(counters.submitStatistics());
- stats_session_.setThrowSessionTimeout(false);
-}
-
-TEST_F(QueryCountersTest, submitStatistics) {
+ statistics_session_.setThrowSessionTimeout(false);
+}
+
+TEST_F(AuthCountersTest, submitStatistics) {
// Submit statistics data.
// Validate if it submits correct data.
+ // Counters should be initialized to 0.
+ EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_UDP));
+ EXPECT_EQ(0, counters.getCounter(AuthCounters::COUNTER_TCP));
+
// UDP query counter is set to 2.
- counters.inc(QueryCounters::COUNTER_UDP);
- counters.inc(QueryCounters::COUNTER_UDP);
+ counters.inc(AuthCounters::COUNTER_UDP);
+ counters.inc(AuthCounters::COUNTER_UDP);
// TCP query counter is set to 1.
- counters.inc(QueryCounters::COUNTER_TCP);
+ counters.inc(AuthCounters::COUNTER_TCP);
counters.submitStatistics();
// Destination is "Stats".
- EXPECT_EQ("Stats", stats_session_.msg_destination);
+ EXPECT_EQ("Stats", statistics_session_.msg_destination);
// Command is "set".
- EXPECT_EQ("set", stats_session_.sent_msg->get("command")
+ EXPECT_EQ("set", statistics_session_.sent_msg->get("command")
->get(0)->stringValue());
- ConstElementPtr stats_data = stats_session_.sent_msg ->get("command")
- ->get(1)->get("stats_data");
+ ConstElementPtr statistics_data = statistics_session_.sent_msg
+ ->get("command")->get(1)
+ ->get("stats_data");
// UDP query counter is 2 and TCP query counter is 1.
- EXPECT_EQ(2, stats_data->get("auth.queries.udp")->intValue());
- EXPECT_EQ(1, stats_data->get("auth.queries.tcp")->intValue());
-}
-
-}
+ EXPECT_EQ(2, statistics_data->get("auth.queries.udp")->intValue());
+ EXPECT_EQ(1, statistics_data->get("auth.queries.tcp")->intValue());
+}
+
+}
More information about the bind10-changes
mailing list