[svn] commit: r2393 - in /branches/trac221/src: bin/auth/ bin/auth/tests/ lib/cc/ lib/config/ lib/config/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Jul 1 22:58:04 UTC 2010
Author: jinmei
Date: Thu Jul 1 22:58:04 2010
New Revision: 2393
Log:
introduced an abstract base Session class so that we can easily create test cases using a mock sessio implementation.
This is probably beyond the scope of this ticket, so it's probably better to make a separate ticket focusing on this refactoring.
Some tests currently fail. They'll be fixed in the next commit.
Modified:
branches/trac221/src/bin/auth/auth_srv.cc
branches/trac221/src/bin/auth/auth_srv.h
branches/trac221/src/bin/auth/main.cc
branches/trac221/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac221/src/lib/cc/session.cc
branches/trac221/src/lib/cc/session.h
branches/trac221/src/lib/cc/session_unittests.cc
branches/trac221/src/lib/config/ccsession.cc
branches/trac221/src/lib/config/ccsession.h
branches/trac221/src/lib/config/tests/ccsession_unittests.cc
branches/trac221/src/lib/config/tests/fake_session.cc
branches/trac221/src/lib/config/tests/fake_session.h
Modified: branches/trac221/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac221/src/bin/auth/auth_srv.cc (original)
+++ branches/trac221/src/bin/auth/auth_srv.cc Thu Jul 1 22:58:04 2010
@@ -70,8 +70,7 @@
AuthSrvImpl(const AuthSrvImpl& source);
AuthSrvImpl& operator=(const AuthSrvImpl& source);
public:
- AuthSrvImpl(AbstractSession& session_with_xfrin,
- AbstractXfroutClient& xfrout_client);
+ AuthSrvImpl(AbstractXfroutClient& xfrout_client);
~AuthSrvImpl();
isc::data::ElementPtr setDbFile(const isc::data::ElementPtr config);
@@ -91,8 +90,7 @@
bool verbose_mode_;
- bool is_notify_session_established_;
- AbstractSession& session_with_xfrin_;
+ AbstractSession* session_with_xfrin_;
bool is_axfr_connection_established_;
AbstractXfroutClient& xfrout_client_;
@@ -101,11 +99,9 @@
static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
};
-AuthSrvImpl::AuthSrvImpl(AbstractSession& session_with_xfrin,
- AbstractXfroutClient& xfrout_client) :
+AuthSrvImpl::AuthSrvImpl(AbstractXfroutClient& xfrout_client) :
cs_(NULL), verbose_mode_(false),
- is_notify_session_established_(false),
- session_with_xfrin_(session_with_xfrin),
+ session_with_xfrin_(NULL),
is_axfr_connection_established_(false),
xfrout_client_(xfrout_client)
{
@@ -118,20 +114,14 @@
}
AuthSrvImpl::~AuthSrvImpl() {
- if (is_notify_session_established_) {
- session_with_xfrin_.disconnect();
- is_notify_session_established_ = false;
- }
-
if (is_axfr_connection_established_) {
xfrout_client_.disconnect();
is_axfr_connection_established_ = false;
}
}
-AuthSrv::AuthSrv(AbstractSession& session_with_xfrin,
- AbstractXfroutClient& xfrout_client) :
- impl_(new AuthSrvImpl(session_with_xfrin, xfrout_client))
+AuthSrv::AuthSrv(AbstractXfroutClient& xfrout_client) :
+ impl_(new AuthSrvImpl(xfrout_client))
{}
AuthSrv::~AuthSrv() {
@@ -201,6 +191,11 @@
}
void
+AuthSrv::setSession(AbstractSession* session) {
+ impl_->session_with_xfrin_ = session;
+}
+
+void
AuthSrv::setConfigSession(ModuleCCSession* cs) {
impl_->cs_ = cs;
}
@@ -411,19 +406,14 @@
// error happens rather than returning (e.g.) SERVFAIL. RFC 1996 is
// silent about such cases, but there doesn't seem to be anything we can
// improve at the primary server side by sending an error anyway.
- if (!is_notify_session_established_) {
- try {
- session_with_xfrin_.establish(NULL);
- is_notify_session_established_ = true;
- } catch (const isc::cc::SessionError& err) {
+ if (session_with_xfrin_ == NULL) {
if (verbose_mode_) {
- cerr << "[b10-auth] Error in connection with xfrin module: "
- << err.what() << endl;
+ cerr << "[b10-auth] "
+ "session interface for xfrin is not available" << endl;
}
return (false);
- }
- }
-
+ }
+
const string remote_ip_address =
io_message.getRemoteEndpoint().getAddress().toText();
static const string command_template_start =
@@ -437,10 +427,10 @@
command_template_mid + remote_ip_address +
command_template_end);
const unsigned int seq =
- session_with_xfrin_.group_sendmsg(notify_command, "Xfrin",
+ session_with_xfrin_->group_sendmsg(notify_command, "Xfrin",
"*", "*");
ElementPtr env, answer, parsed_answer;
- session_with_xfrin_.group_recvmsg(env, answer, false, seq);
+ session_with_xfrin_->group_recvmsg(env, answer, false, seq);
int rcode;
parsed_answer = parseAnswer(rcode, answer);
if (rcode != 0) {
Modified: branches/trac221/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac221/src/bin/auth/auth_srv.h (original)
+++ branches/trac221/src/bin/auth/auth_srv.h Thu Jul 1 22:58:04 2010
@@ -51,8 +51,7 @@
AuthSrv(const AuthSrv& source);
AuthSrv& operator=(const AuthSrv& source);
public:
- AuthSrv(isc::cc::AbstractSession& session_with_xfrin,
- isc::xfr::AbstractXfroutClient& xfrout_client);
+ AuthSrv(isc::xfr::AbstractXfroutClient& xfrout_client);
~AuthSrv();
//@}
/// \return \c true if the \message contains a response to be returned;
@@ -64,6 +63,7 @@
bool getVerbose() const;
void serve(std::string zone_name);
isc::data::ElementPtr updateConfig(isc::data::ElementPtr config);
+ void setSession(isc::cc::AbstractSession* session);
isc::config::ModuleCCSession* configSession() const;
void setConfigSession(isc::config::ModuleCCSession* cs);
private:
Modified: branches/trac221/src/bin/auth/main.cc
==============================================================================
--- branches/trac221/src/bin/auth/main.cc (original)
+++ branches/trac221/src/bin/auth/main.cc Thu Jul 1 22:58:04 2010
@@ -134,10 +134,10 @@
usage();
}
- // initialize command channel
int ret = 0;
- Session session_with_xfrin; // we should eventually pass io_service here.
+ Session* cc_session = NULL;
+ ModuleCCSession* cs = NULL;
XfroutClient xfrout_client(UNIX_SOCKET_FILE);
try {
string specfile;
@@ -148,26 +148,39 @@
specfile = string(AUTH_SPECFILE_LOCATION);
}
- auth_server = new AuthSrv(session_with_xfrin, xfrout_client);
+ auth_server = new AuthSrv(xfrout_client);
auth_server->setVerbose(verbose_mode);
+ cout << "[b10-auth] Server created." << endl;
io_service = new asio_link::IOService(auth_server, port, use_ipv4,
use_ipv6);
+ cout << "[b10-auth] IOService created." << endl;
- ModuleCCSession cs(specfile, io_service->get_io_service(),
- my_config_handler, my_command_handler);
+ cc_session = new Session(io_service->get_io_service());
+ cout << "[b10-auth] Session channel created." << endl;
- auth_server->setConfigSession(&cs);
+ cs = new ModuleCCSession(specfile, *cc_session, my_config_handler,
+ my_command_handler);
+ cout << "[b10-auth] Configuration 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.
+ // In a next step of refactoring we should make asio_link independent
+ // from auth_server, and create io_service, auth_server, and
+ // cc_session in that order.
+ auth_server->setSession(cc_session);
+ auth_server->setConfigSession(cs);
auth_server->updateConfig(ElementPtr());
-
cout << "[b10-auth] Server started." << endl;
io_service->run();
} catch (const std::exception& ex) {
- cerr << "[b10-auth] " << ex.what() << endl;
+ cerr << "[b10-auth] Initialization failed: " << ex.what() << endl;
ret = 1;
}
+ delete cs;
+ delete cc_session;
delete io_service;
delete auth_server;
return (ret);
Modified: branches/trac221/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac221/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac221/src/bin/auth/tests/auth_srv_unittest.cc Thu Jul 1 22:58:04 2010
@@ -15,6 +15,8 @@
// $Id$
#include <config.h>
+
+#include <boost/function.hpp>
#include <gtest/gtest.h>
@@ -89,6 +91,20 @@
string instance, string to);
virtual bool group_recvmsg(ElementPtr& envelope, ElementPtr& msg,
bool nonblock, int seq);
+ virtual void subscribe(string group UNUSED_PARAM,
+ string instance UNUSED_PARAM)
+ {}
+ virtual void unsubscribe(string group UNUSED_PARAM,
+ string instance UNUSED_PARAM)
+ {}
+ virtual void startRead(
+ boost::function<void()> read_callback UNUSED_PARAM)
+ {}
+ virtual int reply(ElementPtr& envelope UNUSED_PARAM,
+ ElementPtr& newmsg UNUSED_PARAM)
+ { return (0); }
+ virtual bool hasQueuedMsgs() { return (false); }
+
void setMessage(ElementPtr msg) { msg_ = msg; }
bool isEstablished() const { return (is_established_); }
void disableEstablish() { establish_ok_ = false; }
@@ -103,7 +119,7 @@
};
protected:
- AuthSrvTest() : server(notify_session, xfrout),
+ AuthSrvTest() : server(xfrout),
request_message(Message::RENDER),
parse_message(Message::PARSE), default_qid(0x1035),
opcode(Opcode(Opcode::QUERY())), qname("www.example.com"),
@@ -111,7 +127,9 @@
io_message(NULL), endpoint(NULL), request_obuffer(0),
request_renderer(request_obuffer),
response_obuffer(0), response_renderer(response_obuffer)
- {}
+ {
+ server.setSession(¬ify_session);
+ }
~AuthSrvTest() {
delete io_message;
delete endpoint;
Modified: branches/trac221/src/lib/cc/session.cc
==============================================================================
--- branches/trac221/src/lib/cc/session.cc (original)
+++ branches/trac221/src/lib/cc/session.cc Thu Jul 1 22:58:04 2010
@@ -15,7 +15,7 @@
// $Id$
#include <config.h>
-#include "session_config.h"
+#include <cc/session_config.h>
#include <stdint.h>
@@ -41,8 +41,8 @@
#include <exceptions/exceptions.h>
-#include "data.h"
-#include "session.h"
+#include <cc/data.h>
+#include <cc/session.h>
using namespace std;
using namespace isc::cc;
@@ -51,44 +51,26 @@
// some of the asio names conflict with socket API system calls
// (e.g. write(2)) so we don't import the entire asio namespace.
using asio::io_service;
-using asio::ip::tcp;
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
namespace isc {
namespace cc {
-
class SessionImpl {
public:
- SessionImpl() : sequence_(-1) { queue_ = Element::createFromString("[]"); }
- virtual ~SessionImpl() {}
- virtual void establish(const char& socket_file) = 0;
- virtual int getSocket() = 0;
- virtual void disconnect() = 0;
- virtual void writeData(const void* data, size_t datalen) = 0;
- virtual size_t readDataLength() = 0;
- virtual void readData(void* data, size_t datalen) = 0;
- virtual void startRead(boost::function<void()> user_handler) = 0;
-
+ SessionImpl(io_service& io_service) :
+ sequence_(-1), queue_(Element::createFromString("[]")),
+ io_service_(io_service), socket_(io_service_), data_length_(0)
+ {}
+ void establish(const char& socket_file);
+ void disconnect();
+ void writeData(const void* data, size_t datalen);
+ size_t readDataLength();
+ void readData(void* data, size_t datalen);
+ void startRead(boost::function<void()> user_handler);
+
int sequence_; // the next sequence number to use
std::string lname_;
ElementPtr queue_;
-};
-
-class ASIOSession : public SessionImpl {
-public:
- ASIOSession(io_service& io_service) :
- io_service_(io_service), socket_(io_service_), data_length_(0)
- {}
- virtual void establish(const char& socket_file);
- virtual void disconnect();
- virtual int getSocket() { return (socket_.native()); }
- virtual void writeData(const void* data, size_t datalen);
- virtual size_t readDataLength();
- virtual void readData(void* data, size_t datalen);
- virtual void startRead(boost::function<void()> user_handler);
+
private:
void internalRead(const asio::error_code& error,
size_t bytes_transferred);
@@ -101,28 +83,28 @@
asio::error_code error_;
};
-
-
-void
-ASIOSession::establish(const char& socket_file) {
+void
+SessionImpl::establish(const char& socket_file) {
try {
- socket_.connect(asio::local::stream_protocol::endpoint(&socket_file), error_);
- } catch (asio::system_error& se) {
+ socket_.connect(asio::local::stream_protocol::endpoint(&socket_file),
+ error_);
+ } catch(const asio::system_error& se) {
isc_throw(SessionError, se.what());
}
if (error_) {
- isc_throw(SessionError, "Unable to connect to message queue.");
- }
-}
-
-void
-ASIOSession::disconnect() {
+ isc_throw(SessionError, "Unable to connect to message queue: " <<
+ error_.message());
+ }
+}
+
+void
+SessionImpl::disconnect() {
socket_.close();
data_length_ = 0;
}
void
-ASIOSession::writeData(const void* data, size_t datalen) {
+SessionImpl::writeData(const void* data, size_t datalen) {
try {
asio::write(socket_, asio::buffer(data, datalen));
} catch (const asio::system_error& asio_ex) {
@@ -131,7 +113,7 @@
}
size_t
-ASIOSession::readDataLength() {
+SessionImpl::readDataLength() {
size_t ret_len = data_length_;
if (ret_len == 0) {
@@ -147,7 +129,7 @@
}
void
-ASIOSession::readData(void* data, size_t datalen) {
+SessionImpl::readData(void* data, size_t datalen) {
try {
asio::read(socket_, asio::buffer(data, datalen));
} catch (const asio::system_error& asio_ex) {
@@ -158,18 +140,18 @@
}
void
-ASIOSession::startRead(boost::function<void()> user_handler) {
+SessionImpl::startRead(boost::function<void()> user_handler) {
data_length_ = 0;
user_handler_ = user_handler;
async_read(socket_, asio::buffer(&data_length_,
sizeof(data_length_)),
- boost::bind(&ASIOSession::internalRead, this,
+ boost::bind(&SessionImpl::internalRead, this,
asio::placeholders::error,
asio::placeholders::bytes_transferred));
}
void
-ASIOSession::internalRead(const asio::error_code& error,
+SessionImpl::internalRead(const asio::error_code& error,
size_t bytes_transferred)
{
if (!error) {
@@ -184,27 +166,22 @@
}
}
-class SocketSession : public SessionImpl {
-public:
- SocketSession() : sock_(-1) {}
- virtual ~SocketSession() { disconnect(); }
- virtual int getSocket() { return (sock_); }
- void establish(const char& socket_file);
- virtual void disconnect()
- {
- if (sock_ >= 0) {
- close(sock_);
- }
- sock_ = -1;
- }
- virtual void writeData(const void* data, size_t datalen);
- virtual void readData(void* data, size_t datalen);
- virtual size_t readDataLength();
- virtual void startRead(boost::function<void()> user_handler UNUSED_PARAM)
- {} // nothing to do for this class
-private:
- int sock_;
-};
+Session::Session(io_service& io_service) : impl_(new SessionImpl(io_service))
+{}
+
+Session::~Session() {
+ delete impl_;
+}
+
+void
+Session::disconnect() {
+ impl_->disconnect();
+}
+
+void
+Session::startRead(boost::function<void()> read_callback) {
+ impl_->startRead(read_callback);
+}
namespace { // maybe unnecessary.
// This is a helper class to make the establish() method (below) exception-safe
@@ -224,83 +201,6 @@
}
void
-SocketSession::establish(const char& socket_file) {
- struct sockaddr_un s_un;
-#ifdef HAVE_SA_LEN
- s_un.sun_len = sizeof(struct sockaddr_un);
-#endif
-
- if (strlen(&socket_file) >= sizeof(s_un.sun_path)) {
- isc_throw(SessionError, "Unable to connect to message queue; "
- "socket file path too long: " << socket_file);
- }
- s_un.sun_family = AF_UNIX;
- strncpy(s_un.sun_path, &socket_file, sizeof(s_un.sun_path) - 1);
-
- int s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (s < 0) {
- isc_throw(SessionError, "socket() failed");
- }
-
- if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) {
- close(s);
- isc_throw(SessionError, "Unable to connect to message queue");
- }
-
- sock_ = s;
-}
-
-void
-SocketSession::writeData(const void* data, const size_t datalen) {
- int cc = write(sock_, data, datalen);
- if (cc != datalen) {
- isc_throw(SessionError, "Write failed: expect " << datalen <<
- ", actual " << cc);
- }
-}
-
-size_t
-SocketSession::readDataLength() {
- uint32_t length;
- readData(&length, sizeof(length));
- return (ntohl(length));
-}
-
-void
-SocketSession::readData(void* data, const size_t datalen) {
- int cc = read(sock_, data, datalen);
- if (cc != datalen) {
- isc_throw(SessionError, "Read failed: expect " << datalen <<
- ", actual " << cc);
- }
-}
-
-Session::Session() : impl_(new SocketSession)
-{}
-
-Session::Session(io_service& io_service) : impl_(new ASIOSession(io_service))
-{}
-
-Session::~Session() {
- delete impl_;
-}
-
-void
-Session::disconnect() {
- impl_->disconnect();
-}
-
-int
-Session::getSocket() const {
- return (impl_->getSocket());
-}
-
-void
-Session::startRead(boost::function<void()> read_callback) {
- impl_->startRead(read_callback);
-}
-
-void
Session::establish(const char* socket_file) {
if (socket_file == NULL) {
socket_file = getenv("BIND10_MSGQ_SOCKET_FILE");
@@ -333,7 +233,8 @@
}
//
-// Convert to wire format and send this on the TCP stream with its length prefix
+// Convert to wire format and send this via the stream socket with its length
+// prefix.
//
void
Session::sendmsg(ElementPtr& msg) {
Modified: branches/trac221/src/lib/cc/session.h
==============================================================================
--- branches/trac221/src/lib/cc/session.h (original)
+++ branches/trac221/src/lib/cc/session.h Thu Jul 1 22:58:04 2010
@@ -68,12 +68,20 @@
virtual void disconnect() = 0;
virtual int group_sendmsg(isc::data::ElementPtr msg,
std::string group,
- std::string instance,
- std::string to) = 0;
+ std::string instance = "*",
+ std::string to = "*") = 0;
virtual bool group_recvmsg(isc::data::ElementPtr& envelope,
isc::data::ElementPtr& msg,
- bool nonblock,
- int seq) = 0;
+ bool nonblock = true,
+ int seq = -1) = 0;
+ virtual void subscribe(std::string group,
+ std::string instance = "*") = 0;
+ virtual void unsubscribe(std::string group,
+ std::string instance = "*") = 0;
+ virtual void startRead(boost::function<void()> read_callback) = 0;
+ virtual int reply(isc::data::ElementPtr& envelope,
+ isc::data::ElementPtr& newmsg) = 0;
+ virtual bool hasQueuedMsgs() = 0;
};
class Session : public AbstractSession {
@@ -85,14 +93,10 @@
Session& operator=(const Session& source);
public:
- Session();
Session(asio::io_service& ioservice);
virtual ~Session();
- // XXX: quick hack to allow the user to watch the socket directly.
- int getSocket() const;
-
- void startRead(boost::function<void()> read_callback);
+ virtual void startRead(boost::function<void()> read_callback);
virtual void establish(const char* socket_file = NULL);
void disconnect();
@@ -106,9 +110,9 @@
isc::data::ElementPtr& msg,
bool nonblock = true,
int seq = -1);
- void subscribe(std::string group,
- std::string instance = "*");
- void unsubscribe(std::string group,
+ virtual void subscribe(std::string group,
+ std::string instance = "*");
+ virtual void unsubscribe(std::string group,
std::string instance = "*");
virtual int group_sendmsg(isc::data::ElementPtr msg,
std::string group,
@@ -118,9 +122,9 @@
isc::data::ElementPtr& msg,
bool nonblock = true,
int seq = -1);
- int reply(isc::data::ElementPtr& envelope,
- isc::data::ElementPtr& newmsg);
- bool hasQueuedMsgs();
+ virtual int reply(isc::data::ElementPtr& envelope,
+ isc::data::ElementPtr& newmsg);
+ virtual bool hasQueuedMsgs();
};
} // namespace cc
} // namespace isc
Modified: branches/trac221/src/lib/cc/session_unittests.cc
==============================================================================
--- branches/trac221/src/lib/cc/session_unittests.cc (original)
+++ branches/trac221/src/lib/cc/session_unittests.cc Thu Jul 1 22:58:04 2010
@@ -45,22 +45,3 @@
);
}
-
-TEST(Session, establish) {
- Session sess;
-
- EXPECT_THROW(
- sess.establish("/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- "/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/aaaaaaaaaa/"
- ), isc::cc::SessionError
- );
-
-}
Modified: branches/trac221/src/lib/config/ccsession.cc
==============================================================================
--- branches/trac221/src/lib/config/ccsession.cc (original)
+++ branches/trac221/src/lib/config/ccsession.cc Thu Jul 1 22:58:04 2010
@@ -198,27 +198,17 @@
ModuleCCSession::ModuleCCSession(
std::string spec_file_name,
- asio::io_service& io_service,
+ isc::cc::AbstractSession& session,
isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config),
isc::data::ElementPtr(*command_handler)(
const std::string& command, const isc::data::ElementPtr args)
) throw (isc::cc::SessionError) :
- session_(io_service)
+ session_(session)
{
init(spec_file_name, config_handler, command_handler);
// register callback for asynchronous read
session_.startRead(boost::bind(&ModuleCCSession::startCheck, this));
-}
-
-ModuleCCSession::ModuleCCSession(
- std::string spec_file_name,
- isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config),
- isc::data::ElementPtr(*command_handler)(
- const std::string& command, const isc::data::ElementPtr args)
- ) throw (isc::cc::SessionError)
-{
- init(spec_file_name, config_handler, command_handler);
}
void
@@ -238,7 +228,7 @@
ElementPtr answer, env;
- session_.establish();
+ session_.establish(NULL);
session_.subscribe(module_name_, "*");
//session_.subscribe("Boss", "*");
//session_.subscribe("statistics", "*");
@@ -298,12 +288,6 @@
}
}
return answer;
-}
-
-int
-ModuleCCSession::getSocket()
-{
- return (session_.getSocket());
}
bool
Modified: branches/trac221/src/lib/config/ccsession.h
==============================================================================
--- branches/trac221/src/lib/config/ccsession.h (original)
+++ branches/trac221/src/lib/config/ccsession.h Thu Jul 1 22:58:04 2010
@@ -24,10 +24,6 @@
#include <cc/session.h>
#include <cc/data.h>
-namespace asio {
-class io_service;
-}
-
namespace isc {
namespace config {
@@ -127,25 +123,13 @@
* module specification.
*/
ModuleCCSession(std::string spec_file_name,
- isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config) = NULL,
- isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args) = NULL
+ isc::cc::AbstractSession& session,
+ isc::data::ElementPtr(*config_handler)(
+ isc::data::ElementPtr new_config) = NULL,
+ isc::data::ElementPtr(*command_handler)(
+ const std::string& command,
+ const isc::data::ElementPtr args) = NULL
) throw (isc::cc::SessionError);
- ModuleCCSession(std::string spec_file_name,
- asio::io_service& io_service,
- isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config) = NULL,
- isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args) = NULL
- ) throw (isc::cc::SessionError);
-
- /**
- * Returns the socket that is used to communicate with the msgq
- * command channel. This socket should *only* be used to run a
- * select() loop over it. And if not time-critical, it is strongly
- * recommended to only use checkCommand() to check for messages
- *
- * @return The socket used to communicate with the msgq command
- * channel.
- */
- int getSocket();
/**
* Optional optimization for checkCommand loop; returns true
@@ -238,7 +222,7 @@
void startCheck();
std::string module_name_;
- isc::cc::Session session_;
+ isc::cc::AbstractSession& session_;
ModuleSpec module_specification_;
ElementPtr handleConfigUpdate(ElementPtr new_config);
Modified: branches/trac221/src/lib/config/tests/ccsession_unittests.cc
==============================================================================
--- branches/trac221/src/lib/config/tests/ccsession_unittests.cc (original)
+++ branches/trac221/src/lib/config/tests/ccsession_unittests.cc Thu Jul 1 22:58:04 2010
@@ -14,11 +14,11 @@
// $Id: module_spec_unittests.cc 1321 2010-03-11 10:17:03Z jelte $
-#include "config.h"
+#include <config.h>
#include <gtest/gtest.h>
-#include "fake_session.h"
+#include <config/tests/fake_session.h>
#include <config/ccsession.h>
@@ -28,42 +28,37 @@
using namespace isc::data;
using namespace isc::config;
+using namespace isc::cc;
using namespace std;
-std::string ccspecfile(const std::string name) {
+namespace {
+std::string
+ccspecfile(const std::string name) {
return std::string(TEST_DATA_PATH) + "/" + name;
}
-static ElementPtr
-el(const std::string& str)
-{
+ElementPtr
+el(const std::string& str) {
return Element::createFromString(str);
}
-// upon creation of a ModuleCCSession, the class
-// sends its specification to the config manager
-// it expects an ok answer back, so everytime we
-// create a ModuleCCSession, we must set an initial
-// ok answer
-void
-initFakeSession()
-{
- initial_messages = el("[]");
- msg_queue = el("[]");
- subscriptions = el("[]");
- initial_messages->add(createAnswer());
-}
-
-void
-endFakeSession()
-{
- initial_messages = ElementPtr();
- msg_queue = ElementPtr();
- subscriptions = ElementPtr();
-}
-
-TEST(CCSession, createAnswer)
-{
+class CCSessionTest : public ::testing::Test {
+protected:
+ CCSessionTest() :
+ session(el("[]"), el("[]"), el("[]"))
+ {
+ // upon creation of a ModuleCCSession, the class
+ // sends its specification to the config manager.
+ // it expects an ok answer back, so everytime we
+ // create a ModuleCCSession, we must set an initial
+ // ok answer.
+ session.getMessages()->add(createAnswer());
+ }
+ ~CCSessionTest() {}
+ FakeSession session;
+};
+
+TEST_F(CCSessionTest, createAnswer) {
ElementPtr answer;
answer = createAnswer();
EXPECT_EQ("{\"result\": [ 0 ]}", answer->str());
@@ -78,8 +73,7 @@
EXPECT_EQ("{\"result\": [ 0, [ \"just\", \"some\", \"data\" ] ]}", answer->str());
}
-TEST(CCSession, parseAnswer)
-{
+TEST_F(CCSessionTest, parseAnswer) {
ElementPtr answer;
ElementPtr arg;
int rcode;
@@ -110,8 +104,7 @@
EXPECT_EQ("[ \"just\", \"some\", \"data\" ]", arg->str());
}
-TEST(CCSession, createCommand)
-{
+TEST_F(CCSessionTest, createCommand) {
ElementPtr command;
ElementPtr arg;
@@ -131,8 +124,7 @@
ASSERT_EQ("{\"command\": [ \"foo\", {\"a\": \"map\"} ]}", command->str());
}
-TEST(CCSession, parseCommand)
-{
+TEST_F(CCSessionTest, parseCommand) {
ElementPtr arg;
std::string cmd;
@@ -159,44 +151,38 @@
}
-TEST(CCSession, session1)
-{
- initFakeSession();
- EXPECT_EQ(false, haveSubscription("Spec1", "*"));
- ModuleCCSession mccs(ccspecfile("spec1.spec"), NULL, NULL);
- EXPECT_EQ(true, haveSubscription("Spec1", "*"));
-
- EXPECT_EQ(1, msg_queue->size());
+TEST_F(CCSessionTest, session1) {
+ EXPECT_EQ(false, session.haveSubscription("Spec1", "*"));
+ ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL);
+ EXPECT_EQ(true, session.haveSubscription("Spec1", "*"));
+
+ EXPECT_EQ(1, session.getMsgQueue()->size());
ElementPtr msg;
std::string group, to;
- msg = getFirstMessage(group, to);
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"command\": [ \"module_spec\", {\"module_name\": \"Spec1\"} ]}", msg->str());
EXPECT_EQ("ConfigManager", group);
EXPECT_EQ("*", to);
- EXPECT_EQ(0, msg_queue->size());
- endFakeSession();
-}
-
-TEST(CCSession, session2)
+ EXPECT_EQ(0, session.getMsgQueue()->size());
+}
+
+TEST_F(CCSessionTest, session2)
{
- initFakeSession();
- EXPECT_EQ(false, haveSubscription("Spec2", "*"));
- ModuleCCSession mccs(ccspecfile("spec2.spec"), NULL, NULL);
- EXPECT_EQ(true, haveSubscription("Spec2", "*"));
-
- EXPECT_EQ(1, msg_queue->size());
+ EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+ ModuleCCSession mccs(ccspecfile("spec2.spec"), session, NULL, NULL);
+ EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+
+ EXPECT_EQ(1, session.getMsgQueue()->size());
ElementPtr msg;
std::string group, to;
- msg = getFirstMessage(group, to);
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"command\": [ \"module_spec\", {\"commands\": [ {\"command_args\": [ {\"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": False, \"item_type\": \"string\"} ], \"command_description\": \"Print the given message to stdout\", \"command_name\": \"print_message\"}, {\"command_args\": [ ], \"command_description\": \"Shut down BIND 10\", \"command_name\": \"shutdown\"} ], \"config_data\": [ {\"item_default\": 1, \"item_name\": \"item1\", \"item_optional\": False, \"item_type\": \"integer\"}, {\"item_default\": 1.1, \"item_name\": \"item2\", \"item_optional\": False, \"item_type\": \"real\"}, {\"item_default\": True, \"item_name\": \"item3\", \"item_optional\": False, \"item_type\": \"boolean\"}, {\"item_default\": \"test\", \"item_name\": \"item4\", \"item_optional\": False, \"item_type\": \"string\"}, {\"item_default\": [ \"a\", \"b\" ], \"item_name\": \"item5\", \"item_optional\": False, \"item_type\": \"list\", \"list_item_spec\": {\"item_def
ault\": \"\", \"item_name\": \"list_element\", \"item_optional\": False, \"item_type\": \"string\"}}, {\"item_default\": {}, \"item_name\": \"item6\", \"item_optional\": False, \"item_type\": \"map\", \"map_item_spec\": [ {\"item_default\": \"default\", \"item_name\": \"value1\", \"item_optional\": True, \"item_type\": \"string\"}, {\"item_name\": \"value2\", \"item_optional\": True, \"item_type\": \"integer\"} ]} ], \"module_name\": \"Spec2\"} ]}", msg->str());
EXPECT_EQ("ConfigManager", group);
EXPECT_EQ("*", to);
- EXPECT_EQ(0, msg_queue->size());
- endFakeSession();
-}
-
-ElementPtr my_config_handler(ElementPtr new_config)
-{
+ EXPECT_EQ(0, session.getMsgQueue()->size());
+}
+
+ElementPtr my_config_handler(ElementPtr new_config) {
if (new_config && new_config->contains("item1") &&
new_config->get("item1")->intValue() == 5) {
return createAnswer(6, "I do not like the number 5");
@@ -204,7 +190,8 @@
return createAnswer();
}
-ElementPtr my_command_handler(const std::string& command, ElementPtr arg UNUSED_PARAM)
+ElementPtr my_command_handler(const std::string& command,
+ ElementPtr arg UNUSED_PARAM)
{
if (command == "good_command") {
return createAnswer();
@@ -223,185 +210,179 @@
}
}
-TEST(CCSession, session3)
-{
- initFakeSession();
+TEST_F(CCSessionTest, session3) {
// client will ask for config
- initial_messages->add(createAnswer(0, el("{}")));
-
- EXPECT_EQ(false, haveSubscription("Spec2", "*"));
- ModuleCCSession mccs(ccspecfile("spec2.spec"), my_config_handler, my_command_handler);
- EXPECT_EQ(true, haveSubscription("Spec2", "*"));
-
- EXPECT_EQ(2, msg_queue->size());
+ session.getMessages()->add(createAnswer(0, el("{}")));
+
+ EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+ ModuleCCSession mccs(ccspecfile("spec2.spec"), session, my_config_handler,
+ my_command_handler);
+ EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+
+ EXPECT_EQ(2, session.getMsgQueue()->size());
ElementPtr msg;
std::string group, to;
- msg = getFirstMessage(group, to);
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"command\": [ \"module_spec\", {\"commands\": [ {\"command_args\": [ {\"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": False, \"item_type\": \"string\"} ], \"command_description\": \"Print the given message to stdout\", \"command_name\": \"print_message\"}, {\"command_args\": [ ], \"command_description\": \"Shut down BIND 10\", \"command_name\": \"shutdown\"} ], \"config_data\": [ {\"item_default\": 1, \"item_name\": \"item1\", \"item_optional\": False, \"item_type\": \"integer\"}, {\"item_default\": 1.1, \"item_name\": \"item2\", \"item_optional\": False, \"item_type\": \"real\"}, {\"item_default\": True, \"item_name\": \"item3\", \"item_optional\": False, \"item_type\": \"boolean\"}, {\"item_default\": \"test\", \"item_name\": \"item4\", \"item_optional\": False, \"item_type\": \"string\"}, {\"item_default\": [ \"a\", \"b\" ], \"item_name\": \"item5\", \"item_optional\": False, \"item_type\": \"list\", \"list_item_spec\": {\"item_def
ault\": \"\", \"item_name\": \"list_element\", \"item_optional\": False, \"item_type\": \"string\"}}, {\"item_default\": {}, \"item_name\": \"item6\", \"item_optional\": False, \"item_type\": \"map\", \"map_item_spec\": [ {\"item_default\": \"default\", \"item_name\": \"value1\", \"item_optional\": True, \"item_type\": \"string\"}, {\"item_name\": \"value2\", \"item_optional\": True, \"item_type\": \"integer\"} ]} ], \"module_name\": \"Spec2\"} ]}", msg->str());
EXPECT_EQ("ConfigManager", group);
EXPECT_EQ("*", to);
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"command\": [ \"get_config\", {\"module_name\": \"Spec2\"} ]}", msg->str());
EXPECT_EQ("ConfigManager", group);
EXPECT_EQ("*", to);
- EXPECT_EQ(0, msg_queue->size());
- endFakeSession();
-}
-
-TEST(CCSession, checkCommand)
-{
- initFakeSession();
+ EXPECT_EQ(0, session.getMsgQueue()->size());
+}
+
+TEST_F(CCSessionTest, checkCommand) {
// client will ask for config
- initial_messages->add(createAnswer(0, el("{}")));
-
- EXPECT_EQ(false, haveSubscription("Spec2", "*"));
- ModuleCCSession mccs(ccspecfile("spec2.spec"), my_config_handler, my_command_handler);
- EXPECT_EQ(true, haveSubscription("Spec2", "*"));
-
- EXPECT_EQ(2, msg_queue->size());
+ session.getMessages()->add(createAnswer(0, el("{}")));
+
+ EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
+ ModuleCCSession mccs(ccspecfile("spec2.spec"), session, my_config_handler,
+ my_command_handler);
+ EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
+
+ EXPECT_EQ(2, session.getMsgQueue()->size());
ElementPtr msg;
std::string group, to;
// checked above, drop em
- msg = getFirstMessage(group, to);
- msg = getFirstMessage(group, to);
+ msg = session.getFirstMessage(group, to);
+ msg = session.getFirstMessage(group, to);
int result;
result = mccs.checkCommand();
EXPECT_EQ(0, result);
// not a command, should be ignored
- addMessage(el("1"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(0, result);
-
- addMessage(el("{ \"command\": [ \"good_command\" ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("1"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(0, result);
+
+ session.addMessage(el("{ \"command\": [ \"good_command\" ] }"), "Spec2",
+ "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 0 ]}", msg->str());
EXPECT_EQ(0, result);
- addMessage(el("{ \"command\": \"bad_command\" }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": \"bad_command\" }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 1, \"Command part in command message missing, empty, or not a list\" ]}", msg->str());
EXPECT_EQ(0, result);
- addMessage(el("{ \"command\": [ \"bad_command\" ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"bad_command\" ] }"),
+ "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 1, \"bad command\" ]}", msg->str());
EXPECT_EQ(0, result);
- addMessage(el("{ \"command\": [ \"command_with_arg\", 1 ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"command_with_arg\", 1 ] }"),
+ "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 0, 2 ]}", msg->str());
EXPECT_EQ(0, result);
- addMessage(el("{ \"command\": [ \"command_with_arg\" ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"command_with_arg\" ] }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 1, \"arg missing\" ]}", msg->str());
EXPECT_EQ(0, result);
- addMessage(el("{ \"command\": [ \"command_with_arg\", \"asdf\" ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"command_with_arg\", \"asdf\" ] }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 1, \"arg bad type\" ]}", msg->str());
EXPECT_EQ(0, result);
mccs.setCommandHandler(NULL);
- addMessage(el("{ \"command\": [ \"whatever\" ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"whatever\" ] }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 1, \"Command given but no command handler for module\" ]}", msg->str());
EXPECT_EQ(0, result);
EXPECT_EQ(1, mccs.getValue("item1")->intValue());
- addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 2 } ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 2 } ] }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 0 ]}", msg->str());
EXPECT_EQ(0, result);
EXPECT_EQ(2, mccs.getValue("item1")->intValue());
- addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": \"asdf\" } ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": \"asdf\" } ] }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 2, \"Error in config validation: Type mismatch\" ]}", msg->str());
EXPECT_EQ(0, result);
EXPECT_EQ(2, mccs.getValue("item1")->intValue());
- addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 5 } ] }"), "Spec2", "*");
- result = mccs.checkCommand();
- EXPECT_EQ(1, msg_queue->size());
- msg = getFirstMessage(group, to);
+ session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 5 } ] }"), "Spec2", "*");
+ result = mccs.checkCommand();
+ EXPECT_EQ(1, session.getMsgQueue()->size());
+ msg = session.getFirstMessage(group, to);
EXPECT_EQ("{\"result\": [ 6, \"I do not like the number 5\" ]}", msg->str());
EXPECT_EQ(0, result);
EXPECT_EQ(2, mccs.getValue("item1")->intValue());
-
- endFakeSession();
-}
-
-TEST(CCSession, remoteConfig)
-{
+}
+
+TEST_F(CCSessionTest, remoteConfig) {
std::string module_name;
int item1;
- initFakeSession();
- ModuleCCSession mccs(ccspecfile("spec1.spec"), NULL, NULL);
- EXPECT_EQ(true, haveSubscription("Spec1", "*"));
+ ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL);
+ EXPECT_EQ(true, session.haveSubscription("Spec1", "*"));
// first simply connect, with no config values, and see we get
// the default
- initial_messages->add(createAnswer(0, el("{}")));
-
- EXPECT_EQ(false, haveSubscription("Spec2", "*"));
+ session.getMessages()->add(createAnswer(0, el("{}")));
+
+ EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
module_name = mccs.addRemoteConfig(ccspecfile("spec2.spec"));
EXPECT_EQ("Spec2", module_name);
- EXPECT_EQ(true, haveSubscription("Spec2", "*"));
+ EXPECT_EQ(true, session.haveSubscription("Spec2", "*"));
item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
EXPECT_EQ(1, item1);
// Remove it and see we get an error asking for a config value
mccs.removeRemoteConfig(module_name);
- EXPECT_EQ(false, haveSubscription("Spec2", "*"));
+ EXPECT_EQ(false, session.haveSubscription("Spec2", "*"));
EXPECT_THROW(mccs.getRemoteConfigValue(module_name, "item1"), CCSessionError);
// Now re-add it, with a specific config value, and see we get that
- initial_messages->add(createAnswer(0, el("{ \"item1\": 2 }")));
+ session.getMessages()->add(createAnswer(0, el("{ \"item1\": 2 }")));
module_name = mccs.addRemoteConfig(ccspecfile("spec2.spec"));
item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
EXPECT_EQ(2, item1);
// Try a config_update command
- addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 3 } ] }"), module_name, "*");
+ session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 3 } ] }"), module_name, "*");
mccs.checkCommand();
item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
EXPECT_EQ(3, item1);
// remove, re-add, now with a *bad* config request answer
mccs.removeRemoteConfig(module_name);
- initial_messages->add(el("{}"));
+ session.getMessages()->add(el("{}"));
EXPECT_THROW(mccs.addRemoteConfig(ccspecfile("spec2.spec")), CCSessionError);
- initial_messages->add(createAnswer(1, "my_error"));
+ session.getMessages()->add(createAnswer(1, "my_error"));
EXPECT_THROW(mccs.addRemoteConfig(ccspecfile("spec2.spec")), CCSessionError);
- initial_messages->add(createAnswer());
+ session.getMessages()->add(createAnswer());
mccs.addRemoteConfig(ccspecfile("spec2.spec"));
-
- endFakeSession();
-}
-
+}
+}
Modified: branches/trac221/src/lib/config/tests/fake_session.cc
==============================================================================
--- branches/trac221/src/lib/config/tests/fake_session.cc (original)
+++ branches/trac221/src/lib/config/tests/fake_session.cc Thu Jul 1 22:58:04 2010
@@ -38,26 +38,21 @@
#include <sys/socket.h>
#include <netinet/in.h>
-isc::data::ElementPtr initial_messages;
-isc::data::ElementPtr subscriptions;
-isc::data::ElementPtr msg_queue;
-
// ok i want these in cc/data
-static bool
-listContains(ElementPtr list, ElementPtr el)
-{
+bool
+listContains(ElementPtr list, ElementPtr el) {
if (!list) {
- return false;
+ return (false);
}
BOOST_FOREACH(ElementPtr l_el, list->listValue()) {
if (l_el == el) {
- return true;
+ return (true);
}
}
- return false;
-}
-
-static void
+ return (false);
+}
+
+void
listRemove(ElementPtr list, ElementPtr el) {
int i = -1;
BOOST_FOREACH(ElementPtr s_el, list->listValue()) {
@@ -72,119 +67,65 @@
}
// endwant
-ElementPtr
-getFirstMessage(std::string& group, std::string& to)
-{
- ElementPtr el;
- if (msg_queue && msg_queue->size() > 0) {
- el = msg_queue->get(0);
- msg_queue->remove(0);
- group = el->get(0)->stringValue();
- to = el->get(1)->stringValue();
- return el->get(2);
- } else {
- group = "";
- to = "";
- return ElementPtr();
- }
-}
-
-void
-addMessage(ElementPtr msg, const std::string& group, const std::string& to)
-{
- ElementPtr m_el = Element::createFromString("[]");
- m_el->add(Element::create(group));
- m_el->add(Element::create(to));
- m_el->add(msg);
- if (!msg_queue) {
- msg_queue = Element::createFromString("[]");
- }
- msg_queue->add(m_el);
-}
-
-bool
-haveSubscription(const std::string& group, const std::string& instance)
-{
- if (!subscriptions) {
- return false;
- }
- ElementPtr s1 = Element::createFromString("[]");
- ElementPtr s2 = Element::createFromString("[]");
- s1->add(Element::create(group));
- s1->add(Element::create(instance));
- s2->add(Element::create(group));
- s2->add(Element::create("*"));
- bool result = (listContains(subscriptions, s1) || listContains(subscriptions, s2));
- return result;
-}
-
-bool
-haveSubscription(const ElementPtr group, const ElementPtr instance)
-{
- return haveSubscription(group->stringValue(), instance->stringValue());
-}
-
namespace isc {
namespace cc {
-Session::Session()
-{
-}
-
-Session::Session(asio::io_service& io_service UNUSED_PARAM)
-{
-}
-
-Session::~Session() {
-}
-
-bool
-Session::connect() {
- return true;
-}
-
-void
-Session::disconnect() {
-}
-
-int
-Session::getSocket() const {
- return 1;
-}
-
-void
-Session::startRead(boost::function<void()> read_callback UNUSED_PARAM) {
-}
-
-void
-Session::establish(const char* socket_file) {
+FakeSession::FakeSession(isc::data::ElementPtr initial_messages,
+ isc::data::ElementPtr subscriptions,
+ isc::data::ElementPtr msg_queue) :
+ messages_(initial_messages),
+ subscriptions_(subscriptions),
+ msg_queue_(msg_queue)
+{
+}
+
+FakeSession::~FakeSession() {
+}
+
+bool
+FakeSession::connect() {
+ return (true);
+}
+
+void
+FakeSession::disconnect() {
+}
+
+void
+FakeSession::startRead(boost::function<void()> read_callback UNUSED_PARAM) {
+}
+
+void
+FakeSession::establish(const char* socket_file) {
}
//
// Convert to wire format and send this on the TCP stream with its length prefix
//
void
-Session::sendmsg(ElementPtr& msg) {
+FakeSession::sendmsg(ElementPtr& msg) {
//cout << "[XX] client sends message: " << msg << endl;
// err, to where?
addMessage(msg, "*", "*");
}
void
-Session::sendmsg(ElementPtr& env, ElementPtr& msg) {
+FakeSession::sendmsg(ElementPtr& env, ElementPtr& msg) {
//cout << "[XX] client sends message: " << msg << endl;
//cout << "[XX] env: " << env << endl;
addMessage(msg, env->get("group")->stringValue(), env->get("to")->stringValue());
}
bool
-Session::recvmsg(ElementPtr& msg, bool nonblock UNUSED_PARAM, int seq UNUSED_PARAM) {
+FakeSession::recvmsg(ElementPtr& msg, bool nonblock UNUSED_PARAM,
+ int seq UNUSED_PARAM)
+{
//cout << "[XX] client asks for message " << endl;
- if (initial_messages &&
- initial_messages->getType() == Element::list &&
- initial_messages->size() > 0) {
- msg = initial_messages->get(0);
- initial_messages->remove(0);
+ if (messages_ &&
+ messages_->getType() == Element::list &&
+ messages_->size() > 0) {
+ msg = messages_->get(0);
+ messages_->remove(0);
} else {
msg = ElementPtr();
}
@@ -192,18 +133,21 @@
}
bool
-Session::recvmsg(ElementPtr& env, ElementPtr& msg, bool nonblock UNUSED_PARAM, int seq UNUSED_PARAM) {
+FakeSession::recvmsg(ElementPtr& env, ElementPtr& msg,
+ bool nonblock UNUSED_PARAM,
+ int seq UNUSED_PARAM)
+{
//cout << "[XX] client asks for message and env" << endl;
env = ElementPtr();
- if (initial_messages &&
- initial_messages->getType() == Element::list &&
- initial_messages->size() > 0) {
+ if (messages_ &&
+ messages_->getType() == Element::list &&
+ messages_->size() > 0) {
// do we need initial message to have env[group] and [to] too?
- msg = initial_messages->get(0);
- initial_messages->remove(0);
+ msg = messages_->get(0);
+ messages_->remove(0);
return true;
- } else if (msg_queue) {
- BOOST_FOREACH(ElementPtr c_m, msg_queue->listValue()) {
+ } else if (msg_queue_) {
+ BOOST_FOREACH(ElementPtr c_m, msg_queue_->listValue()) {
ElementPtr to_remove = ElementPtr();
if (haveSubscription(c_m->get(0), c_m->get(1))) {
env = Element::createFromString("{}");
@@ -213,7 +157,7 @@
to_remove = c_m;
}
if (to_remove) {
- listRemove(msg_queue, to_remove);
+ listRemove(msg_queue_, to_remove);
return true;
}
}
@@ -224,32 +168,32 @@
}
void
-Session::subscribe(std::string group, std::string instance) {
+FakeSession::subscribe(std::string group, std::string instance) {
//cout << "[XX] client subscribes to " << group << " . " << instance << endl;
ElementPtr s_el = Element::createFromString("[]");
s_el->add(Element::create(group));
s_el->add(Element::create(instance));
- if (!subscriptions) {
- subscriptions = Element::createFromString("[]");
- }
- subscriptions->add(s_el);
-}
-
-void
-Session::unsubscribe(std::string group, std::string instance) {
+ if (!subscriptions_) {
+ subscriptions_ = Element::createFromString("[]");
+ }
+ subscriptions_->add(s_el);
+}
+
+void
+FakeSession::unsubscribe(std::string group, std::string instance) {
//cout << "[XX] client unsubscribes from " << group << " . " << instance << endl;
ElementPtr s_el = Element::createFromString("[]");
s_el->add(Element::create(group));
s_el->add(Element::create(instance));
- if (!subscriptions) {
+ if (!subscriptions_) {
return;
}
- listRemove(subscriptions, s_el);
-}
-
-unsigned int
-Session::group_sendmsg(ElementPtr msg, std::string group,
- std::string to, std::string instance UNUSED_PARAM)
+ listRemove(subscriptions_, s_el);
+}
+
+int
+FakeSession::group_sendmsg(ElementPtr msg, std::string group,
+ std::string to, std::string instance UNUSED_PARAM)
{
//cout << "[XX] client sends message: " << msg << endl;
//cout << "[XX] to: " << group << " . " << instance << "." << to << endl;
@@ -258,14 +202,14 @@
}
bool
-Session::group_recvmsg(ElementPtr& envelope, ElementPtr& msg,
- bool nonblock, int seq)
+FakeSession::group_recvmsg(ElementPtr& envelope, ElementPtr& msg,
+ bool nonblock, int seq)
{
return (recvmsg(envelope, msg, nonblock, seq));
}
-unsigned int
-Session::reply(ElementPtr& envelope, ElementPtr& newmsg) {
+int
+FakeSession::reply(ElementPtr& envelope, ElementPtr& newmsg) {
//cout << "[XX] client sends reply: " << newmsg << endl;
//cout << "[XX] env: " << envelope << endl;
addMessage(newmsg, envelope->get("group")->stringValue(), envelope->get("to")->stringValue());
@@ -273,9 +217,64 @@
}
bool
-Session::hasQueuedMsgs() {
+FakeSession::hasQueuedMsgs() {
return false;
}
-}
-}
+ElementPtr
+FakeSession::getFirstMessage(std::string& group, std::string& to) {
+ ElementPtr el;
+ if (msg_queue_ && msg_queue_->size() > 0) {
+ el = msg_queue_->get(0);
+ msg_queue_->remove(0);
+ group = el->get(0)->stringValue();
+ to = el->get(1)->stringValue();
+ return el->get(2);
+ } else {
+ group = "";
+ to = "";
+ return (ElementPtr());
+ }
+}
+
+void
+FakeSession::addMessage(ElementPtr msg, const std::string& group,
+ const std::string& to)
+{
+ ElementPtr m_el = Element::createFromString("[]");
+ m_el->add(Element::create(group));
+ m_el->add(Element::create(to));
+ m_el->add(msg);
+ if (!msg_queue_) {
+ msg_queue_ = Element::createFromString("[]");
+ }
+ msg_queue_->add(m_el);
+}
+
+bool
+FakeSession::haveSubscription(const std::string& group,
+ const std::string& instance)
+{
+ if (!subscriptions_) {
+ return (false);
+ }
+ ElementPtr s1 = Element::createFromString("[]");
+ ElementPtr s2 = Element::createFromString("[]");
+ s1->add(Element::create(group));
+ s1->add(Element::create(instance));
+ s2->add(Element::create(group));
+ s2->add(Element::create("*"));
+ bool result = (listContains(subscriptions_, s1) ||
+ listContains(subscriptions_, s2));
+ return (result);
+}
+
+bool
+FakeSession::haveSubscription(const ElementPtr group,
+ const ElementPtr instance)
+{
+ return (haveSubscription(group->stringValue(), instance->stringValue()));
+}
+
+}
+}
Modified: branches/trac221/src/lib/config/tests/fake_session.h
==============================================================================
--- branches/trac221/src/lib/config/tests/fake_session.h (original)
+++ branches/trac221/src/lib/config/tests/fake_session.h Thu Jul 1 22:58:04 2010
@@ -14,8 +14,8 @@
// $Id: session.h 1250 2010-03-09 22:52:15Z jinmei $
-#ifndef _ISC_SESSION_H
-#define _ISC_SESSION_H 1
+#ifndef _ISC_FAKESESSION_H
+#define _ISC_FAKESESSION_H 1
#include <string>
@@ -24,85 +24,78 @@
#include <exceptions/exceptions.h>
#include <cc/data.h>
-
-namespace asio {
-class io_service;
-}
-
-// global variables so tests can insert
-// update and check, before, during and after
-// the actual session object was created/destroyed
-
-// if initial_messages contains a list of messages,
-// these are sent when recv_msg or group_recvmsg is called
-// instead of whatever is in the msg queue
-extern isc::data::ElementPtr initial_messages;
-extern isc::data::ElementPtr subscriptions;
-extern isc::data::ElementPtr msg_queue;
-
-bool haveSubscription(const std::string& group, const std::string& instance);
-bool haveSubscription(const isc::data::ElementPtr group, const isc::data::ElementPtr instance);
-isc::data::ElementPtr getFirstMessage(std::string& group, std::string& to);
-void addMessage(isc::data::ElementPtr, const std::string& group, const std::string& to);
+#include <cc/session.h>
namespace isc {
- namespace cc {
+namespace cc {
+class FakeSession : public AbstractSession {
+private:
+ FakeSession(const Session& source);
+ FakeSession& operator=(const Session& source);
- class SessionError : public isc::Exception {
- public:
- SessionError(const char* file, size_t line, const char* what) :
- isc::Exception(file, line, what) {}
- };
+public:
+ // public so tests can inspect them
- class Session {
- private:
- Session(const Session& source);
- Session& operator=(const Session& source);
+ // if initial_messages contains a list of messages,
+ // these are sent when recv_msg or group_recvmsg is called
+ // instead of whatever is in the msg queue
+ FakeSession(isc::data::ElementPtr initial_messages,
+ isc::data::ElementPtr subscriptions,
+ isc::data::ElementPtr msg_queue);
+ virtual ~FakeSession();
- public:
- // public so tests can inspect them
-
- Session();
- Session(asio::io_service& ioservice);
- ~Session();
+ virtual void startRead(boost::function<void()> read_callback);
- // XXX: quick hack to allow the user to watch the socket directly.
- int getSocket() const;
-
- void startRead(boost::function<void()> read_callback);
-
- void establish(const char* socket_file = NULL);
- bool connect();
- void disconnect();
- void sendmsg(isc::data::ElementPtr& msg);
- void sendmsg(isc::data::ElementPtr& env,
- isc::data::ElementPtr& msg);
- bool recvmsg(isc::data::ElementPtr& msg,
- bool nonblock = true, int seq = -1);
- bool recvmsg(isc::data::ElementPtr& env,
- isc::data::ElementPtr& msg,
- bool nonblock = true, int seq = -1);
- void subscribe(std::string group,
+ virtual void establish(const char* socket_file = NULL);
+ bool connect();
+ virtual void disconnect();
+ void sendmsg(isc::data::ElementPtr& msg);
+ void sendmsg(isc::data::ElementPtr& env,
+ isc::data::ElementPtr& msg);
+ bool recvmsg(isc::data::ElementPtr& msg,
+ bool nonblock = true, int seq = -1);
+ bool recvmsg(isc::data::ElementPtr& env,
+ isc::data::ElementPtr& msg,
+ bool nonblock = true, int seq = -1);
+ virtual void subscribe(std::string group,
std::string instance = "*");
- void unsubscribe(std::string group,
+ virtual void unsubscribe(std::string group,
std::string instance = "*");
- unsigned int group_sendmsg(isc::data::ElementPtr msg,
- std::string group,
- std::string instance = "*",
- std::string to = "*");
- bool group_recvmsg(isc::data::ElementPtr& envelope,
+ virtual int group_sendmsg(isc::data::ElementPtr msg,
+ std::string group,
+ std::string instance = "*",
+ std::string to = "*");
+ virtual bool group_recvmsg(isc::data::ElementPtr& envelope,
isc::data::ElementPtr& msg,
bool nonblock = true,
int seq = -1);
- unsigned int reply(isc::data::ElementPtr& envelope,
- isc::data::ElementPtr& newmsg);
- bool hasQueuedMsgs();
+ virtual int reply(isc::data::ElementPtr& envelope,
+ isc::data::ElementPtr& newmsg);
+ virtual bool hasQueuedMsgs();
+ isc::data::ElementPtr getFirstMessage(std::string& group, std::string& to);
+ void addMessage(isc::data::ElementPtr, const std::string& group,
+ const std::string& to);
+ bool haveSubscription(const std::string& group,
+ const std::string& instance);
+ bool haveSubscription(const isc::data::ElementPtr group,
+ const isc::data::ElementPtr instance);
- };
- } // namespace cc
+ // For the convenience of tests, we share these internal members
+ // with the tester. The test code may insert update and check,
+ // before (via the constructor parameters), during and after the actual
+ // session object was created/destroyed.
+ isc::data::ElementPtr getMessages() { return (messages_); }
+ isc::data::ElementPtr getMsgQueue() { return (msg_queue_); }
+
+private:
+ const isc::data::ElementPtr messages_;
+ isc::data::ElementPtr subscriptions_;
+ isc::data::ElementPtr msg_queue_;
+};
+} // namespace cc
} // namespace isc
-#endif // _ISC_SESSION_H
+#endif // _ISC_FAKESESSION_H
// Local Variables:
// mode: c++
More information about the bind10-changes
mailing list