[svn] commit: r2459 - in /trunk: ./ src/bin/auth/ src/bin/xfrin/ src/lib/cc/ src/lib/config/ src/lib/config/tests/ src/lib/datasrc/ src/lib/dns/ src/lib/dns/rdata/generic/ src/lib/dns/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Jul 9 19:18:11 UTC 2010
Author: jinmei
Date: Fri Jul 9 19:18:11 2010
New Revision: 2459
Log:
merged branches/275 (for trac #275).
Modified:
trunk/ (props changed)
trunk/src/bin/auth/main.cc
trunk/src/bin/xfrin/ (props changed)
trunk/src/lib/cc/ (props changed)
trunk/src/lib/cc/session.cc
trunk/src/lib/cc/session.h
trunk/src/lib/cc/session_unittests.cc
trunk/src/lib/config/ccsession.cc
trunk/src/lib/config/ccsession.h
trunk/src/lib/config/tests/ccsession_unittests.cc
trunk/src/lib/config/tests/fake_session.cc
trunk/src/lib/config/tests/fake_session.h
trunk/src/lib/datasrc/ (props changed)
trunk/src/lib/dns/ (props changed)
trunk/src/lib/dns/rdata/generic/rrsig_46.cc (props changed)
trunk/src/lib/dns/tests/ (props changed)
Modified: trunk/src/bin/auth/main.cc
==============================================================================
--- trunk/src/bin/auth/main.cc (original)
+++ trunk/src/bin/auth/main.cc Fri Jul 9 19:18:11 2010
@@ -138,8 +138,9 @@
usage();
}
- // initialize command channel
int ret = 0;
+ Session* cc_session = NULL;
+ ModuleCCSession* cs = NULL;
try {
string specfile;
if (getenv("B10_FROM_BUILD")) {
@@ -151,23 +152,31 @@
auth_server = new AuthSrv(cache);
auth_server->setVerbose(verbose_mode);
+ cout << "[b10-auth] Server created." << endl;
io_service = new asio_link::IOService(auth_server, address, 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;
+
+ 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: trunk/src/lib/cc/session.cc
==============================================================================
--- trunk/src/lib/cc/session.cc (original)
+++ trunk/src/lib/cc/session.cc Fri Jul 9 19:18:11 2010
@@ -15,7 +15,7 @@
// $Id$
#include <config.h>
-#include "session_config.h"
+#include <cc/session_config.h>
#include <stdint.h>
@@ -42,8 +42,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;
@@ -52,44 +52,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::createList(); }
- 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::createList()),
+ 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);
+
long 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);
@@ -102,28 +84,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) {
@@ -132,7 +114,7 @@
}
size_t
-ASIOSession::readDataLength() {
+SessionImpl::readDataLength() {
size_t ret_len = data_length_;
if (ret_len == 0) {
@@ -148,7 +130,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) {
@@ -159,18 +141,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) {
@@ -185,27 +167,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
@@ -225,83 +202,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");
@@ -334,7 +234,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: trunk/src/lib/cc/session.h
==============================================================================
--- trunk/src/lib/cc/session.h (original)
+++ trunk/src/lib/cc/session.h Fri Jul 9 19:18:11 2010
@@ -40,7 +40,36 @@
isc::Exception(file, line, what) {}
};
- class Session {
+ class AbstractSession {
+ private:
+ AbstractSession(const AbstractSession& source);
+ AbstractSession& operator=(const AbstractSession& source);
+ protected:
+ AbstractSession() {}
+ public:
+ virtual ~AbstractSession() {}
+ //@}
+ virtual void establish(const char* socket_file) = 0;
+ virtual void disconnect() = 0;
+ virtual int group_sendmsg(isc::data::ElementPtr msg,
+ std::string group,
+ std::string instance = "*",
+ std::string to = "*") = 0;
+ virtual bool group_recvmsg(isc::data::ElementPtr& envelope,
+ isc::data::ElementPtr& msg,
+ 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 {
private:
SessionImpl* impl_;
@@ -49,17 +78,29 @@
Session& operator=(const Session& source);
public:
- Session();
Session(asio::io_service& ioservice);
~Session();
- // XXX: quick hack to allow the user to watch the socket directly.
- int getSocket() const;
+ virtual void startRead(boost::function<void()> read_callback);
- void startRead(boost::function<void()> read_callback);
-
- void establish(const char* socket_file = NULL);
- void disconnect();
+ virtual void establish(const char* socket_file = NULL);
+ virtual void disconnect();
+ 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,
+ std::string instance = "*",
+ std::string to = "*");
+ virtual bool group_recvmsg(isc::data::ElementPtr& envelope,
+ isc::data::ElementPtr& msg,
+ bool nonblock = true,
+ int seq = -1);
+ virtual int reply(isc::data::ElementPtr& envelope,
+ isc::data::ElementPtr& newmsg);
+ virtual bool hasQueuedMsgs();
+ private:
void sendmsg(isc::data::ElementPtr& msg);
void sendmsg(isc::data::ElementPtr& env,
isc::data::ElementPtr& msg);
@@ -70,21 +111,6 @@
isc::data::ElementPtr& msg,
bool nonblock = true,
int seq = -1);
- void subscribe(std::string group,
- std::string instance = "*");
- void unsubscribe(std::string group,
- std::string instance = "*");
- int group_sendmsg(isc::data::ElementPtr msg,
- std::string group,
- std::string instance = "*",
- std::string to = "*");
- bool group_recvmsg(isc::data::ElementPtr& envelope,
- isc::data::ElementPtr& msg,
- bool nonblock = true,
- int seq = -1);
- int reply(isc::data::ElementPtr& envelope,
- isc::data::ElementPtr& newmsg);
- bool hasQueuedMsgs();
};
} // namespace cc
} // namespace isc
Modified: trunk/src/lib/cc/session_unittests.cc
==============================================================================
--- trunk/src/lib/cc/session_unittests.cc (original)
+++ trunk/src/lib/cc/session_unittests.cc Fri Jul 9 19:18:11 2010
@@ -47,22 +47,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: trunk/src/lib/config/ccsession.cc
==============================================================================
--- trunk/src/lib/config/ccsession.cc (original)
+++ trunk/src/lib/config/ccsession.cc Fri Jul 9 19:18:11 2010
@@ -197,37 +197,13 @@
}
ModuleCCSession::ModuleCCSession(
- std::string spec_file_name,
- asio::io_service& io_service,
+ const std::string& spec_file_name,
+ 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)
-{
- 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
-ModuleCCSession::init(
- 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)
+ session_(session)
{
module_specification_ = readModuleSpecification(spec_file_name);
setModuleSpec(module_specification_);
@@ -238,7 +214,7 @@
ElementPtr answer, env;
- session_.establish();
+ session_.establish(NULL);
session_.subscribe(module_name_, "*");
//session_.subscribe("Boss", "*");
//session_.subscribe("statistics", "*");
@@ -265,6 +241,9 @@
std::cerr << "[" << module_name_ << "] Error getting config: " << new_config << std::endl;
}
}
+
+ // register callback for asynchronous read
+ session_.startRead(boost::bind(&ModuleCCSession::startCheck, this));
}
/// Validates the new config values, if they are correct,
@@ -298,12 +277,6 @@
}
}
return answer;
-}
-
-int
-ModuleCCSession::getSocket()
-{
- return (session_.getSocket());
}
bool
Modified: trunk/src/lib/config/ccsession.h
==============================================================================
--- trunk/src/lib/config/ccsession.h (original)
+++ trunk/src/lib/config/ccsession.h Fri Jul 9 19:18:11 2010
@@ -24,10 +24,6 @@
#include <cc/session.h>
#include <cc/data.h>
-namespace asio {
-class io_service;
-}
-
namespace isc {
namespace config {
@@ -112,7 +108,7 @@
};
///
-/// \brief This modules keeps a connection to the command channel,
+/// \brief This module keeps a connection to the command channel,
/// holds configuration information, and handles messages from
/// the command channel
///
@@ -120,32 +116,29 @@
public:
/**
* Initialize a config/command session
- * @param module_name: The name of this module. This is not a
- * reference because we expect static strings
- * to be passed here.
- * @param spec_file_name: The name of the file containing the
+ *
+ * @param spec_file_name The name of the file containing the
* 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
+ * @param session A Session object over which configuration and command
+ * data are exchanged.
+ * @param config_handler A callback function pointer to be called when
+ * configuration of the local module needs to be updated.
+ * This must refer to a valid object of a concrete derived class of
+ * AbstractSession without establishing the session.
+ * Note: the design decision on who is responsible for establishing the
+ * session is in flux, and may change in near future.
+ * @param command_handler A callback function pointer to be called when
+ * a control command from a remote agent needs to be performed on the
+ * local module.
+ */
+ ModuleCCSession(const std::string& spec_file_name,
+ 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
@@ -227,18 +220,11 @@
ElementPtr getRemoteConfigValue(const std::string& module_name, const std::string& identifier);
private:
- void init(
- 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);
ModuleSpec readModuleSpecification(const std::string& filename);
void startCheck();
std::string module_name_;
- isc::cc::Session session_;
+ isc::cc::AbstractSession& session_;
ModuleSpec module_specification_;
ElementPtr handleConfigUpdate(ElementPtr new_config);
Modified: trunk/src/lib/config/tests/ccsession_unittests.cc
==============================================================================
--- trunk/src/lib/config/tests/ccsession_unittests.cc (original)
+++ trunk/src/lib/config/tests/ccsession_unittests.cc Fri Jul 9 19:18:11 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,35 @@
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::fromJSON(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 +71,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 +102,7 @@
EXPECT_EQ("[ \"just\", \"some\", \"data\" ]", arg->str());
}
-TEST(CCSession, createCommand)
-{
+TEST_F(CCSessionTest, createCommand) {
ElementPtr command;
ElementPtr arg;
@@ -131,8 +122,7 @@
ASSERT_EQ("{ \"command\": [ \"foo\", { \"a\": \"map\" } ] }", command->str());
}
-TEST(CCSession, parseCommand)
-{
+TEST_F(CCSessionTest, parseCommand) {
ElementPtr arg;
std::string cmd;
@@ -159,44 +149,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_sp
ec\": { \"item_default\": \"\", \"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 +188,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 +208,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_sp
ec\": { \"item_default\": \"\", \"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: trunk/src/lib/config/tests/fake_session.cc
==============================================================================
--- trunk/src/lib/config/tests/fake_session.cc (original)
+++ trunk/src/lib/config/tests/fake_session.cc Fri Jul 9 19:18:11 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,118 +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::createList();
- m_el->add(Element::create(group));
- m_el->add(Element::create(to));
- m_el->add(msg);
- if (!msg_queue) {
- msg_queue = Element::createList();
- }
- msg_queue->add(m_el);
-}
-
-bool
-haveSubscription(const std::string& group, const std::string& instance)
-{
- if (!subscriptions) {
- return false;
- }
- ElementPtr s1 = Element::createList();
- ElementPtr s2 = Element::createList();
- 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();
}
@@ -191,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::createMap();
@@ -212,7 +157,7 @@
to_remove = c_m;
}
if (to_remove) {
- listRemove(msg_queue, to_remove);
+ listRemove(msg_queue_, to_remove);
return true;
}
}
@@ -223,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::createList();
s_el->add(Element::create(group));
s_el->add(Element::create(instance));
- if (!subscriptions) {
- subscriptions = Element::createList();
- }
- subscriptions->add(s_el);
-}
-
-void
-Session::unsubscribe(std::string group, std::string instance) {
+ if (!subscriptions_) {
+ subscriptions_ = Element::createList();
+ }
+ 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::createList();
s_el->add(Element::create(group));
s_el->add(Element::create(instance));
- if (!subscriptions) {
+ if (!subscriptions_) {
return;
}
- listRemove(subscriptions, s_el);
+ listRemove(subscriptions_, s_el);
}
int
-Session::group_sendmsg(ElementPtr msg, std::string group,
- std::string to, std::string instance UNUSED_PARAM)
+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;
@@ -257,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));
}
int
-Session::reply(ElementPtr& envelope, ElementPtr& newmsg) {
+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());
@@ -272,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::createList();
+ m_el->add(Element::create(group));
+ m_el->add(Element::create(to));
+ m_el->add(msg);
+ if (!msg_queue_) {
+ msg_queue_ = Element::createList();
+ }
+ msg_queue_->add(m_el);
+}
+
+bool
+FakeSession::haveSubscription(const std::string& group,
+ const std::string& instance)
+{
+ if (!subscriptions_) {
+ return (false);
+ }
+ ElementPtr s1 = Element::createList();
+ ElementPtr s2 = Element::createList();
+ 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: trunk/src/lib/config/tests/fake_session.h
==============================================================================
--- trunk/src/lib/config/tests/fake_session.h (original)
+++ trunk/src/lib/config/tests/fake_session.h Fri Jul 9 19:18:11 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:
+ // 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.
+ // The test can also add data to a copy of the message later to tweak
+ // the group_recvmsg() behavior. See getMessages() below.
+ FakeSession(isc::data::ElementPtr initial_messages,
+ isc::data::ElementPtr subscriptions,
+ isc::data::ElementPtr msg_queue);
+ virtual ~FakeSession();
- class Session {
- private:
- Session(const Session& source);
- Session& operator=(const Session& source);
+ virtual void startRead(boost::function<void()> read_callback);
- public:
- // public so tests can inspect them
-
- Session();
- Session(asio::io_service& ioservice);
- ~Session();
-
- // 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 = "*");
- int group_sendmsg(isc::data::ElementPtr msg,
+ virtual int group_sendmsg(isc::data::ElementPtr msg,
std::string group,
std::string instance = "*",
std::string to = "*");
- bool group_recvmsg(isc::data::ElementPtr& envelope,
+ virtual bool group_recvmsg(isc::data::ElementPtr& envelope,
isc::data::ElementPtr& msg,
bool nonblock = true,
int seq = -1);
- int reply(isc::data::ElementPtr& envelope,
+ virtual int reply(isc::data::ElementPtr& envelope,
isc::data::ElementPtr& newmsg);
- bool hasQueuedMsgs();
+ 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