BIND 10 trac2768, updated. 845ffd35d10646345dc1f534ad725cada568fa5c [2768] Implement the rpcCall method
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Feb 20 11:29:31 UTC 2013
The branch, trac2768 has been updated
via 845ffd35d10646345dc1f534ad725cada568fa5c (commit)
via ce19b150c67834a91d7742f362a175904172a7d7 (commit)
from 2fb30723fa35fa5a9ffae03b0715650a76a5f20a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 845ffd35d10646345dc1f534ad725cada568fa5c
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Feb 20 12:29:11 2013 +0100
[2768] Implement the rpcCall method
commit ce19b150c67834a91d7742f362a175904172a7d7
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Feb 20 11:16:28 2013 +0100
[2768] Tests for the rpcCall method
They currently fail, as the method is empty. Provide at least an empty
implementation, to make it compile.
-----------------------------------------------------------------------
Summary of changes:
src/lib/config/ccsession.cc | 20 +++++++++++
src/lib/config/ccsession.h | 15 ++++++++
src/lib/config/tests/ccsession_unittests.cc | 50 +++++++++++++++++++++++++++
3 files changed, 85 insertions(+)
-----------------------------------------------------------------------
diff --git a/src/lib/config/ccsession.cc b/src/lib/config/ccsession.cc
index 378f2b4..cd01603 100644
--- a/src/lib/config/ccsession.cc
+++ b/src/lib/config/ccsession.cc
@@ -857,5 +857,25 @@ ModuleCCSession::cancelAsyncRecv(const AsyncRecvRequestID& id) {
async_recv_requests_.erase(id);
}
+ConstElementPtr
+ModuleCCSession::rpcCall(const std::string &command, const std::string &group,
+ const std::string &instance, const std::string &to,
+ const ConstElementPtr ¶ms)
+{
+ const ConstElementPtr &command_el(createCommand(command, params));
+ const int seq = session_.group_sendmsg(command_el, group, instance, to);
+ ConstElementPtr env, answer;
+ session_.group_recvmsg(env, answer, false, seq);
+ int rcode;
+ const ConstElementPtr &result(parseAnswer(rcode, answer));
+ if (rcode == isc::cc::CC_REPLY_NO_RECPT) {
+ isc_throw(RPCRecipientMissing, result);
+ } else if (rcode != isc::cc::CC_REPLY_SUCCESS) {
+ isc_throw_1(RPCError, result, rcode);
+ } else {
+ return (result);
+ }
+}
+
}
}
diff --git a/src/lib/config/ccsession.h b/src/lib/config/ccsession.h
index b21fef2..c9a6ffe 100644
--- a/src/lib/config/ccsession.h
+++ b/src/lib/config/ccsession.h
@@ -418,6 +418,21 @@ public:
params =
isc::data::ConstElementPtr());
+ /// \brief Convenience version of rpcCall
+ ///
+ /// This is exactly the same as the previous version of rpcCall, except
+ /// that the instance and to parameters are at their default. This
+ /// allows to sending a command with parameters to a named module
+ /// without long typing of the parameters.
+ isc::data::ConstElementPtr rpcCall(const std::string& command,
+ const std::string& group,
+ const isc::data::ConstElementPtr&
+ params)
+ {
+ return rpcCall(command, group, isc::cc::CC_INSTANCE_WILDCARD,
+ isc::cc::CC_TO_WILDCARD, params);
+ }
+
/// \brief Forward declaration of internal data structure.
///
/// This holds information about one asynchronous request to receive
diff --git a/src/lib/config/tests/ccsession_unittests.cc b/src/lib/config/tests/ccsession_unittests.cc
index 2a5e758..824125b 100644
--- a/src/lib/config/tests/ccsession_unittests.cc
+++ b/src/lib/config/tests/ccsession_unittests.cc
@@ -58,6 +58,26 @@ protected:
// ok answer.
session.getMessages()->add(createAnswer());
}
+ ConstElementPtr rpcCheck(const std::string& reply) {
+ ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL,
+ false, false);
+ // Prepare the answer beforehand, it'll block until it gets one
+ const ConstElementPtr& reply_el(el(reply));
+ session.getMessages()->add(reply_el);
+ const ConstElementPtr& result(mccs.rpcCall("test", "Spec2",
+ el("{\"param1\": \"Param 1\","
+ "\"param2\": \"Param 2\"}")));
+ const ConstElementPtr& request(el("[\"Spec2\", \"*\", {"
+ " \"command\": [\"test\", {"
+ " \"param1\": \"Param 1\","
+ " \"param2\": \"Param 2\""
+ "}]}, -1]"));
+ // The 0th one is from the initialization, to ConfigManager.
+ // our is the 1st.
+ EXPECT_TRUE(request->equals(*session.getMsgQueue()->get(1))) <<
+ session.getMsgQueue()->get(1)->toWire();
+ return (result);
+ }
~CCSessionTest() {
isc::log::setRootLoggerName(root_name);
}
@@ -65,6 +85,36 @@ protected:
const std::string root_name;
};
+// Test we can send an RPC (command) and get an answer. The answer is success
+// in this case.
+TEST_F(CCSessionTest, rpcCallSuccess) {
+ const ConstElementPtr &result =
+ rpcCheck("{\"result\": [0, {\"Hello\": \"a\"}]}");
+ EXPECT_TRUE(el("{\"Hello\": \"a\"}")->equals(*result));
+}
+
+// Test success of RPC, but the answer is empty (eg. a void function on the
+// remote side).
+TEST_F(CCSessionTest, rpcCallSuccessNone) {
+ EXPECT_FALSE(rpcCheck("{\"result\": [0]}"));
+}
+
+// Test it successfully raises CCSessionError if the answer is malformed.
+TEST_F(CCSessionTest, rpcCallMalformedAnswer) {
+ EXPECT_THROW(rpcCheck("[\"Nonsense\"]"), CCSessionError);
+}
+
+// Test it raises exception when the remote side reports an error
+TEST_F(CCSessionTest, rpcCallError) {
+ EXPECT_THROW(rpcCheck("{\"result\": [1, \"Error\"]}"), RPCError);
+}
+
+// Test it raises exception when the remote side doesn't exist
+TEST_F(CCSessionTest, rpcNoRecpt) {
+ EXPECT_THROW(rpcCheck("{\"result\": [-1, \"Error\"]}"),
+ RPCRecipientMissing);
+}
+
TEST_F(CCSessionTest, createAnswer) {
ConstElementPtr answer;
answer = createAnswer();
More information about the bind10-changes
mailing list