2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
21 * @file mesh/mesh_test_lib.c
22 * @author Bartlomiej Polot
23 * @brief library for writing MESH tests
26 #include "gnunet_util_lib.h"
27 #include "gnunet_testing_lib.h"
28 #include "mesh_test_lib.h"
29 #include "gnunet_mesh_service.h"
32 * Test context for a MESH Test.
34 struct GNUNET_MESH_TEST_Context
37 * Array of running peers.
39 struct GNUNET_TESTBED_Peer **peers;
42 * Array of handles to the MESH for each peer.
44 struct GNUNET_MESH_Handle **meshes;
47 * Operation associated with the connection to the MESH.
49 struct GNUNET_TESTBED_Operation **ops;
52 * Main function of the test to run once all MESHs are available.
54 GNUNET_MESH_TEST_AppMain app_main;
57 * Closure for 'app_main'.
62 * Number of peers running, size of the arrays above.
64 unsigned int num_peers;
67 * Handler for incoming tunnels.
69 GNUNET_MESH_InboundTunnelNotificationHandler *new_tunnel;
72 * Cleaner for destroyed incoming tunnels.
74 GNUNET_MESH_TunnelEndHandler *cleaner;
79 struct GNUNET_MESH_MessageHandler* handlers;
84 const GNUNET_MESH_ApplicationType* stypes;
90 * Context for a mesh adapter callback.
92 struct GNUNET_MESH_TEST_AdapterContext
95 * Peer number for the particular peer.
102 struct GNUNET_MESH_TEST_Context *ctx;
107 * Adapter function called to establish a connection to
111 * @param cfg configuration of the peer to connect to; will be available until
112 * GNUNET_TESTBED_operation_done() is called on the operation returned
113 * from GNUNET_TESTBED_service_connect()
114 * @return service handle to return in 'op_result', NULL on error
117 mesh_connect_adapter (void *cls,
118 const struct GNUNET_CONFIGURATION_Handle *cfg)
120 struct GNUNET_MESH_TEST_AdapterContext *actx = cls;
121 struct GNUNET_MESH_TEST_Context *ctx = actx->ctx;
122 struct GNUNET_MESH_Handle *h;
124 h = GNUNET_MESH_connect (cfg,
125 (void *) (long) actx->peer,
135 * Adapter function called to destroy a connection to
139 * @param op_result service handle returned from the connect adapter
142 mesh_disconnect_adapter (void *cls,
145 struct GNUNET_MESH_Handle *mesh = op_result;
146 struct GNUNET_MESH_TEST_AdapterContext *actx = cls;
149 GNUNET_MESH_disconnect (mesh);
154 * Callback to be called when a service connect operation is completed.
156 * @param cls The callback closure from functions generating an operation.
157 * @param op The operation that has been finished.
158 * @param ca_result The service handle returned from
159 * GNUNET_TESTBED_ConnectAdapter() (mesh handle).
160 * @param emsg Error message in case the operation has failed.
161 * NULL if operation has executed successfully.
164 mesh_connect_cb (void *cls,
165 struct GNUNET_TESTBED_Operation *op,
169 struct GNUNET_MESH_TEST_Context *ctx = cls;
174 fprintf (stderr, "Failed to connect to MESH service: %s\n",
176 GNUNET_SCHEDULER_shutdown ();
179 for (i = 0; i < ctx->num_peers; i++)
180 if (op == ctx->ops[i])
181 ctx->meshes[i] = ca_result;
182 for (i = 0; i < ctx->num_peers; i++)
183 if (NULL == ctx->meshes[i])
184 return; /* still some MESH connections missing */
185 /* all MESH connections ready! */
186 ctx->app_main (ctx->app_main_cls,
195 * Clean up the testbed.
197 * @param ctx handle for the testbed
200 GNUNET_MESH_TEST_cleanup (struct GNUNET_MESH_TEST_Context *ctx)
204 for (i = 0; i < ctx->num_peers; i++)
206 GNUNET_assert (NULL != ctx->ops[i]);
207 GNUNET_TESTBED_operation_done (ctx->ops[i]);
210 GNUNET_free (ctx->ops);
211 GNUNET_free (ctx->meshes);
213 GNUNET_SCHEDULER_shutdown ();
218 * Callback run when the testbed is ready (peers running and connected to
221 * @param cls Closure (context).
222 * @param num_peers Number of peers that are running.
223 * @param peers Handles to each one of the @c num_peers peers.
226 mesh_test_run (void *cls,
227 unsigned int num_peers,
228 struct GNUNET_TESTBED_Peer **peers)
230 struct GNUNET_MESH_TEST_Context *ctx = cls;
233 GNUNET_assert (num_peers == ctx->num_peers);
235 for (i = 0; i < num_peers; i++)
237 struct GNUNET_MESH_TEST_AdapterContext *newctx;
238 newctx = GNUNET_malloc (sizeof (struct GNUNET_MESH_TEST_AdapterContext));
241 ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
246 &mesh_connect_adapter,
247 &mesh_disconnect_adapter,
254 * Run a test using the given name, configuration file and number of
256 * All mesh callbacks will receive the peer number as the closure.
258 * @param testname Name of the test (for logging).
259 * @param cfgname Name of the configuration file.
260 * @param num_peers Number of peers to start.
261 * @param tmain Main function to run once the testbed is ready.
262 * @param tmain_cls Closure for 'tmain'.
263 * @param new_tunnel Handler for incoming tunnels.
264 * @param cleaner Cleaner for destroyed incoming tunnels.
265 * @param handlers Message handlers.
266 * @param stypes Application types.
269 GNUNET_MESH_TEST_run (const char *testname,
271 unsigned int num_peers,
272 GNUNET_MESH_TEST_AppMain tmain,
274 GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
275 GNUNET_MESH_TunnelEndHandler cleaner,
276 struct GNUNET_MESH_MessageHandler* handlers,
277 const GNUNET_MESH_ApplicationType* stypes)
279 struct GNUNET_MESH_TEST_Context *ctx;
281 ctx = GNUNET_malloc (sizeof (struct GNUNET_MESH_TEST_Context));
282 ctx->num_peers = num_peers;
283 ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *));
284 ctx->meshes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_MESH_Handle *));
285 ctx->app_main = tmain;
286 ctx->app_main_cls = tmain_cls;
287 ctx->new_tunnel = new_tunnel;
288 ctx->cleaner = cleaner;
289 ctx->handlers = handlers;
290 ctx->stypes = stypes;
291 GNUNET_TESTBED_test_run (testname,
295 &mesh_test_run, ctx);
298 /* end of mesh_test_lib.c */