fake_session.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <stdint.h>
  16. #include <cstdio>
  17. #include <vector>
  18. #include <iostream>
  19. #include <sstream>
  20. #include <boost/foreach.hpp>
  21. #include <exceptions/exceptions.h>
  22. #include <cc/data.h>
  23. #include <config/tests/fake_session.h>
  24. using namespace std;
  25. using namespace isc::cc;
  26. using namespace isc::data;
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. // ok i want these in cc/data
  31. bool
  32. listContains(ConstElementPtr list, ConstElementPtr el) {
  33. if (!list) {
  34. return (false);
  35. }
  36. BOOST_FOREACH(ConstElementPtr l_el, list->listValue()) {
  37. if (*l_el == *el) {
  38. return (true);
  39. }
  40. }
  41. return (false);
  42. }
  43. void
  44. listRemove(ElementPtr list, ConstElementPtr el) {
  45. int i = 0;
  46. BOOST_FOREACH(ConstElementPtr s_el, list->listValue()) {
  47. if (*el == *s_el) {
  48. list->remove(i);
  49. return;
  50. }
  51. i++;
  52. }
  53. }
  54. // endwant
  55. namespace isc {
  56. namespace cc {
  57. FakeSession::FakeSession(isc::data::ElementPtr initial_messages,
  58. isc::data::ElementPtr subscriptions,
  59. isc::data::ElementPtr msg_queue) :
  60. messages_(initial_messages),
  61. subscriptions_(subscriptions),
  62. msg_queue_(msg_queue),
  63. started_(false)
  64. {
  65. }
  66. FakeSession::~FakeSession() {
  67. }
  68. void
  69. FakeSession::disconnect() {
  70. }
  71. void
  72. FakeSession::startRead(boost::function<void()>) {
  73. started_ = true;
  74. }
  75. void
  76. FakeSession::establish(const char*) {
  77. }
  78. bool
  79. FakeSession::recvmsg(ConstElementPtr& msg, bool nonblock, int) {
  80. if (started_ && !nonblock) {
  81. // This would schedule another read for length, leading to
  82. // corputed data
  83. isc_throw(DoubleRead, "Second read scheduled from recvmsg");
  84. }
  85. //cout << "[XX] client asks for message " << endl;
  86. if (messages_ &&
  87. messages_->getType() == Element::list &&
  88. messages_->size() > 0) {
  89. msg = messages_->get(0);
  90. messages_->remove(0);
  91. } else {
  92. msg = ElementPtr();
  93. }
  94. return (true);
  95. }
  96. bool
  97. FakeSession::recvmsg(ConstElementPtr& env, ConstElementPtr& msg, bool nonblock,
  98. int)
  99. {
  100. if (started_ && !nonblock) {
  101. // This would schedule another read for length, leading to
  102. // corputed data
  103. isc_throw(DoubleRead, "Second read scheduled from recvmsg");
  104. }
  105. //cout << "[XX] client asks for message and env" << endl;
  106. env = ElementPtr();
  107. if (messages_ &&
  108. messages_->getType() == Element::list &&
  109. messages_->size() > 0) {
  110. // do we need initial message to have env[group] and [to] too?
  111. msg = messages_->get(0);
  112. messages_->remove(0);
  113. return (true);
  114. } else if (msg_queue_) {
  115. BOOST_FOREACH(ConstElementPtr c_m, msg_queue_->listValue()) {
  116. ConstElementPtr to_remove = ElementPtr();
  117. if (haveSubscription(c_m->get(0), c_m->get(1))) {
  118. ElementPtr new_env = Element::createMap();
  119. new_env->set("group", c_m->get(0));
  120. new_env->set("to", c_m->get(1));
  121. env = new_env;
  122. msg = c_m->get(2);
  123. to_remove = c_m;
  124. }
  125. if (to_remove) {
  126. listRemove(msg_queue_, to_remove);
  127. return (true);
  128. }
  129. }
  130. }
  131. msg = ElementPtr();
  132. env = ElementPtr();
  133. return (false);
  134. }
  135. void
  136. FakeSession::subscribe(std::string group, std::string instance) {
  137. //cout << "[XX] client subscribes to " << group << " . " << instance << endl;
  138. ElementPtr s_el = Element::createList();
  139. s_el->add(Element::create(group));
  140. s_el->add(Element::create(instance));
  141. if (!subscriptions_) {
  142. subscriptions_ = Element::createList();
  143. }
  144. subscriptions_->add(s_el);
  145. }
  146. void
  147. FakeSession::unsubscribe(std::string group, std::string instance) {
  148. //cout << "[XX] client unsubscribes from " << group << " . " << instance << endl;
  149. ElementPtr s_el = Element::createList();
  150. s_el->add(Element::create(group));
  151. s_el->add(Element::create(instance));
  152. if (!subscriptions_) {
  153. return;
  154. }
  155. listRemove(subscriptions_, s_el);
  156. }
  157. int
  158. FakeSession::group_sendmsg(ConstElementPtr msg, std::string group,
  159. std::string to, std::string)
  160. {
  161. //cout << "[XX] client sends message: " << msg << endl;
  162. //cout << "[XX] to: " << group << " . " << instance << "." << to << endl;
  163. addMessage(msg, group, to);
  164. return (1);
  165. }
  166. bool
  167. FakeSession::group_recvmsg(ConstElementPtr& envelope, ConstElementPtr& msg,
  168. bool nonblock, int seq)
  169. {
  170. return (recvmsg(envelope, msg, nonblock, seq));
  171. }
  172. int
  173. FakeSession::reply(ConstElementPtr envelope, ConstElementPtr newmsg) {
  174. //cout << "[XX] client sends reply: " << newmsg << endl;
  175. //cout << "[XX] env: " << envelope << endl;
  176. addMessage(newmsg, envelope->get("group")->stringValue(),
  177. envelope->get("to")->stringValue());
  178. return (1);
  179. }
  180. bool
  181. FakeSession::hasQueuedMsgs() const {
  182. return (false);
  183. }
  184. ConstElementPtr
  185. FakeSession::getFirstMessage(std::string& group, std::string& to) const {
  186. ConstElementPtr el;
  187. if (msg_queue_ && msg_queue_->size() > 0) {
  188. el = msg_queue_->get(0);
  189. msg_queue_->remove(0);
  190. group = el->get(0)->stringValue();
  191. to = el->get(1)->stringValue();
  192. return (el->get(2));
  193. } else {
  194. group = "";
  195. to = "";
  196. return (ElementPtr());
  197. }
  198. }
  199. void
  200. FakeSession::addMessage(ConstElementPtr msg, const std::string& group,
  201. const std::string& to)
  202. {
  203. ElementPtr m_el = Element::createList();
  204. m_el->add(Element::create(group));
  205. m_el->add(Element::create(to));
  206. m_el->add(msg);
  207. if (!msg_queue_) {
  208. msg_queue_ = Element::createList();
  209. }
  210. msg_queue_->add(m_el);
  211. }
  212. bool
  213. FakeSession::haveSubscription(const std::string& group,
  214. const std::string& instance)
  215. {
  216. if (!subscriptions_) {
  217. return (false);
  218. }
  219. ElementPtr s1 = Element::createList();
  220. ElementPtr s2 = Element::createList();
  221. s1->add(Element::create(group));
  222. s1->add(Element::create(instance));
  223. s2->add(Element::create(group));
  224. s2->add(Element::create("*"));
  225. bool result = (listContains(subscriptions_, s1) ||
  226. listContains(subscriptions_, s2));
  227. return (result);
  228. }
  229. bool
  230. FakeSession::haveSubscription(ConstElementPtr group, ConstElementPtr instance)
  231. {
  232. return (haveSubscription(group->stringValue(), instance->stringValue()));
  233. }
  234. }
  235. }