diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-08-29 22:10:16 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-08-29 22:10:16 +0000 |
commit | 7252393613f08dea54b5838691e6e608818901c3 (patch) | |
tree | 1d5d21a8f884b8981ff176d9453672ea422c69f0 /src/testbed/testbed_api_testbed.c | |
parent | 308eab2402422262d9b895f98008a4d5b176be59 (diff) | |
download | gnunet-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.c | 284 |
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 | */ | ||
75 | struct 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 | */ |
97 | struct RunContext | 81 | struct 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 | */ | ||
239 | static void | ||
240 | start_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 | |||
253 | peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg) | 268 | peer_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 | */ | ||
302 | static void | ||
303 | shutdown_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 | */ | ||
337 | static void | ||
338 | event_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 | |||
289 | controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, | 398 | controller_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 | */ |
339 | void | 451 | struct GNUNET_TESTBED_RunHandle * |
340 | GNUNET_TESTBED_run (const char *host_filename, | 452 | GNUNET_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 | */ | ||
489 | void | ||
490 | GNUNET_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 */ |