2 This file is part of GNUnet
3 (C) 2008--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.
22 * @file testbed/testbed_api_testbed.c
23 * @brief high-level testbed management
24 * @author Christian Grothoff
25 * @author Sree Harsha Totakura
28 #include "gnunet_testbed_service.h"
31 * Generic loggins shorthand
33 #define LOG(kind,...) \
34 GNUNET_log_from (kind, "testbed-api", __VA_ARGS__)
37 * Opaque handle to an abstract operation to be executed by the testing framework.
39 struct GNUNET_TESTBED_Testbed
51 * The testbed operation handle
53 struct GNUNET_TESTBED_Operation *op;
56 * Context information for GNUNET_TESTBED_run()
58 struct RunContext *rc;
61 * The next pointer for DLL
63 struct DLLOperation *next;
66 * The prev pointer for DLL
68 struct DLLOperation *prev;
78 * Handle to testbed peer
80 struct GNUNET_TESTBED_Peer *peer;
83 * The next pointer for DLL
88 * The pre pointer for DLL
95 * Context information for GNUNET_TESTBED_run()
100 * The controller handle
102 struct GNUNET_TESTBED_Controller *c;
105 * Handle to the host on which the controller runs
107 struct GNUNET_TESTBED_Host *h;
110 * The handle to the controller process
112 struct GNUNET_TESTBED_ControllerProc *cproc;
115 * The callback to use as controller callback
117 GNUNET_TESTBED_ControllerCallback cc;
120 * The pointer to the controller callback
125 * Master task to call when testbed initialization is done
127 GNUNET_SCHEDULER_Task master;
130 * The closure for the master task
135 * The head element of DLL operations
137 struct DLLOperation *dll_op_head;
140 * The tail element of DLL operations
142 struct DLLOperation *dll_op_tail;
145 * The head element of DLL peers
147 struct DLLPeer *dll_peer_head;
150 * The tail element of DLL peers
152 struct DLLPeer *dll_peer_tail;
155 * The event mask for the controller
160 * number of peers to start
162 unsigned int num_peers;
170 * Configure and run a testbed using the given
171 * master controller on 'num_hosts' starting
172 * 'num_peers' using the given peer configuration.
174 * @param controller master controller for the testbed
175 * (must not be destroyed until after the
176 * testbed is destroyed).
177 * @param num_hosts number of hosts in 'hosts', 0 to only
179 * @param hosts list of hosts to use for the testbed
180 * @param num_peers number of peers to start
181 * @param peer_cfg peer configuration template to use
182 * @param underlay_topology underlay topology to create
183 * @param va topology-specific options
184 * @return handle to the testbed
186 struct GNUNET_TESTBED_Testbed *
187 GNUNET_TESTBED_create_va (struct GNUNET_TESTBED_Controller *controller,
188 unsigned int num_hosts,
189 struct GNUNET_TESTBED_Host **hosts,
190 unsigned int num_peers,
191 const struct GNUNET_CONFIGURATION_Handle *peer_cfg,
192 enum GNUNET_TESTBED_TopologyOption underlay_topology,
201 * Configure and run a testbed using the given
202 * master controller on 'num_hosts' starting
203 * 'num_peers' using the given peer configuration.
205 * @param controller master controller for the testbed
206 * (must not be destroyed until after the
207 * testbed is destroyed).
208 * @param num_hosts number of hosts in 'hosts', 0 to only
210 * @param hosts list of hosts to use for the testbed
211 * @param num_peers number of peers to start
212 * @param peer_cfg peer configuration template to use
213 * @param underlay_topology underlay topology to create
214 * @param ... topology-specific options
216 struct GNUNET_TESTBED_Testbed *
217 GNUNET_TESTBED_create (struct GNUNET_TESTBED_Controller *controller,
218 unsigned int num_hosts,
219 struct GNUNET_TESTBED_Host **hosts,
220 unsigned int num_peers,
221 const struct GNUNET_CONFIGURATION_Handle *peer_cfg,
222 enum GNUNET_TESTBED_TopologyOption underlay_topology,
231 * Destroy a testbed. Stops all running peers and then
232 * destroys all peers. Does NOT destroy the master controller.
234 * @param testbed testbed to destroy
237 GNUNET_TESTBED_destroy (struct GNUNET_TESTBED_Testbed *testbed)
244 * Functions of this signature are called when a peer has been successfully
247 * @param cls the closure from GNUNET_TESTBED_peer_create()
248 * @param peer the handle for the created peer; NULL on any error during
250 * @param emsg NULL if peer is not NULL; else MAY contain the error description
253 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
255 struct DLLOperation *dll_op = cls;
256 struct RunContext *rc;
257 struct DLLPeer *dll_peer;
259 GNUNET_assert (NULL != dll_op);
261 GNUNET_assert (NULL != rc);
262 GNUNET_CONTAINER_DLL_remove (rc->dll_op_head, rc->dll_op_tail, dll_op);
263 GNUNET_TESTBED_operation_done (dll_op->op);
264 GNUNET_free (dll_op);
268 LOG (GNUNET_ERROR_TYPE_WARNING, "Error while creating a peer: %s\n", emsg);
271 dll_peer = GNUNET_malloc (sizeof (struct DLLPeer));
272 dll_peer->peer = peer;
273 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_peer_head, rc->dll_peer_tail,
280 * Callback to signal successfull startup of the controller process
282 * @param cls the closure from GNUNET_TESTBED_controller_start()
283 * @param cfg the configuration with which the controller has been started;
284 * NULL if status is not GNUNET_OK
285 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
286 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
289 controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
292 struct RunContext *rc = cls;
293 struct DLLOperation *dll_op;
296 if (status != GNUNET_OK)
298 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed startup failed\n");
301 rc->c = GNUNET_TESTBED_controller_connect (cfg, rc->h, rc->event_mask, rc->cc,
303 GNUNET_assert (NULL != rc->c);
304 for (peer = 0; peer < rc->num_peers; peer++)
306 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
308 dll_op->op = GNUNET_TESTBED_peer_create (rc->c, rc->h, cfg, peer_create_cb,
310 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, dll_op);
316 * Convenience method for running a testbed with
317 * a single call. Underlay and overlay topology
318 * are configured using the "UNDERLAY" and "OVERLAY"
319 * options in the "[testbed]" section of the configuration\
320 * (with possible options given in "UNDERLAY_XXX" and/or
323 * The testbed is to be terminated using a call to
324 * "GNUNET_SCHEDULER_shutdown".
326 * @param host_filename name of the file with the 'hosts', NULL
327 * to run everything on 'localhost'
328 * @param cfg configuration to use (for testbed, controller and peers)
329 * @param num_peers number of peers to start; FIXME: maybe put that ALSO into cfg?
330 * @param event_mask bit mask with set of events to call 'cc' for;
331 * or-ed values of "1LL" shifted by the
332 * respective 'enum GNUNET_TESTBED_EventType'
333 * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) || ...")
334 * @param cc controller callback to invoke on events
335 * @param cc_cls closure for cc
336 * @param master task to run once the testbed is ready
337 * @param master_cls closure for 'task'.
340 GNUNET_TESTBED_run (const char *host_filename,
341 const struct GNUNET_CONFIGURATION_Handle *cfg,
342 unsigned int num_peers,
344 GNUNET_TESTBED_ControllerCallback cc,
346 GNUNET_SCHEDULER_Task master,
349 struct RunContext *rc;
351 rc = GNUNET_malloc (sizeof (struct RunContext));
352 GNUNET_break (NULL != host_filename); /* Currently we do not support host
354 host_filename = NULL;
355 rc->h = GNUNET_TESTBED_host_create (NULL, NULL, 0);
356 GNUNET_assert (NULL != rc->h);
357 rc->cproc = GNUNET_TESTBED_controller_start ("127.0.0.1", rc->h, cfg,
358 &controller_status_cb, rc);
359 GNUNET_assert (NULL != rc->cproc);
360 rc->num_peers = num_peers;
361 rc->event_mask = event_mask;
365 rc->master_cls = master_cls;
370 /* end of testbed_api_testbed.c */