cadet_test_lib.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012 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 cadet/cadet_test_lib.c
  19. * @author Bartlomiej Polot
  20. * @brief library for writing CADET tests
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "cadet_test_lib.h"
  25. #include "gnunet_cadet_service.h"
  26. /**
  27. * Test context for a CADET Test.
  28. */
  29. struct GNUNET_CADET_TEST_Context
  30. {
  31. /**
  32. * Array of running peers.
  33. */
  34. struct GNUNET_TESTBED_Peer **peers;
  35. /**
  36. * Array of handles to the CADET for each peer.
  37. */
  38. struct GNUNET_CADET_Handle **cadetes;
  39. /**
  40. * Operation associated with the connection to the CADET.
  41. */
  42. struct GNUNET_TESTBED_Operation **ops;
  43. /**
  44. * Main function of the test to run once all CADETs are available.
  45. */
  46. GNUNET_CADET_TEST_AppMain app_main;
  47. /**
  48. * Closure for 'app_main'.
  49. */
  50. void *app_main_cls;
  51. /**
  52. * Number of peers running, size of the arrays above.
  53. */
  54. unsigned int num_peers;
  55. /**
  56. * Handler for incoming tunnels.
  57. */
  58. GNUNET_CADET_InboundChannelNotificationHandler *new_channel;
  59. /**
  60. * Cleaner for destroyed incoming tunnels.
  61. */
  62. GNUNET_CADET_ChannelEndHandler *cleaner;
  63. /**
  64. * Message handlers.
  65. */
  66. struct GNUNET_CADET_MessageHandler* handlers;
  67. /**
  68. * Application ports.
  69. */
  70. const uint32_t *ports;
  71. };
  72. /**
  73. * Context for a cadet adapter callback.
  74. */
  75. struct GNUNET_CADET_TEST_AdapterContext
  76. {
  77. /**
  78. * Peer number for the particular peer.
  79. */
  80. unsigned int peer;
  81. /**
  82. * General context.
  83. */
  84. struct GNUNET_CADET_TEST_Context *ctx;
  85. };
  86. /**
  87. * Adapter function called to establish a connection to
  88. * the CADET service.
  89. *
  90. * @param cls closure
  91. * @param cfg configuration of the peer to connect to; will be available until
  92. * GNUNET_TESTBED_operation_done() is called on the operation returned
  93. * from GNUNET_TESTBED_service_connect()
  94. * @return service handle to return in 'op_result', NULL on error
  95. */
  96. static void *
  97. cadet_connect_adapter (void *cls,
  98. const struct GNUNET_CONFIGURATION_Handle *cfg)
  99. {
  100. struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
  101. struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
  102. struct GNUNET_CADET_Handle *h;
  103. h = GNUNET_CADET_connect (cfg,
  104. (void *) (long) actx->peer,
  105. ctx->new_channel,
  106. ctx->cleaner,
  107. ctx->handlers,
  108. ctx->ports);
  109. return h;
  110. }
  111. /**
  112. * Adapter function called to destroy a connection to
  113. * the CADET service.
  114. *
  115. * @param cls closure
  116. * @param op_result service handle returned from the connect adapter
  117. */
  118. static void
  119. cadet_disconnect_adapter (void *cls,
  120. void *op_result)
  121. {
  122. struct GNUNET_CADET_Handle *cadet = op_result;
  123. struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
  124. GNUNET_free (actx);
  125. GNUNET_CADET_disconnect (cadet);
  126. }
  127. /**
  128. * Callback to be called when a service connect operation is completed.
  129. *
  130. * @param cls The callback closure from functions generating an operation.
  131. * @param op The operation that has been finished.
  132. * @param ca_result The service handle returned from
  133. * GNUNET_TESTBED_ConnectAdapter() (cadet handle).
  134. * @param emsg Error message in case the operation has failed.
  135. * NULL if operation has executed successfully.
  136. */
  137. static void
  138. cadet_connect_cb (void *cls,
  139. struct GNUNET_TESTBED_Operation *op,
  140. void *ca_result,
  141. const char *emsg)
  142. {
  143. struct GNUNET_CADET_TEST_Context *ctx = cls;
  144. unsigned int i;
  145. if (NULL != emsg)
  146. {
  147. fprintf (stderr, "Failed to connect to CADET service: %s\n",
  148. emsg);
  149. GNUNET_SCHEDULER_shutdown ();
  150. return;
  151. }
  152. for (i = 0; i < ctx->num_peers; i++)
  153. if (op == ctx->ops[i])
  154. {
  155. ctx->cadetes[i] = ca_result;
  156. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i);
  157. }
  158. for (i = 0; i < ctx->num_peers; i++)
  159. if (NULL == ctx->cadetes[i])
  160. return; /* still some CADET connections missing */
  161. /* all CADET connections ready! */
  162. ctx->app_main (ctx->app_main_cls,
  163. ctx,
  164. ctx->num_peers,
  165. ctx->peers,
  166. ctx->cadetes);
  167. }
  168. void
  169. GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx)
  170. {
  171. unsigned int i;
  172. for (i = 0; i < ctx->num_peers; i++)
  173. {
  174. GNUNET_assert (NULL != ctx->ops[i]);
  175. GNUNET_TESTBED_operation_done (ctx->ops[i]);
  176. ctx->ops[i] = NULL;
  177. }
  178. GNUNET_free (ctx->ops);
  179. GNUNET_free (ctx->cadetes);
  180. GNUNET_free (ctx);
  181. GNUNET_SCHEDULER_shutdown ();
  182. }
  183. /**
  184. * Callback run when the testbed is ready (peers running and connected to
  185. * each other)
  186. *
  187. * @param cls Closure (context).
  188. * @param h the run handle
  189. * @param num_peers Number of peers that are running.
  190. * @param peers Handles to each one of the @c num_peers peers.
  191. * @param links_succeeded the number of overlay link connection attempts that
  192. * succeeded
  193. * @param links_failed the number of overlay link connection attempts that
  194. * failed
  195. */
  196. static void
  197. cadet_test_run (void *cls,
  198. struct GNUNET_TESTBED_RunHandle *h,
  199. unsigned int num_peers,
  200. struct GNUNET_TESTBED_Peer **peers,
  201. unsigned int links_succeeded,
  202. unsigned int links_failed)
  203. {
  204. struct GNUNET_CADET_TEST_Context *ctx = cls;
  205. unsigned int i;
  206. if (num_peers != ctx->num_peers)
  207. {
  208. GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n",
  209. num_peers, ctx->num_peers);
  210. exit (1);
  211. }
  212. ctx->peers = peers;
  213. for (i = 0; i < num_peers; i++)
  214. {
  215. struct GNUNET_CADET_TEST_AdapterContext *newctx;
  216. newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext);
  217. newctx->peer = i;
  218. newctx->ctx = ctx;
  219. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to cadet %u\n", i);
  220. ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
  221. peers[i],
  222. "cadet",
  223. &cadet_connect_cb,
  224. ctx,
  225. &cadet_connect_adapter,
  226. &cadet_disconnect_adapter,
  227. newctx);
  228. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "op handle %p\n", ctx->ops[i]);
  229. }
  230. }
  231. void
  232. GNUNET_CADET_TEST_run (const char *testname,
  233. const char *cfgname,
  234. unsigned int num_peers,
  235. GNUNET_CADET_TEST_AppMain tmain,
  236. void *tmain_cls,
  237. GNUNET_CADET_InboundChannelNotificationHandler new_channel,
  238. GNUNET_CADET_ChannelEndHandler cleaner,
  239. struct GNUNET_CADET_MessageHandler* handlers,
  240. const uint32_t *ports)
  241. {
  242. struct GNUNET_CADET_TEST_Context *ctx;
  243. ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
  244. ctx->num_peers = num_peers;
  245. ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *));
  246. ctx->cadetes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_CADET_Handle *));
  247. ctx->app_main = tmain;
  248. ctx->app_main_cls = tmain_cls;
  249. ctx->new_channel = new_channel;
  250. ctx->cleaner = cleaner;
  251. ctx->handlers = handlers;
  252. ctx->ports = ports;
  253. GNUNET_TESTBED_test_run (testname,
  254. cfgname,
  255. num_peers,
  256. 0LL, NULL, NULL,
  257. &cadet_test_run, ctx);
  258. }
  259. /* end of cadet_test_lib.c */