aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/testbed_api_testbed.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-08-29 22:10:16 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-08-29 22:10:16 +0000
commit7252393613f08dea54b5838691e6e608818901c3 (patch)
tree1d5d21a8f884b8981ff176d9453672ea422c69f0 /src/testbed/testbed_api_testbed.c
parent308eab2402422262d9b895f98008a4d5b176be59 (diff)
downloadgnunet-7252393613f08dea54b5838691e6e608818901c3.tar.gz
gnunet-7252393613f08dea54b5838691e6e608818901c3.zip
GNUNET_TESTBED_run and test cases
Diffstat (limited to 'src/testbed/testbed_api_testbed.c')
-rw-r--r--src/testbed/testbed_api_testbed.c284
1 files changed, 214 insertions, 70 deletions
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c
index fd0bbfaa8..95eb5d093 100644
--- a/src/testbed/testbed_api_testbed.c
+++ b/src/testbed/testbed_api_testbed.c
@@ -24,6 +24,7 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Sree Harsha Totakura 25 * @author Sree Harsha Totakura
26 */ 26 */
27
27#include "platform.h" 28#include "platform.h"
28#include "gnunet_testbed_service.h" 29#include "gnunet_testbed_service.h"
29 30
@@ -31,7 +32,7 @@
31 * Generic loggins shorthand 32 * Generic loggins shorthand
32 */ 33 */
33#define LOG(kind,...) \ 34#define LOG(kind,...) \
34 GNUNET_log_from (kind, "testbed-api", __VA_ARGS__) 35 GNUNET_log_from (kind, "testbed-api-testbed", __VA_ARGS__)
35 36
36/** 37/**
37 * Opaque handle to an abstract operation to be executed by the testing framework. 38 * Opaque handle to an abstract operation to be executed by the testing framework.
@@ -55,46 +56,29 @@ struct DLLOperation
55 /** 56 /**
56 * Context information for GNUNET_TESTBED_run() 57 * Context information for GNUNET_TESTBED_run()
57 */ 58 */
58 struct RunContext *rc; 59 struct GNUNET_TESTBED_RunHandle *rh;
59
60 /**
61 * The next pointer for DLL
62 */
63 struct DLLOperation *next;
64
65 /**
66 * The prev pointer for DLL
67 */
68 struct DLLOperation *prev;
69};
70
71 60
72/**
73 * DLL of peers
74 */
75struct DLLPeer
76{
77 /** 61 /**
78 * Handle to testbed peer 62 * Closure
79 */ 63 */
80 struct GNUNET_TESTBED_Peer *peer; 64 void *cls;
81 65
82 /** 66 /**
83 * The next pointer for DLL 67 * The next pointer for DLL
84 */ 68 */
85 struct DLLPeer *next; 69 struct DLLOperation *next;
86 70
87 /** 71 /**
88 * The pre pointer for DLL 72 * The prev pointer for DLL
89 */ 73 */
90 struct DLLPeer *prev; 74 struct DLLOperation *prev;
91}; 75};
92 76
93 77
94/** 78/**
95 * Context information for GNUNET_TESTBED_run() 79 * Testbed Run Handle
96 */ 80 */
97struct RunContext 81struct GNUNET_TESTBED_RunHandle
98{ 82{
99 /** 83 /**
100 * The controller handle 84 * The controller handle
@@ -142,24 +126,30 @@ struct RunContext
142 struct DLLOperation *dll_op_tail; 126 struct DLLOperation *dll_op_tail;
143 127
144 /** 128 /**
145 * The head element of DLL peers 129 * Array of peers which we create
146 */ 130 */
147 struct DLLPeer *dll_peer_head; 131 struct GNUNET_TESTBED_Peer **peers;
148
149 /**
150 * The tail element of DLL peers
151 */
152 struct DLLPeer *dll_peer_tail;
153 132
154 /** 133 /**
155 * The event mask for the controller 134 * The event mask for the controller
156 */ 135 */
157 uint64_t event_mask; 136 uint64_t event_mask;
137
138 /**
139 * Current peer count for an operation; Set this to 0 and increment for each
140 * successful operation on a peer
141 */
142 unsigned int peer_count;
158 143
159 /** 144 /**
160 * number of peers to start 145 * number of peers to start
161 */ 146 */
162 unsigned int num_peers; 147 unsigned int num_peers;
148
149 /**
150 * Are we cleaning up?
151 */
152 int in_shutdown;
163 153
164}; 154};
165 155
@@ -241,6 +231,31 @@ GNUNET_TESTBED_destroy (struct GNUNET_TESTBED_Testbed *testbed)
241 231
242 232
243/** 233/**
234 * Task for starting peers
235 *
236 * @param cls the RunHandle
237 * @param tc the task context from scheduler
238 */
239static void
240start_peers_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
241{
242 struct GNUNET_TESTBED_RunHandle *rh = cls;
243 struct DLLOperation *dll_op;
244 unsigned int peer;
245
246 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting Peers\n");
247 for (peer = 0; peer < rh->num_peers; peer++)
248 {
249 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
250 dll_op->op = GNUNET_TESTBED_peer_start (rh->peers[peer]);
251 dll_op->cls = rh->peers[peer];
252 GNUNET_CONTAINER_DLL_insert_tail (rh->dll_op_head, rh->dll_op_tail, dll_op);
253 }
254 rh->peer_count = 0;
255}
256
257
258/**
244 * Functions of this signature are called when a peer has been successfully 259 * Functions of this signature are called when a peer has been successfully
245 * created 260 * created
246 * 261 *
@@ -253,25 +268,119 @@ static void
253peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg) 268peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
254{ 269{
255 struct DLLOperation *dll_op = cls; 270 struct DLLOperation *dll_op = cls;
256 struct RunContext *rc; 271 struct GNUNET_TESTBED_RunHandle *rh;
257 struct DLLPeer *dll_peer;
258 272
259 GNUNET_assert (NULL != dll_op); 273 GNUNET_assert (NULL != dll_op);
260 rc = dll_op->rc; 274 rh = dll_op->rh;
261 GNUNET_assert (NULL != rc); 275 GNUNET_assert (NULL != rh);
262 GNUNET_CONTAINER_DLL_remove (rc->dll_op_head, rc->dll_op_tail, dll_op); 276 GNUNET_CONTAINER_DLL_remove (rh->dll_op_head, rh->dll_op_tail, dll_op);
263 GNUNET_TESTBED_operation_done (dll_op->op); 277 GNUNET_TESTBED_operation_done (dll_op->op);
264 GNUNET_free (dll_op); 278 GNUNET_free (dll_op);
265 if (NULL == peer) 279 if (NULL == peer)
266 { 280 {
267 if (NULL != emsg) 281 if (NULL != emsg)
268 LOG (GNUNET_ERROR_TYPE_WARNING, "Error while creating a peer: %s\n", emsg); 282 LOG (GNUNET_ERROR_TYPE_WARNING, "Error while creating a peer: %s\n",
283 emsg);
284 /* FIXME: GNUNET_TESTBED_shutdown_run()? */
285 return;
286 }
287 rh->peers[rh->peer_count] = peer;
288 rh->peer_count++;
289 if (rh->peer_count < rh->num_peers)
290 return;
291 LOG (GNUNET_ERROR_TYPE_DEBUG, "Required peers created successfully\n");
292 GNUNET_SCHEDULER_add_now (&start_peers_task, rh);
293}
294
295
296/**
297 * Assuming all peers have been destroyed cleanup run handle
298 *
299 * @param cls the run handle
300 * @param tc the task context from scheduler
301 */
302static void
303shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
304{
305 struct GNUNET_TESTBED_RunHandle *rh = cls;
306 struct DLLOperation *dll_op;
307
308 GNUNET_assert (NULL == rh->peers);
309 if (NULL != rh->c)
310 GNUNET_TESTBED_controller_disconnect (rh->c);
311 if (NULL != rh->cproc)
312 GNUNET_TESTBED_controller_stop (rh->cproc);
313 if (NULL != rh->h)
314 GNUNET_TESTBED_host_destroy (rh->h);
315 if (NULL != rh->dll_op_head)
316 {
317 LOG (GNUNET_ERROR_TYPE_WARNING,
318 _("Some operations are still pending. Cancelling them\n"));
319 while (NULL != (dll_op = rh->dll_op_head))
320 {
321 GNUNET_TESTBED_operation_cancel (dll_op->op);
322 GNUNET_CONTAINER_DLL_remove (rh->dll_op_head, rh->dll_op_tail, dll_op);
323 GNUNET_free (dll_op);
324 }
325 }
326 GNUNET_free (rh);
327}
328
329
330/**
331 * Signature of the event handler function called by the
332 * respective event controller.
333 *
334 * @param cls closure
335 * @param event information about the event
336 */
337static void
338event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
339{
340 struct GNUNET_TESTBED_RunHandle *rh = cls;
341 struct DLLOperation *dll_op;
342
343 if ((GNUNET_YES == rh->in_shutdown) &&
344 (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type))
345 {
346 for (dll_op = rh->dll_op_head; NULL != dll_op; dll_op = dll_op->next)
347 {
348 if (event->details.operation_finished.operation == dll_op->op)
349 break;
350 }
351 if (NULL == dll_op)
352 goto call_cc;
353 GNUNET_CONTAINER_DLL_remove (rh->dll_op_head, rh->dll_op_tail, dll_op);
354 GNUNET_TESTBED_operation_done (dll_op->op);
355 GNUNET_free (dll_op);
356 rh->peer_count++;
357 if (rh->peer_count < rh->num_peers)
358 return;
359 GNUNET_free (rh->peers);
360 rh->peers = NULL;
361 LOG (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully destroyed\n");
362 GNUNET_SCHEDULER_add_now (&shutdown_run_task, rh);
269 return; 363 return;
270 } 364 }
271 dll_peer = GNUNET_malloc (sizeof (struct DLLPeer)); 365
272 dll_peer->peer = peer; 366 call_cc:
273 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_peer_head, rc->dll_peer_tail, 367 rh->cc (rh->cc_cls, event);
274 dll_peer); 368 if (GNUNET_TESTBED_ET_PEER_START != event->type)
369 return;
370 for (dll_op = rh->dll_op_head; NULL != dll_op; dll_op = dll_op->next)
371 if ((NULL != dll_op->cls) &&
372 (event->details.peer_start.peer == dll_op->cls))
373 break;
374 GNUNET_assert (NULL != dll_op);
375 GNUNET_CONTAINER_DLL_remove (rh->dll_op_head, rh->dll_op_tail, dll_op);
376 GNUNET_TESTBED_operation_done (dll_op->op);
377 GNUNET_free (dll_op);
378 rh->peer_count++;
379 if (rh->peer_count < rh->num_peers)
380 return;
381 LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers started successfully\n");
382 GNUNET_SCHEDULER_add_continuation (rh->master, rh->master_cls,
383 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
275} 384}
276 385
277 386
@@ -289,7 +398,7 @@ static void
289controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, 398controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
290 int status) 399 int status)
291{ 400{
292 struct RunContext *rc = cls; 401 struct GNUNET_TESTBED_RunHandle *rh = cls;
293 struct DLLOperation *dll_op; 402 struct DLLOperation *dll_op;
294 unsigned int peer; 403 unsigned int peer;
295 404
@@ -298,17 +407,20 @@ controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
298 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed startup failed\n"); 407 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed startup failed\n");
299 return; 408 return;
300 } 409 }
301 rc->c = GNUNET_TESTBED_controller_connect (cfg, rc->h, rc->event_mask, rc->cc, 410 rh->c = GNUNET_TESTBED_controller_connect (cfg, rh->h, rh->event_mask,
302 rc->cc_cls); 411 &event_cb, rh);
303 GNUNET_assert (NULL != rc->c); 412 rh->peers = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Peer *)
304 for (peer = 0; peer < rc->num_peers; peer++) 413 * rh->num_peers);
414 GNUNET_assert (NULL != rh->c);
415 rh->peer_count = 0;
416 for (peer = 0; peer < rh->num_peers; peer++)
305 { 417 {
306 dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); 418 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
307 dll_op->rc = rc; 419 dll_op->rh = rh;
308 dll_op->op = GNUNET_TESTBED_peer_create (rc->c, rc->h, cfg, peer_create_cb, 420 dll_op->op = GNUNET_TESTBED_peer_create (rh->c, rh->h, cfg, peer_create_cb,
309 dll_op); 421 dll_op);
310 GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, dll_op); 422 GNUNET_CONTAINER_DLL_insert_tail (rh->dll_op_head, rh->dll_op_tail, dll_op);
311 } 423 }
312} 424}
313 425
314 426
@@ -334,9 +446,9 @@ controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
334 * @param cc controller callback to invoke on events 446 * @param cc controller callback to invoke on events
335 * @param cc_cls closure for cc 447 * @param cc_cls closure for cc
336 * @param master task to run once the testbed is ready 448 * @param master task to run once the testbed is ready
337 * @param master_cls closure for 'task'. 449 * @return the handle for this testbed run
338 */ 450 */
339void 451struct GNUNET_TESTBED_RunHandle *
340GNUNET_TESTBED_run (const char *host_filename, 452GNUNET_TESTBED_run (const char *host_filename,
341 const struct GNUNET_CONFIGURATION_Handle *cfg, 453 const struct GNUNET_CONFIGURATION_Handle *cfg,
342 unsigned int num_peers, 454 unsigned int num_peers,
@@ -346,25 +458,57 @@ GNUNET_TESTBED_run (const char *host_filename,
346 GNUNET_SCHEDULER_Task master, 458 GNUNET_SCHEDULER_Task master,
347 void *master_cls) 459 void *master_cls)
348{ 460{
349 struct RunContext *rc; 461 struct GNUNET_TESTBED_RunHandle *rh;
350 462
351 rc = GNUNET_malloc (sizeof (struct RunContext)); 463 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START);
352 GNUNET_break (NULL != host_filename); /* Currently we do not support host 464 rh = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_RunHandle));
465 GNUNET_break (NULL == host_filename); /* Currently we do not support host
353 files */ 466 files */
354 host_filename = NULL; 467 host_filename = NULL;
355 rc->h = GNUNET_TESTBED_host_create (NULL, NULL, 0); 468 rh->h = GNUNET_TESTBED_host_create (NULL, NULL, 0);
356 GNUNET_assert (NULL != rc->h); 469 GNUNET_assert (NULL != rh->h);
357 rc->cproc = GNUNET_TESTBED_controller_start ("127.0.0.1", rc->h, cfg, 470 rh->cproc = GNUNET_TESTBED_controller_start ("127.0.0.1", rh->h, cfg,
358 &controller_status_cb, rc); 471 &controller_status_cb, rh);
359 GNUNET_assert (NULL != rc->cproc); 472 GNUNET_assert (NULL != rh->cproc);
360 rc->num_peers = num_peers; 473 rh->num_peers = num_peers;
361 rc->event_mask = event_mask; 474 rh->event_mask = event_mask;
362 rc->cc = cc; 475 rh->cc = cc;
363 rc->cc_cls = cc_cls; 476 rh->cc_cls = cc_cls;
364 rc->master = master; 477 rh->master = master;
365 rc->master_cls = master_cls; 478 rh->master_cls = master_cls;
479 rh->in_shutdown = GNUNET_NO;
480 return rh;
366} 481}
367 482
368 483
484/**
485 * Stops the testbed run and releases any used resources
486 *
487 * @param rh the tesbed run handle
488 */
489void
490GNUNET_TESTBED_shutdown_run (struct GNUNET_TESTBED_RunHandle *rh)
491{
492 struct DLLOperation *dll_op;
493 unsigned int peer;
494
495 rh->in_shutdown = GNUNET_YES;
496 if (NULL != rh->c)
497 {
498 if (NULL != rh->peers)
499 {
500 rh->peer_count = 0;
501 for (peer = 0; peer < rh->num_peers; peer++)
502 {
503 dll_op = GNUNET_malloc (sizeof (struct DLLOperation));
504 dll_op->op = GNUNET_TESTBED_peer_destroy (rh->peers[peer]);
505 GNUNET_CONTAINER_DLL_insert_tail (rh->dll_op_head, rh->dll_op_tail,
506 dll_op);
507 }
508 return;
509 }
510 }
511 GNUNET_SCHEDULER_add_now (&shutdown_run_task, rh);
512}
369 513
370/* end of testbed_api_testbed.c */ 514/* end of testbed_api_testbed.c */