test_testbed_api_2peers_1controller.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*
  2. This file is part of GNUnet
  3. (C) 2008--2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file testbed/test_testbed_api_2peers_1controller.c
  19. * @brief testcases for the testbed api: 2 peers are configured, started and
  20. * connected together. The 2 peer reside on a single controller.
  21. * @author Sree Harsha Totakura
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_testing_lib.h"
  26. #include "gnunet_testbed_service.h"
  27. /**
  28. * Generic logging shortcut
  29. */
  30. #define LOG(kind,...) \
  31. GNUNET_log (kind, __VA_ARGS__)
  32. /**
  33. * Relative time seconds shorthand
  34. */
  35. #define TIME_REL_SECS(sec) \
  36. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
  37. /**
  38. * Peer context
  39. */
  40. struct PeerContext
  41. {
  42. /**
  43. * The peer handle
  44. */
  45. struct GNUNET_TESTBED_Peer *peer;
  46. /**
  47. * Operations involving this peer
  48. */
  49. struct GNUNET_TESTBED_Operation *operation;
  50. /**
  51. * set to GNUNET_YES when peer is started
  52. */
  53. int is_running;
  54. };
  55. /**
  56. * Our localhost
  57. */
  58. static struct GNUNET_TESTBED_Host *host;
  59. /**
  60. * The controller process
  61. */
  62. static struct GNUNET_TESTBED_ControllerProc *cp;
  63. /**
  64. * The controller handle
  65. */
  66. static struct GNUNET_TESTBED_Controller *controller;
  67. /**
  68. * A neighbouring host
  69. */
  70. static struct GNUNET_TESTBED_Host *neighbour;
  71. /**
  72. * Handle for neighbour registration
  73. */
  74. static struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle;
  75. /**
  76. * peer 1
  77. */
  78. static struct PeerContext peer1;
  79. /**
  80. * peer2
  81. */
  82. static struct PeerContext peer2;
  83. /**
  84. * Handle to configuration
  85. */
  86. static struct GNUNET_CONFIGURATION_Handle *cfg;
  87. /**
  88. * Handle to operations involving both peers
  89. */
  90. static struct GNUNET_TESTBED_Operation *common_operation;
  91. /**
  92. * Abort task identifier
  93. */
  94. static GNUNET_SCHEDULER_TaskIdentifier abort_task;
  95. /**
  96. * Delayed connect job identifier
  97. */
  98. static GNUNET_SCHEDULER_TaskIdentifier delayed_connect_task;
  99. /**
  100. * Different stages in testing
  101. */
  102. enum Stage
  103. {
  104. /**
  105. * Initial stage
  106. */
  107. INIT,
  108. /**
  109. * peers are created
  110. */
  111. PEERS_CREATED,
  112. /**
  113. * peers are started
  114. */
  115. PEERS_STARTED,
  116. /**
  117. * peers are connected
  118. */
  119. PEERS_CONNECTED,
  120. /**
  121. * Peers are connected once again (this should not fail as they are already connected)
  122. */
  123. PEERS_CONNECTED_2,
  124. /**
  125. * peers are stopped
  126. */
  127. PEERS_STOPPED,
  128. /**
  129. * Final success stage
  130. */
  131. SUCCESS
  132. };
  133. /**
  134. * The testing result
  135. */
  136. static enum Stage result;
  137. /**
  138. * shortcut to exit during failure
  139. */
  140. #define FAIL_TEST(cond) do { \
  141. if (!(cond)) { \
  142. GNUNET_break(0); \
  143. if (GNUNET_SCHEDULER_NO_TASK != abort_task) \
  144. GNUNET_SCHEDULER_cancel (abort_task); \
  145. abort_task = GNUNET_SCHEDULER_NO_TASK; \
  146. GNUNET_SCHEDULER_add_now (do_shutdown, NULL); \
  147. return; \
  148. } \
  149. } while (0)
  150. /**
  151. * Shutdown nicely
  152. *
  153. * @param cls NULL
  154. * @param tc the task context
  155. */
  156. static void
  157. do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  158. {
  159. if (GNUNET_SCHEDULER_NO_TASK != abort_task)
  160. GNUNET_SCHEDULER_cancel (abort_task);
  161. if (GNUNET_SCHEDULER_NO_TASK != delayed_connect_task)
  162. GNUNET_SCHEDULER_cancel (delayed_connect_task);
  163. if (NULL != reg_handle)
  164. GNUNET_TESTBED_cancel_registration (reg_handle);
  165. GNUNET_TESTBED_controller_disconnect (controller);
  166. GNUNET_CONFIGURATION_destroy (cfg);
  167. if (NULL != cp)
  168. GNUNET_TESTBED_controller_stop (cp);
  169. GNUNET_TESTBED_host_destroy (neighbour);
  170. GNUNET_TESTBED_host_destroy (host);
  171. }
  172. /**
  173. * abort task to run on test timed out
  174. *
  175. * @param cls NULL
  176. * @param tc the task context
  177. */
  178. static void
  179. do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  180. {
  181. LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
  182. abort_task = GNUNET_SCHEDULER_NO_TASK;
  183. do_shutdown (cls, tc);
  184. }
  185. /**
  186. * Callback to be called when an operation is completed
  187. *
  188. * @param cls the callback closure from functions generating an operation
  189. * @param op the operation that has been finished
  190. * @param emsg error message in case the operation has failed; will be NULL if
  191. * operation has executed successfully.
  192. */
  193. static void
  194. op_comp_cb (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg);
  195. /**
  196. * task for delaying a connect
  197. *
  198. * @param cls NULL
  199. * @param tc the task context
  200. */
  201. static void
  202. do_delayed_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  203. {
  204. delayed_connect_task = GNUNET_SCHEDULER_NO_TASK;
  205. FAIL_TEST (NULL == common_operation);
  206. common_operation =
  207. GNUNET_TESTBED_overlay_connect (NULL, &op_comp_cb, NULL, peer1.peer,
  208. peer2.peer);
  209. }
  210. /**
  211. * Callback to be called when an operation is completed
  212. *
  213. * @param cls the callback closure from functions generating an operation
  214. * @param op the operation that has been finished
  215. * @param emsg error message in case the operation has failed; will be NULL if
  216. * operation has executed successfully.
  217. */
  218. static void
  219. op_comp_cb (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
  220. {
  221. FAIL_TEST (common_operation == op);
  222. switch (result)
  223. {
  224. case PEERS_STARTED:
  225. FAIL_TEST (NULL == peer1.operation);
  226. FAIL_TEST (NULL == peer2.operation);
  227. FAIL_TEST (NULL != common_operation);
  228. break;
  229. case PEERS_CONNECTED:
  230. FAIL_TEST (NULL == peer1.operation);
  231. FAIL_TEST (NULL == peer2.operation);
  232. FAIL_TEST (NULL != common_operation);
  233. break;
  234. default:
  235. FAIL_TEST (0);
  236. }
  237. }
  238. /**
  239. * Signature of the event handler function called by the
  240. * respective event controller.
  241. *
  242. * @param cls closure
  243. * @param event information about the event
  244. */
  245. static void
  246. controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
  247. {
  248. switch (event->type)
  249. {
  250. case GNUNET_TESTBED_ET_OPERATION_FINISHED: /* Will be reached when we destroy peers */
  251. FAIL_TEST (PEERS_STOPPED == result);
  252. FAIL_TEST (NULL == event->op_cls);
  253. FAIL_TEST (NULL == event->details.operation_finished.emsg);
  254. FAIL_TEST (NULL == event->details.operation_finished.generic);
  255. if (event->op == peer1.operation)
  256. {
  257. GNUNET_TESTBED_operation_done (peer1.operation);
  258. peer1.operation = NULL;
  259. peer1.peer = NULL;
  260. }
  261. else if (event->op == peer2.operation)
  262. {
  263. GNUNET_TESTBED_operation_done (peer2.operation);
  264. peer2.operation = NULL;
  265. peer2.peer = NULL;
  266. }
  267. else
  268. FAIL_TEST (0);
  269. if ((NULL == peer1.peer) && (NULL == peer2.peer))
  270. {
  271. result = SUCCESS;
  272. GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
  273. }
  274. break;
  275. case GNUNET_TESTBED_ET_PEER_START:
  276. FAIL_TEST (INIT == result);
  277. FAIL_TEST (event->details.peer_start.host == host);
  278. if (event->details.peer_start.peer == peer1.peer)
  279. {
  280. peer1.is_running = GNUNET_YES;
  281. GNUNET_TESTBED_operation_done (peer1.operation);
  282. peer1.operation = NULL;
  283. }
  284. else if (event->details.peer_start.peer == peer2.peer)
  285. {
  286. peer2.is_running = GNUNET_YES;
  287. GNUNET_TESTBED_operation_done (peer2.operation);
  288. peer2.operation = NULL;
  289. }
  290. else
  291. FAIL_TEST (0);
  292. if ((GNUNET_YES == peer1.is_running) && (GNUNET_YES == peer2.is_running))
  293. {
  294. result = PEERS_STARTED;
  295. common_operation =
  296. GNUNET_TESTBED_overlay_connect (NULL, &op_comp_cb, NULL, peer1.peer,
  297. peer2.peer);
  298. }
  299. break;
  300. case GNUNET_TESTBED_ET_PEER_STOP:
  301. FAIL_TEST (PEERS_CONNECTED_2 == result);
  302. if (event->details.peer_stop.peer == peer1.peer)
  303. {
  304. peer1.is_running = GNUNET_NO;
  305. GNUNET_TESTBED_operation_done (peer1.operation);
  306. peer1.operation = GNUNET_TESTBED_peer_destroy (peer1.peer);
  307. }
  308. else if (event->details.peer_stop.peer == peer2.peer)
  309. {
  310. peer2.is_running = GNUNET_NO;
  311. GNUNET_TESTBED_operation_done (peer2.operation);
  312. peer2.operation = GNUNET_TESTBED_peer_destroy (peer2.peer);
  313. }
  314. else
  315. FAIL_TEST (0);
  316. if ((GNUNET_NO == peer1.is_running) && (GNUNET_NO == peer2.is_running))
  317. result = PEERS_STOPPED;
  318. break;
  319. case GNUNET_TESTBED_ET_CONNECT:
  320. switch (result)
  321. {
  322. case PEERS_STARTED:
  323. FAIL_TEST (NULL == peer1.operation);
  324. FAIL_TEST (NULL == peer2.operation);
  325. FAIL_TEST (NULL != common_operation);
  326. FAIL_TEST ((event->details.peer_connect.peer1 == peer1.peer) &&
  327. (event->details.peer_connect.peer2 == peer2.peer));
  328. GNUNET_TESTBED_operation_done (common_operation);
  329. common_operation = NULL;
  330. result = PEERS_CONNECTED;
  331. LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers connected\n");
  332. delayed_connect_task =
  333. GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (3), &do_delayed_connect,
  334. NULL);
  335. break;
  336. case PEERS_CONNECTED:
  337. FAIL_TEST (NULL == peer1.operation);
  338. FAIL_TEST (NULL == peer2.operation);
  339. FAIL_TEST (NULL != common_operation);
  340. GNUNET_TESTBED_operation_done (common_operation);
  341. common_operation = NULL;
  342. result = PEERS_CONNECTED_2;
  343. LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers connected again\n");
  344. peer1.operation = GNUNET_TESTBED_peer_stop (NULL, peer1.peer, NULL, NULL);
  345. peer2.operation = GNUNET_TESTBED_peer_stop (NULL, peer2.peer, NULL, NULL);
  346. break;
  347. default:
  348. FAIL_TEST (0);
  349. }
  350. break;
  351. default:
  352. FAIL_TEST (0);
  353. };
  354. }
  355. /**
  356. * Functions of this signature are called when a peer has been successfully
  357. * created
  358. *
  359. * @param cls the closure from GNUNET_TESTBED_peer_create()
  360. * @param peer the handle for the created peer; NULL on any error during
  361. * creation
  362. * @param emsg NULL if peer is not NULL; else MAY contain the error description
  363. */
  364. static void
  365. peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
  366. {
  367. struct PeerContext *pc = cls;
  368. FAIL_TEST (NULL != pc->operation);
  369. FAIL_TEST (NULL != peer);
  370. FAIL_TEST (NULL == pc->peer);
  371. pc->peer = peer;
  372. GNUNET_TESTBED_operation_done (pc->operation);
  373. pc->operation = GNUNET_TESTBED_peer_start (NULL, pc->peer, NULL, NULL);
  374. }
  375. /**
  376. * Callback which will be called to after a host registration succeeded or failed
  377. *
  378. * @param cls the host which has been registered
  379. * @param emsg the error message; NULL if host registration is successful
  380. */
  381. static void
  382. registration_comp (void *cls, const char *emsg)
  383. {
  384. FAIL_TEST (cls == neighbour);
  385. reg_handle = NULL;
  386. peer1.operation =
  387. GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb,
  388. &peer1);
  389. peer2.operation =
  390. GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb,
  391. &peer2);
  392. FAIL_TEST (NULL != peer1.operation);
  393. FAIL_TEST (NULL != peer2.operation);
  394. }
  395. /**
  396. * Callback to signal successfull startup of the controller process
  397. *
  398. * @param cls the closure from GNUNET_TESTBED_controller_start()
  399. * @param cfg the configuration with which the controller has been started;
  400. * NULL if status is not GNUNET_OK
  401. * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
  402. * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
  403. */
  404. static void
  405. status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg_, int status)
  406. {
  407. uint64_t event_mask;
  408. if (GNUNET_OK != status)
  409. {
  410. cp = NULL;
  411. FAIL_TEST (0);
  412. }
  413. event_mask = 0;
  414. event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
  415. event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
  416. event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
  417. event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
  418. controller =
  419. GNUNET_TESTBED_controller_connect (host, event_mask, &controller_cb,
  420. NULL);
  421. FAIL_TEST (NULL != controller);
  422. neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, cfg, 0);
  423. FAIL_TEST (NULL != neighbour);
  424. reg_handle =
  425. GNUNET_TESTBED_register_host (controller, neighbour, &registration_comp,
  426. neighbour);
  427. FAIL_TEST (NULL != reg_handle);
  428. }
  429. /**
  430. * Main run function.
  431. *
  432. * @param cls NULL
  433. * @param args arguments passed to GNUNET_PROGRAM_run
  434. * @param cfgfile the path to configuration file
  435. * @param cfg the configuration file handle
  436. */
  437. static void
  438. run (void *cls, char *const *args, const char *cfgfile,
  439. const struct GNUNET_CONFIGURATION_Handle *config)
  440. {
  441. cfg = GNUNET_CONFIGURATION_dup (config);
  442. host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0);
  443. FAIL_TEST (NULL != host);
  444. cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, status_cb,
  445. NULL);
  446. abort_task =
  447. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
  448. (GNUNET_TIME_UNIT_MINUTES, 3), &do_abort,
  449. NULL);
  450. }
  451. /**
  452. * Main function
  453. */
  454. int
  455. main (int argc, char **argv)
  456. {
  457. int ret;
  458. char *const argv2[] = { "test_testbed_api_2peers_1controller",
  459. "-c", "test_testbed_api.conf",
  460. NULL
  461. };
  462. struct GNUNET_GETOPT_CommandLineOption options[] = {
  463. GNUNET_GETOPT_OPTION_END
  464. };
  465. result = INIT;
  466. ret =
  467. GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
  468. "test_testbed_api_2peers_1controller", "nohelp",
  469. options, &run, NULL);
  470. if ((GNUNET_OK != ret) || (SUCCESS != result))
  471. return 1;
  472. return 0;
  473. }
  474. /* end of test_testbed_api_2peers_1controller.c */