ccsession_unittests.cc 18 KB

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