ccsession_unittests.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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. // $Id: module_spec_unittests.cc 1321 2010-03-11 10:17:03Z jelte $
  15. #include <config.h>
  16. #include <gtest/gtest.h>
  17. #include <config/tests/fake_session.h>
  18. #include <config/ccsession.h>
  19. #include <fstream>
  20. #include <config/tests/data_def_unittests_config.h>
  21. using namespace isc::data;
  22. using namespace isc::config;
  23. using namespace isc::cc;
  24. using namespace std;
  25. namespace {
  26. std::string
  27. ccspecfile(const std::string name) {
  28. return (std::string(TEST_DATA_PATH) + "/" + name);
  29. }
  30. ElementPtr
  31. el(const std::string& str) {
  32. return (Element::fromJSON(str));
  33. }
  34. class CCSessionTest : public ::testing::Test {
  35. protected:
  36. CCSessionTest() : session(el("[]"), el("[]"), el("[]")) {
  37. // upon creation of a ModuleCCSession, the class
  38. // sends its specification to the config manager.
  39. // it expects an ok answer back, so everytime we
  40. // create a ModuleCCSession, we must set an initial
  41. // ok answer.
  42. session.getMessages()->add(createAnswer());
  43. }
  44. ~CCSessionTest() {}
  45. FakeSession session;
  46. };
  47. TEST_F(CCSessionTest, createAnswer) {
  48. ConstElementPtr answer;
  49. answer = createAnswer();
  50. EXPECT_EQ("{ \"result\": [ 0 ] }", answer->str());
  51. answer = createAnswer(1, "error");
  52. EXPECT_EQ("{ \"result\": [ 1, \"error\" ] }", answer->str());
  53. EXPECT_THROW(createAnswer(1, ElementPtr()), CCSessionError);
  54. EXPECT_THROW(createAnswer(1, Element::create(1)), CCSessionError);
  55. ConstElementPtr arg = el("[ \"just\", \"some\", \"data\" ]");
  56. answer = createAnswer(0, arg);
  57. EXPECT_EQ("{ \"result\": [ 0, [ \"just\", \"some\", \"data\" ] ] }", answer->str());
  58. }
  59. TEST_F(CCSessionTest, parseAnswer) {
  60. ConstElementPtr answer;
  61. ConstElementPtr arg;
  62. int rcode;
  63. EXPECT_THROW(parseAnswer(rcode, ElementPtr()), CCSessionError);
  64. EXPECT_THROW(parseAnswer(rcode, el("1")), CCSessionError);
  65. EXPECT_THROW(parseAnswer(rcode, el("[]")), CCSessionError);
  66. EXPECT_THROW(parseAnswer(rcode, el("{ }")), CCSessionError);
  67. EXPECT_THROW(parseAnswer(rcode, el("{ \"something\": 1 }")), CCSessionError);
  68. EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": 0 }")), CCSessionError);
  69. EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": 1 }")), CCSessionError);
  70. EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 1 ] }")), CCSessionError);
  71. EXPECT_THROW(parseAnswer(rcode, el("{ \"result\": [ 1, 1 ] }")), CCSessionError);
  72. answer = el("{ \"result\": [ 0 ] }");
  73. arg = parseAnswer(rcode, answer);
  74. EXPECT_EQ(0, rcode);
  75. EXPECT_TRUE(isNull(arg));
  76. answer = el("{ \"result\": [ 1, \"error\"] }");
  77. arg = parseAnswer(rcode, answer);
  78. EXPECT_EQ(1, rcode);
  79. EXPECT_EQ("error", arg->stringValue());
  80. answer = el("{ \"result\": [ 0, [ \"just\", \"some\", \"data\" ] ] }");
  81. arg = parseAnswer(rcode, answer);
  82. EXPECT_EQ(0, rcode);
  83. EXPECT_EQ("[ \"just\", \"some\", \"data\" ]", arg->str());
  84. }
  85. TEST_F(CCSessionTest, createCommand) {
  86. ConstElementPtr command;
  87. ConstElementPtr arg;
  88. command = createCommand("my_command");
  89. ASSERT_EQ("{ \"command\": [ \"my_command\" ] }", command->str());
  90. arg = el("1");
  91. command = createCommand("my_command", arg);
  92. ASSERT_EQ("{ \"command\": [ \"my_command\", 1 ] }", command->str());
  93. arg = el("[ \"a\", \"b\" ]");
  94. command = createCommand("my_cmd", arg);
  95. ASSERT_EQ("{ \"command\": [ \"my_cmd\", [ \"a\", \"b\" ] ] }", command->str());
  96. arg = el("{ \"a\": \"map\" }");
  97. command = createCommand("foo", arg);
  98. ASSERT_EQ("{ \"command\": [ \"foo\", { \"a\": \"map\" } ] }", command->str());
  99. }
  100. TEST_F(CCSessionTest, parseCommand) {
  101. ConstElementPtr arg;
  102. std::string cmd;
  103. // should throw
  104. EXPECT_THROW(parseCommand(arg, ElementPtr()), CCSessionError);
  105. EXPECT_THROW(parseCommand(arg, el("1")), CCSessionError);
  106. EXPECT_THROW(parseCommand(arg, el("{ }")), CCSessionError);
  107. EXPECT_THROW(parseCommand(arg, el("{ \"not a command\": 1 }")), CCSessionError);
  108. EXPECT_THROW(parseCommand(arg, el("{ \"command\": 1 }")), CCSessionError);
  109. EXPECT_THROW(parseCommand(arg, el("{ \"command\": [] }")), CCSessionError);
  110. EXPECT_THROW(parseCommand(arg, el("{ \"command\": [ 1 ] }")), CCSessionError);
  111. cmd = parseCommand(arg, el("{ \"command\": [ \"my_command\" ] }"));
  112. EXPECT_EQ("my_command", cmd);
  113. EXPECT_EQ(*arg, *Element::createMap());
  114. cmd = parseCommand(arg, el("{ \"command\": [ \"my_command\", 1 ] }"));
  115. EXPECT_EQ("my_command", cmd);
  116. EXPECT_EQ("1", arg->str());
  117. parseCommand(arg, el("{ \"command\": [ \"my_command\", [ \"some\", \"argument\", \"list\" ] ] }"));
  118. EXPECT_EQ("my_command", cmd);
  119. EXPECT_EQ("[ \"some\", \"argument\", \"list\" ]", arg->str());
  120. }
  121. TEST_F(CCSessionTest, session1) {
  122. EXPECT_FALSE(session.haveSubscription("Spec1", "*"));
  123. ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL);
  124. EXPECT_TRUE(session.haveSubscription("Spec1", "*"));
  125. EXPECT_EQ(1, session.getMsgQueue()->size());
  126. ConstElementPtr msg;
  127. std::string group, to;
  128. msg = session.getFirstMessage(group, to);
  129. EXPECT_EQ("{ \"command\": [ \"module_spec\", { \"module_name\": \"Spec1\" } ] }", msg->str());
  130. EXPECT_EQ("ConfigManager", group);
  131. EXPECT_EQ("*", to);
  132. EXPECT_EQ(0, session.getMsgQueue()->size());
  133. }
  134. TEST_F(CCSessionTest, session2) {
  135. EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
  136. ModuleCCSession mccs(ccspecfile("spec2.spec"), session, NULL, NULL);
  137. EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
  138. EXPECT_EQ(1, session.getMsgQueue()->size());
  139. ConstElementPtr msg;
  140. std::string group, to;
  141. msg = session.getFirstMessage(group, to);
  142. 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_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());
  143. EXPECT_EQ("ConfigManager", group);
  144. EXPECT_EQ("*", to);
  145. EXPECT_EQ(0, session.getMsgQueue()->size());
  146. }
  147. ConstElementPtr my_config_handler(ConstElementPtr new_config) {
  148. if (new_config && new_config->contains("item1") &&
  149. new_config->get("item1")->intValue() == 5) {
  150. return (createAnswer(6, "I do not like the number 5"));
  151. }
  152. return (createAnswer());
  153. }
  154. ConstElementPtr my_command_handler(const std::string& command,
  155. ConstElementPtr arg)
  156. {
  157. if (command == "good_command") {
  158. return (createAnswer());
  159. } else if (command == "command_with_arg") {
  160. if (arg->contains("number")) {
  161. if (arg->get("number")->getType() == Element::integer) {
  162. return (createAnswer(0, el("2")));
  163. } else {
  164. return (createAnswer(1, "arg bad type"));
  165. }
  166. } else {
  167. return (createAnswer(1, "arg missing"));
  168. }
  169. } else {
  170. return (createAnswer(1, "bad command"));
  171. }
  172. }
  173. TEST_F(CCSessionTest, session3) {
  174. // client will ask for config
  175. session.getMessages()->add(createAnswer(0, el("{}")));
  176. EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
  177. ModuleCCSession mccs(ccspecfile("spec2.spec"), session, my_config_handler,
  178. my_command_handler);
  179. EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
  180. EXPECT_EQ(2, session.getMsgQueue()->size());
  181. ConstElementPtr msg;
  182. std::string group, to;
  183. msg = session.getFirstMessage(group, to);
  184. 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_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());
  185. EXPECT_EQ("ConfigManager", group);
  186. EXPECT_EQ("*", to);
  187. EXPECT_EQ(1, session.getMsgQueue()->size());
  188. msg = session.getFirstMessage(group, to);
  189. EXPECT_EQ("{ \"command\": [ \"get_config\", { \"module_name\": \"Spec2\" } ] }", msg->str());
  190. EXPECT_EQ("ConfigManager", group);
  191. EXPECT_EQ("*", to);
  192. EXPECT_EQ(0, session.getMsgQueue()->size());
  193. }
  194. TEST_F(CCSessionTest, checkCommand) {
  195. // client will ask for config
  196. session.getMessages()->add(createAnswer(0, el("{}")));
  197. EXPECT_FALSE(session.haveSubscription("Spec29", "*"));
  198. ModuleCCSession mccs(ccspecfile("spec29.spec"), session, my_config_handler,
  199. my_command_handler);
  200. EXPECT_TRUE(session.haveSubscription("Spec29", "*"));
  201. EXPECT_EQ(2, session.getMsgQueue()->size());
  202. ConstElementPtr msg;
  203. std::string group, to;
  204. // checked above, drop em
  205. msg = session.getFirstMessage(group, to);
  206. msg = session.getFirstMessage(group, to);
  207. int result;
  208. result = mccs.checkCommand();
  209. EXPECT_EQ(0, result);
  210. // not a command, should be ignored
  211. session.addMessage(el("1"), "Spec29", "*");
  212. result = mccs.checkCommand();
  213. EXPECT_EQ(0, result);
  214. session.addMessage(el("{ \"command\": [ \"good_command\" ] }"), "Spec29",
  215. "*");
  216. result = mccs.checkCommand();
  217. EXPECT_EQ(1, session.getMsgQueue()->size());
  218. msg = session.getFirstMessage(group, to);
  219. EXPECT_EQ("{ \"result\": [ 0 ] }", msg->str());
  220. EXPECT_EQ(0, result);
  221. session.addMessage(el("{ \"command\": \"bad_command\" }"), "Spec29", "*");
  222. result = mccs.checkCommand();
  223. EXPECT_EQ(1, session.getMsgQueue()->size());
  224. msg = session.getFirstMessage(group, to);
  225. EXPECT_EQ("{ \"result\": [ 1, \"Command part in command message missing, empty, or not a list\" ] }", msg->str());
  226. EXPECT_EQ(0, result);
  227. session.addMessage(el("{ \"command\": [ \"bad_command\" ] }"),
  228. "Spec29", "*");
  229. result = mccs.checkCommand();
  230. EXPECT_EQ(1, session.getMsgQueue()->size());
  231. msg = session.getFirstMessage(group, to);
  232. EXPECT_EQ("{ \"result\": [ 1, \"bad command\" ] }", msg->str());
  233. EXPECT_EQ(0, result);
  234. session.addMessage(el("{ \"command\": [ \"command_with_arg\", {\"number\": 1} ] }"),
  235. "Spec29", "*");
  236. result = mccs.checkCommand();
  237. EXPECT_EQ(1, session.getMsgQueue()->size());
  238. msg = session.getFirstMessage(group, to);
  239. EXPECT_EQ("{ \"result\": [ 0, 2 ] }", msg->str());
  240. EXPECT_EQ(0, result);
  241. session.addMessage(el("{ \"command\": [ \"command_with_arg\" ] }"), "Spec29", "*");
  242. result = mccs.checkCommand();
  243. EXPECT_EQ(1, session.getMsgQueue()->size());
  244. msg = session.getFirstMessage(group, to);
  245. EXPECT_EQ("{ \"result\": [ 1, \"arg missing\" ] }", msg->str());
  246. EXPECT_EQ(0, result);
  247. session.addMessage(el("{ \"command\": [ \"command_with_arg\", \"asdf\" ] }"), "Spec29", "*");
  248. result = mccs.checkCommand();
  249. EXPECT_EQ(1, session.getMsgQueue()->size());
  250. msg = session.getFirstMessage(group, to);
  251. EXPECT_EQ("{ \"result\": [ 3, \"Error in command validation: args for command command_with_arg is not a map\" ] }", msg->str());
  252. EXPECT_EQ(0, result);
  253. mccs.setCommandHandler(NULL);
  254. session.addMessage(el("{ \"command\": [ \"whatever\" ] }"), "Spec29", "*");
  255. result = mccs.checkCommand();
  256. EXPECT_EQ(1, session.getMsgQueue()->size());
  257. msg = session.getFirstMessage(group, to);
  258. EXPECT_EQ("{ \"result\": [ 1, \"Command given but no command handler for module\" ] }", msg->str());
  259. EXPECT_EQ(0, result);
  260. }
  261. // A heuristic workaround for clang++: It doesn't seem to compile the whole
  262. // test, probably due to its length. Dividing the tests into two separate
  263. // test cases seems to work.
  264. TEST_F(CCSessionTest, checkCommand2) {
  265. session.getMessages()->add(createAnswer(0, el("{}")));
  266. EXPECT_FALSE(session.haveSubscription("Spec29", "*"));
  267. ModuleCCSession mccs(ccspecfile("spec29.spec"), session, my_config_handler,
  268. my_command_handler);
  269. EXPECT_TRUE(session.haveSubscription("Spec29", "*"));
  270. ConstElementPtr msg;
  271. std::string group, to;
  272. // checked above, drop em
  273. msg = session.getFirstMessage(group, to);
  274. msg = session.getFirstMessage(group, to);
  275. EXPECT_EQ(1, mccs.getValue("item1")->intValue());
  276. session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 2 } ] }"), "Spec29", "*");
  277. int result = mccs.checkCommand();
  278. EXPECT_EQ(1, session.getMsgQueue()->size());
  279. msg = session.getFirstMessage(group, to);
  280. EXPECT_EQ("{ \"result\": [ 0 ] }", msg->str());
  281. EXPECT_EQ(0, result);
  282. EXPECT_EQ(2, mccs.getValue("item1")->intValue());
  283. session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": \"asdf\" } ] }"), "Spec29", "*");
  284. result = mccs.checkCommand();
  285. EXPECT_EQ(1, session.getMsgQueue()->size());
  286. msg = session.getFirstMessage(group, to);
  287. EXPECT_EQ("{ \"result\": [ 2, \"Error in config validation: Type mismatch\" ] }", msg->str());
  288. EXPECT_EQ(0, result);
  289. EXPECT_EQ(2, mccs.getValue("item1")->intValue());
  290. session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 5 } ] }"), "Spec29", "*");
  291. result = mccs.checkCommand();
  292. EXPECT_EQ(1, session.getMsgQueue()->size());
  293. msg = session.getFirstMessage(group, to);
  294. EXPECT_EQ("{ \"result\": [ 6, \"I do not like the number 5\" ] }", msg->str());
  295. EXPECT_EQ(0, result);
  296. EXPECT_EQ(2, mccs.getValue("item1")->intValue());
  297. }
  298. TEST_F(CCSessionTest, remoteConfig) {
  299. std::string module_name;
  300. int item1;
  301. ModuleCCSession mccs(ccspecfile("spec1.spec"), session, NULL, NULL);
  302. EXPECT_TRUE(session.haveSubscription("Spec1", "*"));
  303. // first simply connect, with no config values, and see we get
  304. // the default
  305. session.getMessages()->add(createAnswer(0, el("{}")));
  306. EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
  307. module_name = mccs.addRemoteConfig(ccspecfile("spec2.spec"));
  308. EXPECT_EQ("Spec2", module_name);
  309. EXPECT_TRUE(session.haveSubscription("Spec2", "*"));
  310. item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
  311. EXPECT_EQ(1, item1);
  312. // Remove it and see we get an error asking for a config value
  313. mccs.removeRemoteConfig(module_name);
  314. EXPECT_FALSE(session.haveSubscription("Spec2", "*"));
  315. EXPECT_THROW(mccs.getRemoteConfigValue(module_name, "item1"), CCSessionError);
  316. // Now re-add it, with a specific config value, and see we get that
  317. session.getMessages()->add(createAnswer(0, el("{ \"item1\": 2 }")));
  318. module_name = mccs.addRemoteConfig(ccspecfile("spec2.spec"));
  319. item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
  320. EXPECT_EQ(2, item1);
  321. // Try a config_update command
  322. session.addMessage(el("{ \"command\": [ \"config_update\", { \"item1\": 3 } ] }"), module_name, "*");
  323. mccs.checkCommand();
  324. item1 = mccs.getRemoteConfigValue(module_name, "item1")->intValue();
  325. EXPECT_EQ(3, item1);
  326. // remove, re-add, now with a *bad* config request answer
  327. mccs.removeRemoteConfig(module_name);
  328. session.getMessages()->add(el("{}"));
  329. EXPECT_THROW(mccs.addRemoteConfig(ccspecfile("spec2.spec")), CCSessionError);
  330. session.getMessages()->add(createAnswer(1, "my_error"));
  331. EXPECT_THROW(mccs.addRemoteConfig(ccspecfile("spec2.spec")), CCSessionError);
  332. session.getMessages()->add(createAnswer());
  333. EXPECT_THROW(mccs.addRemoteConfig(ccspecfile("spec2.spec")), CCSessionError);
  334. }
  335. TEST_F(CCSessionTest, ignoreRemoteConfigCommands) {
  336. // client will ask for config
  337. session.getMessages()->add(createAnswer(0, el("{ }")));
  338. EXPECT_FALSE(session.haveSubscription("Spec29", "*"));
  339. ModuleCCSession mccs(ccspecfile("spec29.spec"), session, my_config_handler, my_command_handler);
  340. EXPECT_TRUE(session.haveSubscription("Spec29", "*"));
  341. EXPECT_EQ(2, session.getMsgQueue()->size());
  342. ConstElementPtr msg;
  343. std::string group, to;
  344. // drop the module_spec and config commands
  345. session.getFirstMessage(group, to);
  346. session.getFirstMessage(group, to);
  347. session.getMessages()->add(createAnswer(0, el("{ }")));
  348. mccs.addRemoteConfig(ccspecfile("spec1.spec"));
  349. EXPECT_EQ(1, session.getMsgQueue()->size());
  350. msg = session.getFirstMessage(group, to);
  351. // Check if commands for the module are handled
  352. session.addMessage(el("{ \"command\": [ \"good_command\" ] }"), "Spec29", "*");
  353. int result = mccs.checkCommand();
  354. EXPECT_EQ(1, session.getMsgQueue()->size());
  355. msg = session.getFirstMessage(group, to);
  356. EXPECT_EQ("{ \"result\": [ 0 ] }", msg->str());
  357. EXPECT_EQ(0, result);
  358. // Check if commands for the other module are ignored
  359. session.addMessage(el("{ \"command\": [ \"good_command\" ] }"), "Spec1", "*");
  360. EXPECT_EQ(1, session.getMsgQueue()->size());
  361. result = mccs.checkCommand();
  362. EXPECT_EQ(0, session.getMsgQueue()->size());
  363. }
  364. }